From bcb803c0c37b8b3a540ad4d4c5267c3448edba8e Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Wed, 18 Aug 2021 22:10:25 +0200 Subject: [PATCH] Add new setting to enable experimental security features --- data/hooks/conf_regen/01-yunohost | 15 +++++++++++++++ data/hooks/conf_regen/15-nginx | 1 + data/templates/nginx/security.conf.inc | 10 ++++++++++ data/templates/yunohost/proc-hidepid.service | 14 ++++++++++++++ locales/en.json | 1 + src/yunohost/settings.py | 7 +++++++ 6 files changed, 48 insertions(+) create mode 100644 data/templates/yunohost/proc-hidepid.service diff --git a/data/hooks/conf_regen/01-yunohost b/data/hooks/conf_regen/01-yunohost index 1a10a6954..8d2280e89 100755 --- a/data/hooks/conf_regen/01-yunohost +++ b/data/hooks/conf_regen/01-yunohost @@ -144,6 +144,14 @@ HandleLidSwitch=ignore HandleLidSwitchDocked=ignore HandleLidSwitchExternalPower=ignore EOF + + mkdir -p ${pending_dir}/etc/systemd/ + if [[ "$(yunohost settings get 'security.experimental.enabled')" == "True" ]] + then + cp proc-hidepid.service ${pending_dir}/etc/systemd/system/proc-hidepid.service + else + touch ${pending_dir}/etc/systemd/system/proc-hidepid.service + fi } @@ -204,6 +212,13 @@ do_post_regen() { # Propagates changes in systemd service config overrides [[ ! "$regen_conf_files" =~ "ntp.service.d/ynh-override.conf" ]] || { systemctl daemon-reload; systemctl restart ntp; } [[ ! "$regen_conf_files" =~ "nftables.service.d/ynh-override.conf" ]] || systemctl daemon-reload + [[ ! "$regen_conf_files" =~ "login.conf.d/ynh-override.conf" ]] || systemctl daemon-reload + if [[ "$regen_conf_files" =~ "proc-hidepid.service" ]] + then + systemctl daemon-reload + action=$([[ -e /etc/systemd/system/proc-hidepid.service ]] && echo 'enable' || echo 'disable') + systemctl $action proc-hidepid --quiet --now + fi } _update_services() { diff --git a/data/hooks/conf_regen/15-nginx b/data/hooks/conf_regen/15-nginx index e211a3aca..a2d8f1259 100755 --- a/data/hooks/conf_regen/15-nginx +++ b/data/hooks/conf_regen/15-nginx @@ -61,6 +61,7 @@ do_pre_regen() { # Support different strategy for security configurations 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" cert_status=$(yunohost domain cert-status --json) diff --git a/data/templates/nginx/security.conf.inc b/data/templates/nginx/security.conf.inc index 0d0b74db1..bcb821770 100644 --- a/data/templates/nginx/security.conf.inc +++ b/data/templates/nginx/security.conf.inc @@ -25,7 +25,11 @@ ssl_dhparam /usr/share/yunohost/other/ffdhe2048.pem; # Follows the Web Security Directives from the Mozilla Dev Lab and the Mozilla Obervatory + Partners # https://wiki.mozilla.org/Security/Guidelines/Web_Security # https://observatory.mozilla.org/ +{% if experimental == "True" %} +more_set_headers "Content-Security-Policy : upgrade-insecure-requests; default-src https: data:"; +{% else %} more_set_headers "Content-Security-Policy : upgrade-insecure-requests"; +{% endif %} more_set_headers "Content-Security-Policy-Report-Only : default-src https: data: 'unsafe-inline' 'unsafe-eval' "; more_set_headers "X-Content-Type-Options : nosniff"; more_set_headers "X-XSS-Protection : 1; mode=block"; @@ -34,7 +38,13 @@ more_set_headers "X-Permitted-Cross-Domain-Policies : none"; more_set_headers "X-Frame-Options : SAMEORIGIN"; # Disable the disaster privacy thing that is FLoC +{% if experimental == "True" %} +more_set_headers "Permissions-Policy : fullscreen=(), geolocation=(), payment=(), accelerometer=(), battery=(), magnetometer=(), usb=(), interest-cohort=()"; +# Force HTTPOnly and Secure for all cookies +proxy_cookie_path ~$ "; HTTPOnly; Secure;"; +{% else %} more_set_headers "Permissions-Policy : interest-cohort=()"; +{% endif %} # Disable gzip to protect against BREACH # Read https://trac.nginx.org/nginx/ticket/1720 (text/html cannot be disabled!) diff --git a/data/templates/yunohost/proc-hidepid.service b/data/templates/yunohost/proc-hidepid.service new file mode 100644 index 000000000..ec6fabede --- /dev/null +++ b/data/templates/yunohost/proc-hidepid.service @@ -0,0 +1,14 @@ +[Unit] +Description=Mounts /proc with hidepid=2 +DefaultDependencies=no +Before=sysinit.target +Requires=local-fs.target +After=local-fs.target + +[Service] +Type=oneshot +ExecStart=/bin/mount -o remount,nosuid,nodev,noexec,hidepid=2 /proc +RemainAfterExit=yes + +[Install] +WantedBy=sysinit.target diff --git a/locales/en.json b/locales/en.json index 693e9d24d..044461d9a 100644 --- a/locales/en.json +++ b/locales/en.json @@ -340,6 +340,7 @@ "global_settings_setting_smtp_relay_password": "SMTP relay host password", "global_settings_setting_security_webadmin_allowlist_enabled": "Allow only some IPs to access the webadmin.", "global_settings_setting_security_webadmin_allowlist": "IP adresses allowed to access the webadmin. Comma-separated.", + "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_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_unknown_type": "Unexpected situation, the setting {setting} appears to have the type {unknown_type} but it is not a type supported by the system.", "good_practices_about_admin_password": "You are now about to define a new administration password. The password should be at least 8 characters long—though it is good practice to use a longer password (i.e. a passphrase) and/or to use a variation of characters (uppercase, lowercase, digits and special characters).", diff --git a/src/yunohost/settings.py b/src/yunohost/settings.py index ec0e7566c..fe072cddb 100644 --- a/src/yunohost/settings.py +++ b/src/yunohost/settings.py @@ -102,6 +102,7 @@ DEFAULTS = OrderedDict( ("ssowat.panel_overlay.enabled", {"type": "bool", "default": True}), ("security.webadmin.allowlist.enabled", {"type": "bool", "default": False}), ("security.webadmin.allowlist", {"type": "string", "default": ""}), + ("security.experimental.enabled", {"type": "bool", "default": False}), ] ) @@ -399,6 +400,12 @@ def reconfigure_nginx(setting_name, old_value, new_value): regen_conf(names=["nginx"]) +@post_change_hook("security.experimental.enabled") +def reconfigure_nginx_and_yunohost(setting_name, old_value, new_value): + if old_value != new_value: + regen_conf(names=["nginx", "yunohost"]) + + @post_change_hook("security.ssh.compatibility") def reconfigure_ssh(setting_name, old_value, new_value): if old_value != new_value: