Skip to content

Commit

Permalink
adds makecerts: creates ssl certs for the app, nginx (static) and loc…
Browse files Browse the repository at this point in the history
…alstack
  • Loading branch information
scott2b committed May 30, 2020
1 parent 3da9344 commit 9634bb4
Show file tree
Hide file tree
Showing 8 changed files with 232 additions and 20 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
.env
.in
.localstack/
package-lock.json
node_modules/*


# Ignore the build directory

Expand Down
76 changes: 76 additions & 0 deletions README_DOCKER.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@


## Development


### Additional repositories

[fablib](https://github.com/NUKnightLab/fablib) and the
[knightlab cdn](https://github.com/NUKnightLab/cdn.knightlab.com) should be
co-resident with this repository:

```
$ cd ..
$ git clone [email protected]:NUKnightLab/fablib.git
$ git clone [email protected]:NUKnightLab/cdn.knightlab.com.git
```

### Install less

```
$ npm install -g npm
$ npm install less -g
$ npm install uglify-js -g
```

### Build the static media

Build static to the build directory:

```
$ fab build
```

- **or** -

Build static and copy files to the dev location in the cdn repository:

```
$ fab stage_dev
```

Static files are hosted via an Nginx container from the build directory. See
the compose file for details.

### Setup ssl

```
$ ./makecerts.sh
```

Set SSL cert trust:

#### Firefox:

* Preferences > Certificates
* View certificates
* Import: .localstack/KnightLabRoot.pem

#### Chrome (Mac):

Add the cert to keychain:

* File > Import items ...
* .localstack/server.test.pem
* set trust SSL


For building static media, you will need a Python2 virtualenvironment with the
dependencies in `requirements.p2.txt` installed. See the fablib repo for static
build details.

### Run the stack

```
$ docker-compose up
```
14 changes: 8 additions & 6 deletions api.py
Original file line number Diff line number Diff line change
Expand Up @@ -970,17 +970,19 @@ def redirect_old_urls(path):
opts, args = getopt.getopt(sys.argv[1:], "sp:", ["port="])
for opt, arg in opts:
if opt == '-s':
if (os.path.isfile('local_only.crt') and os.path.isfile('local_only.key')):
ssl_context = ('local_only.crt', 'local_only.key')
crt_file = os.environ.get('APP_SSL_CRT_FILE', 'local_only.crt')
key_file = os.environ.get('APP_SSL_KEY_FILE', 'local_only.key')
if (os.path.isfile(crt_file) and os.path.isfile(key_file)):
ssl_context = (crt_file, key_file)
else:
print('''
print("""
To run HTTPS locally you should create a crt/key file.
Don't put them in the repository, because if you tell your browser to trust the certificate
and an adversary got the cert from the public repository, they could take
advantage of you.
Use this command to create the files:
openssl req -x509 -sha256 -nodes -days 10000 -newkey rsa:2048 -keyout local_only.key -out local_only.crt
''')
Run ./makecerts.sh to create the files:
""")
sys.exit(1)
elif opt in ('-p', '--port'):
port = int(arg)
Expand Down
7 changes: 4 additions & 3 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ services:
- localstack:localstack
volumes:
- .:/usr/src/apps/StoryMapJS
- .localstack:/usr/src/apps/StoryMapJS/.localstack
env_file: .env
command: python api.py -s -p 5000
depends_on:
Expand All @@ -33,9 +34,9 @@ services:
image: nginx:alpine
volumes:
- ./build:/var/www
- ./default.conf:/etc/nginx/conf.d/default.conf
- ./localhost.crt:/etc/nginx/conf.d/server.crt
- ./localhost.key:/etc/nginx/conf.d/server.key
- ./localhost/default.conf:/etc/nginx/conf.d/default.conf
- .localstack/server.test.pem.crt:/etc/nginx/conf.d/server.crt
- .localstack/server.test.pem.key:/etc/nginx/conf.d/server.key
ports:
- "3000:443"

Expand Down
67 changes: 67 additions & 0 deletions localhost/default.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
server {
listen 80 default_server;
listen [::]:80 default_server;
return 301 https://$server_name$request_uri;
}

server {
listen 443 ssl;

server_name ~.;

ssl_certificate /etc/nginx/conf.d/server.crt;
ssl_certificate_key /etc/nginx/conf.d/server.key;

#location / {
# add_header 'Access-Control-Allow-Origin' $http_origin;
# add_header 'Access-Control-Allow-Credentials' 'true';
# add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
# add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
# root /var/www;
#}

#
# Wide-open CORS config for nginx
# https://enable-cors.org/server_nginx.html
#
location / {
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' $host;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
#
# Custom headers and headers various browsers *should* be OK with but aren't
#
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
#
# Tell client that this pre-flight info is valid for 20 days
#
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204;
}
if ($request_method = 'POST') {
add_header 'Access-Control-Allow-Origin' $host;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
}
if ($request_method = 'GET') {
add_header 'Access-Control-Allow-Origin' $host;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
}
root /var/www;
}

## If the static server was another docker service,
## It is possible to forward requests to its port:
# location / {
# proxy_set_header Host $host;
# proxy_set_header X-Real-IP $remote_addr;
# proxy_pass http://web:3000/;
# }
}


6 changes: 6 additions & 0 deletions localhost/domains.ext
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names
[alt_names]
DNS.1 = localhost
11 changes: 0 additions & 11 deletions makecert.sh

This file was deleted.

68 changes: 68 additions & 0 deletions makecerts.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# Adapted from:
# https://gist.github.com/cecilemuller/9492b848eb8fe46d462abeb26656c4f8

CERTDIR=.localstack
CA=KnightLabRootCA
FN=server.test.pem
STATE=Illinois
CITY=Evanston
COUNTRY=US
ORG=KnightLab
COMMON_NAME=localhost.storymap

mkdir -p .localstack

if [[ -f $CERTDIR/$FN
|| -f $CERTDIR/$FN.crt
|| -f $CERTDIR/$FN.key
|| -f $CERTDIR/$CA.crt
|| -f $CERTDIR/$CA.key
|| -f $CERTDIR/$CA.pem
|| -f $CERTDIR/$CA.srl
]]; then
echo "Please delete existing cert files to run this script.\n\nTo delete, execute: rm $CERTDIR/$FN*; rm $CERTDIR/$CA.*"
exit 1
fi

# Generate CA


openssl req \
-x509 \
-nodes \
-new \
-sha256 \
-days 1024 \
-newkey rsa:2048 \
-keyout $CERTDIR/$CA.key \
-out $CERTDIR/$CA.pem \
-subj "/C=$COUNTRY/CN=$CA"

openssl x509 -outform pem -in $CERTDIR/$CA.pem -out $CERTDIR/$CA.crt

# Generate domain name cert


openssl req \
-new \
-nodes \
-newkey rsa:2048 \
-keyout $CERTDIR/$FN.key \
-out $CERTDIR/$FN.csr \
-subj "/C=$COUNTRY/ST=$STATE/L=$CITY/O=$ORG/CN=$COMMON_NAME"

openssl x509 \
-req \
-sha256 \
-days 1024 \
-in $CERTDIR/$FN.csr \
-CA $CERTDIR/$CA.pem \
-CAkey $CERTDIR/$CA.key \
-CAcreateserial \
-extfile localhost/domains.ext \
-out $CERTDIR/$FN.crt

cat $CERTDIR/$FN.key $CERTDIR/$FN.crt > $CERTDIR/$FN

echo "Trust cert. E.g.: Apple Keychain > System. File > Import items: $CERTDIR/$FN\n\nSet to trust SSL."
echo "\nFor Firefox: Preferences > Certificates > View Certificates > Import $CERTDIR/$FN."

0 comments on commit 9634bb4

Please sign in to comment.