Skip to content

Commit

Permalink
tunspace: always use a new ephemeral private key
Browse files Browse the repository at this point in the history
- filesystem access not need anymore
- don't run into wginstaller's key registration timeouts
  • Loading branch information
pktpls committed Sep 19, 2024
1 parent 6208791 commit ee60f28
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 21 deletions.
1 change: 0 additions & 1 deletion packages/tunspace/tunspace.defaults
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ config wg-interface
option ipv4 "10.31.174.138/32"
option mtu 1280
option port 51820
option keyfile "/etc/tunspace/ts_wg0.key"
option disabled 0
EOT
Expand Down
15 changes: 0 additions & 15 deletions packages/tunspace/tunspace.init
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ boot() {

start_service() {
config_load tunspace
config_foreach gen_wg_key "wg-interface"

procd_open_instance
procd_set_param command /usr/bin/tunspace
Expand All @@ -36,20 +35,6 @@ stop_service() {
del_uplink_netns
}

gen_wg_key() {
local section="$1"
local _value keyfile
config_get keyfile "$section" keyfile
test -n "$keyfile" || return # path is empty, skip
test -s "$keyfile" && return # keyfile exists, skip
mkdir -p "$(dirname "$keyfile")"

config_get _value "$section" ifname
logger -t tunspace "generating private key for $_value, this could take a while..."
head -c32 /dev/random | ucode -lfs -p 'b64enc(fs.stdin.read("all"));' > "$keyfile"
logger -t tunspace "finished generating key for $_value"
}

del_wg_iface() {
local section="$1"
local _value
Expand Down
26 changes: 21 additions & 5 deletions packages/tunspace/tunspace.uc
Original file line number Diff line number Diff line change
Expand Up @@ -57,15 +57,11 @@ function load_config(name) {
});

ctx.foreach(name, "wg-interface", function(c) {
let key = fs.readfile(""+c.keyfile);
assert(key, fs.error());

cfg.wireguard_interfaces[""+c.ifname] = {
"ipv6": ""+c.ipv6,
"ipv4": ""+c.ipv4,
"mtu": int(c.mtu),
"port": int(c.port),
"private_key": rtrim(key),
"disabled": int(c.disabled) != 0,
};
});
Expand Down Expand Up @@ -199,7 +195,6 @@ function create_wg_interface(nsid, ifname, ifcfg, netns) {
wg_request(wg.const.WG_CMD_SET_DEVICE, wg.const.NLM_F_REQUEST, {
"ifname": ifname,
"listenPort": ifcfg.port,
"privateKey": ifcfg.private_key
});
if (err = wg.error()) {
log("WG_CMD_SET_DEVICE failed: "+err);
Expand Down Expand Up @@ -247,6 +242,24 @@ function wg_interface_ok(st, ifname) {
function wg_replace_endpoint(ifname, cfg, url) {
let ifcfg = cfg.wireguard_interfaces[ifname];

// generate a fresh private key
let randfd = fs.open("/dev/random");
let privkey = randfd.read(32);
randfd.close();
if (length(privkey) < 32) {
log("failed to read 32 bytes from /dev/random");
return false;
}
let reply = wg_request(wg.const.WG_CMD_SET_DEVICE, wg.const.NLM_F_REQUEST, {
"ifname": ifname,
"privateKey": b64enc(privkey),
});
if (err = wg.error()) {
log("WG_CMD_SET_DEVICE failed: "+err);
return false;
}

// get the public key for registration
let reply = wg_request(wg.const.WG_CMD_GET_DEVICE,
rtnl.const.NLM_F_REQUEST|rtnl.const.NLM_F_DUMP, {
"ifname": ifname,
Expand All @@ -261,6 +274,7 @@ function wg_replace_endpoint(ifname, cfg, url) {
}
let pubkey = reply[0].publicKey;

// ubus login on the tunnel server
let msg = {
"jsonrpc": "2.0",
"id": 1,
Expand All @@ -286,6 +300,7 @@ function wg_replace_endpoint(ifname, cfg, url) {
}
let sid = reply.result[1].ubus_rpc_session;

// tunnel registration
let msg = {
"jsonrpc": "2.0",
"id": 1,
Expand Down Expand Up @@ -319,6 +334,7 @@ function wg_replace_endpoint(ifname, cfg, url) {
"endpoint": replace(url, regexp('^https?://([^/]+).*$'), '$1:'+reply.result[1].gw_port),
};

// set tunnel server as our peer
let reply = wg_request(wg.const.WG_CMD_SET_DEVICE, wg.const.NLM_F_REQUEST, {
"ifname": ifname,
"flags": wg.const.WGDEVICE_F_REPLACE_PEERS,
Expand Down

0 comments on commit ee60f28

Please sign in to comment.