read pubkey from wireguard privkey

This commit is contained in:
Jamil Bou Kheir
2020-12-26 12:12:20 -06:00
parent d9ab70469c
commit 2e1afa6e79
6 changed files with 36 additions and 39 deletions

View File

@@ -58,6 +58,13 @@ defmodule FgVpn.CLI do
{privkey, pubkey}
end
def pubkey(privkey) when is_nil(privkey), do: nil
def pubkey(privkey) when is_binary(privkey) do
exec("echo #{privkey} | wg pubkey")
|> String.trim()
end
defp exec(cmd) do
case System.cmd("bash", ["-c", cmd]) do
{result, 0} ->

View File

@@ -55,6 +55,7 @@ defmodule FgVpn.Config do
def read_privkey do
read_config_file()
|> extract_privkey()
|> (&{&1, CLI.pubkey(&1)}).()
end
defp extract_privkey(config_str) do
@@ -95,10 +96,14 @@ defmodule FgVpn.Config do
end
defp interface_to_config(config) do
# XXX: Use config listen_port here
listen_port =
Application.get_env(:fg_http, :vpn_endpoint)
|> String.split(":")
|> List.last()
~s"""
[Interface]
ListenPort = 51820
ListenPort = #{listen_port}
PrivateKey = #{config[:privkey]}
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o #{
config[:default_int]
@@ -136,13 +141,16 @@ defmodule FgVpn.Config do
end
defp read_and_rewrite_config do
{privkey, pubkey} = read_privkey() || CLI.genkey()
config = %{
default_int: CLI.default_interface(),
privkey: read_privkey() || elem(CLI.genkey(), 0),
privkey: privkey,
peers: read_peers() || []
}
write!(config)
Application.put_env(:fg_vpn, :pubkey, pubkey)
config
end

View File

@@ -13,4 +13,10 @@ defmodule FgVpn.CLITest do
assert is_binary(privkey)
assert is_binary(pubkey)
end
test "pubkey" do
{privkey, pubkey} = CLI.genkey()
assert pubkey == CLI.pubkey(privkey)
end
end

View File

@@ -2,6 +2,8 @@ defmodule FgVpn.ConfigTest do
use ExUnit.Case, async: true
alias FgVpn.Config
@test_privkey "GMqk2P3deotcQqgqJHfLGB1JtU//f1FgX868bfPKSVc="
@empty """
"""
@@ -16,16 +18,18 @@ defmodule FgVpn.ConfigTest do
@privkey """
[Interface]
ListenPort = 51820
PrivateKey = test-privkey
PrivateKey = GMqk2P3deotcQqgqJHfLGB1JtU//f1FgX868bfPKSVc=
"""
@rendered_privkey "kPCNOTbBoHC/j5daxhMHcZ+PeNr6oaA8qIWcBuFlM0s="
@rendered_config """
# This file is being managed by the fireguard systemd service. Any changes
# will be overwritten eventually.
[Interface]
ListenPort = 51820
PrivateKey = rendered-privkey
PrivateKey = kPCNOTbBoHC/j5daxhMHcZ+PeNr6oaA8qIWcBuFlM0s=
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o noop -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o noop -j MASQUERADE
@@ -59,7 +63,7 @@ defmodule FgVpn.ConfigTest do
assert %{
peers: [],
default_int: _,
privkey: "test-privkey"
privkey: @test_privkey
} = :sys.get_state(test_pid)
end
@@ -105,7 +109,7 @@ defmodule FgVpn.ConfigTest do
test "renders config" do
assert Config.render(%{
default_int: "noop",
privkey: "rendered-privkey",
privkey: @rendered_privkey,
peers: ["test-pubkey"]
}) == @rendered_config
end

View File

@@ -28,13 +28,6 @@ live_view_signing_salt =
/opt/fireguard/config.env
"""
pubkey =
System.get_env("PUBKEY") ||
raise """
Environment variable PUBKEY is missing. Please generate
with the "wg" utility.
"""
ssl_cert_file =
System.get_env("SSL_CERT_FILE") ||
raise """
@@ -66,7 +59,9 @@ wg_listen_port = System.get_env("WG_LISTEN_PORT" || "51820")
wg_listen_address = System.get_env("WG_LISTEN_ADDRESS") || "localhost"
url_host = System.get_env("URL_HOST") || "localhost"
config :fg_vpn, pubkey: pubkey
# Will be replaced when FgVpn starts up and config is rewritten
config :fg_vpn, pubkey: nil
config :fg_http, disable_signup: disable_signup
config :fg_http, FgHttp.Repo,

View File

@@ -29,9 +29,8 @@ sudo -i -u postgres psql -c "CREATE ROLE ${db_user} WITH LOGIN PASSWORD '${db_pa
sudo -i -u postgres psql -c "CREATE DATABASE fireguard;" || true
sudo -i -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE fireguard to ${db_user};" || true
# Generate WireGuard priv/pubkeys
# Generate WireGuard privkey
privkey=$(wg genkey)
pubkey=$(echo ${privkey} | wg pubkey)
# Write FireGuard SSL files
mkdir -p /opt/fireguard/ssl
@@ -67,12 +66,6 @@ SECRET_KEY_BASE="${secret_key_base}"
# user has privileges to create and modify tables.
DATABASE_URL="ecto://${db_user}:${db_password}@127.0.0.1/fireguard"
# The public key for the WireGuard interface controlled by FireGuard.
# This should match what's in the WireGuard config at
# /etc/wireguard/wg-fireguard.conf.
# Re-generate this using the "wg" utility, e.g. "wg genkey | wg pubkey"
PUBKEY="${pubkey}"
# The HTTPS port to listen on. Defaults to 8800.
HTTPS_LISTEN_PORT=8800
@@ -102,21 +95,5 @@ URL_HOST=${hostname}
DISABLE_SIGNUP=yes
EOT
# Grab default route interface
default_int=$(route | grep '^default' | grep -o '[^ ]*$')
# Write WireGuard config file
# XXX: Figure out whether to write config using postinst script or via Elixir
# process. Elixir process decouples packaging logic from configuration
# management a bit more.
cat <<EOT >> /opt/fireguard/wg-fireguard.conf
[Interface]
ListenPort = 51820
PrivateKey = ${privkey}
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o ${default_int} -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o ${default_int} -j MASQUERADE
EOT
systemctl enable fireguard
systemctl start fireguard