Fix NAT-PMP struct format and renewal interval

ProtonVPN returns 16-byte success responses (last field is uint32 lifetime,
not uint16). The previous !BBHIHHH format expected 14 bytes causing unpack
failure. Fixed to !BBHIHHI (16 bytes).

ProtonVPN grants 60s leases; request 60s and renew every 45s instead of
sleeping 240s which let leases expire between renewals.
This commit is contained in:
Will Anderson
2026-04-15 17:34:00 -05:00
parent 8a43279164
commit 5a50e2bb63
+8 -6
View File
@@ -161,9 +161,10 @@ spec:
# Install curl and python3 for NAT-PMP port forwarding
until apk add -q curl python3 2>/dev/null; do sleep 5; done
# NAT-PMP: single-line Python to request TCP port mapping from ProtonVPN gateway
# NAT-PMP: request TCP port from ProtonVPN gateway (60s lease; renew every 45s)
# Response is 16 bytes: BB H I H H I (last field is uint32 lifetime, not uint16)
get_natpmp_port() {
python3 -c "import socket,struct;s=socket.socket(2,2);s.settimeout(5);s.sendto(struct.pack('!BBHHHI',0,2,0,0,0,7776000),('10.2.0.1',5351));d=s.recvfrom(256)[0];r=struct.unpack('!BBHIHHH',d[:16]) if len(d)>=16 else None;print(r[5] if r and r[2]==0 else 0)" 2>/dev/null || echo 0
python3 -c "import socket,struct;s=socket.socket(2,2);s.settimeout(5);s.sendto(struct.pack('!BBHHHI',0,2,0,0,0,60),('10.2.0.1',5351));d=s.recvfrom(256)[0];r=struct.unpack('!BBHIHHI',d) if len(d)==16 else None;print(r[5] if r and r[2]==0 else 0)" 2>/dev/null || echo 0
}
echo "Requesting port via NAT-PMP..."
@@ -193,7 +194,7 @@ spec:
fi
LAST_PORT="$PORT"
fi
sleep 240
sleep 45
done
env:
- name: COORDINATOR_URL
@@ -415,9 +416,10 @@ spec:
until apk add -q curl python3 2>/dev/null; do sleep 5; done
# NAT-PMP: single-line Python to request TCP port mapping from ProtonVPN gateway
# NAT-PMP: request TCP port from ProtonVPN gateway (60s lease; renew every 45s)
# Response is 16 bytes: BB H I H H I (last field is uint32 lifetime, not uint16)
get_natpmp_port() {
python3 -c "import socket,struct;s=socket.socket(2,2);s.settimeout(5);s.sendto(struct.pack('!BBHHHI',0,2,0,0,0,7776000),('10.2.0.1',5351));d=s.recvfrom(256)[0];r=struct.unpack('!BBHIHHH',d[:16]) if len(d)>=16 else None;print(r[5] if r and r[2]==0 else 0)" 2>/dev/null || echo 0
python3 -c "import socket,struct;s=socket.socket(2,2);s.settimeout(5);s.sendto(struct.pack('!BBHHHI',0,2,0,0,0,60),('10.2.0.1',5351));d=s.recvfrom(256)[0];r=struct.unpack('!BBHIHHI',d) if len(d)==16 else None;print(r[5] if r and r[2]==0 else 0)" 2>/dev/null || echo 0
}
echo "Requesting port via NAT-PMP..."
@@ -445,7 +447,7 @@ spec:
fi
LAST_PORT="$PORT"
fi
sleep 240
sleep 45
done
env:
- name: COORDINATOR_URL