NATS文档
  • 欢迎
  • 发行备注
    • 最新情况
      • NATS 2.2
      • NATS 2.0
  • NATS 概念
    • 概览
      • 比较 NATS
    • 什么是NATS
      • 演练安装
    • 基于主题的消息
    • 核心NATS
      • 发布和订阅
        • 发布/订阅演 练
      • 请求和响应
        • 请求/响应 演练
      • 队列组
        • 队列 演练
    • JetStream
      • 流
      • 消费者
        • 示例
      • JetStream 演练
      • 键值对存储
        • 键值对存储演练
      • 对象存储
        • 对象存储演练
    • 主题映射与分区
    • NATS服务器基础架构
      • NATS部署架构适配
    • 安全
    • 连接性
  • 使用 NATS
    • NATS工具
      • nats
        • nats基准测试
      • nk
      • nsc
        • 基础
        • 流
        • 服务
        • 签名密钥
        • 撤销
        • 管理操作
      • nats-top
        • 教程
    • 用NATS开发
      • 一个NATS应用的解剖
      • 连接
        • 连接到默认服务器
        • 连接到特定服务器
        • 连接到群集
        • 连接名称
        • 用用户名和密码做认证
        • 用令牌做认证
        • 用NKey做认证
        • 用一个可信文件做认证
        • 用TLS加密连接
        • 设置连接超时
        • 乒乓协议
        • 关闭响应消息
        • 杂技功能
        • 自动恢复
          • 禁用自动重连
          • 设置自动重新连接的最大次数
          • 随机
          • 重连尝试之间暂停
          • 关注重连事件
          • 重连尝试期间缓存消息
        • 监视连接
          • 关注连接事件
          • 低速消费者
      • 接收消息
        • 同步订阅
        • 异步订阅
        • 取消订阅
        • N个消息后取消订阅
        • 回复一个消息
        • 通配符订阅
        • 队列订阅
        • 断开连接前清除消息
        • 接收结构化数据
      • 发送消息
        • 包含一个回复主题
        • 请求回复语义
        • 缓存刷入和乒
        • 发送结构化数据
      • JetStream
        • 深入JetStream模型
        • 管理流和消费者
        • 消费者详情
        • 发布到流
        • 使用键值对存储
        • 使用对象存储
      • 教程
        • 用go做个自定义拨号器
  • 运行一个NATS服务
    • 安装、运行和部署NATS服务
      • 安装一个NATS服务
      • 运行和部署一个NATS服务
      • Windows服务
      • 信号
    • 环境约束
    • NATS和Docker
      • 教程
      • Docker Swarm
      • Python 和 NGS 运行在Docker
      • JetStream
    • NATS和Kubernetes
      • 用Helm 部署NATS
      • 创建一个Kubernetes群集
      • NATS群集和认证管理
      • 用cfssl保护NATS群集
      • 用负载均衡来保护外部的NATS访问
      • 在Digital Ocean用Helm创建超级NATS群集
      • 使用Helm从0到K8S再到叶子节点
    • NATS服务的客户端
    • 配置 NATS服务
      • 配置 JetStream
        • 配置管理 Management
          • NATS管理命令行
          • 地形
          • GitHub Actions
          • Kubernetes控制器
      • 群集
        • 群集配置
        • JetStream 群集
          • 管理
      • 网关超级群集
        • 配置
      • 叶子节点
        • 配置
        • JetStream在叶子节点
      • 安全加固NATS
        • 使用 TLS
        • 认证
          • 令牌
          • 用户名/密码
          • TLS认证
            • 群集中的TLS认证
          • NKeys
          • 认证超时
          • 去中心化的 JWT 认证/授权
            • 使用解析器查找帐户
            • 内存解析器教程
            • 混合认证/授权安装
        • 授权
        • 基于账户的多租户
        • OCSP Stapling
      • 日志
      • 使用监控
      • MQTT
        • 配置
      • 配置主题映射
      • 系统事件
        • 系统时间和去中心化的JWT教程
      • WebSocket
        • 配置
    • 管理和监控你的NATS服务基础架构
      • 监控
        • 监控 JetStream
      • 管理 JetStream
        • 账号信息
        • 命名流,消费者和账号
        • 流
        • 消费者
        • 数据复制
        • 灾难回复
        • 加密Rest
      • 管理JWT安全
        • 深入JWT指南
      • 升级一个群集
      • 慢消费者
      • 信号
      • 跛脚鸭模式
  • 参考
    • 常见问题
    • NATS协议
      • 协议演示
      • 客户端协议
        • 开发一个客户端
      • NATS群集协议
      • JetStream API参考
  • 遗产
    • STAN='NATS流'
      • STAN概念
        • 和NATS的关系
        • 客户端连接
        • 频道
          • 消息日志
          • 订阅
            • 通常的
            • 持久化的
            • 队列组
            • 重新投递
        • 存储接口
        • 存储加密
        • 群集
          • Supported Stores
          • Configuration
          • Auto Configuration
          • Containers
        • Fault Tolerance
          • Active Server
          • Standby Servers
          • Shared State
          • Failover
        • Partitioning
        • Monitoring
          • Endpoints
      • Developing With STAN
        • Connecting to NATS Streaming Server
        • Publishing to a Channel
        • Receiving Messages from a Channel
        • Durable Subscriptions
        • Queue Subscriptions
        • Acknowledgements
        • The Streaming Protocol
      • STAN NATS Streaming Server
        • Installing
        • Running
        • Configuring
          • Command Line Arguments
          • Configuration File
          • Store Limits
          • Persistence
            • File Store
            • SQL Store
          • Securing
        • Process Signaling
        • Windows Service
        • Embedding NATS Streaming Server
        • Docker Swarm
        • Kubernetes
          • NATS Streaming with Fault Tolerance.
    • nats账号服务
      • Basics
      • Inspecting JWTs
      • Directory Store
      • Update Notifications
由 GitBook 提供支持
在本页
  • TLS Timeout
  • Certificate Authorities
  • Self Signed Certificates for Testing
  • Problems With Self Signed Certificates
  • Creating Self Signed Certificates for Testing
  • TLS-Terminating Reverse Proxies
  • nats.go
  • nats.java
  • nats.js
  • nats.rs
  1. 运行一个NATS服务
  2. 配置 NATS服务
  3. 安全加固NATS

使用 TLS

上一页安全加固NATS下一页认证

最后更新于2年前

The NATS server uses modern TLS semantics to encrypt client, route, and monitoring connections. Server configuration revolves around a tls map, which has the following properties:

Property
Description

cert_file

TLS certificate file.

key_file

TLS certificate key file.

ca_file

cipher_suites

When set, only the specified TLS cipher suites will be allowed. Values must match the golang version used to build the server.

curve_preferences

List of TLS cipher curves to use in order.

insecure

Skip certificate verification. This only applies to outgoing connections, NOT incoming client connections. NOT Recommended

timeout

verify

verify_and_map

verify_cert_and_check_known_urls

pinned_certs

List of hex-encoded SHA256 of DER encoded public key fingerprints. When present, during the TLS handshake, the provided certificate's fingerprint is required to be present in the list or the connection is closed. This sequence of commands generates an entry for a provided certificate: `openssl x509 -noout -pubkey -in

openssl pkey -pubin -outform DER

