Snawoot / opera-proxy

Standalone client for proxies of Opera VPN
MIT License
672 stars 62 forks source link

Feature request: Ability to select the outgoing IP address #41

Closed przemyslaw0 closed 9 months ago

przemyslaw0 commented 9 months ago

Just like Tor does, I think it's a good idea:

From $man tor:

       OutboundBindAddress IP
           Make all outbound connections originate from the IP address specified. This is only useful when you have multiple network interfaces,
           and you want all of Tor’s outgoing connections to use a single one. This option may be used twice, once with an IPv4 address and once
           with an IPv6 address. IPv6 addresses should be wrapped in square brackets. This setting will be ignored for connections to the loopback
           addresses (127.0.0.0/8 and ::1), and is not used for DNS requests as well.

The option could be specified twice, one for IPv4 and other for IPv6.

Snawoot commented 9 months ago

Hello!

What will be use case for this? I understand the general idea and I have similar feature (source IP hints) in dumbproxy. But I can't see why regular user might want it.

przemyslaw0 commented 9 months ago

It's just like a proxy, you select an IP address for outgoing packets, but the address should be local in the host.

I connect to two VPNs, one is for browsing and another for P2P and things that demand high traffic, this another one is a VPN server with 10Gbits/s, and I don't trust 100% the Opera VPN log policies and data retention, so that it should be better to send its traffic over the another fast VPN.

Another use case is policy based routing, the user set up tables, fwmarks and IPs (with ip rule add from table

) for each different network interface and force the traffic of some applications to bind to the selected IP in routing.

Let's suppose Opera VPN is blocked in a country but a VPN that the user use is not, he could just force the traffic of Opera VPN to go through VPN using policy based routing.

But ok, if you find irrelevant my suggestion you can close my issue topic.

Have a nice day.

Snawoot commented 9 months ago

Right, now I understand how it is supposed to be used.

It is possible to implement "dialer" which will accept source IP address hints or bind to specific device or even set SO_MARK socket option to add fwmark natively. But later two options are Linux-specific while most of application users are Windows users.

Another problem is how Golang runtime does DNS queries. It may use either pure golang DNS-client implementation "netgo", or use native system routines. For example, on Android it is the only option to use their libc. In that case I can't control how name resolving is done and can't set any options to UDP socket of DNS client. In order to prevent that kind of "leak" it will be required to ship application with such DNS client aware about possible options and taking all responsibility for DNS resolving process. Won't work on Android, though.

But there are solutions which you can use for your (quite specific) use-case right now! And these solutions are quite reliable and won't allow any leaks via another interface.

If you need to redirect any application through specific tunnel, you may use Linux VRF. I even already wrote guide for dumbproxy, but it applies to other applications as well. Basically it runs binary using ip vrf exec, which runs app in separate cgroup with eBPF filter attached to bind all sockets to specific VRF device and will live in separate forwarding domain.

If you need to ensure application sets specific SO_MARK to match fwmark in iproute2 rules, there is a similar wrapper to do that: https://github.com/zhangyoufu/fwmark I haven't tried it, but I believe such approach is viable.

I understand these solutions are a bit complex, but they are stackable with any app and probably it's the best way to address it with desirable level of guarantees.

Snawoot commented 9 months ago

Just had an idea. opera-proxy supports upstream proxy via --proxy option. And dumbproxy supports dialer with IP hints. You can just run dumbproxy -bind-address 127.0.0.1:8080 -ip-hints VPN_LOCAL_ADDRESS and opera-proxy -proxy http://127.0.0.1:8080.

przemyslaw0 commented 9 months ago

I tested that zhangyoufu/fwmark, it works great, but it requires root privileges, but there is sudo.

Thanks, I will test opera-proxy with dumbproxy too.