Skip to content

Commit

Permalink
move to nginx
Browse files Browse the repository at this point in the history
  • Loading branch information
GeneralTao2 committed Feb 22, 2025
1 parent f0c4eeb commit de0cd3b
Show file tree
Hide file tree
Showing 17 changed files with 448 additions and 20 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,6 @@ test/run-backup-restore/logging
test/run-backup-restore/portainer
test/run-backup-restore/docker-compose.yml
cicd/docker-webhook/shared/envs

nginx/certbot/duckdns.ini
nginx/data
nginx/certbot/letsencrypt
11 changes: 8 additions & 3 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,15 @@ services:
file: portainer/docker-compose.yml
service: portainer

nginx-proxy-manager:
nginx:
extends:
file: nginx-proxy-manager/docker-compose.yml
service: nginx-proxy-manager
file: nginx/nginx/docker-compose.yml
service: nginx

certbot:
extends:
file: nginx/certbot/docker-compose.yml
service: certbot

volumes:
backup-data:
Expand Down
16 changes: 0 additions & 16 deletions nginx-proxy-manager/docker-compose.yml

This file was deleted.

14 changes: 14 additions & 0 deletions nginx/certbot/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
version: '2.4'

services:
certbot:
image: infinityofspace/certbot_dns_duckdns
# entrypoint: "/bin/sh -c 'ls /etc/letsencrypt/live'"
volumes:
# - ./../data/certbot/letsencrypt:/etc/letsencrypt
- ./../data/certbot/www:/var/www/certbot
- ./letsencrypt:/var/log/letsencrypt
- ./duckdns.ini:/duckdns.ini
entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'"
# restart: unless-stopped

11 changes: 11 additions & 0 deletions nginx/certbot/run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
docker compose run certbot \
certonly \
--non-interactive \
--agree-tos \
--email $1 \
--preferred-challenges dns \
--authenticator dns-duckdns \
--dns-duckdns-credentials /duckdns.ini \
--dns-duckdns-propagation-seconds 120 \
-d "*.$2" \
-d "$2"
36 changes: 36 additions & 0 deletions nginx/nginx/conf.d/default.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# "You are not configured" page, which is the default if another default doesn't exist
server {
listen 80;
listen [::]:80;

set $forward_scheme "http";
set $server "127.0.0.1";
set $port "80";

server_name localhost-nginx-proxy-manager;
# include conf.d/include/assets.conf;
include conf.d/include/block-exploits.conf;
include conf.d/include/letsencrypt-acme-challenge.conf;

location / {
index index.html;
root /var/www/html;
}
}

# First 443 Host, which is the default if another default doesn't exist
server {
listen 443 ssl;
listen [::]:443 ssl;

set $forward_scheme "https";
set $server "127.0.0.1";
set $port "443";

server_name localhost;
error_log /dev/null crit;
include conf.d/include/ssl-ciphers.conf;
ssl_reject_handshake on;

return 444;
}
33 changes: 33 additions & 0 deletions nginx/nginx/conf.d/gitea.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
server {
server_name gitea.taonity.duckdns.org;

listen 80;
listen [::]:80;
listen 443 ssl http2;
listen [::]:443 ssl http2;

# Let's Encrypt SSL
include conf.d/include/letsencrypt-acme-challenge.conf;
include conf.d/include/ssl-ciphers.conf;
ssl_certificate /etc/letsencrypt/live/taonity.duckdns.org/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/taonity.duckdns.org/privkey.pem;

# Block Exploits
include conf.d/include/block-exploits.conf;
# Force SSL
include conf.d/include/force-ssl.conf;

proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $http_connection;
proxy_http_version 1.1;

location / {
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $http_connection;
proxy_http_version 1.1;

# Proxy!
include conf.d/include/proxy.conf;
proxy_pass http://host.docker.internal:3001;
}
}
44 changes: 44 additions & 0 deletions nginx/nginx/conf.d/grafana.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
server {
server_name grafana.taonity.duckdns.org;

# TODO: variable substitution doesn't work
# set $forward_scheme "http";
# set $server "grafana";
# set $port "3000";

listen 80;
listen [::]:80;
listen 443 ssl http2;
listen [::]:443 ssl http2;

# Let's Encrypt SSL
include conf.d/include/letsencrypt-acme-challenge.conf;
include conf.d/include/ssl-ciphers.conf;
ssl_certificate /etc/letsencrypt/live/taonity.duckdns.org/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/taonity.duckdns.org/privkey.pem;

# Asset Caching
# TODO: fix it
# nginx | 2025/02/22 21:26:35 [emerg] 1#1: "proxy_cache" zone "public-cache" is unknown in /etc/nginx/nginx.conf:32
# nginx | nginx: [emerg] "proxy_cache" zone "public-cache" is unknown in /etc/nginx/nginx.conf:32
# include conf.d/include/assets.conf;

# Block Exploits
include conf.d/include/block-exploits.conf;
# Force SSL
include conf.d/include/force-ssl.conf;

proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $http_connection;
proxy_http_version 1.1;

location / {
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $http_connection;
proxy_http_version 1.1;

# Proxy!
include conf.d/include/proxy.conf;
proxy_pass http://grafana:3000;
}
}
31 changes: 31 additions & 0 deletions nginx/nginx/conf.d/include/assets.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
location ~* ^.*\.(css|js|jpe?g|gif|png|webp|woff|eot|ttf|svg|ico|css\.map|js\.map)$ {
if_modified_since off;

# use the public cache
proxy_cache public-cache;
proxy_cache_key $host$request_uri;

# ignore these headers for media
proxy_ignore_headers Set-Cookie Cache-Control Expires X-Accel-Expires;

# cache 200s and also 404s (not ideal but there are a few 404 images for some reason)
proxy_cache_valid any 30m;
proxy_cache_valid 404 1m;

# strip this header to avoid If-Modified-Since requests
proxy_hide_header Last-Modified;
proxy_hide_header Cache-Control;
proxy_hide_header Vary;

proxy_cache_bypass 0;
proxy_no_cache 0;

proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504 http_404;
proxy_connect_timeout 5s;
proxy_read_timeout 45s;

expires @30m;
access_log off;

include conf.d/include/proxy.conf;
}
136 changes: 136 additions & 0 deletions nginx/nginx/conf.d/include/block-exploits.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
## Block SQL injections
set $block_sql_injections 0;

if ($query_string ~ "union.*select.*\(") {
set $block_sql_injections 1;
}

if ($query_string ~ "union.*all.*select.*") {
set $block_sql_injections 1;
}

if ($query_string ~ "concat.*\(") {
set $block_sql_injections 1;
}

if ($block_sql_injections = 1) {
return 403;
}

## Block file injections
set $block_file_injections 0;

if ($query_string ~ "[a-zA-Z0-9_]=http://") {
set $block_file_injections 1;
}

if ($query_string ~ "[a-zA-Z0-9_]=(\.\.//?)+") {
set $block_file_injections 1;
}

if ($query_string ~ "[a-zA-Z0-9_]=/([a-z0-9_.]//?)+") {
set $block_file_injections 1;
}

if ($block_file_injections = 1) {
return 403;
}

## Block common exploits
set $block_common_exploits 0;

if ($query_string ~ "(<|%3C).*script.*(>|%3E)") {
set $block_common_exploits 1;
}

if ($query_string ~ "GLOBALS(=|\[|\%[0-9A-Z]{0,2})") {
set $block_common_exploits 1;
}

if ($query_string ~ "_REQUEST(=|\[|\%[0-9A-Z]{0,2})") {
set $block_common_exploits 1;
}

if ($query_string ~ "proc/self/environ") {
set $block_common_exploits 1;
}

if ($query_string ~ "mosConfig_[a-zA-Z_]{1,21}(=|\%3D)") {
set $block_common_exploits 1;
}

if ($query_string ~ "base64_(en|de)code\(.*\)") {
set $block_common_exploits 1;
}

if ($block_common_exploits = 1) {
return 403;
}

## Block spam
set $block_spam 0;

if ($query_string ~ "\b(ultram|unicauca|valium|viagra|vicodin|xanax|ypxaieo)\b") {
set $block_spam 1;
}

if ($query_string ~ "\b(erections|hoodia|huronriveracres|impotence|levitra|libido)\b") {
set $block_spam 1;
}

if ($query_string ~ "\b(ambien|blue\spill|cialis|cocaine|ejaculation|erectile)\b") {
set $block_spam 1;
}

if ($query_string ~ "\b(lipitor|phentermin|pro[sz]ac|sandyauer|tramadol|troyhamby)\b") {
set $block_spam 1;
}

if ($block_spam = 1) {
return 403;
}

## Block user agents
set $block_user_agents 0;

# Disable Akeeba Remote Control 2.5 and earlier
if ($http_user_agent ~ "Indy Library") {
set $block_user_agents 1;
}

# Common bandwidth hoggers and hacking tools.
if ($http_user_agent ~ "libwww-perl") {
set $block_user_agents 1;
}

if ($http_user_agent ~ "GetRight") {
set $block_user_agents 1;
}

if ($http_user_agent ~ "GetWeb!") {
set $block_user_agents 1;
}

if ($http_user_agent ~ "Go!Zilla") {
set $block_user_agents 1;
}

if ($http_user_agent ~ "Download Demon") {
set $block_user_agents 1;
}

if ($http_user_agent ~ "Go-Ahead-Got-It") {
set $block_user_agents 1;
}

if ($http_user_agent ~ "TurnitinBot") {
set $block_user_agents 1;
}

if ($http_user_agent ~ "GrabNet") {
set $block_user_agents 1;
}

if ($block_user_agents = 1) {
return 403;
}
3 changes: 3 additions & 0 deletions nginx/nginx/conf.d/include/force-ssl.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
if ($scheme = "http") {
return 301 https://$host$request_uri;
}
32 changes: 32 additions & 0 deletions nginx/nginx/conf.d/include/letsencrypt-acme-challenge.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Rule for legitimate ACME Challenge requests (like /.well-known/acme-challenge/xxxxxxxxx)
# We use ^~ here, so that we don't check other regexes (for speed-up). We actually MUST cancel
# other regex checks, because in our other config files have regex rule that denies access to files with dotted names.
location ^~ /.well-known/acme-challenge/ {
# Since this is for letsencrypt authentication of a domain and they do not give IP ranges of their infrastructure
# we need to open up access by turning off auth and IP ACL for this location.
auth_basic off;
auth_request off;
allow all;

# Set correct content type. According to this:
# https://community.letsencrypt.org/t/using-the-webroot-domain-verification-method/1445/29
# Current specification requires "text/plain" or no content header at all.
# It seems that "text/plain" is a safe option.
default_type "text/plain";

# This directory must be the same as in /etc/letsencrypt/cli.ini
# as "webroot-path" parameter. Also don't forget to set "authenticator" parameter
# there to "webroot".
# Do NOT use alias, use root! Target directory is located here:
# /var/www/common/letsencrypt/.well-known/acme-challenge/

# Chnaged
root /var/www/certbot;
}

# Hide /acme-challenge subdirectory and return 404 on all requests.
# It is somewhat more secure than letting Nginx return 403.
# Ending slash is important!
location = /.well-known/acme-challenge/ {
return 404;
}
Loading

0 comments on commit de0cd3b

Please sign in to comment.