openssl dgst -sha256`.

The simplest configuration:

tls: {
  cert_file: "./server-cert.pem"
  key_file: "./server-key.pem"
}

Or by using :

nats-server --tls --tlscert=./server-cert.pem --tlskey=./server-key.pem
[21417] 2019/05/16 11:21:19.801539 [INF] Starting nats-server version 2.0.0
[21417] 2019/05/16 11:21:19.801621 [INF] Git commit [not set]
[21417] 2019/05/16 11:21:19.801777 [INF] Listening for client connections on 0.0.0.0:4222
[21417] 2019/05/16 11:21:19.801782 [INF] TLS required for client connections
[21417] 2019/05/16 11:21:19.801785 [INF] Server id is ND6ZZDQQDGKYQGDD6QN2Y26YEGLTH6BMMOJZ2XJB2VASPVII3XD6RFOQ
[21417] 2019/05/16 11:21:19.801787 [INF] Server is ready

Notice that the log indicates that the client connections will be required to use TLS. If you run the server in Debug mode with -D or -DV, the logs will show the cipher suite selection for each connected client:

[22242] 2019/05/16 11:22:20.216322 [DBG] 127.0.0.1:51383 - cid:1 - Client connection created
[22242] 2019/05/16 11:22:20.216539 [DBG] 127.0.0.1:51383 - cid:1 - Starting TLS client connection handshake
[22242] 2019/05/16 11:22:20.367275 [DBG] 127.0.0.1:51383 - cid:1 - TLS handshake complete
[22242] 2019/05/16 11:22:20.367291 [DBG] 127.0.0.1:51383 - cid:1 - TLS version 1.2, cipher suite TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256

When a tls section is specified at the root of the configuration, it also affects the monitoring port if https_port option is specified. Other sections such as cluster can specify a tls block.

TLS Timeout

The timeout setting enables you to control the amount of time that a client is allowed to upgrade its connection to tls. If your clients are experiencing disconnects during TLS handshake, you'll want to increase the value, however, if you do be aware that an extended timeout exposes your server to attacks where a client doesn't upgrade to TLS and thus consumes resources. Conversely, if you reduce the TLS timeout too much, you are likely to experience handshake errors.

tls: {
  cert_file: "./server-cert.pem"
  key_file: "./server-key.pem"
  # clients will fail to connect (value is too low)
  timeout: 0.0001
}

Certificate Authorities

The ca_file file should contain one or more Certificate Authorities in PEM format, in a bundle. This is a common format.

When a certificate is issued, it is often accompanied by a copy of the intermediate certificate used to issue it. This is useful for validating that certificate. It is not necessarily a good choice as the only CA suitable for use in verifying other certificates a server may see.

Do consider though that organizations issuing certificates will change the intermediate they use. For instance, a CA might issue intermediates in pairs, with an active and a standby, and reserve the right to switch to the standby without notice. You probably would want to trust both of those for the ca_file directive, to be prepared for such a day, and then after the first CA has been compromised you can remove it. This way the roll from one CA to another will not break your NATS server deployment.

Self Signed Certificates for Testing

If anybody outside your organization needs to connect, get certs from a public certificate authority. Think carefully about revocation and cycling times, as well as automation, when picking a CA. If arbitrary applications inside your organization need to connect, use a cert from your in-house CA. If only resources inside a specific environment need to connect, that environment might have its own dedicated automatic CA, eg in Kubernetes clusters, so use that.

Only for testing purposes does it make sense to generate self-signed certificates, even your own CA. This is a short guide on how to do just that and what to watch out for.

DO NOT USE these certificates in production!!!

Problems With Self Signed Certificates

Missing in Relevant Trust Stores

As they should, these are not trusted by the system your server or clients are running on.

One option is to specify the CA in every client you are using. In case you make use of verify, verify_and_map or verify_cert_and_check_known_urls you need to specify ca_file in the server. If you are having a more complex setup involving cluster, gateways or leaf nodes, ca_file needs to be present in tls maps used to connect to the server with self-signed certificates. While this works for server and libraries from the NATS ecosystem, you will experience issues when connecting with other tools such as your Browser.

Another option is to configure your system's trust store to include self-signed certificate(s). Which trust store needs to be configured depends on what you are testing.

  • This may be your OS for server and certain clients.

  • The runtime environment for other clients like Java, Python or Node.js.

  • Your browser for monitoring endpoints and websockets.

Please check your system's documentation on how to trust a particular self-signed certificate.

Missing Subject Alternative Name

Wrong Key Usage

With respect to NATS the relevant values for extended key usage are:

  • TLS WWW server authentication - To authenticate as server for incoming connections. A NATS server will need a certificate containing this.

  • TLS WWW client authentication - To authenticate as client for outgoing connections. Only needed when connecting to a server where verify, verify_and_map or verify_cert_and_check_known_urls are specified. In these cases, a NATS client will need a certificate with this value.

Note that it's common practice for non-web protocols to use the TLS WWW authentication fields, as a matter of history those have become embedded as generic options.

Creating Self Signed Certificates for Testing

Generate a CA as well as a certificate, valid for server authentication by localhost and the IP ::1(-cert-file and -key-file overwrite default file names). Then start a NATS server using the generated certificate.

mkcert -install
mkcert -cert-file server-cert.pem -key-file server-key.pem localhost ::1
nats-server --tls --tlscert=server-cert.pem --tlskey=server-key.pem -ms 8222
mkcert -client -cert-file client-cert.pem -key-file client-key.pem localhost ::1 email@localhost

Please note:

  • That client refers to connecting process, not necessarily a NATS client.

  • mkcert -client will generate a certificate with key usage suitable for client and server authentication.

Examples in this document make use of the certificates generated so far. To simplify examples using the CA certificate, copy rootCA.pem into the same folder where the certificates were generated. To obtain the CA certificate's location use this command:

mkcert -CAROOT

Once you are done testing, remove the CA from your local system trust store(s).

mkcert -uninstall

However, for inspecting certificates it is quite handy. To inspect the certificates from the above example execute these commands:

openssl x509 -noout -text -in server-cert.pem
openssl x509 -noout -text -in client-cert.pem

TLS-Terminating Reverse Proxies

nats.go

nats.java

package io.nats.client.impl;

public class TlsSocketDataPort extends SocketDataPort {
  @Override
  public void connect(String serverURI, NatsConnection conn, long timeoutNanos) throws IOException {
    super.connect(serverURI, conn, timeoutNanos);
    this.upgradeToSecure();
  }
}
Nats.connect(new Options.Builder()
  .server(server)
  .dataPortType("io.nats.client.impl.TlsSocketDataPort")
  .build())

nats.js

nats.rs

TLS . When not present, default to the system trust store.

TLS handshake in fractional seconds. Default set to 0.5 seconds.

If true, require and client certificates. To support use by Browser, this option does not apply to monitoring.

If true, require and verify client certificates and certificate values for authentication purposes. Does not apply to monitoring either.

Only settable in a non client context where verify: true is the default (/). The incoming connections certificate's X509v3 Subject Alternative Name DNS entries will be matched against all urls in the configuration context that contains this tls map. If a match is found, the connection is accepted and rejected otherwise. Meaning for gateways we will match all DNS entries in the certificate against all gateway urls. For cluster, we will match against all route urls. As a consequence of this, dynamic cluster growth may require config changes in other clusters where this flag is true. DNS name checking is performed according to . Only the full wildcard * is supported for the left most label. This would be one way to keep cluster growth flexible.

Explaining , and fall well outside the scope of this document. So does an explanation on how to obtain a properly trusted certificates.

Another common problem is failed . The IP or DNS name to connect to needs to match a inside the certificate. Meaning, if a client/browser/server connect via tls to 127.0.0.1, the server needs to present a certificate with a SAN containing the IP 127.0.0.1 or the connection will be closed with a handshake error.

When verify_cert_and_check_known_urls is specified, DNS records are necessary. In order to successfully connect there must be an overlap between the DNS records provided as part of the certificate and the urls configured. If you dynamically grow your cluster and use a new certificate, this route or gateway the server connects to will have to be reconfigured to include an url for the new server. Only then can the new server connect. If the DNS record is a wildcard, matching according to will be performed. Using certificates with a wildcard and configuration with url(s) that would match are a way to keep the flexibility of dynamic cluster growth without configuration changes in other clusters.

When generating your certificate you need to make sure to include the right purpose for which you want to use the certificate. This is encoded in and . The necessary values for key usage depend on the ciphers used. Digital Signature and Key Encipherment are an interoperable choice.

connections can be configured with verify as well. Then the connecting NATS server will have to present a certificate with this value too. Certificates containing both values are an option.

connections always have verify enabled. Which server acts as client and server comes down to timing and therefore can't be individually configured. Certificates containing both values are a must.

connections always have verify enabled. Unlike cluster outgoing connections can specify a separate cert. Certificates containing both values are an option that reduce configuration.

The simplest way to generate a CA as well as client and server certificates is . This zero config tool generates and installs the CA into your local system trust store(s) and makes providing SAN straight forward. Check its for installation and your system's trust store. Here is a simple example:

Now you should be able to access the monitoring endpoint https://localhost:8222 with your browser. https://127.0.0.1:8222 however should result in an error as 127.0.0.1 is not listed as SAN. You will not be able to establish a connection from another computer either. For that to work you have to provide appropriate DNS and/or IP

To generate certificates that work with verify and // provide the -client option. It will cause the appropriate key usage for client authentication to be added. This example also adds a SAN email for usage as user name in verify_and_map.

Alternatively, you can also use to . This tool allows a lot more customization of the generated certificates. It is more complex and does not manage installation into the system trust store(s).

Due to the nature of the TLS upgrade mechanism NATS uses, using a with NATS is not supported. However, there are workarounds that can be used in the client libraries to make it work.

Provide a .

See:

Something around here:

Public key infrastructure
Certificate Authorities (CA)
x509
certificates
identity validation
Subject Alternative Name (SAN)
Subject Alternative Name (SAN)
rfc6125
Subject Alternative Name (SAN)
key usage
extended key usage
Leaf node
Cluster
Gateway
mkcert
documentation
cluster
gateway
leaf_nodes
openssl
generate certificates
TLS-terminating reverse proxy
CustomDialer
https://github.com/nats-io/nats.js/issues/369
https://github.com/nats-io/nats.rs/blob/master/src/connector.rs#L232
SAN(s)
cluster
gateway
rfc6125
certificate authority file
timeout
verify
map
server options