NATS Server distribution with auto-TLS
88
natsmagicA wrapper around NATS server which automates TLS certificates provisioning and renewal using Certmagic.
NATS_MAGIC_FILE="/server-01.natsmagic.json" natsmagic
2023-08-29T17:21:57.102+0200 INFO natsmagic natsmagic/natsmagic.go:108 saved config file to /tmp/nats-server954632112
2023-08-29T17:21:57.104+0200 INFO certmagic.maintenance [email protected]/maintain.go:59 started background certificate maintenance {"cache": "0xc0002c2380"}
2023-08-29T17:21:57.104+0200 DEBUG certmagic [email protected]/cache.go:243 added certificate to cache {"subjects": ["nats.example.com"], "expiration": "2023-11-27T08:42:22.000Z", "managed": true, "issuer_key": "acme-v02.api.letsencrypt.org-directory", "hash": "9d97ed29183f98b0f1856c2d21d46554e055a051d7c590b010995e709c339c1b", "cache_size": 1, "cache_capacity": 0}
2023-08-29T17:21:57.107+0200 INFO nats server/server.go:1705 Starting nats-server
2023-08-29T17:21:57.107+0200 INFO nats server/server.go:1716 Version: 2.9.21
2023-08-29T17:21:57.107+0200 INFO nats server/server.go:1717 Git: [not set]
2023-08-29T17:21:57.107+0200 INFO nats server/server.go:1720 Cluster: cluster-01
2023-08-29T17:21:57.107+0200 INFO nats server/server.go:1722 Name: nats-01
2023-08-29T17:21:57.107+0200 INFO nats server/server.go:1724 Node: pZeTdFV7
2023-08-29T17:21:57.107+0200 INFO nats server/server.go:1726 ID: NCRWNFAQZIWFK5Y3VTHMPVM3B7M6M2PHKQPQFCNP4YNDZQCU5FKSH4KZ
2023-08-29T17:21:57.107+0200 INFO nats server/server.go:1755 Using configuration file: /tmp/nats-server954632112
2023-08-29T17:21:57.107+0200 INFO nats server/server.go:1760 Trusted Operators
2023-08-29T17:21:57.107+0200 INFO nats server/server.go:1763 System : ""
2023-08-29T17:21:57.107+0200 INFO nats server/server.go:1764 Operator: "test-operator"
2023-08-29T17:21:57.107+0200 INFO nats server/server.go:1765 Issued : 2023-08-29 00:07:02 +0200 CEST
2023-08-29T17:21:57.107+0200 INFO nats server/server.go:1768 Expires : Never
2023-08-29T17:21:57.107+0200 INFO nats server/accounts.go:4160 Managing all jwt in exclusive directory /jwt
2023-08-29T17:21:57.107+0200 INFO nats server/jetstream.go:179 Starting JetStream
2023-08-29T17:21:57.108+0200 INFO nats server/jetstream.go:366 _ ___ _____ ___ _____ ___ ___ _ __ __
2023-08-29T17:21:57.108+0200 INFO nats server/jetstream.go:367 _ | | __|_ _/ __|_ _| _ \ __| /_\ | \/ |
2023-08-29T17:21:57.108+0200 INFO nats server/jetstream.go:368 | || | _| | | \__ \ | | | / _| / _ \| |\/| |
2023-08-29T17:21:57.108+0200 INFO nats server/jetstream.go:369 \__/|___| |_| |___/ |_| |_|_\___/_/ \_\_| |_|
2023-08-29T17:21:57.108+0200 INFO nats server/jetstream.go:370
2023-08-29T17:21:57.108+0200 INFO nats server/jetstream.go:371 https://docs.nats.io/jetstream
2023-08-29T17:21:57.108+0200 INFO nats server/jetstream.go:372
2023-08-29T17:21:57.108+0200 INFO nats server/jetstream.go:373 ---------------- JETSTREAM ----------------
2023-08-29T17:21:57.108+0200 INFO nats server/jetstream.go:374 Max Memory: 1.00 GB
2023-08-29T17:21:57.108+0200 INFO nats server/jetstream.go:375 Max Storage: 1.00 GB
2023-08-29T17:21:57.108+0200 INFO nats server/jetstream.go:376 Store Directory: "/tmp/jetstream"
2023-08-29T17:21:57.108+0200 INFO nats server/jetstream.go:378 Domain: cluster-01
2023-08-29T17:21:57.108+0200 INFO nats server/jetstream.go:384 -------------------------------------------
2023-08-29T17:21:57.108+0200 INFO nats server/websocket.go:1100 Listening for websocket clients on wss://0.0.0.0:10443
2023-08-29T17:21:57.108+0200 INFO nats server/leafnode.go:670 Listening for leafnode connections on 0.0.0.0:7222
2023-08-29T17:21:57.109+0200 INFO nats server/mqtt.go:409 Listening for MQTT clients on tls://0.0.0.0:8883
2023-08-29T17:21:57.109+0200 INFO nats server/server.go:2202 Listening for client connections on 127.0.0.1:4222
2023-08-29T17:21:57.109+0200 INFO nats server/server.go:2207 TLS required for client connections
2023-08-29T17:21:57.109+0200 INFO nats server/server.go:1989 Server is ready
This tool should be mostly compatible with NATS server, use the --help option to list allowed options.
Note: Logging options are not listed in help, and they are ignored, because
zap is used for logging (as such, syslog and windows service loggers are not available).
By default, natsmagic will behave just like NATS server, and accept both a NATS configuration file using -c option, and command line arguments to configure NATS server.
However, environment variables can be used to automate TLS certificates provisioning and renewal.
export NATS_MAGIC_DOMAINS="nats.example.com,other.example.com"
export NATS_MAGIC_EMAIL="[email protected]"
export NATS_MAGIC_PROVIDER="digitalocean"
export NATS_MAGIC_CA="https://acme-staging-v02.api.letsencrypt.org/directory"
export DO_AUTH_TOKEN="xxxxxxxx"
From this point it's possible to start natsmagic, and TLS certificates will be managed for:
https_port is specified in config or -ms option is used.Note that NATS configuration file should not contain any
tlsblock when using Let's Encrypt certificates.
natsmagic with JetStream and monitoring enabled:./natsmagic -p 4222 -js -ms 8222
NATS_MAGIC_FILE="./leaf-01.natsmagic.json" natsmagic
Advanced example:
{
"domains": [
"leaf-01.example.com"
],
"letsencrypt_email": "[email protected]",
"letsencrypt_ca": "https://acme-staging-v02.api.letsencrypt.org/directory",
"letsencrypt_dns_provider": "digitalocean",
"letsencrypt_dns_auth": {
"do_token": "SECRET!!"
},
"remote_users": {
"ADNU2QRXBD4ZKPJBX2W4GPYIZPJNU25IVC67TPARE22755KLN4JSJRQH": {
"nkey": "SECRET!!",
"token": "eyJhbGciOiJlZDI1NTE5LW5rZXkiLCJ0eXAiOiJKV1QifQ.eyJuYW1lIjoiU1lTIiwic3ViIjoiVUIzR0Q3SVFKUVhESlhLVFYzNFVQSTJSWkVTR1hFR1ozRUtTQUVCRlhBWldJTlE0RTdLR0ZHNFIiLCJpc3MiOiJBQlFDNEJDQkdZSkVZR1c1RExSRlUzWVVSN1laQ1NPWDZPRVZHMjZTQU5GUEFWVVlIQVQ0VEhHVCIsImp0aSI6IkdYTk1TVFRFMkhMQkpXTTZDWlhXTDZCVFZTMkhYTlA2WkM3SEIzWUNZRUVDVkpSWUlWQkEiLCJpYXQiOjE2OTMyNjA0MjIsIm5hdHMiOnsidHlwZSI6InVzZXIiLCJ2ZXJzaW9uIjoyLCJpc3N1ZXJfYWNjb3VudCI6IkFETlUyUVJYQkQ0WktQSkJYMlc0R1BZSVpQSk5VMjVJVkM2N1RQQVJFMjI3NTVLTE40SlNKUlFIIn19.Qs4u3ehBkO96ZmvPGltbC8vYZxpu57-Oa8FeP9bDsk0HtY0Jghu50ZDkvl3iL5dN471X5eT9uz0dJHc1cBS_Bg"
}
},
"logging_preset": "development",
"nats_config": {
"server_name": "leaf-01",
"port": 4224,
"host": "127.0.0.1",
"jetstream": {
"domain": "leaf-01",
"max_memory_store": 1073741824,
"max_file_store": 1073741824
},
"websocket": {
"host": "0.0.0.0",
"port": 10445
},
"mqtt": {
"host": "0.0.0.0",
"port": 8885
},
"leafnodes": {
"remotes": [
{
"url": "nats-leaf://server-01.example.com:7222",
"account": "ADNU2QRXBD4ZKPJBX2W4GPYIZPJNU25IVC67TPARE22755KLN4JSJRQH"
}
]
},
"operator": "eyJhbGciOiJlZDI1NTE5LW5rZXkiLCJ0eXAiOiJKV1QifQ.eyJuYW1lIjoidGVzdC1vcGVyYXRvciIsInN1YiI6Ik9ETzNJVkQzWkdEWEFFSERET1RET0tVVk40WkM1UVlFU1RONUkyUEFMVk9JTzNDTURFUVdQQVhTIiwiaXNzIjoiT0RPM0lWRDNaR0RYQUVIRERPVERPS1VWTjRaQzVRWUVTVE41STJQQUxWT0lPM0NNREVRV1BBWFMiLCJqdGkiOiJHWE5NU1RYWVlXWTRaVzZCNFYyTUNaMklFSk9KVUhJRTVVUUdaVTIzSTVCTUtGSUFWUUZBIiwiaWF0IjoxNjkzMjYwNDIyLCJuYXRzIjp7InR5cGUiOiJvcGVyYXRvciIsInZlcnNpb24iOjJ9fQ.aadO53UH-iWOBYlC0FdD-8OuO7fG-srsf5Re-_dwqx9BaM3Ps-Y2st_RzBWnMpXgvq-e4GXzRRx1M23pr9HtCA",
"system_account": "ADNU2QRXBD4ZKPJBX2W4GPYIZPJNU25IVC67TPARE22755KLN4JSJRQH",
"resolver": {
"type": "full",
"dir": "./nats-01/jwt",
"allow_delete": true,
"interval": "2m"
},
"resolver_preload": {
"ADNU2QRXBD4ZKPJBX2W4GPYIZPJNU25IVC67TPARE22755KLN4JSJRQH": "eyJhbGciOiJlZDI1NTE5LW5rZXkiLCJ0eXAiOiJKV1QifQ.eyJuYW1lIjoiU1lTIiwic3ViIjoiQUROVTJRUlhCRDRaS1BKQlgyVzRHUFlJWlBKTlUyNUlWQzY3VFBBUkUyMjc1NUtMTjRKU0pSUUgiLCJpc3MiOiJPRE8zSVZEM1pHRFhBRUhERE9URE9LVVZONFpDNVFZRVNUTjVJMlBBTFZPSU8zQ01ERVFXUEFYUyIsImp0aSI6IkdYTk1TVFc1WU5OUEhSRlRXQkM1RU9SQUNNUklQQlk1R0I0VlNUNVFBVTdETDQyVTJVRlEiLCJpYXQiOjE2OTMyNjA0MjIsIm5hdHMiOnsidHlwZSI6ImFjY291bnQiLCJ2ZXJzaW9uIjoyLCJzaWduaW5nX2tleXMiOlt7ImtleSI6IkFDRk9XVTZXQU1UV0NHNzJXWTVYN0pWRFU3WExKU0cyWENQTUZISFQ2M1BIR1RWRzVKVDI1VlVDIiwicm9sZSI6Im1vbml0b3IiLCJ0ZW1wbGF0ZSI6eyJwdWIiOnsiYWxsb3ciOlsiJFNZUy5SRVEuQUNDT1VOVC4qLioiLCIkU1lTLlJFUS5TRVJWRVIuKi4qIl19LCJzdWIiOnsiYWxsb3ciOlsiJFNZUy5BQ0NPVU5ULiouPiIsIiRTWVMuU0VSVkVSLiouPiJdfSwic3VicyI6MTAwLCJwYXlsb2FkIjoxMDQ4NTc2LCJhbGxvd2VkX2Nvbm5lY3Rpb25fdHlwZXMiOlsiU1RBTkRBUkQiLCJXRUJTT0NLRVQiXX0sImtpbmQiOiJ1c2VyX3Njb3BlIn0seyJrZXkiOiJBQlVIM0gzQ0VTRkFXU1NVNE1PTlhOVllKNVpLQ0ZWWlNYM0RHNFNDUEY3RUhFTVBETVE1TVYyNiIsInJvbGUiOiJpc3N1ZXIiLCJ0ZW1wbGF0ZSI6eyJwdWIiOnsiYWxsb3ciOlsiJFNZUy5SRVEuQ0xBSU1TLiouIiwiJFNZUy5SRVEuQUNDT1VOVC4qLkNMQUlNUy4qIl19LCJzdWJzIjoxMCwicGF5bG9hZCI6MTA0ODU3NiwiYWxsb3dlZF9jb25uZWN0aW9uX3R5cGVzIjpbIlNUQU5EQVJEIiwiV0VCU09DS0VUIl19LCJraW5kIjoidXNlcl9zY29wZSJ9LHsia2V5IjoiQURER0FYSDNFRlpQM1NaSlVQQUJCR0tYT1lBT1NTWEpHNVc0VlNaNUxTUTQ2U0ZNRElDNUJJQzMiLCJyb2xlIjoiYWRtaW5pc3RyYXRvciIsInRlbXBsYXRlIjp7InB1YiI6eyJhbGxvdyI6WyI-Il19LCJzdWIiOnsiYWxsb3ciOlsiPiJdfSwic3VicyI6MTAsInBheWxvYWQiOjEwNDg1NzYsImFsbG93ZWRfY29ubmVjdGlvbl90eXBlcyI6WyJTVEFOREFSRCIsIldFQlNPQ0tFVCJdfSwia2luZCI6InVzZXJfc2NvcGUifSx7ImtleSI6IkFCUUM0QkNCR1lKRVlHVzVETFJGVTNZVVI3WVpDU09YNk9FVkcyNlNBTkZQQVZVWUhBVDRUSEdUIiwicm9sZSI6ImxlYWZub2RlIiwidGVtcGxhdGUiOnsicHViIjp7ImFsbG93IjpbIj4iXX0sInN1YiI6eyJhbGxvdyI6WyI-Il19LCJzdWJzIjotMSwiZGF0YSI6LTEsInBheWxvYWQiOjEwNDg1NzYsImFsbG93ZWRfY29ubmVjdGlvbl90eXBlcyI6WyJMRUFGTk9ERSIsIkxFQUZOT0RFX1dTIl19LCJraW5kIjoidXNlcl9zY29wZSJ9XSwiZXhwb3J0cyI6W3siZGVzY3JpcHRpb24iOiJBY2NvdW50IHNwZWNpZmljIG1vbml0b3Jpbmcgc3RyZWFtIiwiaW5mb191cmwiOiJodHRwczovL2RvY3MubmF0cy5pby9uYXRzLXNlcnZlci9jb25maWd1cmF0aW9uL3N5c19hY2NvdW50cyIsIm5hbWUiOiJhY2NvdW50LW1vbml0b3Jpbmctc3RyZWFtcyIsInN1YmplY3QiOiIkU1lTLkFDQ09VTlQuKi4-IiwidHlwZSI6InN0cmVhbSIsImFjY291bnRfdG9rZW5fcG9zaXRpb24iOjN9LHsiZGVzY3JpcHRpb24iOiJSZXF1ZXN0IGFjY291bnQgc3BlY2lmaWMgbW9uaXRvcmluZyBzZXJ2aWNlcyBmb3I6IFNVQlNaLCBDT05OWiwgTEVBRlosIEpTWiBhbmQgSU5GTyIsImluZm9fdXJsIjoiaHR0cHM6Ly9kb2NzLm5hdHMuaW8vbmF0cy1zZXJ2ZXIvY29uZmlndXJhdGlvbi9zeXNfYWNjb3VudHMiLCJuYW1lIjoiYWNjb3VudC1tb25pdG9yaW5nLXNlcnZpY2VzIiwic3ViamVjdCI6IiRTWVMuUkVRLkFDQ09VTlQuKi4qIiwidHlwZSI6InNlcnZpY2UiLCJyZXNwb25zZV90eXBlIjoiU3RyZWFtIiwiYWNjb3VudF90b2tlbl9wb3NpdGlvbiI6NH0seyJkZXNjcmlwdGlvbiI6IlJlcXVlc3QgYWNjb3VudCBKV1QiLCJpbmZvX3VybCI6Imh0dHBzOi8vZG9jcy5uYXRzLmlvL25hdHMtc2VydmVyL2NvbmZpZ3VyYXRpb24vc3lzX2FjY291bnRzIiwibmFtZSI6ImFjY291bnQtbG9va3VwLXNlcnZpY2UiLCJzdWJqZWN0IjoiJFNZUy5SRVEuQUNDT1VOVC4qLkNMQUlNUy5MT09LVVAiLCJ0eXBlIjoic2VydmljZSIsInJlc3BvbnNlX3R5cGUiOiJTdHJlYW0iLCJhY2NvdW50X3Rva2VuX3Bvc2l0aW9uIjo0fSx7ImRlc2NyaXB0aW9uIjoiUmVxdWVzdCBhbGwgc2VydmVycyBoZWFsdGgiLCJpbmZvX3VybCI6Imh0dHBzOi8vZG9jcy5uYXRzLmlvL25hdHMtc2VydmVyL2NvbmZpZ3VyYXRpb24vc3lzX2FjY291bnRzIiwibmFtZSI6InNlcnZlci1oZWFsdGgtc2VydmljZSIsInN1YmplY3QiOiIkU1lTLlJFUS5TRVJWRVIuKi5IRUFMVEhaIiwidHlwZSI6InNlcnZpY2UiLCJyZXNwb25zZV90eXBlIjoiU3RyZWFtIn1dLCJsaW1pdHMiOnsiaW1wb3J0cyI6MTAsImV4cG9ydHMiOjUsIndpbGRjYXJkcyI6dHJ1ZSwiY29ubiI6MTAsImxlYWYiOjEwLCJzdWJzIjoxMDAwLCJwYXlsb2FkIjoyMDk3MTUyfX19.lKZj99iabc2ae4mDKh-l5B-nNX00Vqv2QjwQbR8epLUAhkeFE07IrbVFXxOlnviN2iul6o2o26nK3nX5ss2DBA"
}
}
}
The
remote_usersproperty is used to generate credential files for leafnode remote connection. On startup, credential files are generated, and each leafnode remote within nats configuration is updated with the path to the credential file. On shutdown, all files are removed. File are configured with0600permission when created.
Configuration file can also be defined as a URL:
NATS_MAGIC_URL="http://localhost:9000/leaf-01.natsmagic.json" natsmagic
Configuration file can also be obtained securely from a Magic Server. The magic configuration file is never written to disk, only the derived NATS configuration is written to temporary file storage (so secrets such as DNS provider credentials are not persisted to a file).
In order for natsmagic to obtain a configuration file, it must first send a request for a given public key, receive a nonce from the server, and finally send another request with a signature for the nonce. If signature is considered valid by the Magic Server, a configuration is returned as a JSON response. If signature is invalid, or if Magic Server do not reply with expected status code, natsmagic will fail to start.
export NATS_MAGIC_URL="http://localhost:9000"
export NATS_MAGIC_SERVER="SUAA7U6QLN252MI44J3RU5SE3AEEKLOW4C6XWH25DAQC7JHRNSZJB2W5PQ"
natsmagic
The value provided to
NATS_MAGIC_SERVERhere is a Nkey seed. It is never exhanged with remote hosts, and remain secrete to the caller and the process. This nkey seed is used to sign the nonce when authenticating against Magic Server. Note that in order for the request to succeed, a configuration must have been declared for the public key associated to this nkey seed BEFORE starting thenatsmagicprocess.
The authorization is like:
ENV <====== CLIENT ===========> SERVER
Read nkey from env ||
<=================//
||
|| Extract public key
|| and private key
\\===============\\
|| Send public key
\\==============>
||
Send nonce ||
<==================//
||
|| Sign nonce using
|| private key
\\ ================>
||
Verify nonce using public key
||
Send configuration file ||
<==================//
If cluster mode is enabled and either domains are provided through config file or NATS_MAGIC_DOMAINS is provided through environment variable, mTLS will be enabled for cluster routes.
Nodes with certificates issued by a trusted CA with a SAN matching a route entry will be allowed to connect.
Note: In order for two servers to be allowed to connect, a route entry must be created for both servers, else TLS handshake will fail.
Just like for cluster mode, mTLS is enabled for gateway routes if at least one domain is configured.
Content type
Image
Digest
sha256:5df16634e…
Size
14.6 MB
Last updated
about 3 years ago
docker pull gucharbon/natsmagic:v2.9.21-dev.20230829