Add wireguard module #538

Merged
benvin merged 2 commits from benvin/wireguard-module into develop 2026-10-04 14:17:08 +11:00
Member

WireGuard on the router is configured by hand, so its tunnels are not reproducible from code. This adds a module to manage it from hieradata.

  • add wireguard class to install wireguard-tools and manage interfaces from a hash
  • add wireguard::interface to render /etc/wireguard/<iface>.conf (0600) and enable wg-quick@<iface>
  • keep private and preshared keys Sensitive end to end (wireguard::interfaces lookup_options convert_to: Sensitive, typed peer Struct)
  • without private_key, generate /etc/wireguard/<iface>.key (0600) only if absent and load it via PostUp, so the key never rotates
  • apply config changes with wg syncconf instead of restarting the tunnel
WireGuard on the router is configured by hand, so its tunnels are not reproducible from code. This adds a module to manage it from hieradata. - add `wireguard` class to install wireguard-tools and manage interfaces from a hash - add `wireguard::interface` to render `/etc/wireguard/<iface>.conf` (0600) and enable `wg-quick@<iface>` - keep private and preshared keys `Sensitive` end to end (`wireguard::interfaces` lookup_options `convert_to: Sensitive`, typed peer Struct) - without `private_key`, generate `/etc/wireguard/<iface>.key` (0600) only if absent and load it via PostUp, so the key never rotates - apply config changes with `wg syncconf` instead of restarting the tunnel
unkin-agent added 1 commit 2026-10-03 20:54:14 +10:00
Add wireguard module managing wg-quick interfaces
ci/woodpecker/pr/ruby-validate Pipeline was successful
ci/woodpecker/pr/yamllint Pipeline was successful
ci/woodpecker/pr/puppet-lint Pipeline was successful
ci/woodpecker/pr/erb-validate Pipeline was successful
ci/woodpecker/pr/bolt-validate Pipeline was successful
ci/woodpecker/pr/epp-validate Pipeline was successful
ci/woodpecker/pr/ruby-check Pipeline was canceled
ci/woodpecker/pr/puppet-validate Pipeline was canceled
0bbf797693
Author
Member
  • modules/wireguard/manifests/interface.pp:45 — Variant[String, Sensitive[String]] accepts a plain String, and peers is Array[Hash] (line 46) with preshared_key read from it, so eyaml-decrypted keys land as plaintext resource parameters in the catalog/PuppetDB (show_diff => false on the file does not cover that) → type private_key as Optional[Sensitive[String]], and type peers as Array[Struct[{public_key => String[1], allowed_ips => Variant[String,Array[String]], preshared_key => Optional[Sensitive[String]], endpoint => Optional[String], persistent_keepalive => Optional[Integer]}]] with hiera lookup_options convert_to: Sensitive for the nested keys
  • modules/wireguard/templates/wg.conf.erb:100 — when private_key is unset, PostUp runs wg set %i private-key /etc/wireguard/%i.key, but nothing checks or manages that file, so a missing key makes wg-quick@<iface> fail to start → add a file { "/etc/wireguard/${name}.key": ensure => file, mode => "0600", replace => false } (or an unless-style guard) so the dependency is explicit
  • nit: modules/wireguard/templates/wg.conf.erb:98 — if @key is true for an empty string, rendering PrivateKey = → use String[1] in the type
- modules/wireguard/manifests/interface.pp:45 — `Variant[String, Sensitive[String]]` accepts a plain String, and `peers` is `Array[Hash]` (line 46) with `preshared_key` read from it, so eyaml-decrypted keys land as plaintext resource parameters in the catalog/PuppetDB (`show_diff => false` on the file does not cover that) → type `private_key` as `Optional[Sensitive[String]]`, and type peers as `Array[Struct[{public_key => String[1], allowed_ips => Variant[String,Array[String]], preshared_key => Optional[Sensitive[String]], endpoint => Optional[String], persistent_keepalive => Optional[Integer]}]]` with hiera lookup_options `convert_to: Sensitive` for the nested keys - modules/wireguard/templates/wg.conf.erb:100 — when `private_key` is unset, PostUp runs `wg set %i private-key /etc/wireguard/%i.key`, but nothing checks or manages that file, so a missing key makes `wg-quick@<iface>` fail to start → add a `file { "/etc/wireguard/${name}.key": ensure => file, mode => "0600", replace => false }` (or an `unless`-style guard) so the dependency is explicit - nit: modules/wireguard/templates/wg.conf.erb:98 — `if @key` is true for an empty string, rendering `PrivateKey = ` → use `String[1]` in the type
unkin-agent added 1 commit 2026-10-03 20:57:08 +10:00
Keep wireguard keys Sensitive and generate missing private keys
ci/woodpecker/pr/ruby-validate Pipeline was successful
ci/woodpecker/pr/puppet-lint Pipeline was successful
ci/woodpecker/pr/yamllint Pipeline was successful
ci/woodpecker/pr/bolt-validate Pipeline was successful
ci/woodpecker/pr/erb-validate Pipeline was successful
ci/woodpecker/pr/epp-validate Pipeline was successful
ci/woodpecker/pr/ruby-check Pipeline was successful
ci/woodpecker/pr/puppet-validate Pipeline was successful
b903c0d641
Author
Member

No findings.

No findings.
benvin merged commit 0272104504 into develop 2026-10-04 14:17:08 +11:00
benvin deleted branch benvin/wireguard-module 2026-10-04 14:17:08 +11:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: unkin/puppet-prod#538