2528 views
# Using safe TLS/SSL settings in puppet Following a [recent ASDF](https://indico.cern.ch/event/714180/), safe TLS defaults have been added to Puppet. They will be maintained by the Security Team, following standard QA procedures. These default settings can be applied for any configuration using manifests or templates. If you are manually configuring your service with static files, we strongly recommend to use the appropriate module. If such migration is not possible, you can still transform these files into templates, making these settings configurable. ## Modules depending on Apache/Nginx/HAProxy If you are writing or maintaining a module that itself configures Apache/Nginx/HAProxy, for portability purposes it cannot pull the security module default directly. We thus recommend to: * Whenever possible, simply use the default in Apache/Nginx/HAProxy (Configuration would still be possible by hiera) * Otherwise (not recommended): * Expose any TLS/SSL settings you module is configuring as parameters * Use the hiera data to alias the CERN recommendation to your settings. Please contact us in case of doubt. ## Apache ### Manifests If you are fully using the ```apache``` module to configure your website, simply remove any ```ssl_protocol``` and ```ssl_cipher``` from your manifests and hiera data: - Remove ```ssl_protocol``` and ```ssl_cipher``` from your vhosts ```diff apache::vhost{ $::fqdn: docroot => '/var/www/', port => '443', ssl => true, ssl_key => "/var/lib/puppet/ssl/private_keys/${::fqdn}.pem", ssl_cert => "/var/lib/puppet/ssl/certs/${::fqdn}.pem", - ssl_protocol => "HARDCODED STRING", - ssl_cipher => "HARDCODED STRING", } ``` - Remove ```ssl_protocol``` and ```ssl_cipher``` from hiera ```diff -apache::mod::ssl::ssl_protocol: "HARDCODED STRING" -apache::mod::ssl::ssl_cipher: "HARDCODED STRING" ``` ### Custom templates [not supported] If you are defining manually your own configuration using templates, we **strongly recommend** to instead use the ```apache``` module, which comes with several safe defaults that would be hard for you to maintain. If you want to keep using template, consider the following recommendations. **For obvious reason, it is impossible for us to test these changes for all existing configurations, please test such changes in your own environments before deploying it into production!** * Replace any ```SSLProtocol``` or ```SSLCipherSuite``` from hardcoded values with values obtained from the security module via hiera ```diff -SSLProtocol all -SSLv2 -SSLv3 -SSLCipherSuite HIGH:!aNULL:!MD5 +SSLProtocol <%= scope.call_function('lookup', ['security::tls::default::apache::ssl_protocol']).join(' ') %> +SSLCipherSuite <%= scope.call_function('lookup', ['security::tls::default::apache::ssl_cipher']) %> ``` * If you do not have ```SSLProtocol``` or ```SSLCipherSuite``` defined, add them: ```diff <VirtualHost <%= @ipaddress %>:443> ServerName <%= @fqdn %> SSLEngine On + SSLProtocol <%= scope.call_function('lookup', ['security::tls::default::apache::ssl_protocol']).join(' ') %> + SSLCipherSuite <%= scope.call_function('lookup', ['security::tls::default::apache::ssl_cipher']) %> ``` * We also recommend adding the following parameters: ```diff +SSLHonorCipherOrder On +TraceEnable Off ``` ### Raw files [not supported] If you are defining manually your own configuration using static files, we **strongly recommend** to instead use the ```apache``` module, which comes with several safe defaults that would be hard for you to maintain. If you do not want to use the ```apache``` module, we recommend changing the files containing the vhost configuration to templates and apply the recommendations above. ## Nginx ### Manifests If you are fully using the ```nginx``` module to configure your website, simply remove any ```ssl_protocols``` and ```ssl_ciphers``` from your manifests and hiera data: - Remove ```ssl_protocols``` and ```ssl_ciphers``` from your base module: ```diff class { 'nginx': confd_purge => true, server_purge => true, - ssl_protocols => "HARDCODED STRING", - ssl_ciphers => "HARDCODED STRING", } ``` - Remove ```ssl_protocols``` and ```ssl_ciphers``` from your server resources: ```diff nginx::resource::server { 'xxx HTTPS': ssl => true, ssl_cert => '/etc/nginx/ssl/xxx.cert', ssl_key => '/etc/nginx/ssl/xxx.key', - ssl_protocols => "HARDCODED STRING", - ssl_ciphers => "HARDCODED STRING", http2 => 'on', ``` - Remove ```ssl_protocol``` and ```ssl_cipher``` from hiera ```diff -nginx::ssl_protocols: "HARDCODED STRING" -nginx::ssl_ciphers: "HARDCODED STRING" ``` ### Custom templates [not supported] If you are defining manually your own configuration using templates, we **recommend** to instead use the ```nginx``` module, which comes with several safe defaults that would be hard for you to maintain. If you want to keep using template, consider the following recommendations. **For obvious reason, it is impossible for us to test these changes for all existing configuration, please test such changes in your own environments before deploying it into production** * Replace any ```ssl_protocols``` or ```ssl_ciphers``` from hardcoded values with values obtained from the security module via hiera ```diff -ssl_protocols TLSv1 TLSv1.1 TLSv1.2; -ssl_ciphers 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; +ssl_protocols <%= scope.call_function('lookup', ['security::tls::default::nginx::ssl_protocols']) %>; +ssl_ciphers <%= scope.call_function('lookup', ['security::tls::default::nginx::ssl_ciphers']) %>; ``` * If you do not have ```ssl_protocols``` or ```ssl_ciphers``` defined, add them: ```diff server { server_name <%= @fqdn %>; lister 444; ssl on; + ssl_protocols <%= scope.call_function('lookup', ['security::tls::default::nginx::ssl_protocols']) %>; + ssl_ciphers <%= scope.call_function('lookup', ['security::tls::default::nginx::ssl_ciphers']) %>; ``` * We also recommend adding the following parameter: ```diff +ssl_prefer_server_ciphers on; ``` ### Raw files [not supported] If you are defining manually your own configuration using static files, we **recommend** to instead use the ```nginx``` module, which comes with several safe defaults that would be hard for you to maintain. If you do not want to use the ```nginx``` module, we recommend changing the files containing the configuration to templates and apply the recommendations above. ## HAProxy ### Manifests/hiera Unfortunately, it is not reasonably possible for us to set defaults in puppet directly. Still the security module provide defaults that we recommend to use in your configuration. We thus recommend to: * Remove any ciphers option from individual bind/server * If you define ```global_options``` when including the ```haproxy``` class, merge that parameter with those provided in the security module (the key in the rightmost hash takes precedence): ```diff class { 'haproxy': config_file => '/etc/haproxy/haproxy.cfg.withoutteigi', - global_options => { + global_options => merge(lookup('security::tls::default::haproxy::global_options'), { 'log' => "${::ipaddress} local2", 'chroot' => '/var/lib/haproxy', 'pidfile' => '/var/run/haproxy.pid', 'maxconn' => '8000', 'user' => 'haproxy', 'group' => 'haproxy', 'daemon' => '', 'stats' => 'socket /var/lib/haproxy/stats', - 'tune.ssl.default-dh-param' => 2048, - 'ssl-default-bind-ciphers' => 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-$ - }, + }), ``` * If you define your own ```haproxy::global_options``` in hiera, replace any cipher parameter with a hiera alias: ```diff haproxy::global_options: log: "%{::ipaddress} local2" chroot: '/var/lib/haproxy' pidfile: '/var/run/haproxy.pid' maxconn: 8000 user: 'haproxy' group: 'haproxy' daemon: '' stats: 'socket /var/lib/haproxy/stats' tune.ssl.default-dh-param: 2048 - ssl-default-bind-ciphers: 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128:AES256:AES:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK' + ssl-default-bind-ciphers: "%{alias('security::tls::default::haproxy::ciphers')}" + ssl-default-bind-options: "%{alias('security::tls::default::haproxy::options')}" + ssl-default-server-ciphers: "%{alias('security::tls::default::haproxy::ciphers')}" + ssl-default-server-options: "%{alias('security::tls::default::haproxy::options')}" ``` ### Custom templates [not supported] If you are defining your own options/binds in templates, consider replacing hardcoded values with hiera lookups: ```diff global [...] user haproxy group haproxy daemon tune.ssl.default-dh-param 1024 ca-base /etc/grid-security/certificates crt-base /etc/grid-security/certificates - ssl-default-bind-ciphers kEECDH+aRSA+AES:kRSA+AES:+AES256:!RC4:!kEDH:!LOW:!EXP:!MD5:!aNULL:!eNULL + ssl-default-bind-ciphers <%= scope.call_function('lookup', ['security::tls::default::haproxy::ciphers']) %> + ssl-default-bind-options <%= scope.call_function('lookup', ['security::tls::default::haproxy::options']) %> + ssl-default-server-ciphers <%= scope.call_function('lookup', ['security::tls::default::haproxy::ciphers']) %> + ssl-default-server-options <%= scope.call_function('lookup', ['security::tls::default::haproxy::options']) %> ssl-server-verify required ``` ### Files [not supported] If you are hardcoding your settings in files, we recommend either using the module or transforming these files into templates and apply the recommendations above ###### tags: `ASDF`