Fixing proxy subscriptions

This commit is contained in:
SimplifiedPrivacy 2026-07-19 15:33:36 -04:00
parent 2ccbdba06b
commit a116597a38
3 changed files with 144 additions and 15 deletions

View file

@ -59,18 +59,21 @@ def _ensure_proxy_configured(
if not profile.connection.needs_proxy_configuration(): if not profile.connection.needs_proxy_configuration():
return return
_ensure_subscription_ready(profile, connection_observer) if not profile.has_proxy_configuration():
logger.info(f"[CONNECTION] You need a new proxy configuration")
proxy_config = ConnectionController.with_preferred_connection( _ensure_subscription_ready(profile, connection_observer)
profile.subscription.billing_code,
task=WebServiceApiService.get_proxy_configuration, logger.info(f"[CONNECTION] Getting a proxy config from web service..")
connection_observer=connection_observer proxy_config = ConnectionController.with_preferred_connection(
) profile.subscription.billing_code,
task=WebServiceApiService.get_proxy_configuration,
if proxy_config is None: connection_observer=connection_observer
raise InvalidSubscriptionError() )
profile.attach_proxy_configuration(proxy_config) if proxy_config is None:
raise InvalidSubscriptionError()
profile.attach_proxy_configuration(proxy_config)
def _ensure_wireguard_configured( def _ensure_wireguard_configured(
@ -126,4 +129,12 @@ def __should_renegotiate(profile: Union[SessionProfile, SystemProfile]):
if profile.subscription.has_been_activated(): if profile.subscription.has_been_activated():
return True return True
else: else:
return False return False
# Enums
# if profile.type == ProfileType.SYSTEM:
# print("This is a system profile")
# elif profile.type == ProfileType.SESSION:
# print("This is a session profile")

View file

@ -0,0 +1,118 @@
#!/bin/bash
set -euo pipefail
# root check
if [[ "$EUID" -ne 0 ]]; then
echo "[killswitch] ERROR: must be run as root" >&2
exit 1
fi
ACTION="${1:-}"
SERVER_IP="${2:-}"
TUNNEL_IF="${3:-}"
TABLE="hydraveil"
# Confirm the action is among the valid choices:
if [[ "$ACTION" != "arm" && "$ACTION" != "disarm" && "$ACTION" != "status" ]]; then
echo "[killswitch] ERROR: invalid action '$ACTION'. Usage: arm <server_ip> <tunnel_if> | disarm | status" >&2
exit 1
fi
# This function gets the default route. The function is used during the arm phase later on.
_default_iface() {
ip route show default 2>/dev/null | awk 'NR==1{print $5}'
}
# Log changes in the rules:
_log() {
local level="$1"; shift
echo "[killswitch] [$level] $*$(date '+%Y-%m-%d %H:%M:%S')" >&2
}
# use the presence of the table to detect if the rules are active, which we define as "armed"
if [[ "$ACTION" == "status" ]]; then
if nft list table inet "$TABLE" &>/dev/null 2>&1; then
echo "armed"
else
echo "disarmed"
fi
exit 0
fi
# If disarm is chosen, then check if the table rules exist, and if so, delete the table. Then log it.
if [[ "$ACTION" == "disarm" ]]; then
if nft list table inet "$TABLE" &>/dev/null 2>&1; then
nft delete table inet "$TABLE"
_log "INFO" "disarmed"
else
_log "INFO" "already disarmed"
fi
exit 0
fi
# Check the pre-reqs exist. We need a server IP and a tunnel interface.
[[ -z "$SERVER_IP" ]] && { _log "ERROR" "server_ip required for arm"; exit 1; }
[[ -z "$TUNNEL_IF" ]] && { _log "ERROR" "tunnel_if required for arm"; exit 1; }
# Confirm the IPv4 address is a valid format. But does NOT check if it's actually a live server.
# Just that it looks like an IPv4 address.
if ! [[ "$SERVER_IP" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then
_log "ERROR" "invalid IPv4: $SERVER_IP"
exit 1
fi
IFS='.' read -r o1 o2 o3 o4 <<< "$SERVER_IP"
for oct in "$o1" "$o2" "$o3" "$o4"; do
if (( oct > 255 )); then
_log "ERROR" "invalid IPv4 octet ($oct) in $SERVER_IP"
exit 1
fi
done
# This uses the function at the top of the file to get the default WAN interface, and then checks that it got a result.
WAN_IFACE=$(_default_iface)
if [[ -z "$WAN_IFACE" ]]; then
_log "ERROR" "could not detect primary network interface"
exit 1
fi
# Either list out the table rules and delete them, or return True.
nft list table inet "$TABLE" &>/dev/null 2>&1 && nft delete table inet "$TABLE" || true
table inet ${TABLE} {
chain output {
type filter hook output priority filter; policy drop;
# Allow all loopback traffic (localhost)
oifname "lo" accept
# Drop all IPv6 except loopback (::1). This blocks IPv6 from leaving the system entirely
ip6 daddr != ::1 drop
# Allow IPv4 traffic to the server IP on the WAN interface
oifname "${WAN_IFACE}" ip daddr ${SERVER_IP} accept
# Allow all traffic (IPv4 and IPv6) on the WireGuard tunnel interface
oifname "${TUNNEL_IF}" accept
}
chain input {
type filter hook input priority filter; policy drop;
# Allow all loopback traffic (localhost)
iifname "lo" accept
# Drop all IPv6 except loopback (::1). This blocks IPv6 from entering the system entirely
ip6 saddr != ::1 drop
# Allow established and related connections (stateful firewall tracking)
ct state established,related accept
# Allow IPv4 traffic from the server IP on the WAN interface
iifname "${WAN_IFACE}" ip saddr ${SERVER_IP} accept
# Allow all traffic (IPv4 and IPv6) from the WireGuard tunnel interface
iifname "${TUNNEL_IF}" accept
}
chain forward {
type filter hook forward priority filter; policy drop;
# Drop all forwarded traffic (nothing is routed through this system)
}
}

View file

@ -45,7 +45,7 @@ dependencies = [
"typing-inspection==0.4.2", "typing-inspection==0.4.2",
"typing_extensions==4.15.0", "typing_extensions==4.15.0",
"urllib3==2.6.3", "urllib3==2.6.3",
"httpx==0.28.1", "httpx[http2]==0.28.1",
"dnspython==2.8.0", "dnspython==2.8.0",
"socksio==1.0.0", "socksio==1.0.0",
] ]
@ -59,4 +59,4 @@ requires = ["hatchling"]
build-backend = "hatchling.build" build-backend = "hatchling.build"
[tool.hatch.build.targets.wheel] [tool.hatch.build.targets.wheel]
packages = ["core"] packages = ["core"]-