From b903c0d641bdc709eae2db7ccbb459685643db35 Mon Sep 17 00:00:00 2001 From: unkin-agent Date: Sat, 3 Oct 2026 20:57:00 +1000 Subject: [PATCH] Keep wireguard keys Sensitive and generate missing private keys --- hieradata/common.yaml | 2 ++ modules/wireguard/manifests/init.pp | 27 +++++++++++++--- modules/wireguard/manifests/interface.pp | 41 ++++++++++++++++++------ modules/wireguard/templates/wg.conf.erb | 2 +- 4 files changed, 57 insertions(+), 15 deletions(-) diff --git a/hieradata/common.yaml b/hieradata/common.yaml index 02a6d8b..e29de34 100644 --- a/hieradata/common.yaml +++ b/hieradata/common.yaml @@ -178,6 +178,8 @@ lookup_options: convert_to: Sensitive stalwart::fallback_admin_password: convert_to: Sensitive + wireguard::interfaces: + convert_to: Sensitive facts_path: '/opt/puppetlabs/facter/facts.d' diff --git a/modules/wireguard/manifests/init.pp b/modules/wireguard/manifests/init.pp index 64c19c6..a4301b6 100644 --- a/modules/wireguard/manifests/init.pp +++ b/modules/wireguard/manifests/init.pp @@ -1,8 +1,8 @@ # manage wireguard interfaces via wg-quick class wireguard ( - Boolean $manage_package = true, - String $package_name = 'wireguard-tools', - Hash $interfaces = {}, + Boolean $manage_package = true, + String $package_name = 'wireguard-tools', + Variant[Hash, Sensitive[Hash]] $interfaces = {}, ) { if $manage_package { @@ -19,9 +19,26 @@ class wireguard ( mode => '0700', } - $interfaces.each |String $iface, Hash $data| { + # hiera hands eyaml secrets over as plain strings inside the (Sensitive) hash; re-wrap them per resource + $raw = $interfaces ? { + Sensitive => $interfaces.unwrap, + default => $interfaces, + } + + $raw.each |String $iface, Hash $data| { + $peers = $data.get('peers', []).map |Hash $peer| { + $peer['preshared_key'] =~ String ? { + true => $peer + { 'preshared_key' => Sensitive($peer['preshared_key']) }, + default => $peer, + } + } + $private_key = $data['private_key'] =~ String ? { + true => Sensitive($data['private_key']), + default => $data['private_key'], + } + wireguard::interface { $iface: - * => $data, + * => $data + { 'peers' => $peers, 'private_key' => $private_key }, } } } diff --git a/modules/wireguard/manifests/interface.pp b/modules/wireguard/manifests/interface.pp index 516d4be..7428941 100644 --- a/modules/wireguard/manifests/interface.pp +++ b/modules/wireguard/manifests/interface.pp @@ -1,16 +1,39 @@ -# manage one wg-quick interface; without private_key, the existing /etc/wireguard/.key is loaded via PostUp +# manage one wg-quick interface; without private_key, /etc/wireguard/.key is generated once and loaded via PostUp define wireguard::interface ( - Array[Stdlib::IP::Address] $addresses, - Optional[Stdlib::Port] $listen_port = undef, - Optional[Integer[1280, 9000]] $mtu = undef, - Optional[Variant[String, Sensitive[String]]] $private_key = undef, - Array[Hash] $peers = [], + Array[Stdlib::IP::Address] $addresses, + Optional[Stdlib::Port] $listen_port = undef, + Optional[Integer[1280, 9000]] $mtu = undef, + Optional[Sensitive[String[1]]] $private_key = undef, + Array[Struct[{ + public_key => String[1], + allowed_ips => Variant[String[1], Array[String[1], 1]], + preshared_key => Optional[Sensitive[String[1]]], + endpoint => Optional[String[1]], + persistent_keepalive => Optional[Integer[0, 65535]], + }]] $peers = [], ) { $conf = "/etc/wireguard/${name}.conf" - $key = $private_key ? { - Sensitive => $private_key.unwrap, - default => $private_key, + $key = $private_key.then |$k| { $k.unwrap } + + if $private_key =~ Undef { + $keyfile = "/etc/wireguard/${name}.key" + + exec { "wireguard_genkey_${name}": + command => "/bin/sh -c 'umask 077; wg genkey > ${keyfile}'", + creates => $keyfile, + path => ['/usr/bin', '/usr/sbin', '/bin', '/sbin'], + require => File['/etc/wireguard'], + } + + file { $keyfile: + ensure => file, + owner => 'root', + group => 'root', + mode => '0600', + require => Exec["wireguard_genkey_${name}"], + before => [File[$conf], Service["wg-quick@${name}"]], + } } file { $conf: diff --git a/modules/wireguard/templates/wg.conf.erb b/modules/wireguard/templates/wg.conf.erb index b9e8066..01b45bd 100644 --- a/modules/wireguard/templates/wg.conf.erb +++ b/modules/wireguard/templates/wg.conf.erb @@ -19,7 +19,7 @@ PostUp = wg set %i private-key /etc/wireguard/%i.key [Peer] PublicKey = <%= peer['public_key'] %> <% if peer['preshared_key'] -%> -PresharedKey = <%= peer['preshared_key'].respond_to?(:unwrap) ? peer['preshared_key'].unwrap : peer['preshared_key'] %> +PresharedKey = <%= peer['preshared_key'].unwrap %> <% end -%> AllowedIPs = <%= Array(peer['allowed_ips']).join(', ') %> <% if peer['endpoint'] -%>