JsBergbau / BindToInterface

With this program you can bind applications to a specific network interface / network adapter. This is very useful if you have multiple (internet) connections and want your program to use a specific one.
GNU Affero General Public License v3.0
113 stars 14 forks source link

Need Ipv6 binding #7

Closed am0o0 closed 1 year ago

am0o0 commented 1 year ago

Hi, thanks for this excellent tool. Currently, many Cloud providers sell ipv6 for only 1$/month and sell ipv4 3x more than the ipv6 price! So I am using ipv6 for websites supporting it, and I can't say publicly the reason! Another problem is that clouds will give us floating IPs like this : image This means we can have multiple ipv4/6 IPs with the same Interface, so is it possible to make an option like BIND_IP like BIND_INTERFACE?

am0o0 commented 1 year ago

In the code, we should bind the address to the inet that we want, I think we should use this API https://linux.die.net/man/2/bind instead of setsockopt()

JsBergbau commented 1 year ago

Hi amammad, thanks for your report, especially when having multiple IPs on one interface. So for binding to a special IP we need the bind API you posted, but we definitly need setsockopt() to bind to this a specific interface when there are multiple interfaces.

An important question is: In your example fe80 is your link local address https://en.wikipedia.org/wiki/Link-local_address so when establishing a connection to a server in your case the addres beginning 2a01 is used.

You can also try one of the solutions here https://unix.stackexchange.com/a/498140 These work with binding an IP like you asked. However I'm not sure whether these work with IPv6 addresses or not.

EDIT: When having multiple IPs then used IP address is determined by the kernel and routing table when I'm not wrong. So when binding to your link local IP and trying to reach a server in the internet, this wouldn't work because this address isn't routed. Even if your packet would arrive at the destination, the destination server wouldn't know the way back.

am0o0 commented 1 year ago

yeah, I didn't use ipnet6 \<link> at all. I bind inet6 with \<global> tag in python and golang, and it works perfectly, And the source IP was changed correctly for me. ( tested with ifconfig.co) Thank you for helping me. I saw this post before. I don't know why the writer is saying that these tools are not reliable.

JsBergbau commented 1 year ago

These tools are not reliable and might leak IP in the case when you have multiple interfaces. Then traffic might flow via an other interface as intended. Thats why I developed BindToInterface to ensure that traffic can only flow out via the specified interface.

So when I understood you correctly everything works for you as intended.

am0o0 commented 1 year ago

Aha, because of routing issues, when we have multiple interfaces, it can be not reliable. Thanks again.

am0o0 commented 1 year ago

Unfortunately, these approaches do not include golang based executables. https://stackoverflow.com/questions/45444513/golang-ssh-load-ld-preload-and-ld-library-path-environment-variables#comment77857997_45446360

JsBergbau commented 1 year ago

I think it should depent, if you use a standard c-library function or a kernel function that you call. So when you use LD_PRELOAD overrwriting a kernel function it should work. If you're interested to find out, you could provide some GO source code that only prints the IP from ifconfig.me or any other site to stdout. I try that then with the VPN connections to see if it works.

am0o0 commented 1 year ago

I tested it with the following command, and it didn't work for me: echo o-o.myaddr.l.google.com | dnsx -json -r ns1.google.com -txt this CLI tool is a good choice: https://github.com/projectdiscovery/dnsx the command is equal to dig @ns1.google.com TXT o-o.myaddr.l.google.com

JsBergbau commented 1 year ago

Thanks for the hint. I've used https://www.codershood.info/2017/06/25/http-curl-request-golang/ to get IP from ifconfig.me and with go binding doesn't work. I thought it would intercept some kernel call. But my understanding of this is very limited. I've added a warning https://github.com/JsBergbau/BindToInterface#how-does-bind-to-network-interface-work

am0o0 commented 1 year ago

Thanks for giving your time. Should we close this issue now?

JsBergbau commented 1 year ago

Just adding same problem exists for torify or torsocks command with golang programs. Data will be trasmitted without using tor.

am0o0 commented 1 year ago

Does this consider a vulnerability?

JsBergbau commented 1 year ago

Kindof

https://github.com/dgoulet/torsocks

BE ADVISE: It uses the LD_PRELOAD mechanism (man ld.so.8) which means that if the application is not using the libc or for instance uses raw syscalls, torsocks will be useless and the traffic will not go through Tor.

So the caution is given, but I and I suppose a lot of other people wouldn't expect that happening with a simple go program.

JsBergbau commented 1 year ago

Tested a go program on Tails https://tails.boum.org/ which is designed to route all traffic through Tor and not leak data. And here gocurl is not able to connect and get the IP. So Tails does a good job here.

am0o0 commented 1 year ago

interesting, do you familiar with network namespaces? like in docker if here we use network NS, I think we can sure that we wont have data leaks.

JsBergbau commented 1 year ago

Sorry, I only know, that namespaces exit, but didn't try anything with them yet.