Setting routes and dealing more robustly with privileged operations
- Created commands.sh, which is now responsible for all operations that require root permissions: addin/deleting routes and reloading wireguard - Added creation and deletion of routes when creating or deleting a client. This *feels* like a bug in wg-quick, considering that the routes are created/deleted as expected on start/stop. Reload informs wireguard of a peer's existence but fails to set routes. For now, this is a suitable workaround.
This commit is contained in:
parent
2a3e529111
commit
bc44648c30
@ -2,6 +2,7 @@ from datetime import datetime
|
||||
from pathlib import Path
|
||||
from textwrap import dedent
|
||||
from time import sleep
|
||||
import configparser
|
||||
import ipaddress
|
||||
import json
|
||||
import subprocess
|
||||
@ -99,6 +100,18 @@ def run_wg(*args, input: str=None):
|
||||
text=True)
|
||||
return result.stdout
|
||||
|
||||
def run_command(command, *args) -> None:
|
||||
command_path = Path().join('command.sh')
|
||||
subprocess.run(['sudo', command_path.absolute(), command, *args])
|
||||
|
||||
def create_route(client_ip: ipaddress) -> None:
|
||||
run_command('add', f'{client_ip}/32')
|
||||
|
||||
def delete_route(client_ip: str) -> None:
|
||||
# We don't add /32 to the ip because it is already included
|
||||
# from the client config
|
||||
run_command('del', client_ip)
|
||||
|
||||
|
||||
class WireGuard:
|
||||
def __init__(self, config: dict):
|
||||
@ -185,13 +198,16 @@ class WireGuard:
|
||||
in self.user_base.glob(f'*{confsuffix}')]
|
||||
|
||||
def generate_config_files(self, *args) -> None:
|
||||
call_with_lock(self._unsafe_generate_config_files, args, 10)
|
||||
client_ip = call_with_lock(self._unsafe_generate_config_files,
|
||||
args,
|
||||
10)
|
||||
create_route(client_ip)
|
||||
|
||||
def _unsafe_generate_config_files(self,
|
||||
config_id: str,
|
||||
name: str,
|
||||
description: str,
|
||||
creation_time: datetime) -> None:
|
||||
creation_time: datetime) -> ipaddress:
|
||||
client_privkey, client_pubkey = generate_keypair()
|
||||
client_ip = self.get_free_ip()
|
||||
with open(self.config_filepath(config_id), 'x') as cf, \
|
||||
@ -216,6 +232,7 @@ class WireGuard:
|
||||
client_ip,
|
||||
client_pubkey))
|
||||
self.wg_updated = True
|
||||
return client_ip
|
||||
|
||||
def update_config(self,
|
||||
config_id: str,
|
||||
@ -241,13 +258,21 @@ class WireGuard:
|
||||
'data': configdata}
|
||||
|
||||
def delete_config(self, config_id: str) -> None:
|
||||
paths = [self.config_filepath(config_id),
|
||||
config_path = self.config_filepath(config_id)
|
||||
paths = [config_path,
|
||||
self.serverconfig_filepath(config_id),
|
||||
self.meta_filepath(config_id)]
|
||||
for path in paths:
|
||||
if not path.exists():
|
||||
raise FileNotFoundError(path)
|
||||
|
||||
config = configparser.ConfigParser()
|
||||
config.read(config_path)
|
||||
client_ip = config['Interface']['Address']
|
||||
|
||||
[path.unlink() for path in paths]
|
||||
delete_route(client_ip)
|
||||
|
||||
self.wg_updated = True
|
||||
|
||||
def update(self) -> None:
|
||||
@ -257,8 +282,5 @@ class WireGuard:
|
||||
sf.write(self.generate_server_config())
|
||||
|
||||
# Sync updated settings to interface
|
||||
subprocess.run(['sudo',
|
||||
'/usr/bin/systemctl',
|
||||
'reload',
|
||||
f'wg-quick@{self.tunnel_id}.service'])
|
||||
run_command('reload')
|
||||
return
|
||||
|
51
commands.sh
Normal file
51
commands.sh
Normal file
@ -0,0 +1,51 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -eu
|
||||
set -o pipefail
|
||||
|
||||
running_dir="$(dirname "$(readlink -f "$0")")"
|
||||
wg_interface="$(grep 'tunnel_id' "$running_dir/config.ini" \
|
||||
| sed -r 's/[^=]+=\s*//')"
|
||||
|
||||
assist() {
|
||||
cat <<EOF
|
||||
Usage: $0 <action> [<ip>]
|
||||
|
||||
Actions:
|
||||
add <ip> Add a route to the tunnel for this ip
|
||||
del <ip> Remove a route to the tunnel for this ip
|
||||
reload Sync running tunnel config with configuration on disk
|
||||
EOF
|
||||
exit "$1"
|
||||
}
|
||||
|
||||
add() {
|
||||
ip route add "$1" dev "$wg_interface" scope link
|
||||
}
|
||||
|
||||
del() {
|
||||
ip route del "$1" dev "$wg_interface" scope link
|
||||
}
|
||||
|
||||
reload() {
|
||||
systemctl reload "wg-quick@$wg_interface.service"
|
||||
}
|
||||
|
||||
if [ "$#" = 0 ]; then
|
||||
assist 0
|
||||
fi
|
||||
|
||||
action="$1"
|
||||
shift
|
||||
|
||||
case "$action" in
|
||||
add )
|
||||
add "$1"
|
||||
;;
|
||||
del )
|
||||
del "$1"
|
||||
;;
|
||||
reload )
|
||||
reload
|
||||
;;
|
||||
esac
|
Loading…
x
Reference in New Issue
Block a user