1
0
mirror of https://github.com/Mailu/Mailu.git synced 2024-12-14 10:53:30 +02:00
Mailu/core/nginx/conf/nginx.conf

349 lines
11 KiB
Nginx Configuration File
Raw Normal View History

2021-10-29 14:26:23 +02:00
# Basic configuration
2017-09-24 13:09:12 +02:00
user nginx;
worker_processes auto;
pcre_jit on;
error_log /dev/stderr notice;
2017-09-24 13:09:12 +02:00
pid /var/run/nginx.pid;
load_module "modules/ngx_mail_module.so";
events {
2021-10-29 14:26:23 +02:00
worker_connections 1024;
2017-09-24 13:09:12 +02:00
}
http {
# Standard HTTP configuration with slight hardening
include /etc/nginx/mime.types;
default_type application/octet-stream;
sendfile on;
2021-10-29 14:26:23 +02:00
keepalive_timeout 65;
2017-09-24 13:09:12 +02:00
server_tokens off;
absolute_redirect off;
resolver {{ RESOLVER }} valid=30s;
2017-09-24 13:09:12 +02:00
2017-12-05 01:21:58 +02:00
{% if REAL_IP_HEADER %}
real_ip_header {{ REAL_IP_HEADER }};
{% elif PROXY_PROTOCOL in ['all', 'http'] %}
real_ip_header proxy_protocol;
2017-12-05 01:21:58 +02:00
{% endif %}
{% if REAL_IP_FROM %}{% for from_ip in REAL_IP_FROM.split(',') %}
set_real_ip_from {{ from_ip }};
{% endfor %}{% endif %}
# Header maps
map $http_x_forwarded_proto $proxy_x_forwarded_proto {
default $http_x_forwarded_proto;
'' $scheme;
}
2021-09-02 20:48:44 +02:00
map $uri $expires {
default off;
~*\.(ico|css|js|gif|jpeg|jpg|png|woff2?|ttf|otf|svg|tiff|eot|webp)$ 97d;
2021-09-02 20:48:44 +02:00
}
2021-10-30 15:30:59 +02:00
map $request_uri $loggable {
/health 0;
/auth/email 0;
default 1;
}
access_log /dev/stdout combined if=$loggable;
2021-09-02 20:48:44 +02:00
# 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
{% if not KUBERNETES_INGRESS and TLS_FLAVOR in [ 'letsencrypt', 'cert' ] %}
# Enable the proxy for certbot if the flavor is letsencrypt and not on kubernetes
2021-10-29 14:26:23 +02:00
#
server {
# Listen over HTTP
listen 80{% if PROXY_PROTOCOL in ['all', 'http'] %} proxy_protocol{% endif %};
{% if SUBNET6 %}
listen [::]:80{% if PROXY_PROTOCOL in ['all', 'http'] %} proxy_protocol{% endif %};
{% endif %}
2023-04-12 12:33:33 +02:00
{% if TLS_FLAVOR in ['letsencrypt', 'mail-letsencrypt'] %}
location ^~ /.well-known/acme-challenge/ {
proxy_pass http://127.0.0.1:8008;
}
{% endif %}
# redirect to https
location / {
return 301 https://$host$request_uri;
}
2021-09-02 20:48:44 +02:00
2023-04-21 10:08:32 +02:00
location /health {
return 204;
}
}
{% endif %}
# Main HTTP server
2017-09-24 13:09:12 +02:00
server {
# Favicon stuff
root /static;
# Variables for proxifying
set $admin {{ ADMIN_ADDRESS }}:8080;
2022-12-08 13:46:31 +02:00
set $antispam {{ ANTISPAM_ADDRESS }}:11334;
2019-08-21 21:54:42 +02:00
{% if WEBMAIL_ADDRESS %}
2019-02-18 14:46:48 +02:00
set $webmail {{ WEBMAIL_ADDRESS }};
2019-08-21 21:54:42 +02:00
{% endif %}
{% if WEBDAV_ADDRESS %}
2022-12-08 13:46:31 +02:00
set $webdav {{ WEBDAV_ADDRESS }}:5232;
2019-08-21 21:54:42 +02:00
{% endif %}
2022-01-07 09:55:55 +02:00
client_max_body_size {{ MESSAGE_SIZE_LIMIT|int + 8388608 }};
# Listen on HTTP only in kubernetes or behind reverse proxy
{% if KUBERNETES_INGRESS or TLS_FLAVOR in [ 'mail-letsencrypt', 'notls', 'mail' ] %}
listen 80{% if PROXY_PROTOCOL in ['all', 'http'] %} proxy_protocol{% endif %};
{% if SUBNET6 %}
listen [::]:80{% if PROXY_PROTOCOL in ['all', 'http'] %} proxy_protocol{% endif %};
{% endif %}
{% endif %}
2017-09-24 13:09:12 +02:00
2019-08-29 10:21:52 +02:00
# Only enable HTTPS if TLS is enabled with no error and not on kubernetes
{% if not KUBERNETES_INGRESS and TLS and not TLS_ERROR %}
listen 443 ssl http2{% if PROXY_PROTOCOL in ['all', 'http'] %} proxy_protocol{% endif %};
{% if SUBNET6 %}
listen [::]:443 ssl http2{% if PROXY_PROTOCOL in ['all', 'http'] %} proxy_protocol{% endif %};
{% endif %}
2017-09-24 18:43:14 +02:00
include /etc/nginx/tls.conf;
ssl_stapling on;
ssl_stapling_verify on;
ssl_session_cache shared:SSLHTTP:3m;
2017-12-05 01:21:58 +02:00
add_header Strict-Transport-Security 'max-age=31536000';
2017-09-24 14:01:03 +02:00
2017-12-05 01:21:58 +02:00
{% if not TLS_FLAVOR in [ 'mail', 'mail-letsencrypt' ] %}
if ($proxy_x_forwarded_proto = http) {
2017-09-24 14:01:03 +02:00
return 301 https://$host$request_uri;
}
{% endif %}
2017-11-07 17:16:41 +02:00
{% endif %}
2017-09-24 14:01:03 +02:00
# Remove headers to prevent duplication and information disclosure
proxy_hide_header X-XSS-Protection;
proxy_hide_header X-Powered-By;
2021-09-02 20:48:44 +02:00
add_header X-Frame-Options 'SAMEORIGIN';
2017-12-05 01:21:58 +02:00
add_header X-Content-Type-Options 'nosniff';
add_header X-Permitted-Cross-Domain-Policies 'none';
add_header Referrer-Policy 'same-origin';
2022-03-10 10:28:10 +02:00
# mozilla autoconfiguration
2022-03-10 11:00:51 +02:00
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
2022-03-15 11:26:29 +02:00
location ~* ^/Autodiscover/Autodiscover.json {
rewrite ^ /internal/autoconfig/microsoft.json break;
include /etc/nginx/proxy.conf;
proxy_pass http://$admin;
}
2022-03-10 11:00:51 +02:00
location ~* ^/Autodiscover/Autodiscover.xml {
rewrite ^ /internal/autoconfig/microsoft break;
2022-03-10 10:28:10 +02:00
include /etc/nginx/proxy.conf;
proxy_pass http://$admin;
}
2022-03-10 11:29:11 +02:00
# apple mobileconfig
location ~ ^/(apple\.)?mobileconfig {
2022-03-10 11:29:11 +02:00
rewrite ^ /internal/autoconfig/apple break;
include /etc/nginx/proxy.conf;
proxy_pass http://$admin;
}
2022-03-10 10:28:10 +02:00
2023-04-12 12:33:33 +02:00
{% if TLS_FLAVOR in ['letsencrypt', 'mail-letsencrypt'] %}
location ^~ /.well-known/acme-challenge/ {
proxy_pass http://127.0.0.1:8008;
}
{% endif %}
# If TLS is failing, prevent access to anything except certbot
{% if not KUBERNETES_INGRESS and TLS_ERROR and not (TLS_FLAVOR in [ 'mail-letsencrypt', 'mail' ]) %}
location / {
2017-10-21 15:54:09 +02:00
return 403;
}
{% else %}
include /overrides/*.conf;
# Actual logic
{% if ADMIN or WEBMAIL != 'none' %}
2021-12-14 17:10:28 +02:00
location ~ ^/(sso|static)/ {
2021-09-02 18:02:20 +02:00
include /etc/nginx/proxy.conf;
proxy_pass http://$admin;
}
{% endif %}
2023-03-14 10:40:43 +02:00
location @sso_login {
return 302 /sso/login?url=$request_uri;
}
{% if WEB_WEBMAIL != '/' and WEBROOT_REDIRECT != 'none' %}
2017-09-24 13:09:12 +02:00
location / {
expires $expires;
2018-12-19 16:20:24 +02:00
{% if WEBROOT_REDIRECT %}
2023-03-14 10:40:43 +02:00
try_files $uri {{ WEBROOT_REDIRECT }}?homepage;
{% else %}
2019-01-07 14:08:00 +02:00
try_files $uri =404;
{% endif %}
2018-12-07 16:44:42 +02:00
}
2018-12-19 16:20:24 +02:00
{% endif %}
2017-09-24 13:09:12 +02:00
{% if WEBMAIL != 'none' %}
location {{ WEB_WEBMAIL }} {
2018-10-18 14:27:28 +02:00
{% if WEB_WEBMAIL != '/' %}
rewrite ^({{ WEB_WEBMAIL }})$ $1/ permanent;
rewrite ^{{ WEB_WEBMAIL }}/(.*) /$1 break;
2018-10-18 14:27:28 +02:00
{% endif %}
include /etc/nginx/proxy.conf;
2021-10-29 14:26:23 +02:00
auth_request /internal/auth/user;
2023-03-14 10:40:43 +02:00
error_page 403 @sso_login;
proxy_pass http://$webmail;
2021-02-06 18:23:05 +02:00
}
2021-12-14 17:10:28 +02:00
{% if WEB_WEBMAIL == '/' %}
location /sso.php {
2021-12-15 11:53:47 +02:00
{% else %}
2021-02-06 18:23:05 +02:00
location {{ WEB_WEBMAIL }}/sso.php {
2021-12-14 17:10:28 +02:00
{% endif %}
2021-02-06 18:23:05 +02:00
{% if WEB_WEBMAIL != '/' %}
rewrite ^({{ WEB_WEBMAIL }})$ $1/ permanent;
rewrite ^{{ WEB_WEBMAIL }}/(.*) /$1 break;
{% endif %}
include /etc/nginx/proxy.conf;
auth_request /internal/auth/user;
auth_request_set $user $upstream_http_x_user;
auth_request_set $token $upstream_http_x_user_token;
proxy_set_header X-Remote-User $user;
proxy_set_header X-Remote-User-Token $token;
2023-03-14 10:40:43 +02:00
error_page 403 @sso_login;
proxy_pass http://$webmail;
2021-02-06 18:23:05 +02:00
}
{% endif %}
{% if ADMIN %}
location {{ WEB_ADMIN }} {
2021-10-29 10:18:50 +02:00
include /etc/nginx/proxy.conf;
proxy_pass http://$admin;
expires $expires;
}
2021-10-29 14:26:23 +02:00
location {{ WEB_ADMIN }}/antispam {
rewrite ^{{ WEB_ADMIN }}/antispam/(.*) /$1 break;
auth_request /internal/auth/admin;
proxy_set_header X-Real-IP "";
proxy_set_header X-Forwarded-For "";
2023-03-18 10:55:32 +02:00
proxy_set_header X-Forwarded-By: "";
proxy_pass http://$antispam;
2023-03-14 10:40:43 +02:00
error_page 403 @sso_login;
}
2017-09-24 14:01:03 +02:00
{% endif %}
2017-09-24 13:09:12 +02:00
2017-09-24 14:01:03 +02:00
{% if WEBDAV != 'none' %}
2017-09-24 13:09:12 +02:00
location /webdav {
rewrite ^/webdav/(.*) /$1 break;
auth_request /internal/auth/basic;
auth_request_set $user $upstream_http_x_user;
include /etc/nginx/proxy.conf;
proxy_set_header X-Remote-User $user;
proxy_set_header X-Script-Name /webdav;
proxy_pass http://$webdav;
2017-09-24 13:09:12 +02:00
}
location ~ ^/.well-known/(carddav|caldav) {
return 301 /webdav/;
}
2017-09-24 14:01:03 +02:00
{% endif %}
{% endif %}
{% if API %}
location ~ {{ WEB_API or '/api' }} {
include /etc/nginx/proxy.conf;
proxy_pass http://$admin;
}
{% endif %}
location /internal {
internal;
2021-09-23 18:40:49 +02:00
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 "";
}
2023-05-09 09:54:52 +02:00
location /health {
return 204;
}
2017-09-24 13:09:12 +02:00
}
# Forwarding authentication server
server {
# Variables for proxifying
set $admin {{ ADMIN_ADDRESS }}:8080;
listen 127.0.0.1:8000;
2017-10-22 16:43:06 +02:00
location / {
proxy_pass http://$admin/internal$request_uri;
}
}
2023-05-09 09:51:53 +02:00
# Healthcheck over localhost, for docker
server {
listen 127.0.0.1:10204;
location /health {
return 204;
}
}
include /etc/nginx/conf.d/*.conf;
2017-09-24 13:09:12 +02:00
}
mail {
server_name {{ HOSTNAMES.split(",")[0] }};
2017-10-22 16:43:06 +02:00
auth_http http://127.0.0.1:8000/auth/email;
2017-09-24 13:09:12 +02:00
proxy_pass_error_message on;
resolver {{ RESOLVER }} valid=30s;
error_log /dev/stderr info;
2017-09-24 13:09:12 +02:00
2017-09-24 18:43:14 +02:00
{% if TLS and not TLS_ERROR %}
include /etc/nginx/tls.conf;
ssl_session_cache shared:SSLMAIL:3m;
2017-09-24 18:43:14 +02:00
{% endif %}
{% if PROXY_PROTOCOL in ['all', 'mail'] and REAL_IP_FROM %}{% for from_ip in REAL_IP_FROM.split(',') %}
set_real_ip_from {{ from_ip }};
{% endfor %}{% endif %}
2022-10-19 19:36:13 +02:00
# Advertise real capabilities of backends (postfix/dovecot)
smtp_capabilities PIPELINING "SIZE {{ MESSAGE_SIZE_LIMIT }}" ETRN ENHANCEDSTATUSCODES 8BITMIME DSN;
# SMTP is always enabled, to avoid losing emails when TLS is failing
2017-09-24 13:09:12 +02:00
server {
listen 25{% if PROXY_PROTOCOL in ['all', 'mail'] %} proxy_protocol{% endif %};
{% if SUBNET6 %}
listen [::]:25{% if PROXY_PROTOCOL in ['all', 'mail'] %} proxy_protocol{% endif %};
{% endif %}
{% if TLS and not TLS_ERROR %}
{% if TLS_FLAVOR in ['letsencrypt','mail-letsencrypt'] %}
ssl_certificate /certs/letsencrypt/live/mailu/fullchain.pem;
ssl_certificate /certs/letsencrypt/live/mailu-ecdsa/fullchain.pem;
{% endif %}
2022-09-14 11:03:44 +02:00
{% if TLS_PERMISSIVE %}
ssl_protocols TLSv1 TLSv1.1 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:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA;
ssl_prefer_server_ciphers on;
{% endif %}
2017-09-24 18:43:14 +02:00
starttls on;
{% endif %}
2017-09-24 13:09:12 +02:00
protocol smtp;
2017-09-24 18:43:14 +02:00
smtp_auth none;
2021-08-09 20:10:49 +02:00
auth_http_header Auth-Port 25;
2023-05-04 00:14:44 +02:00
auth_http_header Client-Port $remote_port;
2017-09-24 13:09:12 +02:00
}
}