fix: cross-cell routing for split-tunnel peers
Three related fixes for split-tunnel peers that need to reach connected cells: 1. apply_peer_rules/apply_all_peer_rules now accept wg_subnet (actual local VPN subnet) and cell_subnets (connected cells' vpn_subnets) parameters instead of hardcoding 10.0.0.0/24. All callers (startup, add_peer, update_peer, apply-enforcement endpoint) pass the real values. 2. Explicit ACCEPT rules are inserted in FORWARD for each connected cell's subnet so split-tunnel peers (internet_access=False) can still reach connected cells via the wg0→wg0 path. 3. apply_ip_range in network_manager now loads cell_links.json and passes it to generate_corefile(), fixing a race where the bootstrap DNS thread could overwrite the Corefile and wipe cross-cell DNS forwarding zones on startup. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+20
-3
@@ -38,6 +38,13 @@ def add_peer():
|
||||
from app import (peer_registry, wireguard_manager, firewall_manager,
|
||||
email_manager, calendar_manager, file_manager, auth_manager,
|
||||
cell_link_manager, _configured_domain, COREFILE_PATH)
|
||||
try:
|
||||
_wg_addr = wireguard_manager._get_configured_address()
|
||||
_wg_subnet = str(ipaddress.ip_network(_wg_addr, strict=False)) if _wg_addr else '10.0.0.0/24'
|
||||
except Exception:
|
||||
_wg_subnet = '10.0.0.0/24'
|
||||
_cell_links = cell_link_manager.list_connections()
|
||||
_cell_subnets = [l['vpn_subnet'] for l in _cell_links if l.get('vpn_subnet')]
|
||||
data = request.get_json(silent=True)
|
||||
if data is None:
|
||||
return jsonify({"error": "No data provided"}), 400
|
||||
@@ -118,7 +125,8 @@ def add_peer():
|
||||
return jsonify({"error": f"Peer {peer_name} already exists"}), 400
|
||||
peer_added_to_registry = True
|
||||
|
||||
firewall_manager.apply_peer_rules(peer_info['ip'], peer_info)
|
||||
firewall_manager.apply_peer_rules(peer_info['ip'], peer_info,
|
||||
wg_subnet=_wg_subnet, cell_subnets=_cell_subnets)
|
||||
firewall_applied = True
|
||||
|
||||
wg_allowed = f"{assigned_ip}/32" if '/' not in assigned_ip else assigned_ip
|
||||
@@ -153,7 +161,15 @@ def add_peer():
|
||||
@bp.route('/api/peers/<peer_name>', methods=['PUT'])
|
||||
def update_peer(peer_name):
|
||||
try:
|
||||
from app import peer_registry, firewall_manager, cell_link_manager, _configured_domain, COREFILE_PATH
|
||||
from app import (peer_registry, wireguard_manager, firewall_manager,
|
||||
cell_link_manager, _configured_domain, COREFILE_PATH)
|
||||
try:
|
||||
_wg_addr = wireguard_manager._get_configured_address()
|
||||
_wg_subnet = str(ipaddress.ip_network(_wg_addr, strict=False)) if _wg_addr else '10.0.0.0/24'
|
||||
except Exception:
|
||||
_wg_subnet = '10.0.0.0/24'
|
||||
_cell_links = cell_link_manager.list_connections()
|
||||
_cell_subnets = [l['vpn_subnet'] for l in _cell_links if l.get('vpn_subnet')]
|
||||
data = request.get_json(silent=True) or {}
|
||||
existing = peer_registry.get_peer(peer_name)
|
||||
if not existing:
|
||||
@@ -173,7 +189,8 @@ def update_peer(peer_name):
|
||||
if success:
|
||||
updated_peer = peer_registry.get_peer(peer_name)
|
||||
if updated_peer:
|
||||
firewall_manager.apply_peer_rules(updated_peer['ip'], updated_peer)
|
||||
firewall_manager.apply_peer_rules(updated_peer['ip'], updated_peer,
|
||||
wg_subnet=_wg_subnet, cell_subnets=_cell_subnets)
|
||||
firewall_manager.apply_all_dns_rules(peer_registry.list_peers(), COREFILE_PATH, _configured_domain(),
|
||||
cell_links=cell_link_manager.list_connections())
|
||||
return jsonify({"message": f"Peer {peer_name} updated", "config_changed": config_changed})
|
||||
|
||||
+12
-3
@@ -1,4 +1,5 @@
|
||||
import logging
|
||||
import ipaddress
|
||||
from flask import Blueprint, request, jsonify
|
||||
logger = logging.getLogger('picell')
|
||||
bp = Blueprint('wireguard', __name__)
|
||||
@@ -221,11 +222,19 @@ def refresh_external_ip():
|
||||
@bp.route('/api/wireguard/apply-enforcement', methods=['POST'])
|
||||
def apply_wireguard_enforcement():
|
||||
try:
|
||||
from app import peer_registry, firewall_manager, cell_link_manager, _configured_domain, COREFILE_PATH
|
||||
from app import (peer_registry, wireguard_manager, firewall_manager,
|
||||
cell_link_manager, _configured_domain, COREFILE_PATH)
|
||||
peers = peer_registry.list_peers()
|
||||
firewall_manager.apply_all_peer_rules(peers)
|
||||
try:
|
||||
_wg_addr = wireguard_manager._get_configured_address()
|
||||
_wg_subnet = str(ipaddress.ip_network(_wg_addr, strict=False)) if _wg_addr else '10.0.0.0/24'
|
||||
except Exception:
|
||||
_wg_subnet = '10.0.0.0/24'
|
||||
_cell_links = cell_link_manager.list_connections()
|
||||
_cell_subnets = [l['vpn_subnet'] for l in _cell_links if l.get('vpn_subnet')]
|
||||
firewall_manager.apply_all_peer_rules(peers, wg_subnet=_wg_subnet, cell_subnets=_cell_subnets)
|
||||
firewall_manager.apply_all_dns_rules(peers, COREFILE_PATH, _configured_domain(),
|
||||
cell_links=cell_link_manager.list_connections())
|
||||
cell_links=_cell_links)
|
||||
return jsonify({'ok': True, 'peers': len(peers)})
|
||||
except Exception as e:
|
||||
return jsonify({'error': str(e)}), 500
|
||||
|
||||
Reference in New Issue
Block a user