Skip to content
This repository has been archived by the owner on Feb 25, 2023. It is now read-only.

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
chernetsov0 committed Jul 6, 2017
0 parents commit 352d890
Show file tree
Hide file tree
Showing 9 changed files with 220 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.git
.gitignore
.gitattributes
23 changes: 23 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
FROM chernetsov0/nginx-alpine:1.13.2

LABEL maintainer="Alexey Chernetsov <chernetsov0@gmail.com>"

# Default environment
ENV DHLEVEL=2048

# Install Certbot and openssl
RUN apk add --no-cache certbot openssl

# Create directories.
RUN mkdir -p /var/lib/nginx-letsencrypt /usr/share/nginx/acme

# Add local files
COPY etc/ /etc/
COPY nginx-letsencrypt.sh /root/nginx-letsencrypt

# Make scripts executable
RUN chmod a+x \
/root/nginx-letsencrypt \
/etc/periodic/daily/10-letsencrypt-renew

CMD /root/nginx-letsencrypt
39 changes: 39 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
This container sets up an Nginx webserver with built-in letsencrypt client that automates free SSL server certificate generation and renewal processes. It is based on scripts from [linuxserver/letsencrypt](https://hub.docker.com/r/linuxserver/letsencrypt/) with some major differences:

* Does not contain **s6-overlay**.
* Does not contain **PHP**.
* Does not contain **fail2ban**.
* Does not restart **NGINX** when renewing. certificate.
* Contains newer version of **Certbot** (*0.14.0* vs *0.9.3*).

## Usage

```
docker create \
--name=nginx-letsencrypt \
-p 443:443 -p 80:80 \
-v <path to data>:/var/lib/nginx-letsencrypt \
-v <path to letsencrypt>:/etc/letsencrypt \
-e EMAIL=<email> \
-e DOMAINS=<domains> \
-e DHLEVEL=2048
-e TZ=<timezone> \
chernetsov0/nginx-letsencrypt
```

## Parameters

* `-p 80 -p 443` - the port(s) used by **NGINX**.
* `-v <path to data>:/var/lib/nginx-letsencrypt` - dhparams file and previous `DOMAINS` and `DHLEVEL` value reside here.
* `-v <path to letsencrypt>:/etc/letsencrypt` - all files letsencrypt generates and uses reside here (including certificate).
* `-e DOMAINS` - domains for letsencrypt to get certificate for.

_Optional:_
* `-e EMAIL` - your e-mail address for cert registration and notifications
* `-e DHLEVEL` - dhparams bit value, can be set to `1024`, `2048` or `4096`.
* `-e TZ` - timezone ie. `America/New_York`.

## Setting up the application

* Before running this container, make sure that all domains in `DOMAINS` are properly forwarded to this container's host, and that ports 80 and 443 are not being used by another service on the host.
* The container detects changes to `DOMAINS`, revokes existing certificate and generates new one during start. It also detects changes to the `DHLEVEL` parameter and replaces the dhparams file.
26 changes: 26 additions & 0 deletions etc/nginx/conf.d/default.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
server {
listen 443 ssl default_server deferred;
server_name _;

include include.ssl;

location / {
root /usr/share/nginx/html;
index index.html index.htm;
}

error_page 404 /404.html;
location = /404.html {
root /usr/share/nginx/html;
}


error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}

location ~ /\.ht {
deny all;
}
}
13 changes: 13 additions & 0 deletions etc/nginx/conf.d/redirect-letsencrypt.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
server {
listen 80 default_server deferred;
server_name _;

location / {
return 301 https://$host$request_uri;
}

location /.well-known {
root /usr/share/nginx/acme/.well-known;
allow all;
}
}
17 changes: 17 additions & 0 deletions etc/nginx/include.ssl
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;";
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";

ssl_prefer_server_ciphers on;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS;
ssl_session_cache shared:SSL:10m;

