后浪笔记一零二四

在这章之前,可以发现,nats所有的用户配置、权限管理都要改配置文件,改完还要重启服务,当然也可以不停服务重新加载配置,但是还是相当麻烦。

这一章,讲解nats去中心化的认证和授权。

去中心化:各个节点是对等的,每一个节点的角色都是类似的,虽然可以通过某些协议来选举出主节点,但是任何节点都可以升级为主节点。这类系统没有这种管理节点,全部都是对等节点。

nats去中心化认证和授权,引入了一个全新的概念,叫做operator。

operator: 单个认证域下的nats-server配置。

account: nats的环境隔离(多租户)

user: 用户

operator和account之间是一对多的关系,account和user之间也是一对多的关系,operator和account和user三者之间,从上到下,构成一个树形结构。

从配置的过程来看,我们是先定义一个operator,然后,让这个服务端能够信任这个operator,之后我就可以通过客户端去配置整个这个账户用户这些信息。

nats提供了一个工具,nsc: A tool for creating nats account and user access configurations.

通过nsc,我可以配置这些账户用户信息,同时,我能把这些信息发布到这个服务端去。

  1. 创建operator:
$ nsc add operator cjop --sys 

[ OK ] generated and stored operator key "OBJU6EEH55NQCLQ5PZHUKCB5LZM7TH3DJ7Q5OPGOIFYHA4JC4EZPJ3OZ"
[ OK ] added operator "cjop"
[ OK ] When running your own nats-server, make sure they run at least version 2.2.0
[ OK ] created system_account: name:SYS id:AAHRQ6BSALGBDQY7YCTLFE2XMRX7FF4BZNSCSKAY2VDHQMBCPA6UZCFA
[ OK ] created system account user: name:sys id:UBMHD6NWNCCQ7GJTIJLQLWBN4AVAE5B4OK74MXVXE7H2UZ7VAUPHCOJX
[ OK ] system account user creds file stored in `~/.local/share/nats/nsc/keys/creds/cjop/SYS/sys.creds`

$ tree ~/.local/share/nats/nsc

├── keys
│   ├── creds
│   │   └── cjop
│   │       └── SYS
│   │           └── sys.creds
│   └── keys
│       ├── A
│       │   ├── AH
│       │   │   └── AAHRQ6BSALGBDQY7YCTLFE2XMRX7FF4BZNSCSKAY2VDHQMBCPA6UZCFA.nk
│       │   └── CL
│       │       └── ACLQ4WBD4PHRW6CV5FJTN5ZVQQUEVXTCFVGLKPQREZAU4EGB2P2Y7BHF.nk
│       ├── O
│       │   └── BJ
│       │       └── OBJU6EEH55NQCLQ5PZHUKCB5LZM7TH3DJ7Q5OPGOIFYHA4JC4EZPJ3OZ.nk
│       └── U
│           └── BM
│               └── UBMHD6NWNCCQ7GJTIJLQLWBN4AVAE5B4OK74MXVXE7H2UZ7VAUPHCOJX.nk
└── stores
    └── cjop
        ├── accounts
        │   └── SYS
        │       ├── SYS.jwt
        │       └── users
        │           └── sys.jwt
        └── cjop.jwt

我们所有的operatorr,它在和服务端交互来发布这些用户信息的时候,需要通过这种系统用户的方式来和服务端交互。

那我们需要申请一个默认的这个系统账户,包括它的account和user信息,因为之后客户端和服务端需要用到这些信息来交互。

~/.local/share/nats/nsc/stores/cjop 目录下存放了各种jwt文件,这些jwt文件里就包括了这些账户的这个信息,包括账户的一些配置信息,用户的信息,然后包括这个operator的这个jwt,其包含了operator的一些配置信息。

它整个的配置信息,都是在jwt里。

  1. 创建账户
$ nsc add account oa

[ OK ] generated and stored account key "AAPSGKDH4DHGH42RT2KPRISYLDA4W63OTKEJWBB3YOOKOATA2OALOU7L"
[ OK ] added account "oa"

$ tree ~/.local/share/nats/nsc

├── keys
│   ├── creds
│   │   └── cjop
│   │       └── SYS
│   │           └── sys.creds
│   └── keys
│       ├── A
│       │   ├── AH
│       │   │   └── AAHRQ6BSALGBDQY7YCTLFE2XMRX7FF4BZNSCSKAY2VDHQMBCPA6UZCFA.nk
│       │   ├── AP
│       │   │   └── AAPSGKDH4DHGH42RT2KPRISYLDA4W63OTKEJWBB3YOOKOATA2OALOU7L.nk
│       │   └── CL
│       │       └── ACLQ4WBD4PHRW6CV5FJTN5ZVQQUEVXTCFVGLKPQREZAU4EGB2P2Y7BHF.nk
│       ├── O
│       │   └── BJ
│       │       └── OBJU6EEH55NQCLQ5PZHUKCB5LZM7TH3DJ7Q5OPGOIFYHA4JC4EZPJ3OZ.nk
│       └── U
│           └── BM
│               └── UBMHD6NWNCCQ7GJTIJLQLWBN4AVAE5B4OK74MXVXE7H2UZ7VAUPHCOJX.nk
└── stores
    └── cjop
        ├── accounts
        │   ├── oa
        │   │   └── oa.jwt
        │   └── SYS
        │       ├── SYS.jwt
        │       └── users
        │           └── sys.jwt
        └── cjop.jwt
  1. 在oa这个账户下添加用户
$ nsc add user cjzhao --account oa

[ OK ] generated and stored user key "UBUNYMHI6XB23EVWD6GEJNL7FQSW2LBMYG4O5EC3WIUE6ATZK2DD2TOI"
[ OK ] generated user creds file `~/.local/share/nats/nsc/keys/creds/cjop/oa/cjzhao.creds`
[ OK ] added user "cjzhao" to account "oa"

$ tree ~/.local/share/nats/nsc

├── keys
│   ├── creds
│   │   └── cjop
│   │       ├── oa
│   │       │   └── cjzhao.creds
│   │       └── SYS
│   │           └── sys.creds
│   └── keys
│       ├── A
│       │   ├── AH
│       │   │   └── AAHRQ6BSALGBDQY7YCTLFE2XMRX7FF4BZNSCSKAY2VDHQMBCPA6UZCFA.nk
│       │   ├── AP
│       │   │   └── AAPSGKDH4DHGH42RT2KPRISYLDA4W63OTKEJWBB3YOOKOATA2OALOU7L.nk
│       │   └── CL
│       │       └── ACLQ4WBD4PHRW6CV5FJTN5ZVQQUEVXTCFVGLKPQREZAU4EGB2P2Y7BHF.nk
│       ├── O
│       │   └── BJ
│       │       └── OBJU6EEH55NQCLQ5PZHUKCB5LZM7TH3DJ7Q5OPGOIFYHA4JC4EZPJ3OZ.nk
│       └── U
│           ├── BM
│           │   └── UBMHD6NWNCCQ7GJTIJLQLWBN4AVAE5B4OK74MXVXE7H2UZ7VAUPHCOJX.nk
│           └── BU
│               └── UBUNYMHI6XB23EVWD6GEJNL7FQSW2LBMYG4O5EC3WIUE6ATZK2DD2TOI.nk
└── stores
    └── cjop
        ├── accounts
        │   ├── oa
        │   │   ├── oa.jwt
        │   │   └── users
        │   │       └── cjzhao.jwt
        │   └── SYS
        │       ├── SYS.jwt
        │       └── users
        │           └── sys.jwt
        └── cjop.jwt

可以指定账户,也可以不指定,它会默认是上一次操作的这个account。

服务端启动的时候,如何使用nsc创建的那些配置信息呢?

因为operator定义的是同一个认证域下面,你要保证服务端可信,所以我要把这个operator这些配置信息,至少要在服务器上把它配置好。

nsc提供了一个命令行,专门用来生成这个nats server的配置文件。

$ nsc generate config --nats-resolver

# Operator named cjop
operator: eyJ0eXAiOiJKV1QiLCJhbGciOiJlZDI1NTE5LW5rZXkifQ.eyJqdGkiOiJNU1dETk4yNUIyNUpZU1JTSjdaRlVDVU5MREhSRFNaMjNLWjNDSzRHMzZCNUpOQzVNWEJBIiwiaWF0IjoxNzU2MjIwNTU4LCJpc3MiOiJPQkpVNkVFSDU1TlFDTFE1UFpIVUtDQjVMWk03VEgzREo3UTVPUEdPSUZZSEE0SkM0RVpQSjNPWiIsIm5hbWUiOiJjam9wIiwic3ViIjoiT0JKVTZFRUg1NU5RQ0xRNVBaSFVLQ0I1TFpNN1RIM0RKN1E1T1BHT0lGWUhBNEpDNEVaUEozT1oiLCJuYXRzIjp7InN5c3RlbV9hY2NvdW50IjoiQUFIUlE2QlNBTEdCRFFZN1lDVExGRTJYTVJYN0ZGNEJaTlNDU0tBWTJWREhRTUJDUEE2VVpDRkEiLCJ0eXBlIjoib3BlcmF0b3IiLCJ2ZXJzaW9uIjoyfX0.ZSuugGH46ZpX2qcLUffe4KClRg5943XTIp2L4sCC8_r-jF0Il7Y6Msbxwy6IlxmOOuSl1fN6GaFfAda3HZMiDg
# System Account named SYS
system_account: AAHRQ6BSALGBDQY7YCTLFE2XMRX7FF4BZNSCSKAY2VDHQMBCPA6UZCFA

# configuration of the nats based resolver
resolver {
    type: full
    # Directory in which the account jwt will be stored
    dir: './jwt'
    # In order to support jwt deletion, set to true
    # If the resolver type is full delete will rename the jwt.
    # This is to allow manual restoration in case of inadvertent deletion.
    # To restore a jwt, remove the added suffix .delete and restart or send a reload signal.
    # To free up storage you must manually delete files with the suffix .delete.
    allow_delete: false
    # Interval at which a nats-server with a nats based account resolver will compare
    # it's state with one random nats based account resolver in the cluster and if needed, 
    # exchange jwt and converge on the same set of jwt.
    interval: "2m"
    # Timeout for lookup requests in case an account does not exist locally.
    timeout: "1.9s"
}


# Preload the nats based resolver with the system account jwt.
# This is not necessary but avoids a bootstrapping system account. 
# This only applies to the system account. Therefore other account jwt are not included here.
# To populate the resolver:
# 1) make sure that your operator has the account server URL pointing at your nats servers.
#    The url must start with: "nats://" 
#    nsc edit operator --account-jwt-server-url nats://localhost:4222
# 2) push your accounts using: nsc push --all
#    The argument to push -u is optional if your account server url is set as described.
# 3) to prune accounts use: nsc push --prune 
#    In order to enable prune you must set above allow_delete to true
# Later changes to the system account take precedence over the system account jwt listed here.
resolver_preload: {
        AAHRQ6BSALGBDQY7YCTLFE2XMRX7FF4BZNSCSKAY2VDHQMBCPA6UZCFA: eyJ0eXAiOiJKV1QiLCJhbGciOiJlZDI1NTE5LW5rZXkifQ.eyJqdGkiOiJPQTVEWVdTWUcyVTVNRE1JSlFBUU9WMkJHSTNGSk5RT0FIWlNUNUhKTkEzNVozNUo3V1lRIiwiaWF0IjoxNzU2MjIwNTU4LCJpc3MiOiJPQkpVNkVFSDU1TlFDTFE1UFpIVUtDQjVMWk03VEgzREo3UTVPUEdPSUZZSEE0SkM0RVpQSjNPWiIsIm5hbWUiOiJTWVMiLCJzdWIiOiJBQUhSUTZCU0FMR0JEUVk3WUNUTEZFMlhNUlg3RkY0QlpOU0NTS0FZMlZESFFNQkNQQTZVWkNGQSIsIm5hdHMiOnsiZXhwb3J0cyI6W3sibmFtZSI6ImFjY291bnQtbW9uaXRvcmluZy1zdHJlYW1zIiwic3ViamVjdCI6IiRTWVMuQUNDT1VOVC4qLlx1MDAzZSIsInR5cGUiOiJzdHJlYW0iLCJhY2NvdW50X3Rva2VuX3Bvc2l0aW9uIjozLCJkZXNjcmlwdGlvbiI6IkFjY291bnQgc3BlY2lmaWMgbW9uaXRvcmluZyBzdHJlYW0iLCJpbmZvX3VybCI6Imh0dHBzOi8vZG9jcy5uYXRzLmlvL25hdHMtc2VydmVyL2NvbmZpZ3VyYXRpb24vc3lzX2FjY291bnRzIn0seyJuYW1lIjoiYWNjb3VudC1tb25pdG9yaW5nLXNlcnZpY2VzIiwic3ViamVjdCI6IiRTWVMuUkVRLkFDQ09VTlQuKi4qIiwidHlwZSI6InNlcnZpY2UiLCJyZXNwb25zZV90eXBlIjoiU3RyZWFtIiwiYWNjb3VudF90b2tlbl9wb3NpdGlvbiI6NCwiZGVzY3JpcHRpb24iOiJSZXF1ZXN0IGFjY291bnQgc3BlY2lmaWMgbW9uaXRvcmluZyBzZXJ2aWNlcyBmb3I6IFNVQlNaLCBDT05OWiwgTEVBRlosIEpTWiBhbmQgSU5GTyIsImluZm9fdXJsIjoiaHR0cHM6Ly9kb2NzLm5hdHMuaW8vbmF0cy1zZXJ2ZXIvY29uZmlndXJhdGlvbi9zeXNfYWNjb3VudHMifV0sImxpbWl0cyI6eyJzdWJzIjotMSwiZGF0YSI6LTEsInBheWxvYWQiOi0xLCJpbXBvcnRzIjotMSwiZXhwb3J0cyI6LTEsIndpbGRjYXJkcyI6dHJ1ZSwiY29ubiI6LTEsImxlYWYiOi0xfSwic2lnbmluZ19rZXlzIjpbIkFDTFE0V0JENFBIUlc2Q1Y1RkpUTjVaVlFRVUVWWFRDRlZHTEtQUVJFWkFVNEVHQjJQMlk3QkhGIl0sImRlZmF1bHRfcGVybWlzc2lvbnMiOnsicHViIjp7fSwic3ViIjp7fX0sImF1dGhvcml6YXRpb24iOnsiYXV0aF91c2VycyI6bnVsbH0sInR5cGUiOiJhY2NvdW50IiwidmVyc2lvbiI6Mn19.u2wxYaS3woq_l62bsk_PplhN5C0RoQeQApI5uGB0j9iueVbjuUd1vu0hE6DFQQamPfnSK8Ti5iQyvSj8eGnFDw,
}

上面把这个初始配置生成了,那后面的变动就可以根据这个nsc这个工具,和服务端进行交互了,比如加用户,改权限。这样就不用需要再动nats-server的启动配置文件了。

  1. 查看这个operator有哪些参数是可以配置的
$ nsc describe operator

+---------------------------------------------------------------------------------------+
|                                   Operator Details                                    |
+----------------------+----------------------------------------------------------------+
| Name                 | cjop                                                           |
| Operator ID          | OBJU6EEH55NQCLQ5PZHUKCB5LZM7TH3DJ7Q5OPGOIFYHA4JC4EZPJ3OZ       |
| Issuer ID            | OBJU6EEH55NQCLQ5PZHUKCB5LZM7TH3DJ7Q5OPGOIFYHA4JC4EZPJ3OZ       |
| Issued               | 2025-08-26 15:02:38 UTC                                        |
| Expires              |                                                                |
| System Account       | AAHRQ6BSALGBDQY7YCTLFE2XMRX7FF4BZNSCSKAY2VDHQMBCPA6UZCFA / SYS |
| Require Signing Keys | false                                                          |
+----------------------+----------------------------------------------------------------+
  1. 添加参数
$ nsc edit operator --service-url nats://localhost:4222 

$ nsc edit operator --account-jwt-server-url nats://localhost:4222 

$ nsc describe operator

+----------------------------------------------------------------------------------------+
|                                    Operator Details                                    |
+-----------------------+----------------------------------------------------------------+
| Name                  | cjop                                                           |
| Operator ID           | OBJU6EEH55NQCLQ5PZHUKCB5LZM7TH3DJ7Q5OPGOIFYHA4JC4EZPJ3OZ       |
| Issuer ID             | OBJU6EEH55NQCLQ5PZHUKCB5LZM7TH3DJ7Q5OPGOIFYHA4JC4EZPJ3OZ       |
| Issued                | 2025-08-26 15:29:59 UTC                                        |
| Expires               |                                                                |
| Account JWT Server    | nats://localhost:4222                                          |
| Operator Service URLs | nats://localhost:4222                                          |
| System Account        | AAHRQ6BSALGBDQY7YCTLFE2XMRX7FF4BZNSCSKAY2VDHQMBCPA6UZCFA / SYS |
| Require Signing Keys  | false                                                          |
+-----------------------+----------------------------------------------------------------+
  1. 怎样把配置信息,给推到服务端
$ nsc push -A
  1. 怎么连这个server
# 查看配置文件都存放在哪里
$ nsc env

+----------------------------------------------------------------------------------------------------------+
|                                             NSC Environment                                              |
+--------------------+-----+-------------------------------------------------------------------------------+
| Setting            | Set | Effective Value                                                               |
+--------------------+-----+-------------------------------------------------------------------------------+
| $NSC_CWD_ONLY      | No  | If set, default operator/account from cwd only                                |
| $NSC_NO_GIT_IGNORE | No  | If set, no .gitignore files written                                           |
| $NKEYS_PATH        | No  | ~/.local/share/nats/nsc/keys                                                  |
| $NSC_HOME          | No  | ~/.config/nats/nsc                                                            |
| $NATS_CA           | No  | If set, root CAs in the referenced file will be used for nats connections     |
|                    |     | If not set, will default to the system trust store                            |
| $NATS_KEY          | No  | If set, the tls key in the referenced file will be used for nats connections  |
| $NATS_CERT         | No  | If set, the tls cert in the referenced file will be used for nats connections |
+--------------------+-----+-------------------------------------------------------------------------------+
| From CWD           |     | No                                                                            |
| Default Stores Dir |     | ~/.local/share/nats/nsc/stores                                                |
| Current Store Dir  |     | ~/.local/share/nats/nsc/stores                                                |
| Current Operator   |     | cjop                                                                          |
| Current Account    |     | oa                                                                            |
| Root CAs to trust  |     | Default: System Trust Store                                                   |
+--------------------+-----+-------------------------------------------------------------------------------+


$ ~/.local/share/nats/nsc/keys

├── creds
│   └── cjop
│       ├── oa
│       │   └── cjzhao.creds
│       └── SYS
│           └── sys.creds
└── keys
    ├── A
    │   ├── AH
    │   │   └── AAHRQ6BSALGBDQY7YCTLFE2XMRX7FF4BZNSCSKAY2VDHQMBCPA6UZCFA.nk
    │   ├── AP
    │   │   └── AAPSGKDH4DHGH42RT2KPRISYLDA4W63OTKEJWBB3YOOKOATA2OALOU7L.nk
    │   └── CL
    │       └── ACLQ4WBD4PHRW6CV5FJTN5ZVQQUEVXTCFVGLKPQREZAU4EGB2P2Y7BHF.nk
    ├── O
    │   └── BJ
    │       └── OBJU6EEH55NQCLQ5PZHUKCB5LZM7TH3DJ7Q5OPGOIFYHA4JC4EZPJ3OZ.nk
    └── U
        ├── BM
        │   └── UBMHD6NWNCCQ7GJTIJLQLWBN4AVAE5B4OK74MXVXE7H2UZ7VAUPHCOJX.nk
        └── BU
            └── UBUNYMHI6XB23EVWD6GEJNL7FQSW2LBMYG4O5EC3WIUE6ATZK2DD2TOI.nk

连接服务器,会用到 ~/.local/share/nats/nsc/keys/creds/cjop/ 目录下的creds文件

$ nats sub hello --creds ~/.local/share/nats/nsc/keys/creds/cjop/oa/cjzhao.creds

$ nats pub hello world --creds ~/.local/share/nats/nsc/keys/creds/cjop/oa/cjzhao.creds

# 使用tcpdump来抓取数据包,看看nats pub hello world命令,都有哪些数据包,进而分析数据处理流程
$ tcpdump -i lo -A -s 0 'tcp port 4222 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)'

nkey+jwt

header:

{
    "typ": "JWT",
    "alg": "ed25519-nkey"
}

jwt格式: base64(header).base64(playload).sign(header+playload)

使用ED25519进行签名

所有的issuer和subject(实体)使用nkey公钥。

issuer和subject(实体)必须在根据nkey指定相应的角色(包括operators、accounts、users)

Public Keys, have a one byte prefix: O, A, U for various types, O for operator, A for account, and U meaning user.

Private Keys, hava a two byte prefix SO, SA, SU. S stands for seed. The remainders(O, A and U) are the same meaning as in public keys.

  1. operator的jwt的playload
{
    "jti": "PI2F7EG65PEFBX45VX4SIA75X04JD3543XJN56RMWRB5SRPPN6EA",
    "iat": 1650117186,
    "iss": "ODF46YCA43KADDLHVY7FM7U7FFE04KR5R6UEBXWTVNV520ZUTKPCPK4S",
    "name": "MyOperator"
    "sub": "ODF46YCA43KADDLHVY7FM7U7FFE04KR5R6UEBXWTVNV520ZUTKPCPK4S",
    "nats": {
        "account_server_url": "nats://localhost:4222",
        "operator_service_urls": [
            "nats://localhost:4222"
        ],
        "system_account": "AAZ6UR3ZBMLE06GHGZXIUD03K54ZEVPD70APV4H3JXCNAPYE4EMYNNIN",
        "type": "operator",
        "version": 2
    }
}
  1. account的jwt的playload
{
    "jti": "SHFVM424TV4RAFVSX3AJVILWWAWTRSS3FUFH3II6JT3CGBJHXKNQ",
    "iat": "1650118515",
    "iss": "ODF46YCA43KADDLHVY7FM7U7FFE04KR5R6UEBXWTVNV520ZUTKPCPK4S",
    "name": "HR",
    "sub": "ABRXBMLGEWXBWYVGQUVEX36VQT5TTKT6QXVANYN6G26NPLMIK7QCFHI5",
    "nats": {
        "limits": {
            "subs": -1,
            "data": -1,
            "payload": -1,
            "imports": -1,
            "exports": -1,
            "wildcards": true,
            "conn": -1,
            "leaf": -1,
            "mem_storage": 1000000000,
            "disk_storage": 512000000,
            "streams": 10,
            "consumer": 100
        },
        "default_permissions": {
            "pub": {},
            "sub": {}
        },
        "type": "account",
        "version": 2
    }
}
  1. user的jwt的playload
{
  "jti": "KFX2Y6CAWRC4Q6BKAEQBYCWHTI356NVXVA5L2A3UQVRLSYWY5UAQ",
  "iat": "1650118400",
  "iss": "ABRXBMLGEWXBWYVGQUVEX36VQT5TTKT6QXVANYN6G26NPLMIK7QCFHI5",
  "name": "zr",
  "sub": "UD3KBUTRHXZENKQAIDEJUTCZFFAQG5B5L77KMY7V5CJKDWYQTIFRMZH5",
  "nats": {
    "pub": {},
    "sub": {},
    "subs": "-1",
    "data": "-1",
    "payload": "-1",
    "type": "user",
    "version": "2"
  }
}

operator的 sub 和 account 的 iss 是一一对应的, account的 sub 和 user 的 iss 是一一对应的,正是通过这种方式实现的“operator和account之间是一对多的关系,account和user之间也是一对多的关系”。

我的用户信息,它是用account账户信息的这个nkey来做签名的,然后我的这个account的这个信息,它又是用operator这个nkey来做签名的。

如何使用nsc给用户授权

  1. 新增授权
$ nsc edit user --account oa --name cjzhao --allow-pub "hello,oa.*"
  1. 查看用户详情
$ nsc describe user
  1. push到服务器
$ nsc push -A

本文发表于 0001-01-01,最后修改于 0001-01-01。

本站永久域名「 jiavvc.top 」,也可搜索「 后浪笔记一零二四 」找到我。


上一篇 « 下一篇 »

赞赏支持

请我吃鸡腿 =^_^=

i ysf

云闪付

i wechat

微信

推荐阅读

Big Image