Puppet Class: roadwarrior

Inherits:
::roadwarrior::params
Defined in:
manifests/init.pp

Overview

Parameters:

  • packages_strongswan (Any) (defaults to: $::roadwarrior::params::packages_strongswan)
  • service_strongswan (Any) (defaults to: $::roadwarrior::params::service_strongswan)
  • manage_firewall_v4 (Any) (defaults to: $::roadwarrior::params::manage_firewall_v4)
  • manage_firewall_v6 (Any) (defaults to: $::roadwarrior::params::manage_firewall_v6)
  • vpn_name (Any) (defaults to: $::roadwarrior::params::vpn_name)
  • vpn_range_v4 (Any) (defaults to: $::roadwarrior::params::vpn_range_v4)
  • vpn_route_v4 (Any) (defaults to: $::roadwarrior::params::vpn_route_v4)
  • vpn_dns_servers (Any) (defaults to: $::roadwarrior::params::vpn_dns_servers)
  • debug_logging (Any) (defaults to: $::roadwarrior::params::debug_logging)
  • cert_dir (Any) (defaults to: $::roadwarrior::params::cert_dir)
  • cert_lifespan (Any) (defaults to: $::roadwarrior::params::cert_lifespan)
  • cert_password (Any) (defaults to: $::roadwarrior::params::cert_password)


4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'manifests/init.pp', line 4

class roadwarrior (
  $packages_strongswan  = $::roadwarrior::params::packages_strongswan,
  $service_strongswan   = $::roadwarrior::params::service_strongswan,
  $manage_firewall_v4   = $::roadwarrior::params::manage_firewall_v4,
  $manage_firewall_v6   = $::roadwarrior::params::manage_firewall_v6,
  $vpn_name             = $::roadwarrior::params::vpn_name,
  $vpn_range_v4         = $::roadwarrior::params::vpn_range_v4,
  $vpn_route_v4         = $::roadwarrior::params::vpn_route_v4,
  $vpn_dns_servers      = $::roadwarrior::params::vpn_dns_servers,
  $debug_logging        = $::roadwarrior::params::debug_logging,
  $cert_dir             = $::roadwarrior::params::cert_dir,
  $cert_lifespan        = $::roadwarrior::params::cert_lifespan,
  $cert_password        = $::roadwarrior::params::cert_password,
) inherits ::roadwarrior::params {

  validate_string( $vpn_dns_servers )

  # Compat checks
  if ($::operatingsystem != "Debian" and $::operatingsystem != "Ubuntu") {
    fail("Sorry, only Debian or Ubuntu distributions are supported by the roadwarrior module at this time. PRs welcome")
  }

  # Ensure resources is brilliant witchcraft, we can install all the StrongSwan
  # dependencies in a single run and avoid double-definitions if they're already
  # defined elsewhere.
  ensure_packages([$packages_strongswan], {
    'ensure' => 'present',
    'before' => [ Service[$service_strongswan], File['/etc/ipsec.conf'], File['/etc/ipsec.secrets'] ]
  })

  # We need to define the service and make sure it's set to launch at startup.
  service { $service_strongswan:
    ensure => running,
    enable => true,
  }


  # StrongSwan IPSec subsystem configuration. Most of the logic that we
  # need to configure goes here.
  file { '/etc/ipsec.conf':
    ensure  => file,
    mode    => '0644',
    owner   => 'root',
    group   => 'root',
    content => template('roadwarrior/ipsec.conf.erb'),
    notify  => Service[$service_strongswan]
  }

  # As we are doing cert authentication, the secrets file simply needs the
  # private key of the VPN host listed.
  file { '/etc/ipsec.secrets':
    ensure  => file,
    mode    => '0600',
    owner   => 'root',
    group   => 'root',
    content => template('roadwarrior/ipsec.secrets.erb'),
    notify  => Service[$service_strongswan]
  }

  # Charon Configuration File
  # TODO: Adjustments to Charon config for timeouts, etc?


  # Configure firewalling and packet forwarding if appropiate
  if ($manage_firewall_v4 or $manage_firewall_v6) {
    include ::roadwarrior::firewall
  }


  # Handy hack - set the path for all Execs
  Exec {
    path => '/bin:/sbin:/usr/bin:/usr/sbin',
   }

  # Check if the VPN name differs from the CA cert. If so, the admin has probably
  # messed with $vpn_name and now it doens't reflect reality.
  # TODO: write this validation

  # Generate CA key & cert
  exec { 'generate_ca_key':
    command  => "ipsec pki --gen --type rsa --size 4096 --outform pem > ${cert_dir}/private/strongswanKey.pem",
    creates  => "${cert_dir}/private/strongswanKey.pem",
    require  => File['/etc/ipsec.conf'], # Used to pull in all packages
  } ->

  exec { 'generate_ca_cert':
    command => "ipsec pki --self --ca lifetime ${cert_lifespan} --in ${cert_dir}/private/strongswanKey.pem --digest sha256 --type rsa --dn \"C=NZ, O=roadwarrior, CN=${vpn_name} CA\" --outform pem > ${cert_dir}/cacerts/strongswanCert.pem",
    creates  => "${cert_dir}/cacerts/strongswanCert.pem",
  } ->

  # Generate VPN host key & cert
  exec { 'generate_host_key':
    command  => "ipsec pki --gen --type rsa --size 2048 --outform pem > ${cert_dir}/private/vpnHostKey.pem",
    creates  => "${cert_dir}/private/vpnHostKey.pem",
  } ->

  exec { 'generate_host_cert':
    command => "ipsec pki --pub --in ${cert_dir}/private/vpnHostKey.pem --type rsa | ipsec pki --issue --digest sha256 --lifetime ${cert_lifespan} --cacert ${cert_dir}/cacerts/strongswanCert.pem --cakey ${cert_dir}/private/strongswanKey.pem --dn \"C=NZ, O=roadwarrior, CN=${vpn_name}\" --san ${vpn_name} --flag serverAuth --flag ikeIntermediate --outform pem > ${cert_dir}/certs/vpnHostCert.pem",
    creates => "${cert_dir}/certs/vpnHostCert.pem",
    notify  => Service[$service_strongswan], # Make sure the server is restarted with the right cert (if needed)
  } ->

  # Export the CA cert to DER format as well. StrongSwan doesn't need it, but it's useful
  # when generating the client packages as some take DER rather than PEM.
  exec { 'generate_host_cert_der':
    command  => "openssl x509 -in ${cert_dir}/cacerts/strongswanCert.pem -out ${cert_dir}/cacerts/strongswanCert.der -outform DER",
    creates  => "${cert_dir}/cacerts/strongswanCert.der",
  }

  # Create a directory for the distributable packages
  file { "${cert_dir}/dist":
    ensure  => directory,
    mode    => '0600',
    owner   => 'root',
    group   => 'root',
    require => File['/etc/ipsec.conf'],
  }



}