diff --git a/REFERENCE.md b/REFERENCE.md index 017b65f..84ec2c3 100644 --- a/REFERENCE.md +++ b/REFERENCE.md @@ -13,6 +13,7 @@ #### Public Defined types * [`wireguard::interface`](#wireguard--interface): manages a wireguard setup +* [`wireguard::peer`](#wireguard--peer): define a wireguard peer #### Private Defined types @@ -205,6 +206,7 @@ The following parameters are available in the `wireguard::interface` defined typ * [`postup_cmds`](#-wireguard--interface--postup_cmds) * [`predown_cmds`](#-wireguard--interface--predown_cmds) * [`postdown_cmds`](#-wireguard--interface--postdown_cmds) +* [`allowed_ips`](#-wireguard--interface--allowed_ips) ##### `interface` @@ -390,6 +392,78 @@ is an array of commands which should run as preup command (only supported by wgq Default value: `[]` +##### `allowed_ips` + +Data type: `Array[Variant[Stdlib::IP::Address::V4,Stdlib::IP::Address::V6]]` + +different addresses that should be routed to this peer + +Default value: `[]` + +### `wireguard::peer` + +define a wireguard peer + +#### Parameters + +The following parameters are available in the `wireguard::peer` defined type: + +* [`interface`](#-wireguard--peer--interface) +* [`description`](#-wireguard--peer--description) +* [`public_key`](#-wireguard--peer--public_key) +* [`endpoint`](#-wireguard--peer--endpoint) +* [`allowed_ips`](#-wireguard--peer--allowed_ips) +* [`preshared_key`](#-wireguard--peer--preshared_key) +* [`persistent_keepalive`](#-wireguard--peer--persistent_keepalive) + +##### `interface` + +Data type: `String[1]` + +the title of the defined resource, will be used for the targetted wg interface + +##### `description` + +Data type: `Optional[String[1]]` + +provide some identification details about the peer + +Default value: `undef` + +##### `public_key` + +Data type: `String[1]` + +base64 encoded pubkey from the remote peer + +##### `endpoint` + +Data type: `String[1]` + +fqdn:port or ip:port where we connect to + +##### `allowed_ips` + +Data type: `Array[Variant[Stdlib::IP::Address::V4,Stdlib::IP::Address::V6]]` + +different addresses that should be routed to this peer + +##### `preshared_key` + +Data type: `Optional[String[1]]` + +Define preshared key for the remote peer + +Default value: `undef` + +##### `persistent_keepalive` + +Data type: `Integer[0,65535]` + +is set to 1 or greater, that's the interval in seconds wireguard sends a keepalive to the other peer(s). Useful if the sender is behind a NAT gateway or has a dynamic ip address + +Default value: `0` + ## Data types ### `Wireguard::Peers` diff --git a/manifests/interface.pp b/manifests/interface.pp index 6b69624..3acf919 100644 --- a/manifests/interface.pp +++ b/manifests/interface.pp @@ -24,6 +24,7 @@ # @param postup_cmds is an array of commands which should run as preup command (only supported by wgquick) # @param predown_cmds is an array of commands which should run as preup command (only supported by wgquick) # @param postdown_cmds is an array of commands which should run as preup command (only supported by wgquick) +# @param allowed_ips different addresses that should be routed to this peer # # @author Tim Meusel # @author Sebastian Rakel @@ -105,6 +106,7 @@ Boolean $manage_firewall = true, Array[Stdlib::IP::Address] $source_addresses = [], Array[Hash[String,Variant[Stdlib::IP::Address::V4,Stdlib::IP::Address::V6]]] $addresses = [], + Array[Variant[Stdlib::IP::Address::V4,Stdlib::IP::Address::V6]] $allowed_ips = [], Optional[String[1]] $description = undef, Optional[Integer[1200, 9000]] $mtu = undef, Optional[String[1]] $public_key = undef, @@ -243,4 +245,22 @@ fail("provider ${provider} not supported") } } + if 'wireguard_pubkeys' in $facts { + if $interface in $facts['wireguard_pubkeys'] { + $peer_params = { + 'description' => $description, + 'public_key' => $facts['wireguard_pubkeys'][$interface], + 'endpoint' => "${facts['networking']['fqdn']}:${dport}", + 'allowed_ips' => $allowed_ips, + 'preshared_key' => $preshared_key, + 'persistent_keepalive' => $persistent_keepalive, + 'interface' => $interface, + 'tag' => "wireguard-${interface}", + } + @@wireguard::peer { "${facts['networking']['fqdn']}-${interface}-peer": + * => $peer_params, + } + } + } + Wireguard::Peer <<| tag == "wireguard-${interface}" |>> } diff --git a/manifests/peer.pp b/manifests/peer.pp new file mode 100644 index 0000000..7157de4 --- /dev/null +++ b/manifests/peer.pp @@ -0,0 +1,34 @@ +# @summary define a wireguard peer +# +# @param interface the title of the defined resource, will be used for the targetted wg interface +# @param description provide some identification details about the peer +# @param public_key base64 encoded pubkey from the remote peer +# @param endpoint fqdn:port or ip:port where we connect to +# @param allowed_ips different addresses that should be routed to this peer +# @param preshared_key Define preshared key for the remote peer +# @param persistent_keepalive is set to 1 or greater, that's the interval in seconds wireguard sends a keepalive to the other peer(s). Useful if the sender is behind a NAT gateway or has a dynamic ip address +# +define wireguard::peer ( + String[1] $interface, + Optional[String[1]] $description = undef, + String[1] $public_key, + String[1] $endpoint, + Array[Variant[Stdlib::IP::Address::V4,Stdlib::IP::Address::V6]] $allowed_ips, + Optional[String[1]] $preshared_key = undef, + Integer[0,65535] $persistent_keepalive = 0, +) { + $peer_params = { + 'description' => $description, + 'public_key' => $public_key, + 'endpoint' => $endpoint, + 'allowed_ips' => $allowed_ips, + 'preshared_key' => $preshared_key, + 'persistent_keepalive' => $persistent_keepalive, + } + + concat::fragment { $name: + order => 20, + target => "/etc/wireguard/${interface}.conf", + content => epp("${module_name}/wireguard_peer.epp", $peer_params), + } +} diff --git a/manifests/provider/wgquick.pp b/manifests/provider/wgquick.pp index 67121f8..d4e9a3b 100644 --- a/manifests/provider/wgquick.pp +++ b/manifests/provider/wgquick.pp @@ -4,6 +4,7 @@ define wireguard::provider::wgquick ( String[1] $interface = $title, Enum['present', 'absent'] $ensure = 'present', + Boolean $enable = true, Wireguard::Peers $peers = [], Integer[1024, 65000] $dport = Integer(regsubst($title, '^\D+(\d+)$', '\1')), Optional[Integer[0,4294967295]] $firewall_mark = undef, @@ -20,7 +21,6 @@ 'dport' => $dport, 'firewall_mark' => $firewall_mark, 'mtu' => $mtu, - 'peers' => $peers, 'addresses' => $addresses, 'preup_cmds' => $preup_cmds, 'postup_cmds' => $postup_cmds, @@ -28,10 +28,33 @@ 'postdown_cmds' => $postdown_cmds, } - file { "/etc/wireguard/${interface}.conf": - ensure => $ensure, - content => epp("${module_name}/wireguard_conf.epp", $params), - owner => 'root', - mode => '0600', + if ! empty($peers) { + file { "/etc/wireguard/${interface}.conf": + ensure => $ensure, + content => epp("${module_name}/wireguard_conf.epp", $params + { 'peers' => $peers }), + owner => 'root', + mode => '0600', + } + } else { + concat { "/etc/wireguard/${interface}.conf": + ensure => $ensure, + owner => 'root', + mode => '0600', + notify => Service["wg-quick@${interface}"], + } + concat::fragment { "${interface}_head": + order => 10, + target => "/etc/wireguard/${interface}.conf", + content => epp("${module_name}/wireguard_head.epp", $params), + } + } + + $svc_ensure = $ensure ? { + present => 'running', + absent => 'stopped', + } + service { "wg-quick@${interface}": + ensure => $svc_ensure, + enable => $enable, } } diff --git a/metadata.json b/metadata.json index 1070f59..7f68c61 100644 --- a/metadata.json +++ b/metadata.json @@ -22,6 +22,10 @@ { "name": "puppetlabs/stdlib", "version_requirement": ">= 7.1.0 < 9.0.0" + }, + { + "name": "puppetlabs/concat", + "version_requirement": ">= 7.1.0 < 9.0.0" } ], "operatingsystem_support": [ diff --git a/templates/wireguard_head.epp b/templates/wireguard_head.epp new file mode 100644 index 0000000..2c2ea0b --- /dev/null +++ b/templates/wireguard_head.epp @@ -0,0 +1,39 @@ +<%- | + String[1] $interface, + Stdlib::Port $dport, + Optional[Integer] $firewall_mark, + Array[Hash] $addresses, + Array[String[1]] $preup_cmds, + Array[String[1]] $postup_cmds, + Array[String[1]] $predown_cmds, + Array[String[1]] $postdown_cmds, + Optional[Integer[1280, 9000]] $mtu = undef, +| -%> +# THIS FILE IS MANAGED BY PUPPET +<% $addresses.each |$address| { -%> + +[Interface] +<% $address.each |$key, $value| { -%> +<%= $key %>=<%= $value %> +<% } -%> +<% } -%> +ListenPort=<%= $dport %> +<% if $firewall_mark { -%> +FwMark=<%= $firewall_mark %> +<% } -%> +<% $preup_cmds.each |$cmd| { -%> +PreUp=<%= $cmd %> +<% } -%> +PostUp=wg set %i private-key /etc/wireguard/<%= $interface %> +<% $postup_cmds.each |$cmd| { -%> +PostUp=<%= $cmd %> +<% } -%> +<% $predown_cmds.each |$cmd| { -%> +PreDown=<%= $cmd %> +<% } -%> +<% $postdown_cmds.each |$cmd| { -%> +PostDown=<%= $cmd %> +<% } -%> +<% if $mtu { -%> +MTU=<%= $mtu %> +<% } -%> diff --git a/templates/wireguard_peer.epp b/templates/wireguard_peer.epp new file mode 100644 index 0000000..f4ff3d0 --- /dev/null +++ b/templates/wireguard_peer.epp @@ -0,0 +1,22 @@ +<%- | + Optional[String[1]] $description, + String[1] $public_key, + String[1] $endpoint, + Optional[String[1]] $preshared_key, + Optional[Integer[0,65535]] $persistent_keepalive, + Array[Variant[Stdlib::IP::Address::V4,Stdlib::IP::Address::V6]] $allowed_ips, +| -%> + +<% if $description { -%> +# <%= $description %> +<% } -%> +[Peer] +PublicKey=<%= $public_key %> +Endpoint=<%= $endpoint %> +<% if $preshared_key { -%> +PresharedKey=<%= $preshared_key %> +<% } -%> +PersistentKeepalive=<%= pick($persistent_keepalive, 0) %> +<% pick($allowed_ips, ['fe80::/64', 'fd00::/8', '0.0.0.0/0']).each |$allowed_ip| { -%> +AllowedIPs=<%= $allowed_ip %> +<% } -%>