diff --git a/data/hooks/conf_regen/15-nginx b/data/hooks/conf_regen/15-nginx index a2d8f1259..040ed090d 100755 --- a/data/hooks/conf_regen/15-nginx +++ b/data/hooks/conf_regen/15-nginx @@ -60,6 +60,7 @@ do_pre_regen() { main_domain=$(cat /etc/yunohost/current_host) # Support different strategy for security configurations + export redirect_to_https="$(yunohost settings get 'security.nginx.redirect_to_https')" export compatibility="$(yunohost settings get 'security.nginx.compatibility')" export experimental="$(yunohost settings get 'security.experimental.enabled')" ynh_render_template "security.conf.inc" "${nginx_conf_dir}/security.conf.inc" diff --git a/data/templates/nginx/server.tpl.conf b/data/templates/nginx/server.tpl.conf index 8bd689a92..379b597a7 100644 --- a/data/templates/nginx/server.tpl.conf +++ b/data/templates/nginx/server.tpl.conf @@ -12,12 +12,6 @@ server { include /etc/nginx/conf.d/acme-challenge.conf.inc; - include /etc/nginx/conf.d/{{ domain }}.d/*.conf; - - location /yunohost { - return 301 https://$http_host$request_uri; - } - location ^~ '/.well-known/ynh-diagnosis/' { alias /tmp/.well-known/ynh-diagnosis/; } @@ -26,6 +20,16 @@ server { alias /var/www/.well-known/{{ domain }}/autoconfig/mail/; } + {# Note that this != "False" is meant to be failure-safe, in the case the redrect_to_https would happen to contain empty string or whatever value. We absolutely don't want to disable the HTTPS redirect *except* when it's explicitly being asked to be disabled. #} + {% if redirect_to_https != "False" %} + location / { + return 301 https://$http_host$request_uri; + } + {# The app config snippets are not included in the HTTP conf unless HTTPS redirect is disabled, because app's location may blocks will conflict or bypass/ignore the HTTPS redirection. #} + {% else %} + include /etc/nginx/conf.d/{{ domain }}.d/*.conf; + {% endif %} + access_log /var/log/nginx/{{ domain }}-access.log; error_log /var/log/nginx/{{ domain }}-error.log; } diff --git a/locales/en.json b/locales/en.json index 7e98ad2fc..45b77b6f3 100644 --- a/locales/en.json +++ b/locales/en.json @@ -336,6 +336,7 @@ "global_settings_setting_backup_compress_tar_archives": "When creating new backups, compress the archives (.tar.gz) instead of uncompressed archives (.tar). N.B. : enabling this option means create lighter backup archives, but the initial backup procedure will be significantly longer and heavy on CPU.", "global_settings_setting_pop3_enabled": "Enable the POP3 protocol for the mail server", "global_settings_setting_security_experimental_enabled": "Enable experimental security features (don't enable this if you don't know what you're doing!)", + "global_settings_setting_security_nginx_redirect_to_https": "Redirect HTTP requests to HTTPs by default (DO NOT TURN OFF unless you really know what you're doing!)", "global_settings_setting_security_nginx_compatibility": "Compatibility vs. security tradeoff for the web server NGINX. Affects the ciphers (and other security-related aspects)", "global_settings_setting_security_password_admin_strength": "Admin password strength", "global_settings_setting_security_password_user_strength": "User password strength", diff --git a/src/yunohost/settings.py b/src/yunohost/settings.py index fe072cddb..475ac70d1 100644 --- a/src/yunohost/settings.py +++ b/src/yunohost/settings.py @@ -76,6 +76,13 @@ DEFAULTS = OrderedDict( "security.ssh.port", {"type": "int", "default": 22}, ), + ( + "security.nginx.redirect_to_https", + { + "type": "bool", + "default": True, + }, + ), ( "security.nginx.compatibility", { @@ -392,6 +399,7 @@ def trigger_post_change_hook(setting_name, old_value, new_value): @post_change_hook("ssowat.panel_overlay.enabled") +@post_change_hook("security.nginx.redirect_to_https") @post_change_hook("security.nginx.compatibility") @post_change_hook("security.webadmin.allowlist.enabled") @post_change_hook("security.webadmin.allowlist") diff --git a/src/yunohost/tests/test_apps.py b/src/yunohost/tests/test_apps.py index eba5a5916..43125341b 100644 --- a/src/yunohost/tests/test_apps.py +++ b/src/yunohost/tests/test_apps.py @@ -132,7 +132,7 @@ def app_is_exposed_on_http(domain, path, message_in_page): try: r = requests.get( - "http://127.0.0.1" + path + "/", + "https://127.0.0.1" + path + "/", headers={"Host": domain}, timeout=10, verify=False,