This commit is contained in:
Jiang Yio 2021-08-20 18:20:53 -04:00
parent 7fc11199a6
commit b0d5f884aa
17 changed files with 242 additions and 0 deletions

1
.dockerignore Normal file
View File

@ -0,0 +1 @@
**/.git

16
Dockerfile Normal file
View File

@ -0,0 +1,16 @@
FROM openresty/openresty:alpine-fat
LABEL maintainer "Jiang Yio <inportb@gmail.com>"
RUN apk add --no-cache openssl socat wget inotify-tools && \
luarocks install lua-resty-openidc && \
luarocks install lua-resty-session && \
rm /etc/nginx/conf.d/default.conf && \
mv /etc/nginx/conf.d /usr/local/openresty/nginx/conf/ && \
ln -s /usr/local/openresty/nginx/conf/conf.d /etc/nginx/ && \
echo '0 12 * * * /root/.acme.sh/acme.sh --cron --home /root/.acme.sh' >> /etc/crontabs/root
RUN wget -O - https://get.acme.sh | sh
COPY app /root
WORKDIR /root
ENTRYPOINT ["/root/init.sh"]

View File

@ -1,2 +1,28 @@
# docker-nginx-auto
Nginx with tricks
- OpenResty
- Snippets for TLS/SSL, gzip, reverse proxy, websocket proxy, and proxy cache
- Automatic Let's Encrypt certificate
- Automatic reload on configuration change
Production:
```sh
docker run -d --name=docker-nginx-auto \
-e ACME_EMAIL=user@host \
-p 80:80 -p 443:443 \
-v nginx-config:/usr/local/openresty/nginx/conf \
docker-nginx-auto
```
Staging:
```sh
docker run -d --name=docker-nginx-auto \
-e ACME_STAGING=true \
-p 80:80 -p 443:443 \
-v nginx-config:/usr/local/openresty/nginx/conf \
docker-nginx-auto
```

41
app/acme-autocert.sh Executable file
View File

@ -0,0 +1,41 @@
#!/bin/sh
. /root/common.sh
get_domains() {
cat /etc/nginx/conf.d/* \
| sed 's/^[[:blank:]]*//' \
| grep ^server_name \
| grep -v 'NOSSL' \
| cut -d';' -f1 \
| awk '{for(i=2; i<=NF; i++) print $i}' \
| awk '{$1=$1};1' \
| grep -E '^[[:alnum:]_-]+([.][[:alnum:]_-]+)*$' \
| sort | uniq
}
get_args() {
if [ "${ACME_STAGING}" != "" ]; then
echo --staging
fi
if [ "${ACME_EMAIL}" != "" ]; then
echo --email
echo "${ACME_EMAIL}"
fi
echo --issue
echo --webroot
echo /var/www
for h in `get_domains`; do
echo -d
echo "$h"
done
}
if [ "${RELOAD_FIRST}" != "no" ]; then
"${BIN}" -s reload
fi
if /root/.acme.sh/acme.sh \
--key-file "${CONF}/ssl.key" --fullchain-file "${CONF}/ssl.cer" \
"$@" `get_args`; then
"${BIN}" -s reload
fi

3
app/acme-renew.sh Executable file
View File

@ -0,0 +1,3 @@
#!/bin/sh
/root/.acme.sh/acme.sh --cron "$@"

19
app/add-proxy.sh Executable file
View File

@ -0,0 +1,19 @@
#!/bin/sh
NAME="$1"
URL="$2"
. /root/common.sh
cat > "${CONF}/conf.d/auto.${NAME}.conf" <<EOF
server {
server_name ${NAME};
server_tokens off;
include snippets/ssl.conf;
include snippets/gzip.conf;
location / {
proxy_pass ${URL};
include snippets/reverse-proxy.conf;
}
}
EOF

2
app/common.sh Normal file
View File

@ -0,0 +1,2 @@
BIN=/usr/local/openresty/bin/openresty
CONF=/usr/local/openresty/nginx/conf

View File

@ -0,0 +1,9 @@
resolver local=on;
lua_shared_dict sessions 10m;
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=proxycache:5m max_size=5g inactive=60m use_temp_path=off;
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}

View File

@ -0,0 +1,6 @@
gzip on;
gzip_vary on;
gzip_min_length 10240;
gzip_proxied expired no-cache no-store private auth;
gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml;
gzip_disable "MSIE [1-6]\.";

View File

@ -0,0 +1,6 @@
proxy_cache proxycache;
proxy_cache_revalidate on;
proxy_cache_min_uses 3;
proxy_cache_use_stale error timeout invalid_header updating http_500 http_502 http_503 http_504;
proxy_cache_background_update on;
proxy_cache_lock on;

View File

@ -0,0 +1,7 @@
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
proxy_set_header X-Forwarded-Proto $scheme;
#proxy_set_header X-Forwarded-Scheme $scheme;
proxy_set_header X-Scheme $scheme;

View File

@ -0,0 +1,26 @@
listen 80;
listen [::]:80;
listen 443 ssl;
listen [::]:443 ssl;
if ($scheme != "https") {
return 302 https://$host$request_uri;
}
# https://wiki.mozilla.org/Security/Server_Side_TLS
# https://ssl-config.mozilla.org/
ssl_certificate ssl.cer;
ssl_certificate_key ssl.key;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
add_header Strict-Transport-Security "max-age=63072000" always; # HSTS (needs ngx_http_headers_module)
ssl_stapling on; # OCSP stapling
ssl_stapling_verify on;
location /.well-known/ {
root /var/www;
}

View File

@ -0,0 +1,3 @@
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;

18
app/default/ssl.cer Normal file
View File

@ -0,0 +1,18 @@
-----BEGIN CERTIFICATE-----
MIIC2TCCAcGgAwIBAgIUD5GwT+AINCz3va62MacN3fcSnoEwDQYJKoZIhvcNAQEL
BQAwFDESMBAGA1UEAwwJdnBzMTczMTM0MB4XDTIwMDIxODA0MzEwMloXDTMwMDIx
NTA0MzEwMlowFDESMBAGA1UEAwwJdnBzMTczMTM0MIIBIjANBgkqhkiG9w0BAQEF
AAOCAQ8AMIIBCgKCAQEAzqxnIhy3gT4e3HYdz5G8/T6zo4a1QMaTcFixdLzH5IuE
c+9eRMJC23AbJCcscYaXmUb8D8vi03PSIDZZLxQiMeiKXVACMnX04IWTMit11SXa
MWgXkSiA1JUxMyTRYX2u1lMXU9dQl+J7/9HIxgPCZqOe4y87Zl2b5NW8Lzo3sGIK
RIJzmgJyywPDHLcU5VTwlJLO/929GwL9aWy+ExXOeBF3vo0bhQBa3pUHviVpq8iw
1OTwl965BgbCwVZgmRxxY/PivURrh4dPSDpnOwJHxlRixEHoq9WrHC9IUgVf9p4S
MFKIjLYPcf1gmHjmklfCi085ze8Uyx7bxzE2BEe3owIDAQABoyMwITAJBgNVHRME
AjAAMBQGA1UdEQQNMAuCCXZwczE3MzEzNDANBgkqhkiG9w0BAQsFAAOCAQEAHd5R
ztdZrd2m5BlOwTHKht4xmtdfh15jeEADskQqar1JFrHy3Os+EtMHBh0zd4ZDAXke
WuheLO/MxOa22g190Jx+FyZd2hDzbMliRElQGzyTe6q0fFPEpCOfzzG7q4f0iouR
V6825A6FC9zKsCcUS2jEQKwNpHojYQApkRsyzeq44vRkfUlcHvwd5fXET/uFlNxK
b2i7fX4hI/0tM6IAIVsq48hhWpx5j0ilebzW1v51xVGs0kDzOTh0weBcqjFX33nz
hJXFoGYoqexERI1u8Wnc9Zw9dVKX8ovclIAe6u2AzWXzjBY1PmBW+JKSjYNlaejr
pWgePOeIs67AdY0lRQ==
-----END CERTIFICATE-----

28
app/default/ssl.key Normal file
View File

