Set up tls for developing PWA features

This commit is contained in:
PaulSzymanski 2020-03-24 15:11:08 +01:00
parent 283a76f7e9
commit 6910099873
9 changed files with 142 additions and 4 deletions

1
.gitignore vendored
View file

@ -1,2 +1,3 @@
node_modules node_modules
.DS_Store .DS_Store
fqdn.env

View file

@ -53,13 +53,32 @@ ShareDrop uses WebRTC only and isn't compatible with Safari browsers. Snapdrop u
## Local Development ## Local Development
[Install docker with docker-compose.](https://docs.docker.com/compose/install/) [Install docker with docker-compose.](https://docs.docker.com/compose/install/)
Clone the repository:
``` ```
git clone git@github.com:RobinLinus/snapdrop.git git clone git@github.com:RobinLinus/snapdrop.git
cd snapdrop cd snapdrop
docker-compose up docker-compose up -d
``` ```
Now point your browser to http://localhost:8080. To restart the containers run `docker-compose restart`.
To stop the containers run `docker-compose stop`.
Now point your browser to `http://localhost:8080`.
### Testing PWA related features
PWAs require that the app is served under a correctly set up and trusted TLS endpoint.
The nginx container creates a CA certificate and a website certificate for you. To correctly set the common name of the certificate you need to change the FQDN environment variable in `fqdn.env` to the fully qualified domain name of your workstation.
If you want to test PWA features you need to trust the CA of the certificate for your local deployment. For your convenience you can download the crt file from `http://<Your FQDN>:8080/ca.crt`. Install that certificate to the trust store of your operating system.
- On windows make sure to install it to the `Trusted Root Certification Authorities` store.
- On macOS double click the installed CA certificate in `Keychain Access` expand `Trust` and select `Always Trust` for SSL.
- Firefox uses its own trust store. To install the CA point Firefox at `http://<Your FQDN>:8080/ca.crt`. When prompted select `Trust this CA to identify websites` and click OK.
- When using Chrome you need to restart Chrome so it reloads the trust store (`chrome://restart`). Additionally, after installing a new cert you need to clear the Storage (DevTools -> Application -> Clear storagae -> Clear site data).
Please note that the certificates (CA and webserver cert) expire after a day.
Also whenever you restart the nginx docker container new certificates are created.
       
## Deployment Notes ## Deployment Notes
The client expects the server at http(s)://your.domain/server. The client expects the server at http(s)://your.domain/server.

View file

@ -8,9 +8,18 @@ services:
- ./server/:/home/node/app - ./server/:/home/node/app
command: ash -c "npm i && node index.js" command: ash -c "npm i && node index.js"
nginx: nginx:
image: "nginx:alpine" build:
context: ./
dockerfile: nginx-with-openssl.Dockerfile
image: "nginx-with-openssl"
volumes: volumes:
- ./client:/usr/share/nginx/html - ./client:/usr/share/nginx/html
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf - ./nginx/default.conf:/etc/nginx/conf.d/default.conf
- ./certs:/etc/ssl/certs
- ./openssl:/mnt/openssl
ports: ports:
- "8080:80" - "8080:80"
- "443:443"
env_file: fqdn.env
entrypoint: /mnt/openssl/create.sh
command: ["nginx", "-g", "daemon off;"]

1
fqdn.env Normal file
View file

@ -0,0 +1 @@
FQDN=localhost

View file

@ -0,0 +1,3 @@
FROM nginx:alpine
RUN apk add --no-cache openssl

View file

@ -18,6 +18,47 @@ server {
proxy_set_header X-Forwarded-for $remote_addr; proxy_set_header X-Forwarded-for $remote_addr;
} }
location /ca.crt {
alias /etc/ssl/certs/snapdropCA.crt;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
server {
listen 443 ssl http2;
ssl_certificate /etc/ssl/certs/snapdrop-dev.crt;
ssl_certificate_key /etc/ssl/certs/snapdrop-dev.key;
#server_name ;
#charset koi8-r;
#access_log /var/log/nginx/host.access.log main;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
location /server {
proxy_connect_timeout 300;
proxy_pass http://node:3000;
proxy_set_header Connection "upgrade";
proxy_set_header Upgrade $http_upgrade;
proxy_set_header X-Forwarded-for $remote_addr;
}
location /ca.crt {
alias /etc/ssl/certs/snapdropCA.crt;
}
#error_page 404 /404.html; #error_page 404 /404.html;
# redirect server error pages to the static page /50x.html # redirect server error pages to the static page /50x.html

9
openssl/create.sh Executable file
View file

@ -0,0 +1,9 @@
#!/bin/sh
cnf_dir='/mnt/openssl/'
certs_dir='/etc/ssl/certs/'
openssl req -config ${cnf_dir}snapdropCA.cnf -new -x509 -days 1 -keyout ${certs_dir}snapdropCA.key -out ${certs_dir}snapdropCA.crt
openssl req -config ${cnf_dir}snapdropCert.cnf -new -out /tmp/snapdrop-dev.csr -keyout ${certs_dir}snapdrop-dev.key
openssl x509 -req -in /tmp/snapdrop-dev.csr -CA ${certs_dir}snapdropCA.crt -CAkey ${certs_dir}snapdropCA.key -CAcreateserial -extensions req_ext -extfile ${cnf_dir}snapdropCert.cnf -sha512 -days 1 -out ${certs_dir}snapdrop-dev.crt
exec "$@"

26
openssl/snapdropCA.cnf Normal file
View file

@ -0,0 +1,26 @@
[ req ]
default_bits = 2048
default_md = sha256
default_days = 1
encrypt_key = no
distinguished_name = subject
x509_extensions = x509_ext
string_mask = utf8only
prompt = no
[ subject ]
organizationName = Snapdrop
OU = CA
commonName = snapdrop-CA
[ x509_ext ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
# You only need digitalSignature below. *If* you don't allow
# RSA Key transport (i.e., you use ephemeral cipher suites), then
# omit keyEncipherment because that's key transport.
basicConstraints = critical, CA:TRUE, pathlen:0
keyUsage = critical, digitalSignature, keyEncipherment, cRLSign, keyCertSign

29
openssl/snapdropCert.cnf Normal file
View file

@ -0,0 +1,29 @@
[ req ]
default_bits = 2048
default_md = sha256
default_days = 1
encrypt_key = no
distinguished_name = subject
req_extensions = req_ext
string_mask = utf8only
prompt = no
[ subject ]
organizationName = Snapdrop
OU = Development
# Use a friendly name here because it's presented to the user. The server's DNS
# names are placed in Subject Alternate Names. Plus, DNS names here is deprecated
# by both IETF and CA/Browser Forums. If you place a DNS name here, then you
# must include the DNS name in the SAN too (otherwise, Chrome and others that
# strictly follow the CA/Browser Baseline Requirements will fail).
commonName = ${ENV::FQDN}
[ req_ext ]
subjectKeyIdentifier = hash
basicConstraints = CA:FALSE
keyUsage = digitalSignature, keyEncipherment
subjectAltName = DNS:${ENV::FQDN}
nsComment = "OpenSSL Generated Certificate"
extendedKeyUsage = serverAuth