# Basic configuration user nginx; worker_processes auto; pcre_jit on; error_log /dev/stderr notice; pid /var/run/nginx.pid; load_module "modules/ngx_mail_module.so"; events { worker_connections 1024; } http { # Standard HTTP configuration with slight hardening include /etc/nginx/mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; server_tokens off; absolute_redirect off; resolver 127.0.0.11 valid=30s; # Header maps map $http_x_forwarded_proto $proxy_x_forwarded_proto { default $http_x_forwarded_proto; '' $scheme; } map $uri $expires { default off; ~*\.(ico|css|js|gif|jpeg|jpg|png|woff2?|ttf|otf|svg|tiff|eot|webp)$ 97d; } map $request_uri $loggable { /health 0; /auth/email 0; default 1; } access_log /dev/stdout combined if=$loggable; # compression gzip on; gzip_static on; gzip_types text/plain text/css application/xml application/javascript gzip_min_length 1024; # TODO: figure out how to server pre-compressed assets from admin container # Enable the proxy for certbot if the flavor is letsencrypt and not on kubernetes # server { # Listen over HTTP listen 80; location ^~ /.well-known/acme-challenge/testing { return 204; } location ^~ /.well-known/acme-challenge/ { proxy_pass http://127.0.0.1:8008; } # redirect to https location / { return 301 https://$host$request_uri; } location /health { return 204; } } # Main HTTP server server { # Favicon stuff root /static; # Variables for proxifying set $admin admin:8080; set $antispam antispam:11334; set $webmail webmail; set $webdav webdav:5232; client_max_body_size 60817408; http2 on; # Listen on HTTP only in kubernetes or behind reverse proxy # Only enable HTTPS if TLS is enabled with no error # Remove headers to prevent duplication and information disclosure proxy_hide_header X-XSS-Protection; proxy_hide_header X-Powered-By; add_header X-Frame-Options 'SAMEORIGIN'; add_header X-Content-Type-Options 'nosniff'; add_header X-Permitted-Cross-Domain-Policies 'none'; add_header Referrer-Policy 'same-origin'; # mozilla autoconfiguration location ~ ^/(\.well\-known/autoconfig/)?mail/config\-v1\.1\.xml { rewrite ^ /internal/autoconfig/mozilla break; include /etc/nginx/proxy.conf; proxy_pass http://$admin; } # microsoft autoconfiguration location ~* ^/Autodiscover/Autodiscover.json { rewrite ^ /internal/autoconfig/microsoft.json break; include /etc/nginx/proxy.conf; proxy_pass http://$admin; } location ~* ^/Autodiscover/Autodiscover.xml { rewrite ^ /internal/autoconfig/microsoft break; include /etc/nginx/proxy.conf; proxy_pass http://$admin; } # apple mobileconfig location ~ ^/(apple\.)?mobileconfig { rewrite ^ /internal/autoconfig/apple break; include /etc/nginx/proxy.conf; proxy_pass http://$admin; } location ^~ /.well-known/acme-challenge/testing { return 204; } location ^~ /.well-known/acme-challenge/ { proxy_pass http://127.0.0.1:8008; } # If TLS is failing, prevent access to anything except certbot location / { return 403; } location /internal { internal; proxy_set_header X-Real-IP $remote_addr; proxy_set_header Authorization $http_authorization; proxy_pass_header Authorization; proxy_pass http://$admin; proxy_pass_request_body off; proxy_set_header Content-Length ""; } location /health { return 204; } } # Forwarding authentication server server { # Variables for proxifying set $admin admin:8080; listen 127.0.0.1:8000; location / { proxy_pass http://$admin/internal$request_uri; } } # Healthcheck over localhost, for docker server { listen 127.0.0.1:10204; location /health { return 204; } } include /etc/nginx/conf.d/*.conf; } mail { server_name mail.arti24.eu; auth_http http://127.0.0.1:8000/auth/email; proxy_pass_error_message on; resolver 127.0.0.11 valid=30s; error_log /dev/stderr info; # Advertise real capabilities of backends (postfix/dovecot) smtp_capabilities PIPELINING "SIZE 52428800" ETRN ENHANCEDSTATUSCODES 8BITMIME DSN; # SMTP is always enabled, to avoid losing emails when TLS is failing server { listen 25; protocol smtp; smtp_auth none; auth_http_header Auth-Port 25; auth_http_header Client-Port $remote_port; } }