From f7f5f4ecaebffca80a9b53840742c070bd99bf82 Mon Sep 17 00:00:00 2001 From: Victor Lap Date: Tue, 8 Oct 2019 09:39:27 +0200 Subject: [PATCH] Add webmail. subdomain to access roundcube --- conf/nginx-alldomains.conf | 24 ------------------------ conf/nginx-webmail.conf | 22 ++++++++++++++++++++++ management/dns_update.py | 12 +++++++++--- management/web_update.py | 28 ++++++++++++++++++++-------- 4 files changed, 51 insertions(+), 35 deletions(-) create mode 100644 conf/nginx-webmail.conf diff --git a/conf/nginx-alldomains.conf b/conf/nginx-alldomains.conf index 1b3ad5a9..8185c902 100644 --- a/conf/nginx-alldomains.conf +++ b/conf/nginx-alldomains.conf @@ -22,30 +22,6 @@ alias /var/lib/mailinabox/mozilla-autoconfig.xml; } - # Roundcube Webmail configuration. - rewrite ^/mail$ /mail/ redirect; - rewrite ^/mail/$ /mail/index.php; - location /mail/ { - index index.php; - alias /usr/local/lib/roundcubemail/; - } - location ~ /mail/config/.* { - # A ~-style location is needed to give this precedence over the next block. - return 403; - } - location ~ /mail/.*\.php { - # note: ~ has precendence over a regular location block - include fastcgi_params; - fastcgi_split_path_info ^/mail(/.*)()$; - fastcgi_index index.php; - fastcgi_param SCRIPT_FILENAME /usr/local/lib/roundcubemail/$fastcgi_script_name; - fastcgi_pass php-fpm; - - # Outgoing mail also goes through this endpoint, so increase the maximum - # file upload limit to match the corresponding Postfix limit. - client_max_body_size 128M; - } - # Z-Push (Microsoft Exchange ActiveSync) location /Microsoft-Server-ActiveSync { include /etc/nginx/fastcgi_params; diff --git a/conf/nginx-webmail.conf b/conf/nginx-webmail.conf new file mode 100644 index 00000000..3aa40cf2 --- /dev/null +++ b/conf/nginx-webmail.conf @@ -0,0 +1,22 @@ + # Roundcube Webmail configuration. + rewrite ^$WEBMAIL_PATH$ $WEBMAIL_PATH/ redirect; + location $WEBMAIL_PATH/ { + index index.php; + alias /usr/local/lib/roundcubemail/; + } + location ~ $WEBMAIL_PATH/config/.* { + # A ~-style location is needed to give this precedence over the next block. + return 403; + } + location ~ $WEBMAIL_PATH/.*\.php { + # note: ~ has precendence over a regular location block + include fastcgi_params; + fastcgi_split_path_info ^$WEBMAIL_PATH(/.*)()$; + fastcgi_index index.php; + fastcgi_param SCRIPT_FILENAME /usr/local/lib/roundcubemail/$fastcgi_script_name; + fastcgi_pass php-fpm; + + # Outgoing mail also goes through this endpoint, so increase the maximum + # file upload limit to match the corresponding Postfix limit. + client_max_body_size 128M; + } diff --git a/management/dns_update.py b/management/dns_update.py index 7d053d5e..94486f8d 100755 --- a/management/dns_update.py +++ b/management/dns_update.py @@ -288,17 +288,23 @@ def build_zone(domain, all_domains, additional_records, www_redirect_domains, en if not has_rec(qname, "SRV"): records.append((qname, "SRV", "0 0 443 " + env["PRIMARY_HOSTNAME"] + ".", "Recommended. Specifies the hostname of the server that handles CardDAV/CalDAV services for email addresses on this domain.")) - # Adds autoconfiguration A records for all domains. + # Adds additional A records for all domains. # This allows the following clients to automatically configure email addresses in the respective applications. # autodiscover.* - Z-Push ActiveSync Autodiscover # autoconfig.* - Thunderbird Autoconfig - autodiscover_records = [ + additional_records = [ ("autodiscover", "A", env["PUBLIC_IP"], "Provides email configuration autodiscovery support for Z-Push ActiveSync Autodiscover."), ("autodiscover", "AAAA", env["PUBLIC_IPV6"], "Provides email configuration autodiscovery support for Z-Push ActiveSync Autodiscover."), ("autoconfig", "A", env["PUBLIC_IP"], "Provides email configuration autodiscovery support for Thunderbird Autoconfig."), ("autoconfig", "AAAA", env["PUBLIC_IPV6"], "Provides email configuration autodiscovery support for Thunderbird Autoconfig.") ] - for qname, rtype, value, explanation in autodiscover_records: + # webmail.* - Access to roundcube from a subdomain (useful if the top domain is routed to another machine) + if is_zone: + additional_records += [ + ("webmail", "A", env["PUBLIC_IP"], "Optional. Allows the use of webmail.%s to access roundcube. (It is not necessary for receiving mail on this domain.)" % domain), + ("webmail", "AAAA", env["PUBLIC_IPV6"], "Optional. Allows the use of webmail.%s to access roundcube. (It is not necessary for receiving mail on this domain.)" % domain), + ] + for qname, rtype, value, explanation in additional_records: if value is None or value.strip() == "": continue # skip IPV6 if not set if not has_rec(qname, rtype): records.append((qname, rtype, value, explanation)) diff --git a/management/web_update.py b/management/web_update.py index 72295c21..1f50cd2a 100644 --- a/management/web_update.py +++ b/management/web_update.py @@ -30,6 +30,9 @@ def get_web_domains(env, include_www_redirects=True, exclude_dns_elsewhere=True) domains |= set('autoconfig.' + maildomain for maildomain in get_mail_domains(env)) domains |= set('autodiscover.' + maildomain for maildomain in get_mail_domains(env)) + # Add webmail. domains, for domains that have their hosting on different machines. + domains |= set('webmail.' + zone for zone, zonefile in get_dns_zones(env)) + if exclude_dns_elsewhere: # ...Unless the domain has an A/AAAA record that maps it to a different # IP address than this box. Remove those domains from our list. @@ -78,10 +81,11 @@ def do_web_update(env): template0 = open(os.path.join(os.path.dirname(__file__), "../conf/nginx.conf")).read() template1 = open(os.path.join(os.path.dirname(__file__), "../conf/nginx-alldomains.conf")).read() template2 = open(os.path.join(os.path.dirname(__file__), "../conf/nginx-primaryonly.conf")).read() - template3 = "\trewrite ^(.*) https://$REDIRECT_DOMAIN$1 permanent;\n" + template3 = open(os.path.join(os.path.dirname(__file__), "../conf/nginx-webmail.conf")).read() + template4 = "\trewrite ^(.*) https://$REDIRECT_DOMAIN$1 permanent;\n" # Add the PRIMARY_HOST configuration first so it becomes nginx's default server. - nginx_conf += make_domain_config(env['PRIMARY_HOSTNAME'], [template0, template1, template2], ssl_certificates, env) + nginx_conf += make_domain_config(env['PRIMARY_HOSTNAME'], [template0, template1, template2, template3], ssl_certificates, env) # Add configuration all other web domains. has_root_proxy_or_redirect = get_web_domains_with_root_overrides(env) @@ -91,14 +95,18 @@ def do_web_update(env): # PRIMARY_HOSTNAME is handled above. continue if domain in web_domains_not_redirect: - # This is a regular domain. - if domain not in has_root_proxy_or_redirect: - nginx_conf += make_domain_config(domain, [template0, template1], ssl_certificates, env) - else: + # This is a domain that is redirected to another host + if domain in has_root_proxy_or_redirect: nginx_conf += make_domain_config(domain, [template0], ssl_certificates, env) + # This is a webmail domain. + elif is_webmail_domain(domain): + nginx_conf += make_domain_config(domain, [template0, template3], ssl_certificates, env) + # This is a regular domain. + else: + nginx_conf += make_domain_config(domain, [template0, template1, template3], ssl_certificates, env) else: # Add default 'www.' redirect. - nginx_conf += make_domain_config(domain, [template0, template3], ssl_certificates, env) + nginx_conf += make_domain_config(domain, [template0, template4], ssl_certificates, env) # Did the file change? If not, don't bother writing & restarting nginx. nginx_conf_fn = "/etc/nginx/conf.d/local.conf" @@ -119,6 +127,9 @@ def do_web_update(env): return "web updated\n" +def is_webmail_domain(domain): + return domain.startswith('webmail.') + def make_domain_config(domain, templates, ssl_certificates, env): # GET SOME VARIABLES @@ -190,6 +201,7 @@ def make_domain_config(domain, templates, ssl_certificates, env): nginx_conf = nginx_conf.replace("$SSL_KEY", tls_cert["private-key"]) nginx_conf = nginx_conf.replace("$SSL_CERTIFICATE", tls_cert["certificate"]) nginx_conf = nginx_conf.replace("$REDIRECT_DOMAIN", re.sub(r"^www\.", "", domain)) # for default www redirects to parent domain + nginx_conf = nginx_conf.replace("$WEBMAIL_PATH", ("" if is_webmail_domain(domain) else "/mail")) return nginx_conf @@ -226,7 +238,7 @@ def get_web_domains_info(env): "root": get_web_root(domain, env), "custom_root": get_web_root(domain, env, test_exists=False), "ssl_certificate": check_cert(domain), - "static_enabled": domain not in (www_redirects | has_root_proxy_or_redirect), + "static_enabled": domain not in (www_redirects | has_root_proxy_or_redirect) and not is_webmail_domain(domain), } for domain in get_web_domains(env) ]