summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2025-04-18 23:53:53 +0300
committerPaul Buetow <paul@buetow.org>2025-04-18 23:53:53 +0300
commit799c111fb47e03b693074374210c8c9c938bc8e7 (patch)
treebf166ea93c9515f10de92a2a832ee8fe7ad41b2c
parent5e4208c5c3014f96bd2d6804ddad8df6907dc7cf (diff)
can generate keys
-rw-r--r--.gitignore1
-rw-r--r--wireguardmeshgenerator.rb82
2 files changed, 61 insertions, 22 deletions
diff --git a/.gitignore b/.gitignore
index 849ddff..fa29eef 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,2 @@
dist/
+keys/
diff --git a/wireguardmeshgenerator.rb b/wireguardmeshgenerator.rb
index ae7ddd4..2a76e73 100644
--- a/wireguardmeshgenerator.rb
+++ b/wireguardmeshgenerator.rb
@@ -1,7 +1,8 @@
-#!/usr/bin/ruby
+#!/usr/bin/env ruby
require 'fileutils'
+WIREGUARD_TOOL = '/usr/bin/wg'.freeze
HOSTS = {
f0: { lan: { domain: 'lan.buetow.org', ip: '192.168.1.130' },
wg0: { domain: 'wg0.buetow.org', ip: '192.168.2.130' } },
@@ -17,45 +18,82 @@ HOSTS = {
wg0: { domain: 'wg0.buetow.org', ip: '192.168.2.122' } }
}.freeze
-PeerSnippet = Struct.new(:description, :public_key, :preshared_key, :allowed_ips) do
+# Generates Wireguard keys and config files for each host
+class KeyTool
+ def initialize(myself)
+ keys_dir = "keys/#{myself}/"
+ FileUtils.mkdir_p(keys_dir) unless Dir.exist?(keys_dir)
+
+ @pubkey_path = "#{keys_dir}/pubkey"
+ @privkey_path = "#{keys_dir}/privkey"
+ @preshared_path = "#{keys_dir}/preshared"
+
+ generate! if !File.exist?(@pubkey_path) ||
+ !File.exist?(@privkey_path) ||
+ !File.exist?(@preshared_path)
+ end
+
+ def pub = File.read(@pubkey_path).strip
+ def priv = File.read(@privkey_path).strip
+ def preshared = File.read(@preshared_path).strip
+
+ private
+
+ def generate! = gen_privpub! && genpsk!
+ def genpsk! = File.write(@preshared_path, `#{WIREGUARD_TOOL} genpsk`)
+
+ def gen_privpub!
+ privkey = IO.popen("#{WIREGUARD_TOOL} genkey", 'r+', &:read)
+ IO.popen("#{WIREGUARD_TOOL} pubkey", 'r+') do |io|
+ io.puts(privkey)
+ io.close_write
+ File.write(@privkey_path, privkey)
+ File.write(@pubkey_path, io.read)
+ end
+ end
+end
+
+PeerSnippet = Struct.new(:myself, :domain, :allowed_ips) do
def to_s
+ keys = KeyTool.new(myself)
<<~PEER_CONFIG
[Peer]
- # #{description}
- PublicKey = #{public_key}
- PresharedKey = #{preshared_key}
- AllowedIPs = #{allowed_ips}
+ # #{myself}.#{domain}
+ PublicKey = #{keys.pub}
+ PresharedKey = #{keys.preshared}
+ AllowedIPs = #{allowed_ips}/32
PEER_CONFIG
end
end
WireguardConfig = Struct.new(:myself, :hosts) do
- @peers = hosts.map do |name, data|
- PeerSnippet.new("#{name}.#{data[:wg0][:domain]}",
- :PUB_KEY, :PRESHARED_KEY, "#{data[:wg0][:ip]}/32")
- end
-
def to_s
+ peers = hosts.reject { _1 == myself }.map do |hostname, data|
+ PeerSnippet.new(hostname, data[:wg0][:domain], data[:wg0][:ip])
+ end
+
+ keys = KeyTool.new(myself)
<<~CONFIG
[Interface]
+ # #{myself}.#{hosts[myself][:wg0][:domain]}
Address = #{hosts[myself][:wg0][:ip]}
- PrivateKey = #{private_key}
+ PrivateKey = #{keys.priv}
+ PresharedKey = #{keys.preshared}
- #{@peers.map(&:to_s).join("\n")}
+ #{peers.map(&:to_s).join("\n")}
CONFIG
end
-
- private
-
- def private_key = 'PRIVATE_KEY'
end
-HOSTS.each_key do |name|
- config_dir = "dist/#{name}/etc/wireguard"
+HOSTS.each_key do |hostname|
+ raise 'Wireguard tool not found' unless File.exist?(WIREGUARD_TOOL)
+
+ config_dir = "dist/#{hostname}/etc/wireguard"
+ key_dir = "keys/#{hostname}/"
config_path = "#{config_dir}/wg0.conf"
- FileUtils.mkdir_p(config_dir) unless Dir.exist?(config_dir)
+ [config_dir, key_dir].each { FileUtils.mkdir_p(_1) unless Dir.exist?(_1) }
- wg0 = WireguardConfig.new(name, HOSTS)
- puts "Generating config for #{name} at #{config_path}"
+ wg0 = WireguardConfig.new(hostname, HOSTS)
+ puts "Generating config for #{hostname} at #{config_path}"
File.write(config_path, wg0.to_s)
end