-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
31b4fe1
commit d1619c1
Showing
16 changed files
with
383 additions
and
2 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
FROM nginx:1.26.0 | ||
|
||
LABEL org.opencontainers.image.source="https://github.com/fedorov-xyz/nginx" | ||
|
||
RUN apt-get update && apt-get install --no-install-recommends -y \ | ||
nano \ | ||
curl \ | ||
cron \ | ||
certbot \ | ||
&& apt-get clean \ | ||
&& rm -rf /var/lib/apt/lists/* | ||
|
||
WORKDIR /etc/nginx/ | ||
|
||
COPY nginx/nginxconfig.io/ ./nginxconfig.io | ||
COPY nginx/nginx.conf . | ||
|
||
COPY scripts/entrypoint.sh / | ||
RUN ["chmod", "+x", "/entrypoint.sh"] | ||
|
||
COPY scripts/update_cloudflare_ips.sh /usr/local/bin/update_cloudflare_ips.sh | ||
RUN chmod +x /usr/local/bin/update_cloudflare_ips.sh | ||
|
||
COPY cron/crontab /etc/cron.d/crontab | ||
RUN chmod 0644 /etc/cron.d/crontab | ||
RUN crontab /etc/cron.d/crontab | ||
RUN touch /var/log/cron.log | ||
|
||
# Запуск cron и nginx | ||
CMD ["/entrypoint.sh"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,63 @@ | ||
# nginx | ||
Nginx Docker container with standalone certbot and automatic update of Cloudflare IP address ranges | ||
# Enhanced Nginx | ||
|
||
> Documentation in progress | ||
The script to generate the config for Cloudflare is taken from here: https://github.com/ergin/nginx-cloudflare-real-ip | ||
|
||
Nginx Docker container with standalone certbot and automatic update of Cloudflare IP address ranges. | ||
|
||
## How it works | ||
|
||
Instead of agonizing with certbot + nginx + well-known/acme-challenge, let's just let certbot do its job in standalone mode. | ||
|
||
When the container is started for the first time, certbot will bring up its server, issue and fail certificates. And then at the very end nginx will start up. | ||
|
||
When restarting the container, certbot will check the existing certificate for expiration, and if the expiration is ok, it will just not do anything, nginx will start right away. | ||
|
||
## Usage | ||
|
||
1. Specify 2 volumes for nginx and letsencrypt | ||
2. Mount your site config to container. You can mount multiple sites | ||
|
||
You should use the following lines in your nginx config for the site. `REPLACEMENT_CERT_NAME` will be replaced by the name of the certificate you pass to the container. | ||
|
||
```nginx configuration | ||
ssl_certificate /etc/letsencrypt/live/REPLACEMENT_CERT_NAME/fullchain.pem; | ||
ssl_certificate_key /etc/letsencrypt/live/REPLACEMENT_CERT_NAME/privkey.pem; | ||
ssl_trusted_certificate /etc/letsencrypt/live/REPLACEMENT_CERT_NAME/chain.pem; | ||
``` | ||
|
||
If you want to serve multiple domains within a container, list their domains in the `SITE_DOMAINS` environment variable. A common certificate will be issued for them. | ||
|
||
Example configuration for Docker Compose: | ||
|
||
```yaml filename="docker-compose.yml" | ||
volumes: | ||
nginx_data: | ||
letsencrypt_data: | ||
|
||
services: | ||
nginx: | ||
image: fedorov-xyz/enhanced-nginx:latest | ||
ports: | ||
- 80:80 | ||
- 443:443 | ||
volumes: | ||
- nginx_data:/etc/nginx/data | ||
- letsencrypt_data:/etc/letsencrypt | ||
- ./example.com.conf:/sites/example.com.conf | ||
environment: | ||
- SITE_DOMAINS=example.com,staging.example.com | ||
- CERT_NAME=example.com | ||
- CERTBOT_EMAIL=your@email.com | ||
- CERTBOT_TEST_CERT=true | ||
``` | ||
## Environment variables list | ||
| Variable | Requirded | Description | | ||
|----------------------|-----------|--------------------------------------------------------------| | ||
| `SITE_DOMAINS` | yes | Сomma-separated list of domains for Let's Encrypt certificate | | ||
| `CERT_NAME` | yes | Certificate name. | | ||
| `CERTBOT_EMAIL` | yes | Email for Let's Encrypt. | | ||
| `CERTBOT_TEST_CERT` | | Pass `true` for test certificates. | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# Auto sync ip addresses of Cloudflare and reload nginx | ||
# Every day at 8:30 | ||
30 8 * * * /usr/local/bin/update_cloudflare_ips.sh restart_nginx >/dev/null 2>&1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
# Generated by nginxconfig.io | ||
# See nginxconfig.txt for the configuration share link | ||
|
||
user nginx; | ||
pid /var/run/nginx.pid; | ||
worker_processes auto; | ||
worker_rlimit_nofile 65535; | ||
|
||
# Load modules | ||
include /etc/nginx/modules-enabled/*.conf; | ||
|
||
events { | ||
multi_accept on; | ||
worker_connections 65535; | ||
} | ||
|
||
http { | ||
charset utf-8; | ||
sendfile on; | ||
tcp_nopush on; | ||
tcp_nodelay on; | ||
server_tokens off; | ||
log_not_found off; | ||
types_hash_max_size 2048; | ||
types_hash_bucket_size 64; | ||
client_max_body_size 16M; | ||
|
||
# MIME | ||
include mime.types; | ||
default_type application/octet-stream; | ||
|
||
# Log Format | ||
include nginxconfig.io/log_format.conf; | ||
|
||
# Logging | ||
access_log off; | ||
error_log /var/log/nginx/error.log warn; | ||
|
||
# SSL | ||
ssl_session_timeout 1d; | ||
ssl_session_cache shared:SSL:10m; | ||
ssl_session_tickets off; | ||
|
||
# Diffie-Hellman parameter for DHE ciphersuites | ||
ssl_dhparam /etc/nginx/data/dhparam.pem; | ||
|
||
# Mozilla Intermediate configuration | ||
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; | ||
|
||
# OCSP Stapling | ||
ssl_stapling on; | ||
ssl_stapling_verify on; | ||
resolver 1.1.1.1 1.0.0.1 8.8.8.8 8.8.4.4 208.67.222.222 208.67.220.220 valid=60s; | ||
resolver_timeout 2s; | ||
|
||
# Connection header for WebSocket reverse proxy | ||
map $http_upgrade $connection_upgrade { | ||
default upgrade; | ||
"" close; | ||
} | ||
|
||
map $remote_addr $proxy_forwarded_elem { | ||
|
||
# IPv4 addresses can be sent as-is | ||
~^[0-9.]+$ "for=$remote_addr"; | ||
|
||
# IPv6 addresses need to be bracketed and quoted | ||
~^[0-9A-Fa-f:.]+$ "for=\"[$remote_addr]\""; | ||
|
||
# Unix domain socket names cannot be represented in RFC 7239 syntax | ||
default "for=unknown"; | ||
} | ||
|
||
map $http_forwarded $proxy_add_forwarded { | ||
|
||
# If the incoming Forwarded header is syntactically valid, append to it | ||
"~^(,[ \\t]*)*([!#$%&'*+.^_`|~0-9A-Za-z-]+=([!#$%&'*+.^_`|~0-9A-Za-z-]+|\"([\\t \\x21\\x23-\\x5B\\x5D-\\x7E\\x80-\\xFF]|\\\\[\\t \\x21-\\x7E\\x80-\\xFF])*\"))?(;([!#$%&'*+.^_`|~0-9A-Za-z-]+=([!#$%&'*+.^_`|~0-9A-Za-z-]+|\"([\\t \\x21\\x23-\\x5B\\x5D-\\x7E\\x80-\\xFF]|\\\\[\\t \\x21-\\x7E\\x80-\\xFF])*\"))?)*([ \\t]*,([ \\t]*([!#$%&'*+.^_`|~0-9A-Za-z-]+=([!#$%&'*+.^_`|~0-9A-Za-z-]+|\"([\\t \\x21\\x23-\\x5B\\x5D-\\x7E\\x80-\\xFF]|\\\\[\\t \\x21-\\x7E\\x80-\\xFF])*\"))?(;([!#$%&'*+.^_`|~0-9A-Za-z-]+=([!#$%&'*+.^_`|~0-9A-Za-z-]+|\"([\\t \\x21\\x23-\\x5B\\x5D-\\x7E\\x80-\\xFF]|\\\\[\\t \\x21-\\x7E\\x80-\\xFF])*\"))?)*)?)*$" "$http_forwarded, $proxy_forwarded_elem"; | ||
|
||
# Otherwise, replace it | ||
default "$proxy_forwarded_elem"; | ||
} | ||
|
||
# Load configs and sites | ||
# include /etc/nginx/conf.d/*.conf; | ||
include /etc/nginx/data/cloudflare.conf; | ||
include /etc/nginx/sites.d/*.conf; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# favicon.ico | ||
location = /favicon.ico { | ||
log_not_found off; | ||
} | ||
|
||
# robots.txt | ||
location = /robots.txt { | ||
log_not_found off; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# gzip | ||
gzip on; | ||
gzip_vary on; | ||
gzip_proxied any; | ||
gzip_comp_level 6; | ||
gzip_types text/plain text/css text/xml application/json application/javascript application/rss+xml application/atom+xml image/svg+xml; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
log_format cloudflare '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" $http_cf_ray $http_cf_connecting_ip $http_cf_ipcountry'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
proxy_http_version 1.1; | ||
proxy_cache_bypass $http_upgrade; | ||
|
||
# Proxy SSL | ||
proxy_ssl_server_name on; | ||
|
||
# Proxy headers | ||
proxy_set_header Upgrade $http_upgrade; | ||
proxy_set_header Connection $connection_upgrade; | ||
proxy_set_header X-Real-IP $remote_addr; | ||
proxy_set_header Forwarded $proxy_add_forwarded; | ||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | ||
proxy_set_header X-Forwarded-Proto $scheme; | ||
proxy_set_header X-Forwarded-Host $host; | ||
proxy_set_header X-Forwarded-Port $server_port; | ||
|
||
# Proxy timeouts | ||
proxy_connect_timeout 60s; | ||
proxy_send_timeout 60s; | ||
proxy_read_timeout 60s; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
# security headers | ||
add_header X-XSS-Protection "1; mode=block" always; | ||
add_header X-Content-Type-Options "nosniff" always; | ||
add_header Referrer-Policy "no-referrer-when-downgrade" always; | ||
add_header Content-Security-Policy "default-src 'self' http: https: ws: wss: data: blob: 'unsafe-inline'; frame-ancestors 'self';" always; | ||
add_header Permissions-Policy "interest-cohort=()" always; | ||
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always; | ||
|
||
# . files | ||
location ~ /\.(?!well-known) { | ||
deny all; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
#!/bin/bash | ||
|
||
# Static | ||
DOCKER_DATA=/etc/nginx/data | ||
CLOUDFLARE_FILE_PATH=/etc/nginx/data/cloudflare.conf | ||
DHPARAMS_FILE_PATH=$DOCKER_DATA/dhparams.pem | ||
|
||
# External | ||
: "${SITE_DOMAINS:?Must provide SITE_DOMAINS in environment}" | ||
: "${CERT_NAME:?Must provide CERT_NAME in environment}" | ||
: "${CERTBOT_EMAIL:?Must provide CERTBOT_EMAIL in environment}" | ||
|
||
mkdir -p $DOCKER_DATA; | ||
|
||
echo "Init nginx container" | ||
|
||
# Generate dhparams.pem | ||
if [ ! -f $DHPARAMS_FILE_PATH ]; then | ||
echo "Generate dhparams.pem" | ||
openssl dhparam -out $DHPARAMS_FILE_PATH 2048 | ||
chmod 600 $DHPARAMS_FILE_PATH | ||
fi | ||
|
||
# Generate Cloudflare IP ranges | ||
if [ ! -f $CLOUDFLARE_FILE_PATH ]; then | ||
echo "Generate Cloudflare IP ranges config" | ||
/usr/local/bin/update_cloudflare_ips.sh | ||
fi | ||
|
||
# Applying replacements for site configs | ||
|
||
cp -r /sites/* /etc/nginx/sites.d/ | ||
|
||
declare -a replacements=( | ||
"CERT_NAME" | ||
) | ||
|
||
for env in "${replacements[@]}" | ||
do | ||
if [ -n "${!env}" ]; then | ||
replacement=$(printf "%s" "${!env}" | sed 's/[,\/&]/\\&/g') # Escape special characters in the replacement value | ||
for file in /etc/nginx/sites.d/*; do | ||
sed -i "s,REPLACEMENT_$env,$replacement,g" "$file" || exit | ||
done | ||
echo " $env is updated in sites.d" | ||
fi | ||
done | ||
|
||
# Check cert exist | ||
if [ ! -f /etc/letsencrypt/live/"$CERT_NAME"/fullchain.pem ]; then | ||
echo "Certificate $CERT_NAME do not exists, will generate it now" | ||
fi | ||
|
||
echo "Running certbot" | ||
|
||
certbot_args=( | ||
certonly | ||
--standalone | ||
--renew-by-default | ||
--non-interactive | ||
--agree-tos | ||
--cert-name "$CERT_NAME" | ||
--email "$CERTBOT_EMAIL" | ||
-d "$SITE_DOMAINS" | ||
) | ||
|
||
if [ "$CERTBOT_TEST_CERT" = "true" ]; then | ||
echo "Using staging (test) certificate" | ||
certbot_args+=(--test-cert) | ||
fi | ||
|
||
certbot "${certbot_args[@]}" || exit | ||
|
||
echo "Start nginx" | ||
nginx -g "daemon off;" |
Oops, something went wrong.