diff options
Diffstat (limited to 'puppet/modules/openvpn/manifests')
-rw-r--r-- | puppet/modules/openvpn/manifests/client.pp | 187 | ||||
-rw-r--r-- | puppet/modules/openvpn/manifests/client_specific_config.pp | 79 | ||||
-rw-r--r-- | puppet/modules/openvpn/manifests/config.pp | 52 | ||||
-rw-r--r-- | puppet/modules/openvpn/manifests/init.pp | 43 | ||||
-rw-r--r-- | puppet/modules/openvpn/manifests/install.pp | 46 | ||||
-rw-r--r-- | puppet/modules/openvpn/manifests/params.pp | 37 | ||||
-rw-r--r-- | puppet/modules/openvpn/manifests/server.pp | 233 | ||||
-rw-r--r-- | puppet/modules/openvpn/manifests/service.pp | 36 |
8 files changed, 713 insertions, 0 deletions
diff --git a/puppet/modules/openvpn/manifests/client.pp b/puppet/modules/openvpn/manifests/client.pp new file mode 100644 index 00000000..92c6aa4e --- /dev/null +++ b/puppet/modules/openvpn/manifests/client.pp @@ -0,0 +1,187 @@ +# == Define: openvpn::client +# +# This define creates the client certs for a specified openvpn server as well +# as creating a tarball that can be directly imported into openvpn clients +# +# +# === Parameters +# +# [*server*] +# String. Name of the corresponding openvpn endpoint +# Required +# +# [*compression*] +# String. Which compression algorithim to use +# Default: comp-lzo +# Options: comp-lzo or '' (disable compression) +# +# [*dev*] +# String. Device method +# Default: tun +# Options: tun (routed connections), tap (bridged connections) +# +# [*mute*] +# Integer. Set log mute level +# Default: 20 +# +# [*mute_replay_warnings*] +# Boolean. Silence duplicate packet warnings (common on wireless networks) +# Default: true +# +# [*nobind*] +# Boolean. Whether or not to bind to a specific port number +# Default: true +# +# [*persist_key*] +# Boolean. Try to retain access to resources that may be unavailable +# because of privilege downgrades +# Default: true +# +# [*persist_tun*] +# Boolean. Try to retain access to resources that may be unavailable +# because of privilege downgrades +# Default: true +# +# [*port*] +# Integer. The port the openvpn server service is running on +# Default: 1194 +# +# [*proto*] +# String. What IP protocol is being used. +# Default: tcp +# Options: tcp or udp +# +# [*remote_host*] +# String. The IP or hostname of the openvpn server service +# Default: FQDN +# +# [*resolv_retry*] +# Integer/String. How many seconds should the openvpn client try to resolve +# the server's hostname +# Default: infinite +# Options: Integer or infinite +# +# [*verb*] +# Integer. Level of logging verbosity +# Default: 3 +# +# +# === Examples +# +# openvpn::client { +# 'my_user': +# server => 'contractors', +# remote_host => 'vpn.mycompany.com' +# } +# +# * Removal: +# Manual process right now, todo for the future +# +# +# === Authors +# +# * Raffael Schmid <mailto:raffael@yux.ch> +# * John Kinsella <mailto:jlkinsel@gmail.com> +# * Justin Lambert <mailto:jlambert@letsevenup.com> +# +# === License +# +# Copyright 2013 Raffael Schmid, <raffael@yux.ch> +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +define openvpn::client( + $server, + $compression = 'comp-lzo', + $dev = 'tun', + $mute = '20', + $mute_replay_warnings = true, + $nobind = true, + $persist_key = true, + $persist_tun = true, + $port = '1194', + $proto = 'tcp', + $remote_host = $::fqdn, + $resolv_retry = 'infinite', + $verb = '3', +) { + + Openvpn::Server[$server] -> + Openvpn::Client[$name] + + exec { + "generate certificate for ${name} in context of ${server}": + command => ". ./vars && ./pkitool ${name}", + cwd => "/etc/openvpn/${server}/easy-rsa", + creates => "/etc/openvpn/${server}/easy-rsa/keys/${name}.crt", + provider => 'shell'; + } + + file { + [ "/etc/openvpn/${server}/download-configs/${name}", + "/etc/openvpn/${server}/download-configs/${name}/keys"]: + ensure => directory; + + "/etc/openvpn/${server}/download-configs/${name}/keys/${name}.crt": + ensure => link, + target => "/etc/openvpn/${server}/easy-rsa/keys/${name}.crt", + require => Exec["generate certificate for ${name} in context of ${server}"]; + + "/etc/openvpn/${server}/download-configs/${name}/keys/${name}.key": + ensure => link, + target => "/etc/openvpn/${server}/easy-rsa/keys/${name}.key", + require => Exec["generate certificate for ${name} in context of ${server}"]; + + "/etc/openvpn/${server}/download-configs/${name}/keys/ca.crt": + ensure => link, + target => "/etc/openvpn/${server}/easy-rsa/keys/ca.crt", + require => Exec["generate certificate for ${name} in context of ${server}"]; + + "/etc/openvpn/${server}/download-configs/${name}/${name}.conf": + owner => root, + group => root, + mode => '0444', + content => template('openvpn/client.erb'), + notify => Exec["tar the thing ${server} with ${name}"]; + } + + exec { + "tar the thing ${server} with ${name}": + cwd => "/etc/openvpn/${server}/download-configs/", + command => "/bin/rm ${name}.tar.gz; tar --exclude=\\*.conf.d -chzvf ${name}.tar.gz ${name}", + refreshonly => true, + require => [ File["/etc/openvpn/${server}/download-configs/${name}/${name}.conf"], + File["/etc/openvpn/${server}/download-configs/${name}/keys/ca.crt"], + File["/etc/openvpn/${server}/download-configs/${name}/keys/${name}.key"], + File["/etc/openvpn/${server}/download-configs/${name}/keys/${name}.crt"] + ], + notify => Exec["generate ${name}.ovpn in ${server}"]; + } + + exec { + "generate ${name}.ovpn in ${server}": + cwd => "/etc/openvpn/${server}/download-configs/", + command => "/bin/rm ${name}.ovpn; cat ${name}/${name}.conf|perl -lne 'if(m|^ca keys/ca.crt|){ chomp(\$ca=`cat ${name}/keys/ca.crt`); print \"<ca>\n\$ca\n</ca>\"} elsif(m|^cert keys/${name}.crt|) { chomp(\$crt=`cat ${name}/keys/${name}.crt`); print \"<cert>\n\$crt\n</cert>\"} elsif(m|^key keys/${name}.key|){ chomp(\$key=`cat ${name}/keys/${name}.key`); print \"<key>\n\$key\n</key>\"} else { print} ' > ${name}.ovpn", + refreshonly => true, + require => [ File["/etc/openvpn/${server}/download-configs/${name}/${name}.conf"], + File["/etc/openvpn/${server}/download-configs/${name}/keys/ca.crt"], + File["/etc/openvpn/${server}/download-configs/${name}/keys/${name}.key"], + File["/etc/openvpn/${server}/download-configs/${name}/keys/${name}.crt"], + ], + } + + file { "/etc/openvpn/${server}/download-configs/${name}.ovpn": + mode => '0400', + require => Exec["generate ${name}.ovpn in ${server}"], + } +} diff --git a/puppet/modules/openvpn/manifests/client_specific_config.pp b/puppet/modules/openvpn/manifests/client_specific_config.pp new file mode 100644 index 00000000..4287421a --- /dev/null +++ b/puppet/modules/openvpn/manifests/client_specific_config.pp @@ -0,0 +1,79 @@ +# == Define: openvpn::client_specific_config +# +# This define configures options which will be pushed by the server to a +# specific client only. This feature is explained here: +# http://openvpn.net/index.php/open-source/documentation/howto.html#policy +# +# === Parameters +# +# All the parameters are explained in the openvpn documentation: +# http://openvpn.net/index.php/open-source/documentation/howto.html#policy +# +# [*server*] +# String. Name of the corresponding openvpn endpoint +# Required +# +# [*iroute*] +# Array. Array of iroute combinations. +# Default: [] +# +# [*ifconfig*] +# String. IP configuration to push to the client. +# Default: false +# +# [*dhcp_options] +# Array. DHCP options to push to the client. +# Default: [] +# +# +# === Examples +# +# openvpn::client_specific_config { +# 'vpn_client': +# server => 'contractors', +# iroute => ['10.0.1.0 255.255.255.0'], +# ifconfig => '10.10.10.1 10.10.10.2', +# dhcp_options => ['DNS 8.8.8.8'] +# } +# +# * Removal: +# Manual process right now, todo for the future +# +# +# === Authors +# +# * Raffael Schmid <mailto:raffael@yux.ch> +# +# === License +# +# Copyright 2013 Raffael Schmid, <raffael@yux.ch> +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +define openvpn::client_specific_config( + $server, + $iroute = [], + $ifconfig = false, + $dhcp_options = [] +) { + + Openvpn::Server[$server] -> + Openvpn::Client[$name] -> + Openvpn::Client_specific_config[$name] + + file { "/etc/openvpn/${server}/client-configs/${name}": + ensure => present, + content => template('openvpn/client_specific_config.erb') + } + +} diff --git a/puppet/modules/openvpn/manifests/config.pp b/puppet/modules/openvpn/manifests/config.pp new file mode 100644 index 00000000..32b32094 --- /dev/null +++ b/puppet/modules/openvpn/manifests/config.pp @@ -0,0 +1,52 @@ +# == Class: openvpn::config +# +# This class sets up the openvpn enviornment as well as the default config file +# +# +# === Examples +# +# This class should not be directly invoked +# +# === Authors +# +# * Raffael Schmid <mailto:raffael@yux.ch> +# * John Kinsella <mailto:jlkinsel@gmail.com> +# * Justin Lambert <mailto:jlambert@letsevenup.com> +# +# === License +# +# Copyright 2013 Raffael Schmid, <raffael@yux.ch> +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +class openvpn::config { + + if $::osfamily == 'Debian' { + include concat::setup + + concat { + '/etc/default/openvpn': + owner => root, + group => root, + mode => 644, + warn => true; + } + + concat::fragment { + 'openvpn.default.header': + content => template('openvpn/etc-default-openvpn.erb'), + target => '/etc/default/openvpn', + order => 01; + } + } +} diff --git a/puppet/modules/openvpn/manifests/init.pp b/puppet/modules/openvpn/manifests/init.pp new file mode 100644 index 00000000..7e07f025 --- /dev/null +++ b/puppet/modules/openvpn/manifests/init.pp @@ -0,0 +1,43 @@ +# == Class: openvpn +# +# This module installs the openvpn service, configures vpn endpoints, generates +# client certificates, and generates client config files +# +# +# === Examples +# +# * Installation: +# class { 'openvpn': } +# +# +# === Authors +# +# * Raffael Schmid <mailto:raffael@yux.ch> +# * John Kinsella <mailto:jlkinsel@gmail.com> +# * Justin Lambert <mailto:jlambert@letsevenup.com> +# +# === License +# +# Copyright 2013 Raffael Schmid, <raffael@yux.ch> +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +class openvpn { + + class {'openvpn::params': } -> + class {'openvpn::install': } -> + class {'openvpn::config': } ~> + class {'openvpn::service': } -> + Class['openvpn'] + +} diff --git a/puppet/modules/openvpn/manifests/install.pp b/puppet/modules/openvpn/manifests/install.pp new file mode 100644 index 00000000..a230373a --- /dev/null +++ b/puppet/modules/openvpn/manifests/install.pp @@ -0,0 +1,46 @@ +# == Class: openvpn +# +# This module installs the openvpn service, configures vpn endpoints, generates +# client certificates, and generates client config files +# +# +# === Examples +# +# This class should not be directly invoked +# +# +# === Authors +# +# * Raffael Schmid <mailto:raffael@yux.ch> +# * John Kinsella <mailto:jlkinsel@gmail.com> +# * Justin Lambert <mailto:jlambert@letsevenup.com> +# +# === License +# +# Copyright 2013 Raffael Schmid, <raffael@yux.ch> +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +class openvpn::install { + + package { + 'openvpn': + ensure => installed; + } + + file { + [ '/etc/openvpn', '/etc/openvpn/keys' ]: + ensure => directory, + require => Package['openvpn']; + } +} diff --git a/puppet/modules/openvpn/manifests/params.pp b/puppet/modules/openvpn/manifests/params.pp new file mode 100644 index 00000000..33495270 --- /dev/null +++ b/puppet/modules/openvpn/manifests/params.pp @@ -0,0 +1,37 @@ +# === License +# +# Copyright 2013 Raffael Schmid, <raffael@yux.ch> +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +class openvpn::params { + + $group = $::osfamily ? { + 'RedHat' => 'nobody', + default => 'nogroup' + } + + $easyrsa_source = $::osfamily ? { + 'RedHat' => $::operatingsystemmajrelease ? { + 6 => '/usr/share/openvpn/easy-rsa/2.0', + default => '/usr/share/doc/openvpn-2.2.2/easy-rsa/2.0' + }, + default => '/usr/share/doc/openvpn/examples/easy-rsa/2.0' + } + + $link_openssl_cnf = $::osfamily ? { + /(Debian|RedHat)/ => true, + default => false + } + +} diff --git a/puppet/modules/openvpn/manifests/server.pp b/puppet/modules/openvpn/manifests/server.pp new file mode 100644 index 00000000..649048c4 --- /dev/null +++ b/puppet/modules/openvpn/manifests/server.pp @@ -0,0 +1,233 @@ +# == Define: openvpn::server +# +# This define creates the openvpn server instance and ssl certificates +# +# +# === Parameters +# +# [*country*] +# String. Country to be used for the SSL certificate +# +# [*province*] +# String. Province to be used for the SSL certificate +# +# [*city*] +# String. City to be used for the SSL certificate +# +# [*organization*] +# String. Organization to be used for the SSL certificate +# +# [*email*] +# String. Email address to be used for the SSL certificate +# +# [*compression*] +# String. Which compression algorithim to use +# Default: comp-lzo +# Options: comp-lzo or '' (disable compression) +# +# [*dev*] +# String. Device method +# Default: tun +# Options: tun (routed connections), tap (bridged connections) +# +# [*user*] +# String. Group to drop privileges to after startup +# Default: nobody +# +# [*group*] +# String. User to drop privileges to after startup +# Default: depends on your $::osfamily +# +# [*ipp*] +# Boolean. Persist ifconfig information to a file to retain client IP +# addresses between sessions +# Default: false +# +# [*local*] +# String. Interface for openvpn to bind to. +# Default: $::ipaddress_eth0 +# Options: An IP address or '' to bind to all ip addresses +# +# [*logfile*] +# String. Logfile for this openvpn server +# Default: false +# Options: false (syslog) or log file name +# +# [*port*] +# Integer. The port the openvpn server service is running on +# Default: 1194 +# +# [*proto*] +# String. What IP protocol is being used. +# Default: tcp +# Options: tcp or udp +# +# [*status_log*] +# String. Logfile for periodic dumps of the vpn service status +# Default: "${name}/openvpn-status.log" +# +# [*server*] +# String. Network to assign client addresses out of +# Default: None. Required in tun mode, not in tap mode +# +# [*push*] +# Array. Options to push out to the client. This can include routes, DNS +# servers, DNS search domains, and many other options. +# Default: [] +# +# +# === Examples +# +# openvpn::client { +# 'my_user': +# server => 'contractors', +# remote_host => 'vpn.mycompany.com' +# } +# +# * Removal: +# Manual process right now, todo for the future +# +# +# === Authors +# +# * Raffael Schmid <mailto:raffael@yux.ch> +# * John Kinsella <mailto:jlkinsel@gmail.com> +# * Justin Lambert <mailto:jlambert@letsevenup.com> +# +# === License +# +# Copyright 2013 Raffael Schmid, <raffael@yux.ch> +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +define openvpn::server( + $country, + $province, + $city, + $organization, + $email, + $compression = 'comp-lzo', + $dev = 'tun0', + $user = 'nobody', + $group = false, + $ipp = false, + $ip_pool = [], + $local = $::ipaddress_eth0, + $logfile = false, + $port = '1194', + $proto = 'tcp', + $status_log = "${name}/openvpn-status.log", + $server = '', + $push = [] +) { + + include openvpn + Class['openvpn::install'] -> + Openvpn::Server[$name] ~> + Class['openvpn::service'] + + $tls_server = $proto ? { + /tcp/ => true, + default => false + } + + $group_to_set = $group ? { + false => $openvpn::params::group, + default => $group + } + + file { + ["/etc/openvpn/${name}", "/etc/openvpn/${name}/client-configs", "/etc/openvpn/${name}/download-configs" ]: + ensure => directory; + } + + exec { + "copy easy-rsa to openvpn config folder ${name}": + command => "/bin/cp -r ${openvpn::params::easyrsa_source} /etc/openvpn/${name}/easy-rsa", + creates => "/etc/openvpn/${name}/easy-rsa", + notify => Exec["fix_easyrsa_file_permissions_${name}"], + require => File["/etc/openvpn/${name}"]; + } + + exec { + "fix_easyrsa_file_permissions_${name}": + refreshonly => true, + command => "/bin/chmod 755 /etc/openvpn/${name}/easy-rsa/*"; + } + + file { + "/etc/openvpn/${name}/easy-rsa/vars": + ensure => present, + content => template('openvpn/vars.erb'), + require => Exec["copy easy-rsa to openvpn config folder ${name}"]; + } + + file { + "/etc/openvpn/${name}/easy-rsa/openssl.cnf": + require => Exec["copy easy-rsa to openvpn config folder ${name}"]; + } + + if $openvpn::params::link_openssl_cnf == true { + File["/etc/openvpn/${name}/easy-rsa/openssl.cnf"] { + ensure => link, + target => "/etc/openvpn/${name}/easy-rsa/openssl-1.0.0.cnf" + } + } + + exec { + "generate dh param ${name}": + command => '. ./vars && ./clean-all && ./build-dh', + cwd => "/etc/openvpn/${name}/easy-rsa", + creates => "/etc/openvpn/${name}/easy-rsa/keys/dh1024.pem", + provider => 'shell', + require => File["/etc/openvpn/${name}/easy-rsa/vars"]; + + "initca ${name}": + command => '. ./vars && ./pkitool --initca', + cwd => "/etc/openvpn/${name}/easy-rsa", + creates => "/etc/openvpn/${name}/easy-rsa/keys/ca.key", + provider => 'shell', + require => [ Exec["generate dh param ${name}"], File["/etc/openvpn/${name}/easy-rsa/openssl.cnf"] ]; + + "generate server cert ${name}": + command => '. ./vars && ./pkitool --server server', + cwd => "/etc/openvpn/${name}/easy-rsa", + creates => "/etc/openvpn/${name}/easy-rsa/keys/server.key", + provider => 'shell', + require => Exec["initca ${name}"]; + } + + file { + "/etc/openvpn/${name}/keys": + ensure => link, + target => "/etc/openvpn/${name}/easy-rsa/keys", + require => Exec["copy easy-rsa to openvpn config folder ${name}"]; + } + + if $::osfamily == 'Debian' { + concat::fragment { + "openvpn.default.autostart.${name}": + content => "AUTOSTART=\"\$AUTOSTART ${name}\"\n", + target => '/etc/default/openvpn', + order => 10; + } + } + + file { + "/etc/openvpn/${name}.conf": + owner => root, + group => root, + mode => '0444', + content => template('openvpn/server.erb'); + } +} diff --git a/puppet/modules/openvpn/manifests/service.pp b/puppet/modules/openvpn/manifests/service.pp new file mode 100644 index 00000000..54e8db7d --- /dev/null +++ b/puppet/modules/openvpn/manifests/service.pp @@ -0,0 +1,36 @@ +# == Class: openvpn::config +# +# This class maintains the openvpn service +# +# +# === Examples +# +# This class should not be directly invoked +# +# === Authors +# +# * Raffael Schmid <mailto:raffael@yux.ch> +# * John Kinsella <mailto:jlkinsel@gmail.com> +# * Justin Lambert <mailto:jlambert@letsevenup.com> +# +# === License +# +# Copyright 2013 Raffael Schmid, <raffael@yux.ch> +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# lied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +class openvpn::service { + service { + 'openvpn': + ensure => running, + enable => true, + hasrestart => true, + hasstatus => true; + } +} |