Implemented support for configurable client configuration fragments
This commit is contained in:
parent
49abf8ad21
commit
dc051e9439
@ -1,8 +1,8 @@
|
||||
from configparser import ConfigParser
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
from textwrap import dedent
|
||||
from time import sleep
|
||||
import configparser
|
||||
import ipaddress
|
||||
import json
|
||||
import subprocess
|
||||
@ -72,24 +72,23 @@ def generate_user_serverside_config(config_id: str,
|
||||
user_name: str,
|
||||
client_ip: ipaddress,
|
||||
client_pubkey: str):
|
||||
config = {}
|
||||
config = ConfigParser(allow_no_value=True)
|
||||
config['Peer'] = {
|
||||
f'# {user_name}/{config_id}': None,
|
||||
'PublicKey': client_pubkey,
|
||||
'AllowedIPs': f'{client_ip}/32'
|
||||
}
|
||||
return dict_to_ini(config)
|
||||
return config
|
||||
|
||||
def generate_user_clientside_config(client_ip: str,
|
||||
client_privkey: str,
|
||||
server_address: ipaddress,
|
||||
server_port: int,
|
||||
server_pubkey: str,
|
||||
dns_server: str):
|
||||
config = {}
|
||||
fragment_file: Path=None):
|
||||
config = ConfigParser()
|
||||
config['Interface'] = {
|
||||
'Address': f'{client_ip}/32',
|
||||
'DNS': dns_server,
|
||||
'PrivateKey': client_privkey
|
||||
}
|
||||
config['Peer'] = {
|
||||
@ -97,7 +96,13 @@ def generate_user_clientside_config(client_ip: str,
|
||||
'Endpoint': f'{server_address}:{server_port}',
|
||||
'PublicKey': server_pubkey
|
||||
}
|
||||
return dict_to_ini(config)
|
||||
if fragment_file:
|
||||
fragment = ConfigParser()
|
||||
fragment.read(fragment_file)
|
||||
for section, contents in fragment.items():
|
||||
for key, value in contents.items():
|
||||
config[section][key] = value
|
||||
return config
|
||||
|
||||
def run_wg(*args, input: str=None):
|
||||
result = subprocess.run(['wg', *args],
|
||||
@ -129,14 +134,16 @@ class WireGuard:
|
||||
self.tunnel_id = config['tunnel_id']
|
||||
self.server_address = ipaddress.ip_address(config['server_address'])
|
||||
self.server_port = int(config['server_port'])
|
||||
self.dns_server = ipaddress.ip_address(config['dns_server'])
|
||||
self.client_network = ipaddress.ip_network(config['client_network'])
|
||||
self.configs_base = Path(config['configs_base'])
|
||||
self.max_clients = config.getint('user_client_limit', fallback=0)
|
||||
|
||||
self.server_config_base = None
|
||||
if 'server_extra_config' in config.keys():
|
||||
if 'server_extra_config' in config:
|
||||
self.server_config_base = Path(config['server_extra_config'])
|
||||
self.server_client_base = None
|
||||
if 'client_extra_config' in config:
|
||||
self.client_config_base = Path(config['client_extra_config'])
|
||||
|
||||
self.server_config_file = safe_join(workdir, self.tunnel_id + '.conf')
|
||||
|
||||
@ -193,16 +200,20 @@ class WireGuard:
|
||||
return self.filepath(f'{config_id}{metasuffix}')
|
||||
|
||||
def generate_server_config(self):
|
||||
config = {}
|
||||
config = ConfigParser()
|
||||
config['Interface'] = {
|
||||
'Address': self.server_address,
|
||||
'ListenPort': self.server_port,
|
||||
'PrivateKey': self.server_privkey
|
||||
}
|
||||
server_config = dict_to_ini(config)
|
||||
if self.server_config_base:
|
||||
with open(self.server_config_base, 'r') as cb:
|
||||
server_config += cb.read()
|
||||
fragment = ConfigParser()
|
||||
fragment.read(self.server_config_base)
|
||||
for key, value in fragment['Interface'].items():
|
||||
config['Interface'][key] = value
|
||||
# We need to leave configparser-land here due to lots
|
||||
# of duplicated sections when configuring peers
|
||||
server_config = dict_to_ini(config)
|
||||
for conffile in self.configs_base.glob('*/*'+serversuffix):
|
||||
with open(conffile, 'r') as cf:
|
||||
server_config += '\n' + cf.read()
|
||||
@ -240,17 +251,23 @@ class WireGuard:
|
||||
'minutes')}
|
||||
mf.write(json.dumps(metadata))
|
||||
|
||||
cf.write(generate_user_clientside_config(client_ip,
|
||||
client_privkey,
|
||||
self.server_address,
|
||||
self.server_port,
|
||||
self.server_pubkey,
|
||||
self.dns_server))
|
||||
client_config = generate_user_clientside_config(
|
||||
client_ip,
|
||||
client_privkey,
|
||||
self.server_address,
|
||||
self.server_port,
|
||||
self.server_pubkey,
|
||||
self.client_config_base
|
||||
)
|
||||
client_config.write(cf)
|
||||
|
||||
sf.write(generate_user_serverside_config(config_id,
|
||||
self.user_name,
|
||||
client_ip,
|
||||
client_pubkey))
|
||||
server_config = generate_user_serverside_config(
|
||||
config_id,
|
||||
self.user_name,
|
||||
client_ip,
|
||||
client_pubkey
|
||||
)
|
||||
server_config.write(sf)
|
||||
self.wg_updated = True
|
||||
return client_ip
|
||||
|
||||
@ -286,7 +303,7 @@ class WireGuard:
|
||||
if not path.exists():
|
||||
raise FileNotFoundError(path)
|
||||
|
||||
config = configparser.ConfigParser()
|
||||
config = ConfigParser()
|
||||
config.read(config_path)
|
||||
client_ip = config['Interface']['Address']
|
||||
|
||||
|
@ -24,6 +24,10 @@ client_network = a.network.in.cidr/notation
|
||||
# Optional.
|
||||
server_extra_config = path/to/a/conf/fragment
|
||||
|
||||
# Any extra configuration directives to include in client configs.
|
||||
# Optional. Will override defaults.
|
||||
client_extra_config = path/to/another/fragment
|
||||
|
||||
# The maximum number of clients to allow per user.
|
||||
# Optional, defaults to unlimited, equivalent to setting this value to 0.
|
||||
user_client_limit = 3
|
||||
|
Loading…
x
Reference in New Issue
Block a user