Fix race condition in ensure_forward_stateful: add threading.Lock
Concurrent callers (health monitor + startup) could both pass the delete-all loop and each insert a copy, producing duplicate ESTABLISHED,RELATED rules. Lock serialises all calls. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+17
-13
@@ -8,10 +8,13 @@ import os
|
||||
import subprocess
|
||||
import logging
|
||||
import re
|
||||
import threading
|
||||
from typing import Dict, List, Any, Optional
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
_forward_stateful_lock = threading.Lock()
|
||||
|
||||
# Virtual IPs assigned to Caddy per service — must match Caddyfile listeners.
|
||||
# Populated at import time from the default subnet; call update_service_ips()
|
||||
# whenever ip_range changes so all downstream callers see the new values.
|
||||
@@ -459,19 +462,20 @@ def ensure_forward_stateful() -> bool:
|
||||
which pushes this rule down every time wg0 restarts — causing ICMP to hit the
|
||||
per-peer DROP rule before reaching the stateful ACCEPT.
|
||||
"""
|
||||
try:
|
||||
# Remove all existing instances so we can re-anchor at position 1.
|
||||
# PostUp -I FORWARD rules drift this rule down on every wg0 restart.
|
||||
while _wg_exec(['iptables', '-D', 'FORWARD', '-m', 'state',
|
||||
'--state', 'ESTABLISHED,RELATED', '-j', 'ACCEPT']).returncode == 0:
|
||||
pass
|
||||
_wg_exec(['iptables', '-I', 'FORWARD', '1', '-m', 'state',
|
||||
'--state', 'ESTABLISHED,RELATED', '-j', 'ACCEPT'])
|
||||
logger.info('ensure_forward_stateful: ESTABLISHED,RELATED anchored at FORWARD position 1')
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.error(f'ensure_forward_stateful: {e}')
|
||||
return False
|
||||
with _forward_stateful_lock:
|
||||
try:
|
||||
# Remove all existing instances so we can re-anchor at position 1.
|
||||
# PostUp -I FORWARD rules drift this rule down on every wg0 restart.
|
||||
while _wg_exec(['iptables', '-D', 'FORWARD', '-m', 'state',
|
||||
'--state', 'ESTABLISHED,RELATED', '-j', 'ACCEPT']).returncode == 0:
|
||||
pass
|
||||
_wg_exec(['iptables', '-I', 'FORWARD', '1', '-m', 'state',
|
||||
'--state', 'ESTABLISHED,RELATED', '-j', 'ACCEPT'])
|
||||
logger.info('ensure_forward_stateful: ESTABLISHED,RELATED anchored at FORWARD position 1')
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.error(f'ensure_forward_stateful: {e}')
|
||||
return False
|
||||
|
||||
|
||||
def ensure_cell_api_dnat() -> bool:
|
||||
|
||||
Reference in New Issue
Block a user