@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDOrGciHLeBPh7c
dh3Pkbz9PrOjhrVAxpNwWLF0vMfki4Rz715EwkLbcBskJyxxhpeZRvwPy+LTc9Ig
NlkvFCIx6IpdUAIydfTghZMyK3XVJdoxaBeRKIDUlTEzJNFhfa7WUxdT11CX4nv/
0cjGA8Jmo57jLztmXZvk1bwvOjewYgpEgnOaAnLLA8MctxTlVPCUks7/3b0bAv1p
bL4TFc54EXe+jRuFAFrelQe+JWmryLDU5PCX3rkGBsLBVmCZHHFj8+K9RGuHh09I
Omc7AkfGVGLEQeir1ascL0hSBV/2nhIwUoiMtg9x/WCYeOaSV8KLTznN7xTLHtvH
MTYER7ejAgMBAAECggEAM1SEZOeG+BWKqqy3aLdEng01ppata8ImGlAc+uZsKyov
om/AFQm+eyvTwd3s3uFTw6Dqt62mz2fDt3ZoHhY9C/I6c0SM1yWOxTjHvz0mDeNR
1tWIjOfnX2USjCZHzpPdmaOXdp5SiPaaX4Yl/HAwlzdqHfi8Iwd60ZH4JC6saCTv
L1vQzj+nuJwswSaoYxeO/3lBN9W9TL84fPX9g5alh4AdMzQyluFqNmhq2cZqTcDz
sHZ3vXboNAsbRu+RQTWqmG+bzfXDGpbXzxDD0jQbSJMSNAgZx3g1LCb0sdBlXh2R
Hy1dED3Vt5+07UwAB5IVUUSnyNTg4F493l9hUewb8QKBgQDnWP2PPsHtwM9t9xbi
H5dFxrVRce7mV0dCi84g6qnGlcT0r19jNuxkIUdNYO1SywC18MHPTrwAXhcyKz0+
jISrYKGa8Zla8sPwVwoidFyHWkZcJMy55YlVowYGsZkBhzVqIH7C4d9lgpFof0G3
KKsVU4TOpqrcNKqiO6PCuppxewKBgQDkslFBXoAbeKVktliAwR4nwqW5jeLuUSoa
dLVNMGi96griiYixOe5DVhKegeBPz0m2A1Kj58lgnO/v7VOXBQt4ONr3WuhGqca2
8K0d9eEBijMBVjWBEZpJO0E+V9quIpyF050pZyntTjjESpYEp+hFTKVlCxp7+iJn
znBHv6zV+QKBgAKFO6311xMKCLh/+qXYBkPiWFNc1Gd6B/K3pzVAmTzqoMyxpG5m
SMkGe8piBfPi9k0FJHdnujCe1c3cHryxtzhOwzP28d7FylCyAhBCCEgJOb8DP5++
2nIuZoBoKuyTVoejdv4Ui+SFOaRTzpl6PfLriATgV/gyMrG1yKD0e35FAoGAMjVD
yYoprd5K0VWHEJ1VNX1yTM5tp8yB5dUBiLS8ChW71ghDzkTdnkLjS5FP4bWshR0t
o3Zbq65Iru/3jgw5fGdfCzcWD41uZvNnzlAQ2fmxQPXgQTnQGYu8wyceh2Rp4KeY
tWJEviiSJeYKEXObdrthBFHvupArxYZ4+AeItmECgYEA1dFJVGM2mvp4SumdaNYD
qy3Tvy2wpB6TY0bPBvsRQoeAkV/mKOuwi71iBEcZbkJP6aqqccmKwlb8d2s4mfdB
+Ok84Lnz2BO6sORklDAltS3G3b1LC9wQyl4hO+Drf4zjXkH0LEk+ZQMhTJazU5mW
WQUFIyLfPb9HtUk0lhBcZyM=
-----END PRIVATE KEY-----

17
app/init.sh Executable file
View File

@ -0,0 +1,17 @@
#!/bin/sh
. /root/common.sh
false | cp -ai /root/default/* "${CONF}/" 2>/dev/null
if ! [ -e "${CONF}/sites-enabled" ]; then
ln -s conf.d "${CONF}/sites-enabled"
fi
mkdir -p /var/log/nginx /var/cache/nginx
/root/reloader.sh &
(sleep 30; RELOAD_FIRST=no /root/acme-autocert.sh) &
/usr/sbin/crond -b
"${BIN}" -g 'daemon off;' "$@"

14
app/reloader.sh Executable file
View File

@ -0,0 +1,14 @@
#!/bin/sh
. /root/common.sh
while inotifywait -q -r -e create -e modify -e delete -e move \
--exclude .swp "${CONF}"; do
if "${BIN}" -t; then
echo "reloader: new configuration"
"${BIN}" -s reload
RELOAD_FIRST=no /root/acme-autocert.sh
else
echo "reloader: invalid configuration"
fi
done