fix: correct sidebar LAN detection for public access
Deploy Dashboard (Dev) / deploy-dev (push) Successful in 2m27s
Deploy Dashboard (Dev) / deploy-dev (push) Successful in 2m27s
Separate Tailscale IP detection from true LAN detection so public internet users routed through VPS no longer get non-routable port links in the sidebar. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -48,9 +48,10 @@ CHAT_SUMMARY_DB = os.environ.get("CHAT_SUMMARY_DB", "/app/data/chat-summarizer/c
|
||||
OPENCLAW_GATEWAY_TOKEN = os.environ.get("OPENCLAW_GATEWAY_TOKEN", "")
|
||||
|
||||
# Networking configs
|
||||
LAN_IP_RANGES = os.environ.get("LAN_IP_RANGES", "192.168.31.0/24,100.64.0.0/10").split(",")
|
||||
LAN_IP_RANGES = os.environ.get("LAN_IP_RANGES", "192.168.31.0/24").split(",")
|
||||
|
||||
def is_lan_ip(ip_str: str) -> bool:
|
||||
"""Check if IP is in local LAN (not Tailscale)"""
|
||||
import ipaddress
|
||||
try:
|
||||
ip_obj = ipaddress.ip_address(ip_str)
|
||||
@@ -61,6 +62,15 @@ def is_lan_ip(ip_str: str) -> bool:
|
||||
except ValueError:
|
||||
return False
|
||||
|
||||
def is_tailscale_ip(ip_str: str) -> bool:
|
||||
"""Check if IP is in Tailscale CGNAT range (100.64.0.0/10)"""
|
||||
import ipaddress
|
||||
try:
|
||||
ip_obj = ipaddress.ip_address(ip_str)
|
||||
return ip_obj in ipaddress.ip_network("100.64.0.0/10")
|
||||
except ValueError:
|
||||
return False
|
||||
|
||||
TRUSTED_PROXIES = os.environ.get("TRUSTED_PROXIES", "127.0.0.1,::1,172.16.0.0/12").split(",")
|
||||
|
||||
def is_trusted_proxy(ip_str: str) -> bool:
|
||||
|
||||
@@ -134,8 +134,19 @@ async def client_ip(request: Request):
|
||||
forwarded = request.headers.get("x-forwarded-for", "").split(",")[0].strip()
|
||||
if forwarded:
|
||||
ip = forwarded
|
||||
import config
|
||||
lan = config.is_lan_ip(ip) if not ip.startswith("100.") else config.is_lan_ip(ip) and _router_reachable()
|
||||
|
||||
# LAN detection logic:
|
||||
# - True LAN IP (192.168.31.x) → lan=True
|
||||
# - Tailscale IP with router reachable → lan=True (user at home with Tailscale)
|
||||
# - Tailscale IP without router reachable → lan=False (remote via VPS proxy)
|
||||
# - Other IPs → lan=False (public internet)
|
||||
if config.is_lan_ip(ip):
|
||||
lan = True
|
||||
elif config.is_tailscale_ip(ip):
|
||||
lan = _router_reachable()
|
||||
else:
|
||||
lan = False
|
||||
|
||||
return {"lan": lan}
|
||||
|
||||
def _router_reachable():
|
||||
|
||||
Reference in New Issue
Block a user