# an ipsec peer, another node to connect to # # This is the stored config part of ipsec::network. Each node that # is part of a network stores an ipsec::peer entry for itself and # then collects all other nodes of that network, overwriting # the local_* variables for itself. # # @param network_name name of this ipsec network clique # @param ipsec_conf_file the target of the ipsec config file concat # @param ipsec_secrets_file the target of the ipsec secrets file concat # @param local_name the name of this node (overwritten on collecting) # @param local_ipaddress the ipsec endpoint address on this node (overwritten on collecting) # @param local_networks a list of local networks (overwritten on collecting) # @param peer_name the name of this peer # @param peer_ipaddress the ipsec endpoint address of this peer # @param peer_networks a list of networks behind or at this peer 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", } }