From 5d5f736e1bb9aa223599cd696460e808e67a5f9f Mon Sep 17 00:00:00 2001 From: nessi Date: Thu, 19 Mar 2026 22:26:03 +0100 Subject: [PATCH] refactor: move default destination fallback after profile resolution and add nftables input chain filtering for VPN clients Move default 172.16.10.0/24 destination assignment to after profile resolution and only apply when both selectedDestinations and services are empty. Extract selectedServices calculation before conditional check in applyCurrentPolicy. Add nftables input chain to gateway with per-peer filtering. Accept established connections and non-WireGuard traffic. Allow DNS queries to configured --- backend/internal/device/service.go | 10 +++++----- deploy/scripts/gateway-entrypoint.sh | 22 ++++++++++++++++++++++ 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/backend/internal/device/service.go b/backend/internal/device/service.go index 4874fcf..a2fa16c 100644 --- a/backend/internal/device/service.go +++ b/backend/internal/device/service.go @@ -61,13 +61,13 @@ func (s *Service) Enroll(ctx context.Context, userID uuid.UUID, input EnrollRequ if err != nil { return EnrollmentResponse{}, err } - if len(destinations) == 0 { - destinations = []string{"172.16.10.0/24"} - } availableProfiles, selectedProfileID, selectedDestinations, err := s.resolveAccessProfiles(ctx, userID, enrollment.Device.ID) if err != nil { return EnrollmentResponse{}, err } + if len(selectedDestinations) == 0 && len(servicesForSelectedProfile(availableProfiles, selectedProfileID)) == 0 { + selectedDestinations = []string{"172.16.10.0/24"} + } if len(selectedDestinations) == 0 { selectedDestinations = destinations } @@ -215,11 +215,11 @@ func (s *Service) applyCurrentPolicy(ctx context.Context, enrollment EnrollmentR if err != nil { return EnrollmentResponse{}, err } - if len(selectedDestinations) == 0 { + selectedServices := servicesForSelectedProfile(availableProfiles, selectedProfileID) + if len(selectedDestinations) == 0 && len(selectedServices) == 0 { selectedDestinations = []string{"172.16.10.0/24"} } - selectedServices := servicesForSelectedProfile(availableProfiles, selectedProfileID) enrollment.Resources = resourcesFromProfile(selectedDestinations, selectedServices) enrollment.AvailableProfiles = availableProfiles enrollment.SelectedProfileID = selectedProfileID diff --git a/deploy/scripts/gateway-entrypoint.sh b/deploy/scripts/gateway-entrypoint.sh index ae644fa..536b99e 100644 --- a/deploy/scripts/gateway-entrypoint.sh +++ b/deploy/scripts/gateway-entrypoint.sh @@ -107,6 +107,28 @@ EOF { echo "table inet nexavpn {" + echo " chain input {" + echo " type filter hook input priority 0;" + echo " policy accept;" + echo " ct state established,related accept" + echo " iifname != \"${IFACE}\" accept" + + jq -c '.peers[]?' "${STATE_JSON}" | while read -r peer; do + ASSIGNED_IP=$(printf '%s' "${peer}" | jq -r '.assigned_ip') + printf '%s' "${peer}" | jq -r '.dns_servers[]?' | while read -r dns_server; do + echo " iifname \"${IFACE}\" ip saddr ${ASSIGNED_IP} ip daddr ${dns_server} udp dport 53 accept" + echo " iifname \"${IFACE}\" ip saddr ${ASSIGNED_IP} ip daddr ${dns_server} tcp dport 53 accept" + done + printf '%s' "${peer}" | jq -c '.allowed_services[]?' | while read -r service; do + SERVICE_PROXY_IP="$(printf '%s' "${service}" | jq -r '.access_proxy_ip')" + printf '%s' "${service}" | jq -r '.ports[]?' | while read -r service_port; do + echo " iifname \"${IFACE}\" ip saddr ${ASSIGNED_IP} ip daddr ${SERVICE_PROXY_IP} tcp dport ${service_port} accept" + done + done + done + + echo " iifname \"${IFACE}\" drop" + echo " }" echo " chain forward {" echo " type filter hook forward priority 0;" echo " policy accept;"