summaryrefslogtreecommitdiff
path: root/puppet/modules/site_openvpn/manifests/server_config.pp
diff options
context:
space:
mode:
Diffstat (limited to 'puppet/modules/site_openvpn/manifests/server_config.pp')
-rw-r--r--puppet/modules/site_openvpn/manifests/server_config.pp228
1 files changed, 228 insertions, 0 deletions
diff --git a/puppet/modules/site_openvpn/manifests/server_config.pp b/puppet/modules/site_openvpn/manifests/server_config.pp
new file mode 100644
index 00000000..15e6fb38
--- /dev/null
+++ b/puppet/modules/site_openvpn/manifests/server_config.pp
@@ -0,0 +1,228 @@
+#
+# Cipher discussion
+# ================================
+#
+# We want to specify explicit values for the crypto options to prevent a MiTM from forcing
+# a weaker cipher. These should be set in both the server and the client ('auth' and 'cipher'
+# MUST be the same on both ends or no data will get transmitted).
+#
+# tls-cipher DHE-RSA-AES128-SHA
+#
+# dkg: For the TLS control channel, we want to make sure we choose a
+# key exchange mechanism that has PFS (meaning probably some form of ephemeral
+# Diffie-Hellman key exchange), and that uses a standard, well-tested cipher
+# (I recommend AES, and 128 bits is probably fine, since there are some known
+# weaknesses in the 192- and 256-bit key schedules). That leaves us with the
+# choice of public key algorithms: /usr/sbin/openvpn --show-tls | grep DHE |
+# grep AES128 | grep GCM.
+#
+# elijah:
+# I could not get any of these working:
+# * openvpn --show-tls | grep GCM
+# * openvpn --show-tls | grep DHE | grep AES128 | grep SHA256
+# so, i went with this:
+# * openvpn --show-tls | grep DHE | grep AES128 | grep -v SHA256 | grep -v GCM
+# Also, i couldn't get any of the elliptical curve algorithms to work. Not sure how
+# our cert generation interacts with the tls-cipher algorithms.
+#
+# note: in my tests, DHE-RSA-AES256-SHA is the one it negotiates if no value is set.
+#
+# auth SHA1
+#
+# dkg: For HMAC digest to authenticate packets, we just want SHA256. OpenVPN lists
+# a number of "digest" with names like "RSA-SHA256", but this are legacy and
+# should be avoided.
+#
+# elijah: i am not so sure that the digest algo matters for 'auth' option, because
+# i think an attacker would have to forge the digest in real time, which is still far from
+# a possibility for SHA1. So, i am leaving the default for now (SHA1).
+#
+# cipher AES-128-CBC
+#
+# dkg: For the choice of cipher, we need to select an algorithm and a
+# cipher mode. OpenVPN defaults to Blowfish, which is a fine algorithm - but
+# our control channel is already relying on AES not being broken; if the
+# control channel is cracked, then the key material for the tunnel is exposed,
+# and the choice of algorithm is moot. So it makes more sense to me to rely on
+# the same cipher here: AES128. As for the cipher mode, OFB seems cleaner to
+# me, but CBC is more well-tested, and the OpenVPN man page (at least as of
+# version 2.2.1) says "CBC is recommended and CFB and OFB should be considered
+# advanced modes."
+#
+# note: the default is BF-CBC (blowfish)
+#
+
+define site_openvpn::server_config(
+ $port, $proto, $local, $server, $push,
+ $management, $config, $tls_remote = undef) {
+
+ $openvpn_configname = $name
+ $shortname = regsubst(regsubst($name, '_config', ''), '_', '-')
+ $openvpn_status_filename = "/var/run/openvpn-status-${shortname}"
+
+ concat {
+ "/etc/openvpn/${openvpn_configname}.conf":
+ owner => root,
+ group => root,
+ mode => 644,
+ warn => true,
+ require => File['/etc/openvpn'],
+ before => Service['openvpn'],
+ notify => Exec['restart_openvpn'];
+ }
+
+ if $tls_remote != undef {
+ openvpn::option {
+ "tls-remote ${openvpn_configname}":
+ key => 'tls-remote',
+ value => $tls_remote,
+ server => $openvpn_configname;
+ }
+ }
+
+ # according to openvpn man page: tcp-nodelay is a "generally a good latency optimization".
+ if $proto == 'tcp' {
+ openvpn::option {
+ "tcp-nodelay ${openvpn_configname}":
+ key => 'tcp-nodelay',
+ server => $openvpn_configname;
+ }
+ } elsif $proto == 'udp' {
+ if $config['fragment'] != 1500 {
+ openvpn::option {
+ "fragment ${openvpn_configname}":
+ key => 'fragment',
+ value => $config['fragment'],
+ server => $openvpn_configname;
+ "mssfix ${openvpn_configname}":
+ key => 'mssfix',
+ server => $openvpn_configname;
+ }
+ }
+ }
+
+ openvpn::option {
+ "ca ${openvpn_configname}":
+ key => 'ca',
+ value => "${x509::variables::local_CAs}/${site_config::params::ca_bundle_name}.crt",
+ server => $openvpn_configname;
+ "cert ${openvpn_configname}":
+ key => 'cert',
+ value => "${x509::variables::certs}/${site_config::params::cert_name}.crt",
+ server => $openvpn_configname;
+ "key ${openvpn_configname}":
+ key => 'key',
+ value => "${x509::variables::keys}/${site_config::params::cert_name}.key",
+ server => $openvpn_configname;
+ "dh ${openvpn_configname}":
+ key => 'dh',
+ value => '/etc/openvpn/keys/dh.pem',
+ server => $openvpn_configname;
+ "tls-cipher ${openvpn_configname}":
+ key => 'tls-cipher',
+ value => $config['tls-cipher'],
+ server => $openvpn_configname;
+ "auth ${openvpn_configname}":
+ key => 'auth',
+ value => $config['auth'],
+ server => $openvpn_configname;
+ "cipher ${openvpn_configname}":
+ key => 'cipher',
+ value => $config['cipher'],
+ server => $openvpn_configname;
+ "dev ${openvpn_configname}":
+ key => 'dev',
+ value => 'tun',
+ server => $openvpn_configname;
+ "tun-ipv6 ${openvpn_configname}":
+ key => 'tun-ipv6',
+ server => $openvpn_configname;
+ "duplicate-cn ${openvpn_configname}":
+ key => 'duplicate-cn',
+ server => $openvpn_configname;
+ "keepalive ${openvpn_configname}":
+ key => 'keepalive',
+ value => $config['keepalive'],
+ server => $openvpn_configname;
+ "local ${openvpn_configname}":
+ key => 'local',
+ value => $local,
+ server => $openvpn_configname;
+ "mute ${openvpn_configname}":
+ key => 'mute',
+ value => '5',
+ server => $openvpn_configname;
+ "mute-replay-warnings ${openvpn_configname}":
+ key => 'mute-replay-warnings',
+ server => $openvpn_configname;
+ "management ${openvpn_configname}":
+ key => 'management',
+ value => $management,
+ server => $openvpn_configname;
+ "proto ${openvpn_configname}":
+ key => 'proto',
+ value => $proto,
+ server => $openvpn_configname;
+ "push1 ${openvpn_configname}":
+ key => 'push',
+ value => $push,
+ server => $openvpn_configname;
+ "push2 ${openvpn_configname}":
+ key => 'push',
+ value => '"redirect-gateway def1"',
+ server => $openvpn_configname;
+ "push-ipv6 ${openvpn_configname}":
+ key => 'push',
+ value => '"route-ipv6 2000::/3"',
+ server => $openvpn_configname;
+ "script-security ${openvpn_configname}":
+ key => 'script-security',
+ value => '1',
+ server => $openvpn_configname;
+ "server ${openvpn_configname}":
+ key => 'server',
+ value => $server,
+ server => $openvpn_configname;
+ "server-ipv6 ${openvpn_configname}":
+ key => 'server-ipv6',
+ value => '2001:db8:123::/64',
+ server => $openvpn_configname;
+ "status ${openvpn_configname}":
+ key => 'status',
+ value => "${openvpn_status_filename} 10",
+ server => $openvpn_configname;
+ "status-version ${openvpn_configname}":
+ key => 'status-version',
+ value => '3',
+ server => $openvpn_configname;
+ "topology ${openvpn_configname}":
+ key => 'topology',
+ value => 'subnet',
+ server => $openvpn_configname;
+ "verb ${openvpn_configname}":
+ key => 'verb',
+ value => '3',
+ server => $openvpn_configname;
+ "log-append /var/log/leap/openvpn_${proto}.log":
+ key => 'log-append',
+ value => "/var/log/leap/openvpn_${proto}.log",
+ server => $openvpn_configname;
+ }
+
+ # register openvpn services at systemd on nodes newer than wheezy
+ # see https://leap.se/code/issues/7798
+ case $::operatingsystemrelease {
+ /^7.*/: { }
+ default: {
+ exec { "enable_systemd_${openvpn_configname}":
+ refreshonly => true,
+ command => "/bin/systemctl enable openvpn@${openvpn_configname}",
+ subscribe => File["/etc/openvpn/${openvpn_configname}.conf"],
+ notify => Service["openvpn@${openvpn_configname}"];
+ }
+ service { "openvpn@${openvpn_configname}":
+ ensure => running
+ }
+ }
+ }
+}