yellow: Install/configure nginx
We're going to use *nginx* as the reverse proxy in front of Home Assistant, as well as the web consoles for Zigbee2MQTT and ZWaveJS2MQTT. It will provide TLS termination for all of these applications. Since *nginx* will not start without a certificate and private key file for HTTPS, the *gen-nginx-cert.service* systemd unit generates a self-signed certificate if one does not already exist. This ensures that *nginx* can start by default, but still allows the administrator to replace the certificate with a trusted one later. The *nginx* container image has symlinks at `/var/log/nginx/error.log` and `/var/log/nginx/access.log`, pointing to `/dev/stderr` and `/dev/stdout`, respectively. The intent here is to send all log messages to the container runtime. Unfortunately, when the the container is managed by Podman from a systemd unit, the standard output and standard error streams are connected to the systemd journal via a UNIX socket. As a result, the `/dev/stdout` and `/dev/stderr` pseudo-files cannot be "opened" like normal files or pipes. Thus, to forward nginx's logs to the systemd journal correctly, we have to do a bit of trickery. For the error log at least, setting `error_log stderr` works well; nginx simply writes messages to the existing file descriptor. Unfortunately, the access log has no such mechanism. For that, we use nginx's syslog capabilities. The `/dev/log` socket is bind-mounted into the container, and nginx is configured to connect to it.gentoo
parent
02c3a12c08
commit
670c1f7561
|
@ -1,2 +1,4 @@
|
||||||
|
acct-group/nginx
|
||||||
|
acct-user/nginx
|
||||||
app-backup/burp
|
app-backup/burp
|
||||||
app-containers/podman
|
app-containers/podman
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
d burp
|
d burp
|
||||||
d mosquitto
|
d mosquitto
|
||||||
|
d nginx/ssl
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
# vim: set ft=systemd :
|
||||||
|
[Unit]
|
||||||
|
After=network-online.target
|
||||||
|
Wants=network-online.target
|
||||||
|
Requires=gen-nginx-cert.service
|
||||||
|
|
||||||
|
[Container]
|
||||||
|
Image=docker.io/library/nginx
|
||||||
|
Network=host
|
||||||
|
Volume=/etc/nginx/nginx.conf:/etc/nginx/nginx.conf:ro
|
||||||
|
Volume=/etc/nginx/conf.d:/etc/nginx/conf.d:ro
|
||||||
|
Volume=/etc/nginx/ssl:/etc/nginx/ssl:ro
|
||||||
|
Volume=/dev/log:/dev/log
|
||||||
|
User=82
|
||||||
|
Group=82
|
||||||
|
AddCapability=CAP_NET_BIND_SERVICE
|
||||||
|
ReadOnly=true
|
||||||
|
VolatileTmp=yes
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
ProtectSystem=full
|
||||||
|
UMask=0077
|
||||||
|
ExecReload=/usr/bin/podman exec systemd-%N nginx -s reload
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
|
@ -0,0 +1,70 @@
|
||||||
|
# vim: set sw=4 ts=4 sts=4 et :
|
||||||
|
map $http_upgrade $connection_upgrade {
|
||||||
|
default upgrade;
|
||||||
|
'' close;
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 80 default_server;
|
||||||
|
listen [::]:80 default_server;
|
||||||
|
server_name _;
|
||||||
|
root /usr/share/nginx/html;
|
||||||
|
|
||||||
|
return 301 https://$host$request_uri;
|
||||||
|
|
||||||
|
error_page 500 502 503 504 /50x.html;
|
||||||
|
|
||||||
|
location = /50x.html { }
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 443 ssl http2 default_server;
|
||||||
|
listen [::]:443 ssl http2 default_server;
|
||||||
|
server_name _;
|
||||||
|
root /usr/share/nginx/html;
|
||||||
|
|
||||||
|
ssl_certificate "/etc/nginx/ssl/server.crt";
|
||||||
|
ssl_certificate_key "/etc/nginx/ssl/server.key";
|
||||||
|
ssl_session_cache shared:SSL:1m;
|
||||||
|
ssl_prefer_server_ciphers on;
|
||||||
|
|
||||||
|
error_page 500 502 503 504 /50x.html;
|
||||||
|
|
||||||
|
add_header
|
||||||
|
Strict-Transport-Security
|
||||||
|
"max-age=63072000; includeSubDomains"
|
||||||
|
always;
|
||||||
|
|
||||||
|
location = /50x.html { }
|
||||||
|
|
||||||
|
location = /zwave {
|
||||||
|
return 301 https://$host/zwave/;
|
||||||
|
}
|
||||||
|
|
||||||
|
location = /zigbee {
|
||||||
|
return 301 https://$host/zigbee/;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /zwave/ {
|
||||||
|
proxy_pass http://127.0.0.1:8091/;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection $connection_upgrade;
|
||||||
|
proxy_set_header X-External-Path /zwave;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /zigbee/ {
|
||||||
|
proxy_pass http://127.0.0.1:8080/;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection $connection_upgrade;
|
||||||
|
proxy_set_header X-External-Path /zigbee;
|
||||||
|
}
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass http://[::1]:8123/;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection $connection_upgrade;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
worker_processes auto;
|
||||||
|
|
||||||
|
error_log stderr notice;
|
||||||
|
pid /tmp/nginx.pid;
|
||||||
|
|
||||||
|
|
||||||
|
events {
|
||||||
|
worker_connections 1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
http {
|
||||||
|
client_body_temp_path /tmp/client_temp;
|
||||||
|
proxy_temp_path /tmp/proxy_temp;
|
||||||
|
fastcgi_temp_path /tmp/fastcgi_temp;
|
||||||
|
uwsgi_temp_path /tmp/uwsgi_temp;
|
||||||
|
scgi_temp_path /tmp/scgi_temp;
|
||||||
|
|
||||||
|
include /etc/nginx/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"';
|
||||||
|
|
||||||
|
access_log syslog:server=unix:/dev/log main;
|
||||||
|
|
||||||
|
sendfile on;
|
||||||
|
#tcp_nopush on;
|
||||||
|
|
||||||
|
keepalive_timeout 65;
|
||||||
|
|
||||||
|
#gzip on;
|
||||||
|
|
||||||
|
include /etc/nginx/conf.d/*.conf;
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
# vim: set ft=systemd :
|
||||||
|
[Unit]
|
||||||
|
Description=Generate self-signed certificate for nginx
|
||||||
|
Before=nginx.service
|
||||||
|
ConditionPathExists=!/etc/nginx/ssl/server.crt
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
ExecStart=/usr/libexec/gen-nginx-cert
|
||||||
|
User=root
|
||||||
|
Group=nginx
|
||||||
|
CapabilityBoundingSet=
|
||||||
|
DeviceAllow=
|
||||||
|
DevicePolicy=closed
|
||||||
|
IPAddressDeny=any
|
||||||
|
LockPersonality=yes
|
||||||
|
MemoryDenyWriteExecute=yes
|
||||||
|
NoNewPrivileges=yes
|
||||||
|
PrivateDevices=yes
|
||||||
|
PrivateNetwork=yes
|
||||||
|
PrivateTmp=yes
|
||||||
|
PrivateUsers=yes
|
||||||
|
ProcSubset=pid
|
||||||
|
ProtectClock=yes
|
||||||
|
ProtectControlGroups=yes
|
||||||
|
ProtectHome=yes
|
||||||
|
ProtectHostname=yes
|
||||||
|
ProtectKernelLogs=yes
|
||||||
|
ProtectKernelModules=yes
|
||||||
|
ProtectKernelTunables=yes
|
||||||
|
ProtectProc=invisible
|
||||||
|
ProtectSystem=yes
|
||||||
|
RestrictAddressFamilies=
|
||||||
|
RestrictNamespaces=yes
|
||||||
|
RestrictRealtime=yes
|
||||||
|
RestrictSUIDSGID=yes
|
||||||
|
SystemCallArchitectures=native
|
||||||
|
SystemCallFilter=@system-service
|
||||||
|
SystemCallFilter=~@privileged
|
||||||
|
UMask=0027
|
|
@ -0,0 +1,38 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# vim: set sw=4 ts=4 sts=4 et :
|
||||||
|
|
||||||
|
DAYS=90
|
||||||
|
SUBJ=/CN=localhost
|
||||||
|
ALG=EC
|
||||||
|
CURVE=secp384r1
|
||||||
|
|
||||||
|
if [ -f /etc/default/gen-nginx-cert ]; then
|
||||||
|
. /etc/default/gen-nginx-cert
|
||||||
|
fi
|
||||||
|
|
||||||
|
set -- \
|
||||||
|
-out /etc/nginx/ssl/server.key \
|
||||||
|
-algorithm "${ALG}"
|
||||||
|
|
||||||
|
case "${ALG}" in
|
||||||
|
EC)
|
||||||
|
set -- "$@" \
|
||||||
|
-pkeyopt ec_paramgen_curve:${CURVE} \
|
||||||
|
-pkeyopt ec_param_enc:named_curve
|
||||||
|
;;
|
||||||
|
RSA)
|
||||||
|
set -- "$@" \
|
||||||
|
-pkeyopt rsa_keygen_bits:${BITS:+4096}
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
rm -f /etc/nginx/ssl/server.crt /etc/nginx/ssl/server.key
|
||||||
|
: > /etc/nginx/ssl/server.key
|
||||||
|
openssl genpkey "$@"
|
||||||
|
openssl \
|
||||||
|
req -x509 \
|
||||||
|
-subj "${SUBJ}" \
|
||||||
|
-key /etc/nginx/ssl/server.key \
|
||||||
|
-out /etc/nginx/ssl/server.crt \
|
||||||
|
-sha256 \
|
||||||
|
-days "${DAYS}"
|
|
@ -0,0 +1 @@
|
||||||
|
boolean -m -1 container_mounton_non_security
|
Loading…
Reference in New Issue