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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy