8000 Add SNI example · HowProgrammingWorks/NodeServer@8f4f38d · GitHub
[go: up one dir, main page]

Skip to content

Commit 8f4f38d

Browse files
committed
Add SNI example
1 parent 9b93b96 commit 8f4f38d

File tree

4 files changed

+100
-0
lines changed

4 files changed

+100
-0
lines changed

native-sni/README.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Start HTTP server
2+
3+
## With self-signed certificate (for testing)
4+
5+
- Generate certificates, run: `./cert/generate.sh`
6+
- Start server: `node server.js`
7+
- Open in browser: `https://127.0.0.1:8000/`
8+
9+
## With certbot (for production)
10+
11+
- Let's Encrypt is a free certificate authority: https://letsencrypt.org/
12+
- Use Certbot (free tool for automatically generatinging Let’s Encrypt
13+
certificates to enable HTTPS): https://certbot.eff.org/
14+
- Install: `dnf -y install certbot`
15+
- Generate certificate:
16+
`certbot certonly --standalone -d www.domain.com -d domain.com -m your.name@domain.com --agree-tos --no-eff-email`
17+
- Copy certificate:
18+
`cp /etc/letsencrypt/live/domain.com/fullchain.pem ./cert/cert.pem`
19+
- Copy private key:
20+
`cp /etc/letsencrypt/live/domain.com/privkey.pem ./cert/key.pem`
21+
- Or use your web server for challenge exchange:
22+
`certbot certonly --webroot -w ./ -d domain.com -m your.name@domain.com --agree-tos --no-eff-email`

native-sni/cert/generate.ext

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
authorityKeyIdentifier=keyid,issuer
2+
basicConstraints=CA:FALSE
3+
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
4+
subjectAltName = @alt_names
5+
6+
[alt_names]
7+
DNS.1 = domain.com
8+
DNS.2 = localhost
9+
IP.1 = 127.0.0.1
10+
IP.2 = ::1

native-sni/cert/generate.sh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
cd "$(dirname "$0")"
2+
openssl genrsa -out key.pem 3072
3+
openssl req -new -out self.pem -key key.pem -subj '/CN=localhost'
4+
openssl req -text -noout -in self.pem
5+
openssl x509 -req -days 1024 -in self.pem -signkey key.pem -out cert.pem -extfile generate.ext

native-sni/server.js

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
'use strict';
2+
3+
const fs = require('node:fs');
4+
const https = require('node:https');
5+
const tls = require('node:tls');
6+
7+
const user = { name: 'jura', age: 22 };
8+
9+
const routing = {
10+
'/': '<h1>welcome to homepage</h1><hr>',
11+
'/user': user,
12+
'/user/name': () => user.name.toUpperCase(),
13+
'/user/age': () => user.age,
14+
'/hello': { hello: 'world', andArray: [1, 2, 3, 4, 5, 6, 7] },
15+
'/api/method1': (req, res) => {
16+
console.log(req.url + ' ' + res.statusCode);
17+
return { status: res.statusCode };
18+
},
19+
'/api/method2': (req) => ({
20+
user,
21+
url: req.url,
22+
cookie: req.headers.cookie
23+
}),
24+
};
25+
26+
const types = {
27+
object: JSON.stringify,
28+
string: (s) => s,
29+
undefined: () => 'not found',
30+
function: (fn, req, res) => JSON.stringify(fn(req, res)),
31+
};
32+
33+
const key = fs.readFileSync('./cert/key.pem');
34+
const cert = fs.readFileSync('./cert/cert.pem');
35+
36+
const domains = {
37+
'127.0.0.1': tls.createSecureContext({ key, cert }),
38+
'localhost': tls.createSecureContext({ key, cert }),
39+
};
40+
41+
const sni = (servername, callback) => {
42+
console.log({ servername });
43+
const creds = domains[servername];
44+
if (!creds) callback(new Error(`No certificate for ${servername}`));
45+
callback(null, creds);
46+
};
47+
48+
const options = { key, cert, SNICallback: sni };
49+
50+
const server = https.createServer(options, (req, res) => {
51+
const data = routing[req.url];
52+
const type = typeof data;
53+
const serializer = types[type];
54+
const result = serializer(data, req, res);
55+
res.end(result);
56+
});
57+
58+
59+
server.listen(8000);
60+
console.log('Open: https://127.0.0.1:8000');
61+
console.log(' or https://localhost:8000');
62+
63+
setInterval(() => user.age++, 2000);

0 commit comments

Comments
 (0)
0