-
Notifications
You must be signed in to change notification settings - Fork 35
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Route vpn traffic through socks proxy? #32
Comments
Good question. Support for this depends entirely on your VPN software; some VPN software will bypass the system proxy settings, which prevents this approach from working. Other VPN software will use UDP, which is supported by this proxy but not supported by many clients. If your VPN has a fixed endpoint (i.e. you know the IP/port that your VPN will connect to), one approach can be to set up a forwarder which forwards a specific listening port on your iPhone running the proxy to the remote VPN over the cellular connection, then tell your VPN software to connect to your iPhone. Concretely, it would look something like this:
The forwarder doesn't have to be especially complicated; the following script would basically do the trick (for TCP): import socket
import ifaddrs
from collections import defaultdict
from socketserver import ThreadingMixIn, TCPServer, StreamRequestHandler
from select import select
PROXY_HOST = "172.20.10.1"
PROXY_PORT = 1337
CONNECT_HOST = "0.0.0.0"
# Time out connections after being idle for this long (in seconds)
IDLE_TIMEOUT = 1800
TARGET = ("ip.me", 443)
interfaces = ifaddrs.get_interfaces()
iftypes = defaultdict(list)
initial_output = ""
for iface in interfaces:
if not iface.addr:
continue
if iface.name.startswith('lo'):
continue
# XXX implement better classification of interfaces
if iface.name.startswith('en'):
iftypes['en'].append(iface)
elif iface.name.startswith('bridge'):
iftypes['bridge'].append(iface)
else:
iftypes['cell'].append(iface)
if iftypes['bridge']:
iface = next((iface for iface in iftypes['bridge'] if iface.addr.family == socket.AF_INET), None)
if iface:
initial_output = "Assuming proxy will be accessed over hotspot (%s) at %s:%d\n" % (iface.name, iface.addr.address, PROXY_PORT)
PROXY_HOST = iface.addr.address
elif iftypes['en']:
iface = next((iface for iface in iftypes['en'] if iface.addr.family == socket.AF_INET), None)
if iface:
initial_output += "Assuming proxy will be accessed over WiFi (%s) at %s\n" % (iface.name, iface.addr.address)
PROXY_HOST = iface.addr.address
else:
initial_output += 'Warning: could not get WiFi address; assuming %s\n' % PROXY_HOST
if iftypes['cell']:
iface = next((iface for iface in iftypes['cell'] if iface.addr.family == socket.AF_INET), None)
if iface:
initial_output += "Will connect to %s:%d over interface %s at %s\n" % (TARGET[0], TARGET[1], iface.name, iface.addr.address)
CONNECT_HOST = iface.addr.address
print(initial_output)
def tcp_loop(csock, ssock):
while True:
r, _, _ = select([csock, ssock], [], [], IDLE_TIMEOUT)
if not r:
raise socket.timeout()
if csock in r:
data = csock.recv(4096)
if not data:
break
ssock.sendall(data)
if ssock in r:
data = ssock.recv(4096)
if not data:
break
csock.sendall(data)
class ThreadingTCPForwarder(ThreadingMixIn, TCPServer):
daemon_threads = True
allow_reuse_address = True
def __init__(self, target, *args, **kwargs):
self.target = target
super().__init__(*args, **kwargs)
class TCPForwarderHandler(StreamRequestHandler):
def handle(self):
remote = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
remote.bind((CONNECT_HOST, 0))
remote.connect(self.server.target)
tcp_loop(self.connection, remote)
if __name__ == '__main__':
server = ThreadingTCPForwarder(TARGET, (PROXY_HOST, PROXY_PORT), TCPForwarderHandler)
try:
server.serve_forever()
except KeyboardInterrupt:
print("Shutting down.")
server.shutdown() Change |
This is very detailed and I sort of follow but I’m still a noob getting into python 😅 I think NordVPN’s meshnet uses UDP so I could tweak your example to use UDPServer instead. Does the rest stay true? And it also looks like I could implement the example code you have in the original sock5? Or how would I go about adding this forwarding alongside the proxy? I believe the meshnet local address and port I want to ultimately access the sunshine gaming computer is 100.69.184.241:47984 |
Yeah, I think you can tweak it to work with UDPServer. You have to change If you want to use the SOCKS proxy at the same time as a dedicated forwarding proxy, it's as easy as throwing the |
Thanks for all that info! I’ve been playing around with it and hopefully can get it to work. Been googling a lot and trying to learn as much as I can :) |
Hi, can’t thank you enough for this awesome script! It works amazingly. One thing I was wondering though if you could help me understand how to do is to route my vpn to my home network like pivpn or tail scale so that way I can use the unrestricted hotspot speeds with something like sunshine/moonlight for fast game streaming?
It seems when I turn on vpn on either the phone or iPad, it will not go through the socks proxy and be limited as usual.
The text was updated successfully, but these errors were encountered: