在这章之前,可以发现,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,我可以配置这些账户用户信息,同时,我能把这些信息发布到这个服务端去。
- 创建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里。
- 创建账户
$ 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
- 在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的启动配置文件了。
- 查看这个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 |
+----------------------+----------------------------------------------------------------+
- 添加参数
$ 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 |
+-----------------------+----------------------------------------------------------------+
- 怎样把配置信息,给推到服务端
$ nsc push -A
- 怎么连这个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.
- 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
}
}
- 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
}
}
- 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给用户授权
- 新增授权
$ nsc edit user --account oa --name cjzhao --allow-pub "hello,oa.*"
- 查看用户详情
$ nsc describe user
- push到服务器
$ nsc push -A
本文发表于 0001-01-01,最后修改于 0001-01-01。
本站永久域名「 jiavvc.top 」,也可搜索「 后浪笔记一零二四 」找到我。