# an ipsec peer, another node to connect to define ipsec::peer( $ipsec_conf_file, $ipsec_secrets_file, $local_name, $local_ipaddress, $peer_name, $peer_ipaddress, $local_networks = [], $peer_networks = [], $network_name = 'ipsec', ) { $leftsubnet = $local_networks ? { [] => '', default => "leftsubnet = ${$local_networks.join(', ')}" } $rightsubnet = $peer_networks ? { [] => '', default => "rightsubnet = ${$peer_networks.join(', ')}" } concat::fragment { "${network_name}::${ipsec_conf_file}::${name}": target => $ipsec_conf_file, content => @("EOF"), # peer ${name} conn ${network_name}::${peer_name} # left is us (local, ${local_name}) left = ${local_ipaddress} ${leftsubnet} # right is our peer (remote, ${peer_name}) right = ${peer_ipaddress} ${rightsubnet} auto=route | EOF } # create the data portion for the key derivation function # # It needs to be the same data on both ends of a connection, so the # corresponding secrets entry at the peer gets the same PSK. We do # this by putting the peer's info and our info in some arbitrary, # yet canonical order by sorting. $ipsec_psk_data = ("${local_name}(${local_ipaddress})" < "${peer_name}(${peer_ipaddress})") ? { true => "ipsec-peer-psk-${network_name}-${local_name}(${local_ipaddress})-${peer_name}(${peer_ipaddress})", false => "ipsec-peer-psk-${network_name}-${peer_name}(${peer_ipaddress})-${local_name}(${local_ipaddress})" } $ipsec_psk = hkdf('/etc/puppet/secret', $ipsec_psk_data) concat::fragment { "${network_name}::${ipsec_secrets_file}::${name}": target => $ipsec_secrets_file, content => @("EOF"), # peer ${peer_name} ${peer_ipaddress} : PSK "${ipsec_psk}" | EOF } ferm::rule { "${network_name}-${name}": description => "allow ipsec protocols for peer ${peer_name}", domain => '(ip ip6)', chain => 'ipsec-peers', rule => "saddr ${peer_ipaddress} ACCEPT", } }