Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

2 - Fetch cert files from Internet and check validity #8

Merged
merged 5 commits into from
Mar 22, 2021
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
FROM nginx:1.19-alpine
FROM nginx:1.19

EXPOSE 80 443

COPY cert/* /etc/nginx/
RUN cat /etc/nginx/server.pem /etc/nginx/chain.pem > /etc/nginx/server.chained.pem
ENTRYPOINT ["/entrypoint.sh"]

CMD ["nginx", "-g", "daemon off;"]
37 changes: 28 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,27 @@ with https:// , Nginx redirects the request to the HTTPS version
for you 😉.

**Docker note**: A local image is created the first time executed, and
there is no need to rebuild it if you change the Nginx configurations,
unless you want to change the certificates or the Dockerfile script.
there is no need to rebuild it if you change the Nginx configuration or
the `entrypoint.sh` file, unless you want to make changes in
the Dockerfile script, so if you edit the Nginx configuration, or want
to change the ports mapped, only restart the container is needed.
mrsarm marked this conversation as resolved.
Show resolved Hide resolved

### Public SSL certificate

The startup script in the container downloads the cert files
from [local-ip.co](http://local-ip.co/) if they were not previously
downloaded, and checks whether they are expired, if so the script
downloads the certs again from source.

So the certs are downloaded from Internet only the first time, and
cached in the container until they expire.
mrsarm marked this conversation as resolved.
Show resolved Hide resolved

### Running with Medic-OS
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not specific to this PR - but maybe consider making this section generic? That is, it is the default for most any web server to listen on port 80 or 443, not just medic-os container. So while we're Medic and there's lots of medic-os users, generic might be a better way to frame this.

Also, I would imagine that instead of running yet another container, folks who are already running medic-os should likely just install the cert in the existing container, as this is already supported per our self hosted docs. I think we should add a link this and a little information that you can do both (either add the cert to existing container or run this container and remap ports)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes agree, feel free to create another PR to reframe this section, and the name of the .env file.


The default ports used here will conflict with the ports that medic-os uses to run. To get around that you can specify the env-file for medic-os. This will start the container using 444 and 8080 for https and http, making your instance available at `https://192-168-0-3.my.local-ip.co:444/`
The default ports used here will conflict with the ports that medic-os
uses to run. To get around that you can specify the env-file for medic-os.
This will start the container using 444 and 8080 for https and http,
making your instance available at `https://192-168-0-3.my.local-ip.co:444/`.

Command to run:

Expand Down Expand Up @@ -92,29 +107,33 @@ ERROR: for nginx-local-ip_app_1 Cannot start service app: driver failed program
5cdae3a684): Error starting userland proxy: listen tcp4 0.0.0.0:443: bind: address already in use
```

You may need to change one or both ports. For example, you could shift them up to 8xxx like so:
You may need to change one or both ports. For example, you could shift them
up to 8xxx like so:

$ HTTP=8080 HTTPS=8443 APP_URL=http://192.168.1.3:5988 docker-compose up

Also a convenient environment file can be used to store the new values as suggested in the [Running with Medic-OS](#running-with-medic-os) section:
Also a convenient environment file can be used to store the new values as
suggested in the [Running with Medic-OS](#running-with-medic-os) section:

**my.env file:**

HTTP=8080
HTTPS=444
HTTPS=8443

Run with: `APP_URL=https://192.168.1.3:5988 docker-compose --env-file=my.env up`

You would then access your dev instance with the `8443` port. Using the sample URL from above, it would go from `https://192-168-0-3.my.local-ip.co` to this instead `https://192-168-0-3.my.local-ip.co:8443`.
You would then access your dev instance with the `8443` port.
Using the sample URL from above, it would go from `https://192-168-0-3.my.local-ip.co`
to this instead `https://192-168-0-3.my.local-ip.co:8443`.


Copyright
---------

Copyright 2021 Medic Mobile, Inc. <hello@medic.org>.

The certificates files under the `cert/` folder are property of
**local-ip.co**.
The SSL certificate files are downloaded from Internet at runtime,
and are property of **local-ip.co**.


License
Expand Down
26 changes: 0 additions & 26 deletions cert/chain.pem

This file was deleted.

28 changes: 0 additions & 28 deletions cert/server.key

This file was deleted.

30 changes: 0 additions & 30 deletions cert/server.pem

This file was deleted.

1 change: 1 addition & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@ app:
- "${HTTPS}:443"
volumes:
- ./default.conf.template:/etc/nginx/templates/default.conf.template
- ./entrypoint.sh:/entrypoint.sh
environment:
APP_URL: $APP_URL
55 changes: 55 additions & 0 deletions entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#!/bin/bash

# SSL certificate files and source URLs
CERT_PEM='/etc/nginx/server.pem'
CERT_PEM_SRC='http://local-ip.co/cert/server.pem'
CERT_KEY='/etc/nginx/server.key'
CERT_KEY_SRC='http://local-ip.co/cert/server.key'
CERT_CHAIN='/etc/nginx/chain.pem'
CERT_CHAIN_SRC='http://local-ip.co/cert/chain.pem'
CERT_CHAINED='/etc/nginx/server.chained.pem'

CURL_CMD='curl -sS'

install_certs () {
echo "$0: Downloading '$CERT_PEM_SRC' ..."
$CURL_CMD "$CERT_PEM_SRC" -o "$CERT_PEM"

echo "$0: Downloading '$CERT_KEY_SRC' ..."
$CURL_CMD "$CERT_KEY_SRC" -o "$CERT_KEY"

echo "$0: Downloading '$CERT_CHAIN_SRC' ..."
$CURL_CMD "$CERT_CHAIN_SRC" -o "$CERT_CHAIN"

echo "$0: Creating chained cert file '$CERT_CHAINED' ..."
cat "$CERT_PEM" "$CERT_CHAIN" > "$CERT_CHAINED"
}

DOWNLOAD="false"
if [ -f "$CERT_PEM" -a -f "$CERT_KEY" -a -f "$CERT_CHAIN" ]; then
echo "$0: SSL certificate files /etc/nginx/server.* found"
else
echo "$0: SSL certificate files /etc/nginx/server.* not found. Installing ..."
DOWNLOAD="true"
install_certs
fi

CERT_EXP_DATE=$(openssl x509 -enddate -noout -in $CERT_PEM | grep -oP 'notAfter=\K.+')
CERT_EXP_DATE_ISO=$(date -d "$CERT_EXP_DATE" '+%Y-%m-%d')

TODAY_ISO=$(date '+%Y-%m-%d')
if [[ "$CERT_EXP_DATE_ISO" < "$TODAY_ISO" ]]; then
if [ "$DOWNLOAD" == "false" ]; then
echo "$0: SSL certificate expired! Installing new certificate files ..."
install_certs
else
echo "$0: ERROR SSL certificate files have been downloaded but expired since: $CERT_EXP_DATE" >&2
exit -1
fi
else
echo "$0: SSL certificate OK. Expire after: $CERT_EXP_DATE"
fi

. /docker-entrypoint.sh

exec "$@"