mirror of
				https://github.com/optim-enterprises-bv/Mailu.git
				synced 2025-10-30 17:47:55 +00:00 
			
		
		
		
	simplify config with TLS, PORTS and PROXY_PROTOCOL
This commit is contained in:
		| @@ -5,7 +5,7 @@ log_path = /dev/stderr | ||||
| protocols = imap pop3 lmtp sieve | ||||
| postmaster_address = {{ POSTMASTER }}@{{ DOMAIN }} | ||||
| hostname = {{ HOSTNAMES.split(",")[0] }} | ||||
| {%- if PROXY_PROTOCOL in ['all', 'all-but-http', 'mail'] %} | ||||
| {%- if PROXY_PROTOCOL_SMTP %} | ||||
| submission_host = {{ HOSTNAMES.split(",")[0] }} | ||||
| {% else %} | ||||
| submission_host = {{ FRONT_ADDRESS }} | ||||
|   | ||||
| @@ -22,7 +22,7 @@ http { | ||||
|  | ||||
|     {% if REAL_IP_HEADER %} | ||||
|     real_ip_header {{ REAL_IP_HEADER }}; | ||||
|     {% elif PROXY_PROTOCOL in ['all', 'all-but-http', 'http'] %} | ||||
|     {% elif (PROXY_PROTOCOL_HTTPS or PROXY_PROTOCOL_HTTP) and REAL_IP_FROM %} | ||||
|     real_ip_header proxy_protocol; | ||||
|     {% endif %} | ||||
|  | ||||
| @@ -54,14 +54,14 @@ http { | ||||
|     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' ] %} | ||||
|     {% if PORT_80 and TLS_FLAVOR in [ 'letsencrypt', 'cert' ] %} | ||||
|     # Enable the proxy for certbot if the flavor is letsencrypt and not on kubernetes | ||||
|     # | ||||
|     server { | ||||
|       # Listen over HTTP | ||||
|       listen 80{% if PROXY_PROTOCOL in ['all', 'http'] %} proxy_protocol{% endif %}; | ||||
|       listen 80{% if PROXY_PROTOCOL_HTTP %} proxy_protocol{% endif %}; | ||||
| {% if SUBNET6 %} | ||||
|       listen [::]:80{% if PROXY_PROTOCOL in ['all', 'http'] %} proxy_protocol{% endif %}; | ||||
|       listen [::]:80{% if PROXY_PROTOCOL_HTTP %} proxy_protocol{% endif %}; | ||||
| {% endif %} | ||||
|       {% if TLS_FLAVOR in ['letsencrypt', 'mail-letsencrypt'] %} | ||||
|       location ^~ /.well-known/acme-challenge/ { | ||||
| @@ -95,18 +95,18 @@ http { | ||||
|       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 TLS_FLAVOR in [ 'mail-letsencrypt', 'notls', 'mail' ] %} | ||||
|       listen 80{% if PROXY_PROTOCOL_HTTP %} proxy_protocol{% endif %}; | ||||
| {% if SUBNET6 %} | ||||
|       listen [::]:80{% if PROXY_PROTOCOL in ['all', 'http'] %} proxy_protocol{% endif %}; | ||||
|       listen [::]:80{% if PROXY_PROTOCOL_HTTP %} proxy_protocol{% endif %}; | ||||
| {% endif %} | ||||
|       {% endif %} | ||||
|  | ||||
|       # 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', 'all-but-http', 'http'] %} proxy_protocol{% endif %}; | ||||
|       # Only enable HTTPS if TLS is enabled with no error | ||||
|       {% if TLS_443 and not TLS_ERROR %} | ||||
|       listen 443 ssl http2{% if PROXY_PROTOCOL_HTTPS %} proxy_protocol{% endif %}; | ||||
| {% if SUBNET6 %} | ||||
|       listen [::]:443 ssl http2{% if PROXY_PROTOCOL in ['all', 'all-but-http', 'http'] %} proxy_protocol{% endif %}; | ||||
|       listen [::]:443 ssl http2{% if PROXY_PROTOCOL_HTTPS %} proxy_protocol{% endif %}; | ||||
| {% endif %} | ||||
|  | ||||
|       include /etc/nginx/tls.conf; | ||||
| @@ -162,7 +162,7 @@ http { | ||||
|       {% 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' ]) %} | ||||
|       {% if TLS_ERROR and not (TLS_FLAVOR in [ 'mail-letsencrypt', 'mail' ]) %} | ||||
|       location / { | ||||
|         return 403; | ||||
|       } | ||||
| @@ -310,12 +310,12 @@ mail { | ||||
|     resolver {{ RESOLVER }} valid=30s; | ||||
|     error_log /dev/stderr info; | ||||
|  | ||||
|     {% if TLS and not TLS_ERROR %} | ||||
|     {% if TLS_25 and not TLS_ERROR %} | ||||
|     include /etc/nginx/tls.conf; | ||||
|     ssl_session_cache shared:SSLMAIL:3m; | ||||
|     {% endif %} | ||||
|  | ||||
|     {% if PROXY_PROTOCOL in ['all', 'all-but-http', 'mail'] and REAL_IP_FROM %}{% for from_ip in REAL_IP_FROM.split(',') %} | ||||
|     {% if PROXY_PROTOCOL_SMTP and REAL_IP_FROM %}{% for from_ip in REAL_IP_FROM.split(',') %} | ||||
|     set_real_ip_from {{ from_ip }}; | ||||
|     {% endfor %}{% endif %} | ||||
|  | ||||
| @@ -324,11 +324,11 @@ mail { | ||||
|  | ||||
|     # SMTP is always enabled, to avoid losing emails when TLS is failing | ||||
|     server { | ||||
|       listen 25{% if PROXY_PROTOCOL in ['all', 'all-but-http', 'mail'] %} proxy_protocol{% endif %}; | ||||
|       listen 25{% if PROXY_PROTOCOL_SMTP %} proxy_protocol{% endif %}; | ||||
| {% if SUBNET6 %} | ||||
|       listen [::]:25{% if PROXY_PROTOCOL in ['all', 'all-but-http', 'mail'] %} proxy_protocol{% endif %}; | ||||
|       listen [::]:25{% if PROXY_PROTOCOL_SMTP %} proxy_protocol{% endif %}; | ||||
| {% endif %} | ||||
|       {% if TLS and not TLS_ERROR %} | ||||
|       {% if TLS_25 and not TLS_ERROR %} | ||||
|       {% if TLS_FLAVOR in ['letsencrypt','mail-letsencrypt'] %} | ||||
|       ssl_certificate /certs/letsencrypt/live/mailu/DANE-chain.pem; | ||||
|       ssl_certificate /certs/letsencrypt/live/mailu-ecdsa/DANE-chain.pem; | ||||
|   | ||||
| @@ -6,7 +6,7 @@ proxy_hide_header True-Client-IP; | ||||
| proxy_hide_header CF-Connecting-IP; | ||||
|  | ||||
| proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto; | ||||
| {% if (REAL_IP_HEADER or (PROXY_PROTOCOL in ['http', 'all'])) and REAL_IP_FROM %} | ||||
| {% if (REAL_IP_HEADER or (PROXY_PROTOCOL_HTTP or PROXY_PROTOCOL_HTTPS)) and REAL_IP_FROM %} | ||||
| proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | ||||
| proxy_set_header X-Forwarded-By $realip_remote_addr; | ||||
| {% else %} | ||||
|   | ||||
| @@ -70,6 +70,44 @@ with open("/etc/resolv.conf") as handle: | ||||
|     resolver = content[content.index("nameserver") + 1] | ||||
|     args["RESOLVER"] = f"[{resolver}]" if ":" in resolver else resolver | ||||
|  | ||||
| # Configure PROXY_PROTOCOL | ||||
| PROTO_MAIL=['SMTP', 'POP3', 'POP3S', 'IMAP', 'IMAPS', 'SUBMISSION', 'SUBMISSIONS', 'MANAGESIEVE'] | ||||
| PROTO_ALL_BUT_HTTP=PROTO_MAIL.copy() | ||||
| PROTO_ALL_BUT_HTTP.extend(['HTTPS']) | ||||
| PROTO_ALL=PROTO_ALL_BUT_HTTP.copy() | ||||
| PROTO_ALL.extend(['HTTP']) | ||||
| for item in args.get('PROXY_PROTOCOL', '').split(','): | ||||
|     match item: | ||||
|         case '25': args['PROXY_PROTOCOL_SMTP']=True; continue | ||||
|         case '80': args['PROXY_PROTOCOL_HTTP']=True; continue | ||||
|         case '110': args['PROXY_PROTOCOL_POP3']=True; continue | ||||
|         case '143': args['PROXY_PROTOCOL_IMAP']=True; continue | ||||
|         case '443': args['PROXY_PROTOCOL_HTTPS']=True; continue | ||||
|         case '465': args['PROXY_PROTOCOL_SUBMISSIONS']=True; continue | ||||
|         case '587': args['PROXY_PROTOCOL_SUBMISSION']=True; continue | ||||
|         case '993': args['PROXY_PROTOCOL_IMAPS']=True; continue | ||||
|         case '995': args['PROXY_PROTOCOL_POP3S']=True; continue | ||||
|         case '4190': args['PROXY_PROTOCOL_MANAGESIEVE']=True; continue | ||||
|         case 'mail': | ||||
|             for p in PROTO_MAIL: args[f'PROXY_PROTOCOL_{p}']=True; continue | ||||
|         case 'all-but-http': | ||||
|             for p in PROTO_ALL_BUT_HTTP: args[f'PROXY_PROTOCOL_{p}']=True; continue | ||||
|         case 'all': | ||||
|             for p in PROTO_ALL: args[f'PROXY_PROTOCOL_{p}']=True; continue | ||||
|  | ||||
| PORTS_REQUIRING_TLS=['443', '465', '993', '995'] | ||||
| ALL_PORTS='25,80,443,465,587,993,995,4190' | ||||
| for item in args.get('PORTS', ALL_PORTS).split(','): | ||||
|     if item in PORTS_REQUIRING_TLS and args['TLS_FLAVOR'] == 'notls': | ||||
|         continue | ||||
|     args[f'PORT_{item}']=True | ||||
|  | ||||
| for item in args.get('TLS', ALL_PORTS).split(','): | ||||
|     if item in PORTS_REQUIRING_TLS: | ||||
|         if args['TLS_FLAVOR'] == 'notls': | ||||
|             continue | ||||
|         args[f'TLS_{item}']=True | ||||
|  | ||||
| # TLS configuration | ||||
| cert_name = args.get("TLS_CERT_FILENAME", "cert.pem") | ||||
| keypair_name = args.get("TLS_KEYPAIR_FILENAME", "key.pem") | ||||
| @@ -129,6 +167,8 @@ if args["TLS"] and not all(os.path.exists(file_path) for file_path in args["TLS" | ||||
|     print("Missing cert or key file, disabling TLS") | ||||
|     args["TLS_ERROR"] = "yes" | ||||
|  | ||||
| args['TLS_PERMISSIVE'] = str(args.get('TLS_PERMISSIVE')).lower() not in ('false', 'no') | ||||
|  | ||||
| # Build final configuration paths | ||||
| conf.jinja("/conf/tls.conf", args, "/etc/nginx/tls.conf") | ||||
| conf.jinja("/conf/proxy.conf", args, "/etc/nginx/proxy.conf") | ||||
|   | ||||
| @@ -75,11 +75,12 @@ service anvil { | ||||
|   } | ||||
| } | ||||
|  | ||||
| {%- if PORT_4190 %} | ||||
| service managesieve-login { | ||||
|   executable = managesieve-login | ||||
|   inet_listener sieve { | ||||
|     port = 4190 | ||||
| {%- if PROXY_PROTOCOL in ['all', 'all-but-http', 'mail'] %} | ||||
| {%- if PROXY_PROTOCOL_MANAGESIEVE %} | ||||
|     haproxy = yes | ||||
| {% endif %} | ||||
|   } | ||||
| @@ -87,6 +88,7 @@ service managesieve-login { | ||||
|     port = 14190 | ||||
|   } | ||||
| } | ||||
| {% endif %} | ||||
|  | ||||
| protocol imap { | ||||
|   mail_max_userip_connections = 20 | ||||
| @@ -94,42 +96,46 @@ protocol imap { | ||||
| } | ||||
|  | ||||
| service imap-login { | ||||
| {%- if PORT_143 %} | ||||
|   inet_listener imap { | ||||
|     port = 143 | ||||
| {%- if PROXY_PROTOCOL in ['all', 'all-but-http', 'mail'] %} | ||||
| {%- if PROXY_PROTOCOL_IMAP %} | ||||
|     haproxy = yes | ||||
| {% endif %} | ||||
|   } | ||||
| {% endif %} | ||||
| {%- if TLS_993 and PORT_993 %} | ||||
|   inet_listener imaps { | ||||
|     port = 993 | ||||
| {%- if TLS %} | ||||
|     ssl = yes | ||||
| {% endif %} | ||||
| {%- if PROXY_PROTOCOL in ['all', 'all-but-http', 'mail'] %} | ||||
| {%- if PROXY_PROTOCOL_IMAPS %} | ||||
|     haproxy = yes | ||||
| {% endif %} | ||||
|   } | ||||
| {% endif %} | ||||
|   inet_listener imap-webmail { | ||||
|    port = 10143 | ||||
|   } | ||||
| } | ||||
|  | ||||
| service pop3-login { | ||||
| {%- if PORT_110 %} | ||||
|   inet_listener pop3 { | ||||
|     port = 110 | ||||
| {%- if PROXY_PROTOCOL in ['all', 'all-but-http', 'mail'] %} | ||||
| {%- if PROXY_PROTOCOL_POP3 %} | ||||
|     haproxy = yes | ||||
| {% endif %} | ||||
|   } | ||||
| {% endif %} | ||||
| {%- if TLS_995 and PORT_995 %} | ||||
|   inet_listener pop3s { | ||||
|     port = 995 | ||||
| {%- if TLS %} | ||||
|     ssl = yes | ||||
| {% endif %} | ||||
| {%- if PROXY_PROTOCOL in ['all', 'all-but-http', 'mail'] %} | ||||
| {%- if PROXY_PROTOCOL_POP3S %} | ||||
|     haproxy = yes | ||||
| {% endif %} | ||||
|   } | ||||
| {% endif %} | ||||
| } | ||||
|  | ||||
| recipient_delimiter = {{ RECIPIENT_DELIMITER }} | ||||
| @@ -141,21 +147,23 @@ service lmtp { | ||||
| } | ||||
|  | ||||
| service submission-login { | ||||
| {%- if PORT_587 %} | ||||
|    inet_listener submission { | ||||
|     port = 587 | ||||
| {%- if PROXY_PROTOCOL in ['all', 'all-but-http', 'mail'] %} | ||||
| {%- if PROXY_PROTOCOL_SUBMISSION %} | ||||
|     haproxy = yes | ||||
| {% endif %} | ||||
|    } | ||||
| {% endif %} | ||||
| {%- if TLS_465 and PORT_465 %} | ||||
|    inet_listener submissions { | ||||
|     port = 465 | ||||
| {%- if TLS %} | ||||
|     ssl = yes | ||||
| {% endif %} | ||||
| {%- if PROXY_PROTOCOL in ['all', 'all-but-http', 'mail'] %} | ||||
| {%- if PROXY_PROTOCOL_SUBMISSIONS %} | ||||
|     haproxy = yes | ||||
| {% endif %} | ||||
|    } | ||||
| {% endif %} | ||||
|    inet_listener submission-webmail { | ||||
|     port = 10025 | ||||
|    } | ||||
|   | ||||
							
								
								
									
										1
									
								
								towncrier/newsfragments/3061.feature
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								towncrier/newsfragments/3061.feature
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| Introduce new settings for configuring proxying and TLS. Drop TLS_FLAVOR=mail-letsencrypt | ||||
		Reference in New Issue
	
	Block a user
	 Florent Daigniere
					Florent Daigniere