Skip to content
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

tunnelers cannot intercept and spoof the same IP #443

Open
scareything opened this issue Jul 15, 2022 · 2 comments
Open

tunnelers cannot intercept and spoof the same IP #443

scareything opened this issue Jul 15, 2022 · 2 comments

Comments

@scareything
Copy link
Member

scareything commented Jul 15, 2022

Tunnelers cannot currently spoof and intercept a given IP. This situation arises with applications where a single endpoint acts as both a client and a server, and source IP of inbound connections needs to be preserved. SIP and RTP are two examples.

When a client connects to a service with sourceIp set, the hosting tunneler calls bind to set the local address of its connection with the server. In order for bind to succeed, the specified address must be local (assigned to a network interface on the host) - otherwise bind fails with EADDRNOTAVAIL*.

Tunnelers intercept packets by manipulating the operating system's route tables so that packets destined for intercepted IPs are routed to the tun interface that the tSDK is reading from. So essentially the tun read loop receives packets that are going to non-local addresses. Packets that are destined for local addresses (such as those that a hosting tunneler added for IP spoofing) are handled by the operating system's IP stack, and therefore cannot be intercepted by the tun interface because they will not be seen at the tSDK's tun read loop.

* The (Linux-only) IP_FREEBIND socket option is not helpful. While IP_FREEBIND does allow the bind to succeed, the subsequent connect to the server fails with ENETUNREACH if the socket's local address is not assigned to a network interface.

@scareything
Copy link
Member Author

scareything commented Jul 15, 2022

Perhaps the most obvious solution would be to create a server socket using the operating system's sockets API to listen on spoofed IPs. Indeed this could work, but would be cumbersome for services that contain multiple ports and/or ranges in the intercept configuration (a separate listener would be needed for each port).

Alternatively, all packets going to a given IP could be sniffed with a raw socket. Packets from the raw socket could then be fed into the tSDK (via on_packet), and the tSDK's existing service selection and packet processing logic wouldn't know the difference between packets that came from a raw socket or a tun interface.

The raw socket reader approach has been started in https://github.com/openziti/ziti-tunnel-sdk-c/tree/rawsock.forwarder.3

@scareything
Copy link
Member Author

https://github.com/netfoundry/zfw can be used to work around this limitation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant