From 283045dc4a08ff7265bfa7e80391812ad64a0261 Mon Sep 17 00:00:00 2001 From: link2xt Date: Thu, 11 Jul 2024 05:31:02 +0000 Subject: [PATCH] Multiplex HTTPS, IMAP and SMTP on port 443 Services are distinguished based on ALPN. For example, openssl s_client -connect example.org:443 -alpn smtp gives SMTP connection and openssl s_client -connect example.org:443 -alpn imap gives IMAP connection. --- README.md | 3 ++- cmdeploy/src/cmdeploy/__init__.py | 2 +- cmdeploy/src/cmdeploy/nginx/autoconfig.xml.j2 | 14 +++++++++++ cmdeploy/src/cmdeploy/nginx/nginx.conf.j2 | 25 ++++++++++++++++--- 4 files changed, 38 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index b1264fca..c837761f 100644 --- a/README.md +++ b/README.md @@ -155,7 +155,8 @@ While this file is present, account creation will be blocked. [Postfix](http://www.postfix.org/) listens on ports 25 (smtp) and 587 (submission) and 465 (submissions). [Dovecot](https://www.dovecot.org/) listens on ports 143 (imap) and 993 (imaps). -[nginx](https://www.nginx.com/) listens on port 443 (https). +[nginx](https://www.nginx.com/) listens on port 8443 (https-alt) and 443 (https). +Port 443 multiplexes HTTPS, IMAP and SMTP using ALPN to redirect connections to ports 8443, 465 or 993. [acmetool](https://hlandau.github.io/acmetool/) listens on port 80 (http). Delta Chat apps will, however, discover all ports and configurations diff --git a/cmdeploy/src/cmdeploy/__init__.py b/cmdeploy/src/cmdeploy/__init__.py index 84bec704..c7485c23 100644 --- a/cmdeploy/src/cmdeploy/__init__.py +++ b/cmdeploy/src/cmdeploy/__init__.py @@ -534,7 +534,7 @@ def deploy_chatmail(config_path: Path) -> None: apt.packages( name="Install nginx", - packages=["nginx"], + packages=["nginx", "libnginx-mod-stream"], ) apt.packages( diff --git a/cmdeploy/src/cmdeploy/nginx/autoconfig.xml.j2 b/cmdeploy/src/cmdeploy/nginx/autoconfig.xml.j2 index bf4bd8e7..a4b324af 100644 --- a/cmdeploy/src/cmdeploy/nginx/autoconfig.xml.j2 +++ b/cmdeploy/src/cmdeploy/nginx/autoconfig.xml.j2 @@ -19,6 +19,13 @@ password-cleartext %EMAILADDRESS% + + {{ config.domain_name }} + 443 + SSL + password-cleartext + %EMAILADDRESS% + {{ config.domain_name }} 465 @@ -33,5 +40,12 @@ password-cleartext %EMAILADDRESS% + + {{ config.domain_name }} + 443 + SSL + password-cleartext + %EMAILADDRESS% + diff --git a/cmdeploy/src/cmdeploy/nginx/nginx.conf.j2 b/cmdeploy/src/cmdeploy/nginx/nginx.conf.j2 index 6276661e..baf8541f 100644 --- a/cmdeploy/src/cmdeploy/nginx/nginx.conf.j2 +++ b/cmdeploy/src/cmdeploy/nginx/nginx.conf.j2 @@ -1,3 +1,5 @@ +load_module modules/ngx_stream_module.so; + user www-data; worker_processes auto; pid /run/nginx.pid; @@ -8,6 +10,21 @@ events { # multi_accept on; } +stream { + map $ssl_preread_alpn_protocols $proxy { + default 127.0.0.1:8443; + ~\bsmtp\b 127.0.0.1:submissions; + ~\bimap\b 127.0.0.1:imaps; + } + + server { + listen 443; + listen [::]:443; + proxy_pass $proxy; + ssl_preread on; + } +} + http { sendfile on; tcp_nopush on; @@ -26,8 +43,8 @@ http { gzip on; server { - listen 443 ssl default_server; - listen [::]:443 ssl default_server; + listen 8443 ssl default_server; + listen [::]:8443 ssl default_server; root /var/www/html; @@ -78,8 +95,8 @@ http { # Redirect www. to non-www server { - listen 443 ssl; - listen [::]:443 ssl; + listen 8443 ssl; + listen [::]:8443 ssl; server_name www.{{ config.domain_name }}; return 301 $scheme://{{ config.domain_name }}$request_uri; access_log syslog:server=unix:/dev/log,facility=local7;