From 82e661cd070e72ad7a8a6ef1b8a3034f29a7b8d2 Mon Sep 17 00:00:00 2001 From: shibayashi Date: Wed, 29 Aug 2018 01:16:13 +0200 Subject: [PATCH 1/6] installation/caddyfile-pleroma.example: Add Content-Security-Policy --- installation/caddyfile-pleroma.example | 1 + 1 file changed, 1 insertion(+) diff --git a/installation/caddyfile-pleroma.example b/installation/caddyfile-pleroma.example index ed24fc16c..29496d1d7 100644 --- a/installation/caddyfile-pleroma.example +++ b/installation/caddyfile-pleroma.example @@ -22,6 +22,7 @@ social.domain.tld { Referrer-Policy "same-origin" Strict-Transport-Security "max-age=31536000; includeSubDomains;" Expect-CT "enforce, max-age=2592000" + Content-Security-Policy "default-src 'none'; base-uri 'self'; form-action 'self'; img-src 'self' data: https:; media-src 'self' https:; style-src 'self' 'unsafe-inline'; font-src 'self'; script-src 'self'; connect-src 'self' wss://social.domain.tld; upgrade-insecure-requests;" } # If you do not want remote frontends to be able to access your Pleroma backend server, remove these lines. From 3487e15963b04c0d654f2faeedc17d9fcb9a6b0d Mon Sep 17 00:00:00 2001 From: shibayashi Date: Wed, 29 Aug 2018 01:28:10 +0200 Subject: [PATCH 2/6] installation/pleroma.vcl: Add HTTP security headers --- installation/pleroma.vcl | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/installation/pleroma.vcl b/installation/pleroma.vcl index 63c1cb74d..ad5bb3c6c 100644 --- a/installation/pleroma.vcl +++ b/installation/pleroma.vcl @@ -119,3 +119,13 @@ sub vcl_pipe { set bereq.http.connection = req.http.connection; } } + +sub vcl_deliver { + set resp.http.X-Frame-Options = "DENY"; + set resp.http.X-XSS-Protection = "1; mode=block"; + set resp.http.X-Content-Type-Options = "nosniff"; + set resp.http.Referrer-Policy = "same-origin"; + set resp.http.Content-Security-Policy = "default-src 'none'; base-uri 'self'; form-action 'self'; img-src 'self' data: https:; media-src 'self' https:; style-src 'self' 'unsafe-inline'; font-src 'self'; script-src 'self'; connect-src 'self' wss://" + req.http.host + "; upgrade-insecure-requests;"; + # Uncomment this only after you get HTTPS working. + # set resp.http.Strict-Transport-Security= "max-age=31536000; includeSubDomains"; +} \ No newline at end of file From 64388c420a782fecf8cc51c14a353a9e7ebffc00 Mon Sep 17 00:00:00 2001 From: shibayashi Date: Wed, 29 Aug 2018 01:29:04 +0200 Subject: [PATCH 3/6] installation/pleroma-apache.conf: Add TLS configuration and security headers --- installation/pleroma-apache.conf | 60 ++++++++++++++++++++++++-------- 1 file changed, 45 insertions(+), 15 deletions(-) diff --git a/installation/pleroma-apache.conf b/installation/pleroma-apache.conf index bb6d32587..bf8db63ad 100644 --- a/installation/pleroma-apache.conf +++ b/installation/pleroma-apache.conf @@ -1,26 +1,56 @@ +#Example configuration for when Apache httpd and Pleroma are on the same host. +#Needed modules: headers proxy proxy_http proxy_wstunnel rewrite ssl +#This assumes a Debian style Apache config. Put this in /etc/apache2/sites-available +#Install your TLS certificate, possibly using Let's Encrypt. +#Replace 'pleroma.example.com' with your instance's domain wherever it appears + +ServerName pleroma.example.com +ServerTokens Prod + +ErrorLog ${APACHE_LOG_DIR}/error.log +CustomLog ${APACHE_LOG_DIR}/access.log combined + - #Example configuration for when Apache httpd and Pleroma are on the same host. - #Needed modules: proxy proxy_http proxy_wstunnel rewrite - #This assumes a Debian style Apache config. Put this in /etc/apache2/sites-available - #Doesn't include SSL, just run certbot and let it take care of that. - - - #Change this: - ServerName pleroma.example.com - + Redirect permanent / https://pleroma.example.com + + + + SSLEngine on + SSLCertificateFile /etc/letsencrypt/live/pleroma.example.com/cert.pem + SSLCertificateKeyFile /etc/letsencrypt/live/pleroma.example.com/privkey.pem + SSLCertificateChainFile /etc/letsencrypt/live/pleroma.example.com/fullchain.pem + + # Mozilla modern configuration, tweak to your needs + SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1 + SSLCipherSuite ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256 + SSLHonorCipherOrder on + SSLCompression off + SSLSessionTickets off + + # OCSP Stapling, only in httpd 2.3.3 and later + SSLUseStapling on + SSLStaplingResponderTimeout 5 + SSLStaplingReturnResponderErrors off + SSLStaplingCache shmcb:/var/run/ocsp(128000) + + Header always set X-Xss-Protection "1; mode=block" + Header always set X-Frame-Options "DENY" + Header always set X-Content-Type-Options "nosniff" + Header always set Referrer-Policy same-origin + Header always set Content-Security-Policy "default-src 'none'; base-uri 'self'; form-action 'self'; img-src 'self' data: https:; media-src 'self' https:; style-src 'self' 'unsafe-inline'; font-src 'self'; script-src 'self'; connect-src 'self' wss://pleroma.example.tld; upgrade-insecure-requests;" + + # Uncomment this only after you get HTTPS working. + # Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains" + RewriteEngine On RewriteCond %{HTTP:Connection} Upgrade [NC] RewriteCond %{HTTP:Upgrade} websocket [NC] RewriteRule /(.*) ws://localhost:4000/$1 [P,L] - + ProxyRequests off ProxyPass / http://localhost:4000/ ProxyPassReverse / http://localhost:4000/ - - #Change this too: + RequestHeader set Host "pleroma.example.com" ProxyPreserveHost On - - ErrorLog ${APACHE_LOG_DIR}/error.log - CustomLog ${APACHE_LOG_DIR}/access.log combined From d035566116a769b8c5de5f5e9382cb4c50f0d163 Mon Sep 17 00:00:00 2001 From: shibayashi Date: Wed, 29 Aug 2018 19:00:40 +0200 Subject: [PATCH 4/6] installation/pleroma.nginx: Add 'always' to the security headers, so that they are included regardless of the status code --- installation/pleroma.nginx | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/installation/pleroma.nginx b/installation/pleroma.nginx index a333d116c..aaf620de2 100644 --- a/installation/pleroma.nginx +++ b/installation/pleroma.nginx @@ -71,16 +71,16 @@ server { } # stop removing lines here. - add_header X-XSS-Protection "1; mode=block"; - add_header X-Permitted-Cross-Domain-Policies none; - add_header X-Frame-Options DENY; - add_header X-Content-Type-Options nosniff; - add_header Referrer-Policy same-origin; - add_header X-Download-Options noopen; - add_header Content-Security-Policy "default-src 'none'; base-uri 'self'; form-action 'self'; img-src 'self' data: https:; media-src 'self' https:; style-src 'self' 'unsafe-inline'; font-src 'self'; script-src 'self'; connect-src 'self' wss://example.tld; upgrade-insecure-requests;"; + add_header X-XSS-Protection "1; mode=block" always; + add_header X-Permitted-Cross-Domain-Policies "none" always; + add_header X-Frame-Options "DENY" always; + add_header X-Content-Type-Options "nosniff" always; + add_header Referrer-Policy "same-origin" always; + add_header X-Download-Options "noopen" always; + add_header Content-Security-Policy "default-src 'none'; base-uri 'self'; form-action 'self'; img-src 'self' data: https:; media-src 'self' https:; style-src 'self' 'unsafe-inline'; font-src 'self'; script-src 'self'; connect-src 'self' wss://example.tld; upgrade-insecure-requests;" always; # Uncomment this only after you get HTTPS working. - # add_header Strict-Transport-Security "max-age=31536000; includeSubDomains"; + # add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; From d027c53d75dd87eab207bef30f96b2a1f6b5dba0 Mon Sep 17 00:00:00 2001 From: shibayashi Date: Thu, 30 Aug 2018 11:10:16 +0200 Subject: [PATCH 5/6] Add frame-ancestors 'none' to all configs --- installation/caddyfile-pleroma.example | 2 +- installation/pleroma-apache.conf | 2 +- installation/pleroma.nginx | 2 +- installation/pleroma.vcl | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/installation/caddyfile-pleroma.example b/installation/caddyfile-pleroma.example index 29496d1d7..2c1efde2d 100644 --- a/installation/caddyfile-pleroma.example +++ b/installation/caddyfile-pleroma.example @@ -22,7 +22,7 @@ social.domain.tld { Referrer-Policy "same-origin" Strict-Transport-Security "max-age=31536000; includeSubDomains;" Expect-CT "enforce, max-age=2592000" - Content-Security-Policy "default-src 'none'; base-uri 'self'; form-action 'self'; img-src 'self' data: https:; media-src 'self' https:; style-src 'self' 'unsafe-inline'; font-src 'self'; script-src 'self'; connect-src 'self' wss://social.domain.tld; upgrade-insecure-requests;" + Content-Security-Policy "default-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'none'; img-src 'self' data: https:; media-src 'self' https:; style-src 'self' 'unsafe-inline'; font-src 'self'; script-src 'self'; connect-src 'self' wss://social.domain.tld; upgrade-insecure-requests;" } # If you do not want remote frontends to be able to access your Pleroma backend server, remove these lines. diff --git a/installation/pleroma-apache.conf b/installation/pleroma-apache.conf index bf8db63ad..c70d52138 100644 --- a/installation/pleroma-apache.conf +++ b/installation/pleroma-apache.conf @@ -37,7 +37,7 @@ CustomLog ${APACHE_LOG_DIR}/access.log combined Header always set X-Frame-Options "DENY" Header always set X-Content-Type-Options "nosniff" Header always set Referrer-Policy same-origin - Header always set Content-Security-Policy "default-src 'none'; base-uri 'self'; form-action 'self'; img-src 'self' data: https:; media-src 'self' https:; style-src 'self' 'unsafe-inline'; font-src 'self'; script-src 'self'; connect-src 'self' wss://pleroma.example.tld; upgrade-insecure-requests;" + Header always set Content-Security-Policy "default-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'none'; img-src 'self' data: https:; media-src 'self' https:; style-src 'self' 'unsafe-inline'; font-src 'self'; script-src 'self'; connect-src 'self' wss://pleroma.example.tld; upgrade-insecure-requests;" # Uncomment this only after you get HTTPS working. # Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains" diff --git a/installation/pleroma.nginx b/installation/pleroma.nginx index aaf620de2..37871ea5b 100644 --- a/installation/pleroma.nginx +++ b/installation/pleroma.nginx @@ -77,7 +77,7 @@ server { add_header X-Content-Type-Options "nosniff" always; add_header Referrer-Policy "same-origin" always; add_header X-Download-Options "noopen" always; - add_header Content-Security-Policy "default-src 'none'; base-uri 'self'; form-action 'self'; img-src 'self' data: https:; media-src 'self' https:; style-src 'self' 'unsafe-inline'; font-src 'self'; script-src 'self'; connect-src 'self' wss://example.tld; upgrade-insecure-requests;" always; + add_header Content-Security-Policy "default-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'none'; img-src 'self' data: https:; media-src 'self' https:; style-src 'self' 'unsafe-inline'; font-src 'self'; script-src 'self'; connect-src 'self' wss://example.tld; upgrade-insecure-requests;" always; # Uncomment this only after you get HTTPS working. # add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; diff --git a/installation/pleroma.vcl b/installation/pleroma.vcl index ad5bb3c6c..74490be2a 100644 --- a/installation/pleroma.vcl +++ b/installation/pleroma.vcl @@ -125,7 +125,7 @@ sub vcl_deliver { set resp.http.X-XSS-Protection = "1; mode=block"; set resp.http.X-Content-Type-Options = "nosniff"; set resp.http.Referrer-Policy = "same-origin"; - set resp.http.Content-Security-Policy = "default-src 'none'; base-uri 'self'; form-action 'self'; img-src 'self' data: https:; media-src 'self' https:; style-src 'self' 'unsafe-inline'; font-src 'self'; script-src 'self'; connect-src 'self' wss://" + req.http.host + "; upgrade-insecure-requests;"; + set resp.http.Content-Security-Policy = "default-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'none'; img-src 'self' data: https:; media-src 'self' https:; style-src 'self' 'unsafe-inline'; font-src 'self'; script-src 'self'; connect-src 'self' wss://" + req.http.host + "; upgrade-insecure-requests;"; # Uncomment this only after you get HTTPS working. # set resp.http.Strict-Transport-Security= "max-age=31536000; includeSubDomains"; -} \ No newline at end of file +} From 8a4e2f48bfd2fec64eeebbeb7f05f80d23e9bd47 Mon Sep 17 00:00:00 2001 From: shibayashi Date: Mon, 3 Sep 2018 21:41:21 +0200 Subject: [PATCH 6/6] installation/pleroma-apache.conf: OCSP stapling needs to be outside of the virtualhost directive --- installation/pleroma-apache.conf | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/installation/pleroma-apache.conf b/installation/pleroma-apache.conf index c70d52138..992c0c900 100644 --- a/installation/pleroma-apache.conf +++ b/installation/pleroma-apache.conf @@ -27,12 +27,6 @@ CustomLog ${APACHE_LOG_DIR}/access.log combined SSLCompression off SSLSessionTickets off - # OCSP Stapling, only in httpd 2.3.3 and later - SSLUseStapling on - SSLStaplingResponderTimeout 5 - SSLStaplingReturnResponderErrors off - SSLStaplingCache shmcb:/var/run/ocsp(128000) - Header always set X-Xss-Protection "1; mode=block" Header always set X-Frame-Options "DENY" Header always set X-Content-Type-Options "nosniff" @@ -54,3 +48,9 @@ CustomLog ${APACHE_LOG_DIR}/access.log combined RequestHeader set Host "pleroma.example.com" ProxyPreserveHost On + +# OCSP Stapling, only in httpd 2.3.3 and later +SSLUseStapling on +SSLStaplingResponderTimeout 5 +SSLStaplingReturnResponderErrors off +SSLStaplingCache shmcb:/var/run/ocsp(128000) \ No newline at end of file