From 1fbc08f74b5e72cab5fc949a2bf02c1aed1d0378 Mon Sep 17 00:00:00 2001 From: Franziska Kunsmann Date: Thu, 3 Jun 2021 18:56:28 +0200 Subject: [PATCH] bundles/nginx: add a default security.txt to all vhosts --- bundles/nginx/files/security.txt | 9 +++++++++ bundles/nginx/files/site_template | 6 ++++++ bundles/nginx/items.py | 30 +++++++++++++++++++++++++++++- libs/defaults.py | 3 +++ nodes/htz/ex42-1048908.py | 4 ++++ 5 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 bundles/nginx/files/security.txt diff --git a/bundles/nginx/files/security.txt b/bundles/nginx/files/security.txt new file mode 100644 index 0000000..d1c7726 --- /dev/null +++ b/bundles/nginx/files/security.txt @@ -0,0 +1,9 @@ +Contact: ${vhost.get('contact', repo.libs.defaults.security_email)} +Expires: ${vhost.get('expires', expiry)} +Preferred-Languages: ${','.join(sorted(vhost.get('lang', repo.libs.defaults.security_lang)))} +Canonical: ${proto}://${domain}/.well-known/security.txt +% for key, value in sorted(vhost.items()): +% if key[0].isupper(): +${key}: ${value} +% endif +% endfor diff --git a/bundles/nginx/files/site_template b/bundles/nginx/files/site_template index 0e234e7..e632272 100644 --- a/bundles/nginx/files/site_template +++ b/bundles/nginx/files/site_template @@ -72,6 +72,12 @@ server { alias /var/lib/dehydrated/acme-challenges/; } +% if security_txt: + location = /.well-known/security.txt { + alias /etc/nginx/security.txt.d/${vhost}; + } +% endif + % if proxy: % for location, options in proxy.items(): location ${location} { diff --git a/bundles/nginx/items.py b/bundles/nginx/items.py index ecfe3ae..46bb358 100644 --- a/bundles/nginx/items.py +++ b/bundles/nginx/items.py @@ -1,3 +1,5 @@ +from datetime import datetime, timedelta + if node.has_bundle('pacman'): package = 'pkg_pacman:nginx' username = 'http' @@ -12,6 +14,9 @@ directories = { 'svc_systemd:nginx:restart', }, }, + '/etc/nginx/security.txt.d': { + 'purge': True, + }, '/etc/nginx/ssl': { 'purge': True, 'triggers': { @@ -77,16 +82,39 @@ svc_systemd = { }, } +now = datetime.now() +in_three_months = now + timedelta(days=90) +default_security_expiry = in_three_months.strftime('%Y-%m-%d') + 'T00:00:00.000Z' + for vhost, config in node.metadata.get('nginx/vhosts', {}).items(): if not 'domain' in config: config['domain'] = vhost + security_txt_enabled = False + if ( + node.metadata.get('nginx/security.txt/enabled', True) and + config.get('security.txt', {}).get('enabled', True) + ): + security_txt_enabled = True + + files[f'/etc/nginx/security.txt.d/{vhost}'] = { + 'source': 'security.txt', + 'content_type': 'mako', + 'context': { + 'domain': config['domain'], + 'expiry': default_security_expiry, + 'proto': 'https' if config.get('ssl', 'letsencrypt') else 'http', + 'vhost': config.get('security.txt', node.metadata.get('nginx/security.txt', {})), + }, + } + files[f'/etc/nginx/sites/{vhost}'] = { 'source': 'site_template', 'content_type': 'mako', 'context': { - 'vhost': vhost, 'php_version': node.metadata.get('php/version', ''), + 'security_txt': security_txt_enabled, + 'vhost': vhost, **config, }, 'needs': set(), diff --git a/libs/defaults.py b/libs/defaults.py index 771c014..cfa7221 100644 --- a/libs/defaults.py +++ b/libs/defaults.py @@ -4,3 +4,6 @@ influxdb_bucket = 'encrypt$gAAAAABgg9iMnq0nKpODMiMN4NtUw231iqpbyDXV-O8epOAGDSL4j influxdb_org = 'encrypt$gAAAAABgg9hyjz4XtvG8NBw9uYxiumS3v7YKIrtc9tTTABg1f9R22gzn55q8ULP9X3wlsPMUQs_DH7CgGv9neYmvVAriRoyd8g==' influxdb_token = 'encrypt$gAAAAABgg9Ag632Xyuc6SWXaR1uH2tLOChmVKAoBIikhjntSSD2qJFL_eouVQGXCLH2HEuSbSdEXcTPn2qmhOiA9jmFdoDSbVbQUsp0EID1wLsWYG_Um2KOxZSF-tn9eDZlgShQYySjzO3nQRmdlJpVLUnGHsiwv_sHD2FstXGpfzTPZq5_egUqEc0K2X-aN2J6BTYc2fZAN' influxdb_url = 'https://influxdb.kunsmann.eu/' + +security_email = f'mailto:{hostmaster_email}' +security_lang = {'en', 'de'} diff --git a/nodes/htz/ex42-1048908.py b/nodes/htz/ex42-1048908.py index 4602d9b..61c238d 100644 --- a/nodes/htz/ex42-1048908.py +++ b/nodes/htz/ex42-1048908.py @@ -254,6 +254,10 @@ nodes['htz.ex42-1048908'] = { }, }, 'nginx': { + 'security.txt': { + 'contact': 'mailto:security@kunsmann.eu', + 'Encryption': 'https://franzi.business/gpg_hi-kunsmann.eu.asc', + }, 'vhosts': { # TODO maybe some of this can be moved to a bundle? 'dav.kunsmann.eu': {