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
Dustin 2023-03-29 11:20:45 -05:00
parent 02c3a12c08
commit 670c1f7561
8 changed files with 214 additions and 0 deletions

View File

@ -1,2 +1,4 @@
acct-group/nginx
acct-user/nginx
app-backup/burp
app-containers/podman

View File

@ -1,2 +1,3 @@
d burp
d mosquitto
d nginx/ssl

View File

@ -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

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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

View File

@ -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}"

1
yellow/semanage.mods Normal file
View File

@ -0,0 +1 @@
boolean -m -1 container_mounton_non_security