resolver 127.0.0.1;
ssl_stapling on; # Requires nginx >= 1.3.7
ssl_stapling_verify on; # Requires nginx => 1.3.7

ssl_certificate /etc/letsencrypt/live/nginx-letsencrypt/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/nginx-letsencrypt/privkey.pem;
ssl_dhparam /var/lib/nginx-letsencrypt/dhparams.pem;
25 changes: 25 additions & 0 deletions etc/nginx/nginx.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
worker_processes 1;

error_log stderr notice;

events {
worker_connections 1024;
}

http {
include mime.types;
default_type application/octet-stream;

log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';

sendfile on;
#tcp_nopush on;

keepalive_timeout 65;

#gzip on;

include /etc/nginx/conf.d/*.conf;
}
8 changes: 8 additions & 0 deletions etc/periodic/daily/10-letsencrypt-renew
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/sh

echo "Running certbot renew on "$(date)

certbot renew --noninteractive \
--webroot --webroot-path /usr/share/nginx/acme \
--preferred-challenges http \
--post-hook "nginx -s reload"
66 changes: 66 additions & 0 deletions nginx-letsencrypt.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#!/bin/sh

# Check the environment o make sure that the required variables are set.
if [ -z "$DOMAINS" ]; then
echo "Please pass your DOMAINS as an environment variable"
exit 1
fi

# Load or create saved environment.
if [ ! -f "/var/lib/nginx-letsencrypt/current_env" ]; then
echo -e "CURRENT_DOMAINS=\"$DOMAINS\" CURRENT_DHLEVEL=\"$DHLEVEL\"" > /var/lib/nginx-letsencrypt/current_env
fi

. /var/lib/nginx-letsencrypt/current_env

# Compare dhparams existence and level. (Re)create if necessary.
if [ ! "$DHLEVEL" = "$CURRENT_DHLEVEL" ]; then
rm -rf /var/lib/nginx-letsencrypt/dhparams.pem
echo "DH parameters size changed, deleting old file"
fi

if [ ! -f "/var/lib/nginx-letsencrypt/dhparams.pem" ]; then
openssl dhparam -out /var/lib/nginx-letsencrypt/dhparams.pem "$DHLEVEL"
echo "$DHLEVEL-bit parameters successfully created"
else
echo "$DHLEVEL-bit DH parameters present"
fi

# Check whether to use e-mail when generating certificate.
if [ ! -z $EMAIL ]; then
echo "E-mail address entered: ${EMAIL}"
EMAILPARAM="-m ${EMAIL}"
else
echo "No e-mail address entered, proceeding unsafely"
EMAILPARAM="--register-unsafely-without-email"
fi

# Check for changes in DOMAINS.
# Revoke certificate if necessary.
if [ ! "$DOMAINS" = "$CURRENT_DOMAINS" ]; then
echo "Different DOMAINS entered than what was used before"
echo "Revoking and deleting existing certificate"

certbot revoke --non-interactive \
--cert-path /etc/letsencrypt/live/nginx-letsencrypt/fullchain.pem
fi

# Generate certificate if necessary.
if [ ! -f "/var/lib/nginx-letsencrypt/keys/fullchain.pem" ]; then
echo "Generating new certificate"

certbot certonly --non-interactive --agree-tos \
--standalone --preferred-challenges tls-sni --rsa-key-size 4096 \
--cert-name nginx-letsencrypt $EMAILPARAM -d $DOMAINS
else
/etc/periodic/daily/10-letsencrypt-renew
fi

# Save environment.
echo -e "CURRENT_DOMAINS=\"$DOMAINS\" CURRENT_DHLEVEL=\"$DHLEVEL\"" > /var/lib/nginx-letsencrypt/current_env

# Start crond for autorenewal
crond -f -l 6 -L /dev/stdout &

# Start NGINX.
nginx -g "daemon off;"

0 comments on commit 352d890

Please sign in to comment.