fix: config persistence, setup script, and install docs
- app.py: ConfigManager now uses CONFIG_DIR env var for config file path instead of hardcoded './config/cell_config.json' — config was being read from the image's working directory, making all settings writes ephemeral (lost on container restart) - wireguard_manager: generate_config uses configured address/port instead of hardcoded 10.0.0.1 in DNAT rules and Address field - scripts/setup_cell.py: full setup script — generates WireGuard keys (wg binary or Python cryptography fallback), writes wg0.conf and cell_config.json with correct _identity key; CELL_NAME / VPN_ADDRESS / WG_PORT env vars - Makefile: setup target passes env vars through; build-api / build-webui targets - README: replace install.sh references with make setup && make start Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -112,23 +112,25 @@ class WireGuardManager(BaseServiceManager):
|
||||
|
||||
def generate_config(self, interface: str = 'wg0', port: int = DEFAULT_PORT) -> str:
|
||||
"""Return a WireGuard [Interface] config string for the server."""
|
||||
import ipaddress
|
||||
keys = self.get_keys()
|
||||
ext_ip = self.get_external_ip() or ''
|
||||
# Hairpin DNAT: redirect VPN clients targeting the server's public IP
|
||||
# to 10.0.0.1 (the VPN interface), avoiding the Docker network loopback.
|
||||
address = self._get_configured_address() if os.path.exists(self._config_file()) else SERVER_ADDRESS
|
||||
server_ip = str(ipaddress.ip_interface(address).ip)
|
||||
hairpin = (
|
||||
f'iptables -t nat -A PREROUTING -i %i -d {ext_ip} -j DNAT --to-destination 10.0.0.1; '
|
||||
f'iptables -t nat -A PREROUTING -i %i -d {ext_ip} -j DNAT --to-destination {server_ip}; '
|
||||
if ext_ip else ''
|
||||
)
|
||||
hairpin_down = (
|
||||
f'iptables -t nat -D PREROUTING -i %i -d {ext_ip} -j DNAT --to-destination 10.0.0.1; '
|
||||
f'iptables -t nat -D PREROUTING -i %i -d {ext_ip} -j DNAT --to-destination {server_ip}; '
|
||||
if ext_ip else ''
|
||||
)
|
||||
cfg_port = self._get_configured_port() if os.path.exists(self._config_file()) else port
|
||||
return (
|
||||
f'[Interface]\n'
|
||||
f'PrivateKey = {keys["private_key"]}\n'
|
||||
f'Address = {SERVER_ADDRESS}\n'
|
||||
f'ListenPort = {port}\n'
|
||||
f'Address = {address}\n'
|
||||
f'ListenPort = {cfg_port}\n'
|
||||
f'PostUp = iptables -A FORWARD -i %i -j ACCEPT; '
|
||||
f'iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE; '
|
||||
f'{hairpin}'
|
||||
|
||||
Reference in New Issue
Block a user