Skip to content

Commit

Permalink
Add different providers for wireguard
Browse files Browse the repository at this point in the history
  • Loading branch information
sebastianrakel committed Aug 7, 2022
1 parent 9191b76 commit eb9804e
Show file tree
Hide file tree
Showing 6 changed files with 188 additions and 28 deletions.
55 changes: 27 additions & 28 deletions manifests/interface.pp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
# @param routes different routes for the systemd-networkd configuration
# @param private_key Define private key which should be used for this interface, if not provided a private key will be generated
# @param preshared_key Define preshared key which should be used for this interface
# @param provider Set provider for interface config. Allowed values: systemd, wgquick (default: systemd)
#
# @author Tim Meusel <[email protected]>
# @author Sebastian Rakel <[email protected]>
Expand Down Expand Up @@ -94,6 +95,7 @@
Array[Hash[String[1], Variant[String[1], Boolean]]] $routes = [],
Optional[String[1]] $private_key = undef,
Optional[String[1]] $preshared_key = undef,
Enum['systemd', 'wgquick'] $provider = 'systemd',
) {
require wireguard
Expand Down Expand Up @@ -171,33 +173,30 @@
$peer = []
}
systemd::network { "${interface}.netdev":
content => epp("${module_name}/netdev.epp", {
'interface' => $interface,
'dport' => $dport,
'description' => $description,
'preshared_key' => $preshared_key,
'mtu' => $mtu,
'peers' => $peers + $peer,
}),
restart_service => true,
owner => 'root',
group => 'systemd-network',
mode => '0440',
require => File["/etc/wireguard/${interface}"],
}
$network_epp_params = {
'interface' => $interface,
'addresses' => $addresses,
'routes' => $routes,
}
systemd::network { "${interface}.network":
content => epp("${module_name}/network.epp", $network_epp_params),
restart_service => true,
owner => 'root',
group => 'systemd-network',
mode => '0440',
case $provider {
'systemd': {
class { 'wireguard::provider::systemd':
interface => $interface,
peers => $peers + $peer,
dport => $dport,
addresses => $addresses,
description => $description,
mtu => $mtu,
routes => $routes,
preshared_key => $preshared_key,
}
}
'wgquick': {
class { 'wireguard::provider::wgquick':
interface => $interface,
peers => $peers + $peer,
dport => $dport,
addresses => $addresses,
preshared_key => $preshared_key,
}
}
default: {
fail("provider ${provider} not supported")
}
}
}
53 changes: 53 additions & 0 deletions manifests/provider/systemd.pp
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#
# @summary manages a systemd wireguard interface
#
# @param interface the name for the wg interface
# @param peers is an array of struct (Wireguard::Peers) for multiple peers
# @param dport destination for firewall rules / where our wg instance will listen on. defaults to the last digits from the title
# @param addresses different addresses for the systemd-networkd configuration
# @param description an optional string that will be added to the wireguard network interface
# @param mtu configure the MTU (maximum transision unit) for the wireguard tunnel. By default linux will figure this out. You might need to lower it if you're connection through a DSL line. MTU needs to be equal on both tunnel endpoints
# @param routes different routes for the systemd-networkd configuration
# @param preshared_key Define preshared key which should be used for this interface
#
# @see https://www.freedesktop.org/software/systemd/man/systemd.netdev.html#%5BWireGuardPeer%5D%20Section%20Options
class wireguard::provider::systemd (
String[1] $interface,
Wireguard::Peers $peers = [],
Integer[1024, 65000] $dport = Integer(regsubst($title, '^\D+(\d+)$', '\1')),
Array[Hash[String,Variant[Stdlib::IP::Address::V4::CIDR,Stdlib::IP::Address::V6::CIDR]]] $addresses = [],
Optional[String[1]] $description = undef,
Optional[Integer[1280, 9000]] $mtu = undef,
Array[Hash[String[1], Variant[String[1], Boolean]]] $routes = [],
Optional[String[1]] $preshared_key = undef,
) {
systemd::network { "${interface}.netdev":
content => epp("${module_name}/netdev.epp", {
'interface' => $interface,
'dport' => $dport,
'description' => $description,
'mtu' => $mtu,
'peers' => $peers,
'preshared_key' => $preshared_key,
}),
restart_service => true,
owner => 'root',
group => 'systemd-network',
mode => '0440',
require => File["/etc/wireguard/${interface}"],
}

$network_epp_params = {
'interface' => $interface,
'addresses' => $addresses,
'routes' => $routes,
}

systemd::network { "${interface}.network":
content => epp("${module_name}/network.epp", $network_epp_params),
restart_service => true,
owner => 'root',
group => 'systemd-network',
mode => '0440',
}
}
30 changes: 30 additions & 0 deletions manifests/provider/wgquick.pp
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#
# @summary manages a wireguard config file for wg-quick
#
# @param interface the name for the wg interface
# @param peers is an array of struct (Wireguard::Peers) for multiple peers
# @param dport destination for firewall rules / where our wg instance will listen on. defaults to the last digits from the title
# @param addresses different addresses for the systemd-networkd configuration
# @param preshared_key Define preshared key which should be used for this interface
#
class wireguard::provider::wgquick (
String[1] $interface,
Wireguard::Peers $peers = [],
Integer[1024, 65000] $dport = Integer(regsubst($title, '^\D+(\d+)$', '\1')),
Array[Hash[String,Variant[Stdlib::IP::Address::V4::CIDR,Stdlib::IP::Address::V6::CIDR]]] $addresses = [],
Optional[String[1]] $preshared_key = undef,
) {
$params = {
'interface' => $interface,
'dport' => $dport,
'peers' => $peers,
'addresses' => $addresses,
'preshared_key' => $preshared_key,
}

file { "/etc/wireguard/${interface}.conf":
content => epp("${module_name}/wireguard_conf.epp", $params),
owner => 'root',
mode => '0600',
}
}
27 changes: 27 additions & 0 deletions spec/acceptance/init_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,31 @@
end
end
end

context 'with wg-quick' do
let :facts do
facts
end

it 'work with no errors' do
pp = <<-EOS
wireguard::interface { 'tun0':
manage_firewall => false,
dport => 51820,
destination_addresses => [$facts['networking']['ip']],
addresses => [{'Address' => '192.0.2.1/24'}],
provider => 'wgquick',
peers => [
{
public_key => 'hZC2VwCilfF9k9nQC6a86xOBFKaqdAgy123dkA6Z008=',
allowed_ips => ['192.0.2.3'],
}
],
}
EOS

apply_manifest(pp, catch_failures: true)
apply_manifest(pp, catch_changes: true)
end
end
end
23 changes: 23 additions & 0 deletions spec/defines/interface_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,29 @@ class {"systemd":
it { is_expected.to contain_file("/etc/systemd/network/#{title}.network").with_content(%r{Address=fe80::ade1/64}) }
it { is_expected.not_to contain_ferm__rule("allow_wg_#{title}") }
end

context 'wgquick with required params (public_key) and without firewall rules' do
let :params do
{
public_key: 'blabla==',
endpoint: 'wireguard.example.com:1234',
manage_firewall: false,
# we need to set destination_addresses to overwrite the default
# that would configure IPv4+IPv6, but GHA doesn't provide IPv6 for us
destination_addresses: [facts[:networking]['ip'],],
provider: 'wgquick',
}
end

it { is_expected.to compile.with_all_deps }
it { is_expected.to contain_class('wireguard') }
it { is_expected.to contain_exec("generate private key #{title}") }
it { is_expected.to contain_exec("generate public key #{title}") }
it { is_expected.to contain_file("/etc/wireguard/#{title}.pub") }
it { is_expected.to contain_file("/etc/wireguard/#{title}") }
it { is_expected.to contain_file("/etc/wireguard/#{title}.conf") }
it { is_expected.not_to contain_ferm__rule("allow_wg_#{title}") }
end
end
end
end
28 changes: 28 additions & 0 deletions templates/wireguard_conf.epp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<%- |
String[1] $interface,
Stdlib::Port $dport,
Wireguard::Peers $peers,
Array[Hash] $addresses,
Optional[String[1]] $preshared_key,
| -%>
[Interface]
<% $addresses.each |$address| { -%>
Address = <%= $address['Address'] %>
<% } -%>
ListenPort = <%= $dport %>
PostUp = wg set %i private-key /etc/wireguard/<%= $interface %>
<% $peers.each |$peer| { -%>

[Peer]
PublicKey=<%= $peer['public_key'] %>
<% if $peer['endpoint'] { -%>
Endpoint=<%= $peer['endpoint'] %>
<% } -%>
<% if $preshared_key { -%>
PresharedKey=<%= $preshared_key %>
<% } -%>
PersistentKeepalive=<%= pick($peer['persistent_keepalive'], 0) %>
<% pick($peer['allowed_ips'], ['fe80::/64', 'fd00::/8', '0.0.0.0/0']).each |$allowed_ip| { -%>
AllowedIPs=<%= $allowed_ip %>
<% } -%>
<% } -%>

0 comments on commit eb9804e

Please sign in to comment.