[manage.py] Add NGINX

This commit is contained in:
Viyurz 2024-10-15 21:44:02 +02:00
parent 46ae023028
commit 52ac146067
Signed by: Viyurz
SSH key fingerprint: SHA256:IskOHTmhHSJIvAt04N6aaxd5SZCVWW1Guf9tEcxIMj8
22 changed files with 389 additions and 28 deletions

View file

@ -1,6 +1,6 @@
#!/usr/bin/python3
import os, sys, re
import os, sys, re, shutil
import filecmp
from glob import glob
from mako.template import Template
@ -115,6 +115,24 @@ def getUid(service):
return env['podman_uid']
def promptTargetProjects():
projects = os.listdir("projects")
print(f"\nProjects list: {projects}")
if len(sys.argv) > 2:
target_projects = sys.argv[2]
else:
target_projects = input("Target compose project(s), space separated, leave empty to target all: ")
if target_projects.strip() == '':
target_projects = projects
else:
target_projects = re.split(' ?, ?| ', target_projects.strip())
print(f"Target projects: {target_projects}")
return target_projects
def pullProj(project):
print(f"Pulling images for project {project}.")
@ -138,16 +156,16 @@ def pullProj(project):
return pulledImages
def renderFile(templateFile):
print(f"Rendering file {templateFile}.")
def renderFile(templateFile, renderedFile=None):
if renderedFile is None:
renderedFile = re.sub('\\.mako$', '.rendered', templateFile)
renderedFilename = re.sub('\\.mako$', '.rendered', templateFile)
print(f"Rendering file {templateFile} to {renderedFile}.")
template = Template(filename=templateFile)
outputFile = open(renderedFilename, "w")
with open(renderedFile, "w") as outputFile:
outputFile.write(template.render(env=env, secrets=secrets))
outputFile.close()
def runBorg(args, input=None):
@ -192,11 +210,19 @@ def runSudo(args):
child = subprocess.Popen(["sudo"] + args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
if re.search('^\\[sudo\\] password for .+', child.stdout.read().strip()):
stdout = child.stdout.read().strip()
if stdout != '':
print(stdout)
if re.search('^\\[sudo\\] password for .+', stdout):
child.communicate(input=input().encode())[0]
child.wait()
stdout = child.stdout.read().strip()
if stdout != '':
print(stdout)
stderr = child.stderr.read().strip()
if stderr != '':
print(stderr, file=sys.stderr)
@ -259,6 +285,26 @@ def setPerms(path, mode):
print(f"Permissions of {path} already set to {mode}.")
def setupNGINX():
if os.getuid() != 0:
print("Current user is not root, rerunning program as root.")
runSudo([sys.executable, sys.argv[0], "nginx"])
return
for dir in ["sites-enabled", "snippets"]:
print(f"Recreating directory /etc/nginx/{dir}")
shutil.rmtree(f"/etc/nginx/{dir}")
os.mkdir(f"/etc/nginx/{dir}")
for templateFile in glob("nginx/**/*.conf", recursive=True, include_hidden=True):
renderFile(templateFile, "/etc/" + templateFile)
subprocess.run(["nginx", "-t"])
print("Reloading service nginx.")
runSudo("systemctl reload nginx")
def setupProj(project):
print(f"Running setup for project {project}.")
@ -324,6 +370,7 @@ def main():
env = yaml.safe_load(Template(filename=envFile).render())
secrets = yaml.safe_load(secretsfile)
if os.getuid() != 0:
setOwner(secretsFile, os.getuid(), os.getgid())
setPerms(secretsFile, 600)
@ -338,28 +385,16 @@ def main():
print("[1/S] Setup project")
print("[2/U] Update project")
print("[3/B] Backup project")
print("[4/N] Setup NGINX")
while action == '':
action = input("Action: ")
projects = os.listdir("projects")
print(f"\nProjects list: {projects}")
if len(sys.argv) > 2:
target_projects = sys.argv[2]
else:
target_projects = input("Target compose project(s), space separated, leave empty to target all: ")
if target_projects.strip() == '':
target_projects = projects
else:
target_projects = re.split(' ?, ?| ', target_projects.strip())
print(f"Target projects: {target_projects}")
match action.casefold():
case '1' | 's' | 'setup':
target_projects = promptTargetProjects()
setNftables()
for project in target_projects:
@ -371,6 +406,8 @@ def main():
print(f"Failed to setup project {project}.", file=sys.stderr)
case '2' | 'u' | 'update':
target_projects = promptTargetProjects()
for project in target_projects:
try:
print()
@ -380,6 +417,8 @@ def main():
print(f"Failed to update project {project}.", file=sys.stderr)
case '3' | 'b' | 'backup':
target_projects = promptTargetProjects()
print()
if not os.path.exists(env['borg_repo']):
print(f"Creating borg repository {env['borg_repo']}.")
@ -397,6 +436,9 @@ def main():
runBorg(["compact", env['borg_repo']])
case '4' | 'n' | 'nginx':
setupNGINX()
if __name__ == "__main__":
main()

38
nginx/nginx.conf Normal file
View file

@ -0,0 +1,38 @@
user www-data;
worker_processes auto;
worker_rlimit_nofile 1024;
include /etc/nginx/modules-enabled/*.conf;
events {
worker_connections 512;
multi_accept off;
}
http {
sendfile on;
tcp_nopush on;
tcp_nodelay on;
gzip off;
server_tokens off;
keepalive_timeout 30;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
include /etc/nginx/mime.types;
# Needed to support websocket connections
map $http_upgrade $connection_upgrade {
default upgrade;
'' "";
}
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/snippets/proxy.conf;
include /etc/nginx/snippets/ssl.conf;
include /etc/nginx/snippets/ssl-headers.conf;
include /etc/nginx/sites-enabled/*;
}

View file

@ -0,0 +1,12 @@
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name clips.${env['domain']};
location / {
proxy_pass http://127.0.0.1:${env['ports']['fireshare']};
client_max_body_size 500M;
}
}

View file

@ -0,0 +1,17 @@
# Redirect HTTP to HTTPS
server {
listen 80 default_server;
listen [::]:80 default_server;
return 308 https://$host$request_uri;
}
# Default HTTPS server
server {
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
http2 on;
return 404;
}

View file

@ -0,0 +1,9 @@
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name dl.${env['domain']};
root /var/www/html;
autoindex on;
}

View file

@ -0,0 +1,10 @@
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name etebase.${env['domain']};
location / {
proxy_pass http://127.0.0.1:${env['ports']['etebase']};
}
}

View file

@ -0,0 +1,17 @@
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name hedgedoc.${env['domain']};
location / {
proxy_pass http://127.0.0.1:${env['ports']['hedgedoc']};
}
location /socket.io/ {
proxy_pass http://127.0.0.1:${env['ports']['hedgedoc']};
include /etc/nginx/snippets/websocket.conf;
include /etc/nginx/snippets/proxy.conf;
}
}

View file

@ -0,0 +1,25 @@
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name ${env['domain']};
location = /.well-known/matrix/server {
default_type application/json;
return 200 '{ "m.server": "matrix.${env["domain"]}:443" }';
}
location = /.well-known/matrix/client {
default_type application/json;
include /etc/nginx/snippets/ssl-headers.conf;
add_header Access-Control-Allow-Origin '*';
return 200 '{ "m.homeserver": { "base_url": "https://matrix.${env["domain"]}" } }';
}
location / {
proxy_pass http://127.0.0.1:${env['ports']['homepage']};
}
}

View file

@ -0,0 +1,13 @@
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name kc.${env['domain']};
location / {
proxy_pass https://127.0.0.1:${env['ports']['keycloak']};
#include /etc/nginx/snippets/websocket.conf;
#include /etc/nginx/snippets/proxy.conf;
}
}

View file

@ -0,0 +1,43 @@
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name mail.${env['domain']};
location / {
proxy_pass https://127.0.0.1:${env['ports']['mailserver_https']};
include /etc/nginx/snippets/websocket.conf;
include /etc/nginx/snippets/proxy.conf;
}
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name autoconfig.${env['domain']};
location / {
return 404;
}
location = /mail/config-v1.1.xml {
proxy_pass https://127.0.0.1:${env['ports']['mailserver_https']};
}
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name mta-sts.${env['domain']};
location / {
return 404;
}
location = /.well-known/mta-sts.txt {
proxy_pass https://127.0.0.1:${env['ports']['mailserver_https']};
}
}

View file

@ -0,0 +1,13 @@
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name searx.${env['domain']};
location / {
proxy_pass http://127.0.0.1:${env['ports']['searxng']};
include /etc/nginx/snippets/ssl-headers.conf;
add_header Content-Security-Policy "upgrade-insecure-requests; default-src 'none'; script-src 'self'; style-src 'self' 'unsafe-inline'; form-action 'self' https://github.com/searxng/searxng/issues/new; font-src 'self'; frame-ancestors 'self'; base-uri 'self'; connect-src 'self' https://overpass-api.de; img-src 'self' data: https://*.tile.openstreetmap.org; frame-src https://www.youtube-nocookie.com https://player.vimeo.com https://www.dailymotion.com https://www.deezer.com https://www.mixcloud.com https://w.soundcloud.com https://embed.spotify.com";
}
}

View file

@ -0,0 +1,12 @@
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name sex.${env['domain']};
root /var/www/sex;
location / {
random_index on;
}
}

View file

@ -0,0 +1,17 @@
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name stdisco.${env['domain']};
ssl_verify_client optional_no_ca;
location / {
proxy_pass http://127.0.0.1:${env['ports']['syncthing_discosrv']};
proxy_set_header X-Client-Port $remote_port;
proxy_set_header X-SSL-Cert $ssl_client_cert;
include /etc/nginx/snippets/websocket.conf;
include /etc/nginx/snippets/proxy.conf;
}
}

View file

@ -0,0 +1,13 @@
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name stump.${env['domain']};
location / {
proxy_pass http://127.0.0.1:${env['ports']['stump']};
include /etc/nginx/snippets/websocket.conf;
include /etc/nginx/snippets/proxy.conf;
}
}

View file

@ -0,0 +1,12 @@
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name matrix.${env['domain']};
location / {
proxy_pass http://127.0.0.1:${env['ports']['synapse']};
client_max_body_size 50M;
}
}

View file

@ -0,0 +1,13 @@
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name status.${env['domain']};
location / {
proxy_pass http://127.0.0.1:${env['ports']['uptime']};
include /etc/nginx/snippets/websocket.conf;
include /etc/nginx/snippets/proxy.conf;
}
}

View file

@ -0,0 +1,19 @@
upstream vaultwarden {
zone vaultwarden 64k;
server 127.0.0.1:${env['ports']['vaultwarden']};
keepalive 2;
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name vw.${env['domain']};
location / {
proxy_pass http://vaultwarden;
include /etc/nginx/snippets/websocket.conf;
include /etc/nginx/snippets/proxy.conf;
}
}

10
nginx/snippets/proxy.conf Normal file
View file

@ -0,0 +1,10 @@
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Scheme $scheme;
proxy_set_header X-Forwarded-URI $request_uri;
proxy_set_header X-Original-URL $scheme://$http_host$request_uri;
proxy_set_header X-Real-IP $remote_addr;

View file

@ -0,0 +1,3 @@
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
# add_header X-Robots-Tag "noindex, nofollow" always;
add_header Set-Cookie "Path=/; HttpOnly; Secure";

18
nginx/snippets/ssl.conf Normal file
View file

@ -0,0 +1,18 @@
ssl_certificate /etc/letsencrypt/live/${env['domain']}/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/${env['domain']}/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/${env['domain']}/chain.pem;
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:DHE-RSA-CHACHA20-POLY1305;
# curl https://ssl-config.mozilla.org/ffdhe2048.txt > /path/to/dhparam
ssl_dhparam /etc/nginx/dhparam.txt;
ssl_prefer_server_ciphers on;
ssl_session_timeout 1d;
ssl_session_cache shared:MozSSL:10m;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;

View file

@ -0,0 +1,2 @@
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;

View file

@ -15,14 +15,14 @@ declare -a podman_units=(podman.service podman.socket podman-auto-update.service
if [[ "$podman_mode" == "rootless" ]]; then
sudo apt install -y aardvark-dns borgbackup cifs-utils dbus-user-session nftables passt podman podman-compose python3-mako slirp4netns uidmap
sudo apt install -y aardvark-dns borgbackup cifs-utils curl dbus-user-session nftables nginx passt podman podman-compose python3-mako slirp4netns uidmap
sudo loginctl enable-linger "$USER"
sudo systemctl disable --now "${podman_units[@]}"
systemctl --user enable --now "${podman_units[@]}"
else
sudo apt install -y aardvark-dns borgbackup cifs-utils nftables podman podman-compose python3-mako
sudo apt install -y aardvark-dns borgbackup cifs-utils curl nftables nginx podman podman-compose python3-mako
systemctl --user disable --now "${podman_units[@]}"
sudo systemctl enable --now "${podman_units[@]}"
@ -43,4 +43,7 @@ done
sudo sysctl -p /etc/sysctl.d/podman.conf
sudo systemctl enable --now nftables
sudo curl -o /etc/nginx/dhparam.txt https://ssl-config.mozilla.org/ffdhe2048.txt
sudo systemctl enable --now nftables nginx