commit 6910099873f3f2b75dff3a428eb25db84f145a6c
parent 283a76f7e9529286198f768056d8298017baf8cb
Author: PaulSzymanski <519954+PaulSzymanski@users.noreply.github.com>
Date: Tue, 24 Mar 2020 15:11:08 +0100
Set up tls for developing PWA features
Diffstat:
9 files changed, 148 insertions(+), 5 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -1,2 +1,3 @@
node_modules
-.DS_Store
-\ No newline at end of file
+.DS_Store
+fqdn.env
+\ No newline at end of file
diff --git a/README.md b/README.md
@@ -53,13 +53,32 @@ ShareDrop uses WebRTC only and isn't compatible with Safari browsers. Snapdrop u
## Local Development
[Install docker with docker-compose.](https://docs.docker.com/compose/install/)
+Clone the repository:
```
git clone git@github.com:RobinLinus/snapdrop.git
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
The client expects the server at http(s)://your.domain/server.
diff --git a/docker-compose.yml b/docker-compose.yml
@@ -8,9 +8,18 @@ services:
- ./server/:/home/node/app
command: ash -c "npm i && node index.js"
nginx:
- image: "nginx:alpine"
+ build:
+ context: ./
+ dockerfile: nginx-with-openssl.Dockerfile
+ image: "nginx-with-openssl"
volumes:
- ./client:/usr/share/nginx/html
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf
+ - ./certs:/etc/ssl/certs
+ - ./openssl:/mnt/openssl
ports:
- "8080:80"
+ - "443:443"
+ env_file: fqdn.env
+ entrypoint: /mnt/openssl/create.sh
+ command: ["nginx", "-g", "daemon off;"]
+\ No newline at end of file
diff --git a/fqdn.env b/fqdn.env
@@ -0,0 +1 @@
+FQDN=localhost
+\ No newline at end of file
diff --git a/nginx-with-openssl.Dockerfile b/nginx-with-openssl.Dockerfile
@@ -0,0 +1,3 @@
+FROM nginx:alpine
+
+RUN apk add --no-cache openssl
+\ No newline at end of file
diff --git a/nginx/default.conf b/nginx/default.conf
@@ -18,6 +18,47 @@ server {
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;
# redirect server error pages to the static page /50x.html
diff --git a/openssl/create.sh b/openssl/create.sh
@@ -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 "$@"
+\ No newline at end of file
diff --git a/openssl/snapdropCA.cnf b/openssl/snapdropCA.cnf
@@ -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
+
diff --git a/openssl/snapdropCert.cnf b/openssl/snapdropCert.cnf
@@ -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
+\ No newline at end of file