From 14fcf589032a87341c4a2bf58414b2091b42bb90 Mon Sep 17 00:00:00 2001 From: Mariano Cano Date: Wed, 6 Feb 2019 16:41:59 -0800 Subject: [PATCH] Add client implementation of hello-mTLS using nodejs Fixes smallstep/ca-component#138 --- autocert/examples/hello-mtls/README.md | 8 ++-- .../hello-mtls/node/Dockerfile.client | 6 +++ autocert/examples/hello-mtls/node/client.js | 44 +++++++++++++++++++ .../hello-mtls/node/hello-mtls.client.yaml | 22 ++++++++++ autocert/examples/hello-mtls/node/server.js | 6 ++- 5 files changed, 80 insertions(+), 6 deletions(-) create mode 100644 autocert/examples/hello-mtls/node/Dockerfile.client create mode 100644 autocert/examples/hello-mtls/node/client.js create mode 100644 autocert/examples/hello-mtls/node/hello-mtls.client.yaml diff --git a/autocert/examples/hello-mtls/README.md b/autocert/examples/hello-mtls/README.md index a4407881..ec7267f2 100644 --- a/autocert/examples/hello-mtls/README.md +++ b/autocert/examples/hello-mtls/README.md @@ -68,9 +68,9 @@ languages are appreciated! - [X] Restrict to safe ciphersuites and TLS versions - [ ] TLS stack configuration loaded from `step-ca` - [ ] Root certificate rotation -- [ ] Client using autocert root certificate - - [ ] mTLS (send client certificate if server asks for it) - - [ ] Automatic certificate rotation - - [ ] Restrict to safe ciphersuites and TLS versions +- [X] Client using autocert root certificate + - [X] mTLS (send client certificate if server asks for it) + - [X] Automatic certificate rotation + - [X] Restrict to safe ciphersuites and TLS versions - [ ] TLS stack configuration loaded from `step-ca` - [ ] Root certificate rotation diff --git a/autocert/examples/hello-mtls/node/Dockerfile.client b/autocert/examples/hello-mtls/node/Dockerfile.client new file mode 100644 index 00000000..e2ed903b --- /dev/null +++ b/autocert/examples/hello-mtls/node/Dockerfile.client @@ -0,0 +1,6 @@ +FROM node:lts-alpine + +RUN mkdir /src +ADD client.js /src + +CMD ["node", "/src/client.js"] diff --git a/autocert/examples/hello-mtls/node/client.js b/autocert/examples/hello-mtls/node/client.js new file mode 100644 index 00000000..c866ccd5 --- /dev/null +++ b/autocert/examples/hello-mtls/node/client.js @@ -0,0 +1,44 @@ +const fs = require('fs'); +const https = require('https'); + +const config = { + ca: '/var/run/autocert.step.sm/root.crt', + key: '/var/run/autocert.step.sm/site.key', + cert: '/var/run/autocert.step.sm/site.crt', + url: process.env.HELLO_MTLS_URL, + requestFrequency: 5000 +}; + +var options = { + ca: fs.readFileSync(config.ca), + key: fs.readFileSync(config.key), + cert: fs.readFileSync(config.cert), + ciphers: 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256', + minVersion: 'TLSv1.2', + maxVersion: 'TLSv1.2', + // Not necessary as it defaults to true + rejectUnauthorized: true +}; + +fs.watch(config.cert, (event, filename) => { + if (event == 'change') { + options.cert = fs.readFileSync(config.cert); + } +}); + +function loop() { + var req = https.request(config.url, options, function(res) { + res.on('data', (data) => { + process.stdout.write(options.cert) + process.stdout.write(data) + setTimeout(loop, config.requestFrequency); + }); + }); + req.on('error', (e) => { + process.stderr.write('error: ' + e.message + '\n'); + setTimeout(loop, config.requestFrequency); + }) + req.end(); +} + +loop(); diff --git a/autocert/examples/hello-mtls/node/hello-mtls.client.yaml b/autocert/examples/hello-mtls/node/hello-mtls.client.yaml new file mode 100644 index 00000000..14c16fc8 --- /dev/null +++ b/autocert/examples/hello-mtls/node/hello-mtls.client.yaml @@ -0,0 +1,22 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: hello-mtls-client + labels: {app: hello-mtls-client} +spec: + replicas: 1 + selector: {matchLabels: {app: hello-mtls-client}} + template: + metadata: + annotations: + autocert.step.sm/name: hello-mtls-client.default.pod.cluster.local + labels: {app: hello-mtls-client} + spec: + containers: + - name: hello-mtls-client + image: hello-mtls-client-node:latest + imagePullPolicy: Never + resources: {requests: {cpu: 10m, memory: 20Mi}} + env: + - name: HELLO_MTLS_URL + value: https://hello-mtls.default.svc.cluster.local diff --git a/autocert/examples/hello-mtls/node/server.js b/autocert/examples/hello-mtls/node/server.js index 48550e7e..396a4976 100644 --- a/autocert/examples/hello-mtls/node/server.js +++ b/autocert/examples/hello-mtls/node/server.js @@ -9,7 +9,7 @@ var config = { ciphers: 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256', minVersion: 'TLSv1.2', maxVersion: 'TLSv1.2' -} +}; function createSecureContext() { return tls.createSecureContext({ @@ -24,7 +24,7 @@ var ctx = createSecureContext() fs.watch(config.cert, (event, filename) => { if (event == 'change') { - ctx = createSecureContext() + ctx = createSecureContext(); } }); @@ -38,3 +38,5 @@ https.createServer({ res.writeHead(200); res.end('hello nodejs\n'); }).listen(443); + +console.log("Listening on :443 ..."); \ No newline at end of file