summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2025-04-28 00:37:13 +0300
committerPaul Buetow <paul@buetow.org>2025-04-28 00:37:13 +0300
commit31d246e69bcc6afe4383e469ce854c3a9831751b (patch)
tree089ca108ac1fb85ff60938ac664276ee4508a152
parent91977db042be28cfdabc65d4466455752861c121 (diff)
add InstallConfig
-rw-r--r--Gemfile2
-rw-r--r--Gemfile.lock5
-rw-r--r--README.md4
-rw-r--r--wireguardmeshgenerator.rb82
-rw-r--r--wireguardmeshgenerator.yaml36
5 files changed, 107 insertions, 22 deletions
diff --git a/Gemfile b/Gemfile
index 2af88db..11db786 100644
--- a/Gemfile
+++ b/Gemfile
@@ -1,3 +1,5 @@
source 'https://rubygems.org'
+gem 'net-scp'
+gem 'net-ssh'
gem 'yaml'
diff --git a/Gemfile.lock b/Gemfile.lock
index 8f5ebd0..17ee478 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -1,6 +1,9 @@
GEM
remote: https://rubygems.org/
specs:
+ net-scp (4.1.0)
+ net-ssh (>= 2.6.5, < 8.0.0)
+ net-ssh (7.3.0)
yaml (0.4.0)
PLATFORMS
@@ -8,6 +11,8 @@ PLATFORMS
x86_64-linux
DEPENDENCIES
+ net-scp
+ net-ssh
yaml
BUNDLED WITH
diff --git a/README.md b/README.md
index 5e4ff3f..55797aa 100644
--- a/README.md
+++ b/README.md
@@ -15,6 +15,8 @@ sudo dnf install -y wireguard-tools
rake
```
+It will generate the configs and scp the configs to the hosts
+
Result:
```sh
@@ -51,8 +53,10 @@ doas pkg upgrade
reboot
doas pkg install wireguard-tools
+doas mv wg0.conf /usr/local/etc/wireguard/
```
+
### Rocky Linux 9
```sh
diff --git a/wireguardmeshgenerator.rb b/wireguardmeshgenerator.rb
index 9c32e45..ad41312 100644
--- a/wireguardmeshgenerator.rb
+++ b/wireguardmeshgenerator.rb
@@ -1,14 +1,17 @@
#!/usr/bin/env ruby
-require 'yaml'
-require 'fileutils'
require 'English'
+require 'fileutils'
+require 'net/scp'
+require 'net/ssh'
+require 'yaml'
-# Generates Wireguard keys and config files for each host
+# Generates Wireguard keys and configuration files for a specified host.
class KeyTool
def initialize(myself)
raise 'Wireguard tool not found' unless system('which wg > /dev/null 2>&1')
+ # Initialize keys directory based on the host
keys_dir = "keys/#{myself}/"
FileUtils.mkdir_p(keys_dir) unless Dir.exist?(keys_dir)
@@ -16,6 +19,7 @@ class KeyTool
@privkey_path = "#{keys_dir}/privkey"
@preshared_path = "#{keys_dir}/preshared"
+ # Generate keys if any key files are missing
generate! if !File.exist?(@pubkey_path) ||
!File.exist?(@privkey_path) ||
!File.exist?(@preshared_path)
@@ -27,21 +31,26 @@ class KeyTool
private
+ # Triggers key generation steps
def generate! = gen_privpub! && genpsk!
+ # Generates the pre-shared key
def genpsk! = File.write(@preshared_path, `wg genpsk`)
+ # Generates private and public key pairs
def gen_privpub!
- privkey = IO.popen('wg genkey', 'r+', &:read)
- IO.popen('wg pubkey', 'r+') do |io|
+ privkey = IO.popen('wg genkey', 'r+', &:read) # Generate private key
+ IO.popen('wg pubkey', 'r+') do |io| # Generate public key from private key
io.puts(privkey)
io.close_write
- File.write(@privkey_path, privkey)
- File.write(@pubkey_path, io.read)
+ File.write(@privkey_path, privkey) # Save private key to file
+ File.write(@pubkey_path, io.read) # Save public key to file
end
end
end
+# PeerSnippet struct representing Wireguard peer details
PeerSnippet = Struct.new(:myself, :domain, :allowed_ips, :endpoint) do
+ # Generates a peer configuration snippet for Wireguard
def to_s
keytool = KeyTool.new(myself)
@@ -56,7 +65,9 @@ PeerSnippet = Struct.new(:myself, :domain, :allowed_ips, :endpoint) do
end
end
+# WireguardConfig struct representing a Wireguard configuration
WireguardConfig = Struct.new(:myself, :hosts) do
+ # Generates the full Wireguard configuration
def to_s
keytool = KeyTool.new(myself)
@@ -72,6 +83,7 @@ WireguardConfig = Struct.new(:myself, :hosts) do
CONFIG
end
+ # Generates the Wireguard configuration and saves it to a file
def generate!
dist_dir = "dist/#{myself}/etc/wireguard"
FileUtils.mkdir_p(dist_dir) unless Dir.exist?(dist_dir)
@@ -79,16 +91,9 @@ WireguardConfig = Struct.new(:myself, :hosts) do
self
end
- def upload!
- ssh_user = hosts[myself]['lan']['ssh_user']
- wg0_conf = "dist/#{myself}/etc/wireguard/wg0.conf"
- puts "Uploading #{wg0_conf} to #{myself}:."
- system("scp #{wg0_conf} #{ssh_user}@#{myself}:.")
- raise "Unable to upload #{wg0_conf} to #{myself}" unless $CHILD_STATUS.success?
- end
-
private
+ # Builds peer snippets for all hosts except the current one
def peers
hosts.reject { _1 == myself }.map do |hostname, data|
PeerSnippet.new(hostname,
@@ -99,7 +104,52 @@ WireguardConfig = Struct.new(:myself, :hosts) do
end
end
+# This is responsible for handling the installation process of the wireguard configuration.
+InstallConfig = Struct.new(:myself, :hosts) do
+ def initialize(myself, hosts)
+ @ssh_user = hosts[myself]['ssh']['user']
+ @sudo_cmd = hosts[myself]['ssh']['sudo_cmd']
+ @restart_cmd = hosts[myself]['ssh']['restart_cmd']
+ end
+
+ # Uploads the configuration file to a remote host
+ def upload!
+ wg0_conf = "dist/#{myself}/etc/wireguard/wg0.conf"
+ puts "Uploading #{wg0_conf} to #{myself}:."
+ raise "Upload to #{myself} failed" unless Net::SCP.upload!(myself, @ssh_user, wg0_conf, '.')
+
+ self
+ end
+
+ # Installs the Wireguard configuration on the remote host
+ def install!
+ puts "Installing Wireguard config on #{myself}"
+
+ ssh <<~SH
+ if [ ! -d #{@config_path} ]; then
+ #{@sudo_cmd} mkdir -p #{@config_path}
+ #{@sudo_cmd} mv -v wg0.conf #{@config_path}
+ #{@sudo_cmd} #{@restart_cmd}
+ fi
+ SH
+
+ raise "Unable to install Wireguard config on #{myself}" unless $CHILD_STATUS.success?
+
+ self
+ end
+
+ private
+
+ def ssh(command)
+ Net::SSH.start(myself, @ssh_user) do |ssh|
+ ssh.exec!(command)
+ end
+ end
+end
+
+# Load configuration file and generate, upload, and install Wireguard configs for all hosts
CONFIG = YAML.load_file('wireguardmeshgenerator.yaml').freeze
CONFIG['hosts'].each_key do |hostname|
- WireguardConfig.new(hostname, CONFIG['hosts']).generate!.upload!
+ WireguardConfig.new(hostname, CONFIG['hosts']).generate!
+ InstallConfig.new(hostname, CONFIG['hosts']).upload!.install!
end
diff --git a/wireguardmeshgenerator.yaml b/wireguardmeshgenerator.yaml
index a123b83..e58f869 100644
--- a/wireguardmeshgenerator.yaml
+++ b/wireguardmeshgenerator.yaml
@@ -2,48 +2,72 @@
wg_tool: /usr/bin/wg
hosts:
f0:
+ ssh:
+ user: paul
+ config_dir: /usr/local/etc/wireguard
+ sudo_cmd: doas
+ restart_cmd: doas service restart wireguard
lan:
- ssh_user: paul
domain: 'lan.buetow.org'
ip: '192.168.1.130'
wg0:
domain: 'wg0.buetow.org'
ip: '192.168.2.130'
f1:
+ ssh:
+ user: paul
+ config_dir: /usr/local/etc/wireguard
+ sudo_cmd: doas
+ restart_cmd: doas service restart wireguard
lan:
- ssh_user: paul
domain: 'lan.buetow.org'
ip: '192.168.1.131'
wg0:
domain: 'wg0.buetow.org'
ip: '192.168.2.131'
f2:
+ ssh:
+ user: paul
+ config_dir: /usr/local/etc/wireguard
+ sudo_cmd: doas
+ restart_cmd: doas service restart wireguard
lan:
- ssh_user: paul
domain: 'lan.buetow.org'
ip: '192.168.1.132'
wg0:
domain: 'wg0.buetow.org'
ip: '192.168.2.132'
r0:
+ ssh:
+ user: root
+ config_dir: /usr/local/etc/wireguard
+ sudo_cmd:
+ restart_cmd: service restart wireguard
lan:
- ssh_user: root
domain: 'lan.buetow.org'
ip: '192.168.1.120'
wg0:
domain: 'wg0.buetow.org'
ip: '192.168.2.120'
r1:
+ ssh:
+ user: root
+ config_dir: /usr/local/etc/wireguard
+ sudo_cmd:
+ restart_cmd: service restart wireguard
lan:
- ssh_user: root
domain: 'lan.buetow.org'
ip: '192.168.1.121'
wg0:
domain: 'wg0.buetow.org'
ip: '192.168.2.121'
r2:
+ ssh:
+ user: root
+ config_dir: /usr/local/etc/wireguard
+ sudo_cmd:
+ restart_cmd: service restart wireguard
lan:
- ssh_user: root
domain: 'lan.buetow.org'
ip: '192.168.1.122'
wg0: