How can I set source IP to send traffic in Python - sockets

I have a script that sends traffic to a server. It marks incoming traffic as known location traffic for a specific IP.
My script sends traffic via Pycurl. I cannot change Pycurl for now, so is there any way to send traffic by sending that specific source IP.
Options are either set source IP in pycurl or make it use some interface which is created with that specific IP. I need to know how to make a virtual interface to serve traffic for the specific IP in python so that pycurl picks up that interface to send.

If you have multiple interfaces with multiple IP addresses or if you just want the kernel to handle this, you just need to add a host route in your kernel. On linux, this would look something like:
ip route add 10.45.0.20/32 src 10.45.0.10
Where 10.45.0.10 is the IP you want as a source and 10.45.0.20 is the webserver. Note: if you have a gateway to get to the server, then you need to have a 'via' statement and the desired source ip needs to be able to send traffic to it (same subnet).
If you have multiple interfaces and the ip you want to use is the only one bound to one of those interfaces, then you can just add the following to your Pycurl program:
c = pycurl.Curl()
...
c.setopt(pycurl.INTERFACE, "eth2")
Where eth2 is the name of the interface the request will come from. If the IP you want as a source is the only one bound to eth2, then the request will have that source IP.

Related

How does SIP/RTP determine two endpoints are on the same LAN?

I am just experimenting with my phone system and I'm wondering how both endpoints know they are on the same LAN, I have both endpoints breaking out to the cloud phone system with two separate public IP addresses, I've segmented them off from each other with a firewall so they can't see each other however every time I attempt a call between the two end points the call is setup as a peer to peer call and attempts to traverse the local LAN via RTP through the firewall, the firewall blocks the RTP communication and the call has no audio.
I am just wondering how both endpoints are realizing they are behind the same firewall/router since they are both registering with the cloud system from different public IP addresses, I wanted the call to be bridged in the cloud and not traverse the local LAN but somehow both endpoints only attempt the call over the LAN every single time and no idea how they're realising they're on the same LAN.
Anyone else encountered this before?
SIP endpoints don't have to know they are on the same LAN. They just make best use of the IP addresses you provide.
Your INVITE request will provide more insight, but from what you write my guess is that you use public IP addresses for your contact/request URI and local IP addresses in your SDP offer. The local IP addresses are probably routable through the firewall.
With ICE and STUN endpoints may select the best IPs for media traffic - but for that to work the RTP/STUN packets should be able to traverse the firewall in your LAN.
Attempts to communicate directly may mean that LAN uses IPs from public ranges or endpoints a SIP proxy were not smart enough to detect NAT in front of your LAN.

How to intercept IP packets going to the kernel Linux

I need to create a TCP session "manually", without using the connect() function. I have tried to use RAW sockets. But in this case, I only get copies of the incoming IP packets. The original incoming packets slip through to the kernel and it generates an ACK response packet that damages my protocol.
Next, variant 2, I can write a virtual eth interface driver (kernel module) and route incoming traffic to it using iptables. But there is a patched non-original (non vanila) kernel on the machine. Normal linking of the module with the kernel is not possible.
Variant 3. I also tried not to assign an IP address to the NIC interface. In this case, the network TCP/IP layer module in the kernel is not activated and it is possible to generate and receive arbitrary IP packets on the link (ethernet) layer using the PF_PACKET socket domain type in the socket() function. But at this time, any other applications using the TCP/IP protocol can’t work.
How can this problem be solved in other ways?
It would be nice if it were possible to intercept packets going from the network interface to the kernel, that is, intercept the SKBuf buffer. But I don't know how to realize it.
Apparently you are trying to create a tunnel. Instead of trying to hijack an existing interface, the proper way to create a tunnel is to create a new interface, using a kernel module or TUN/TAP. However, tunnels are normally intended to receive traffic generated on the machine which runs the tunnel software, or at least routed through it. That means you will also have to set up the kernel to route the traffic to your tunnel.
You can create a new interface as a TUN/TAP interface. It is like a virtual ethernet driver except you don't need to write a new kernel module. It is designed for tunnels (hence the name).
The difference between TUN and TAP is that a TUN interface is an IP interface that receives IP packets from the kernel's IP routing system, and a TAP interface receives Ethernet packets (which may contain IP packets) so it can alternatively be part of a bridge (a virtual Ethernet switch - which only looks at the Ethernet header, not the IP header).
I think for your scenario, you will find it easiest to create a TAP interface, then create a bridge (virtual Ethernet switch) between the TAP interface, and the interface which the other host is connected to. Neither one needs an IP address - the kernel will happily pass Ethernet-layer traffic without attempting to process the IP information in the packet. Your tunnel software can then emulate a host - or tunnel to an actual host - or whatever you want it to do.
Or in visual form:
If you want the host to also be able to talk to the machine running the tunnel software - without going through the tunnel software - then you may choose to put an IP address on the bridge.

Access external IP address from service

Is it possible to get the external IP address for a POD? It doesn't appear to be populating in the environmental variables for a service, so I was wondering if there was another way to get that information.
Basically: I'm setting up a proftpd service, and it needs to send out its external ip as well as a port for passive communication. Right now, it's sending the local IP address which is causing FTP clients to fail.
The kubernetes service discovery mechanism (DNS or environment variable) doesn't populate the external IP.
One way to work around is to create a static IP first, then assign it to your service.
Or you can exec kubectl inside your cluster to get the external IP but that's nasty.

Stunnel - Specify Outbound IP?

Is there any way to specify a particular outbound IP address for stunnel? Right now, it's always using the main IP of the server, but I'd like it to use a specific outbound IP address.
I actually found my own answer on this one - the "local" directive.
local = host
IP of the outgoing interface is used as source for remote connections.
Use this option to bind a static local IP address, instead.

Bypass default route for outgoing connections

I an writing a small application that needs to connect through one of multiple network interfaces on the machine. The interface is not the "default" one (the one with the default route). Is it possible to bind an outbound TCP socket directly to a specific interface?
Here is an example:
eth0: 192.168.1.10, gateway 192.168.1.1
eth1: 192.168.2.10, gateway 192.168.2.1
default gateway: 192.168.1.1
(both interfaces can reach the Internet through different external IPs)
Now, I want my application to use eth1 to connect to an external server, even if the system is configured to use eth0 for external traffic.
(The question is probably trivial, but I just wanted to know if it is possible at all before spending time on it)
Currently, I am using Python with Twisted, but if I have to use BSD sockets then so be it.
From: http://linux.about.com/od/commands/l/blcmdl7_socket.htm
SO_DONTROUTE - Don't send via a gateway, only send to directly connected hosts. The same effect can be achieved by setting the MSG_DONTROUTE flag on a socket send(2) operation. Expects an integer boolean flag.