I have two machines each with two valid network interfaces, an Ethernet interface eth0 and a tun/tap interface gr0. The goal is to start a TCP connection on machine A using interface gr0 but then have the responses (ACKs, etc) from machine B come back over the Ethernet interface, eth0. So, machine A sends out a SYN on gr0 and machine B receives the SYN on its own gr0 but then sends its SYN/ACK back through eth0. The tun/tap device is a GNU Radio wireless link and we just want the responses to come through the Ethernet.
What's the easiest way to accomplish this? I need to research more on TCP/IP, but I was initially thinking that source-spoofing outgoing packets would tell the receiver to respond to the spoofed address (which should get routed to eth0). This would involve routing the IPs from the tun/tap interfaces through gr0 and leave the other traffic to eth0.
We are using Linux and a Python solution would be preferable.
Thanks for looking!
You could add an additional address to the lo interface on each system and use these new addresses as the TCP connection endpoints. You can then use static routes to direct which path each machine takes to get to the other machine's lo address.
For example:
Machine A:
ip addr add 1.1.1.1/32 dev lo
ip route add 2.2.2.2/32 dev eth0 via <eth0 default gateway>
Machine B:
ip addr add 2.2.2.2/32 dev lo
ip route add 1.1.1.1/32 dev gr0
Then bind to 1.1.1.1 on machine A and connect to 2.2.2.2.
You may be interested in enabling logging of martian packets net.ipv4.conf.all.log_martians, and disable reverse path filtering net.ipv4.conf.<interface>.rp_filter on the affected interfaces.
This sysctl vars are accesible via the sysctl utility and/or the /proc filesystem.
Related
Hints about working with VLAN? I have to write a client-server program, where the client will send a packet through eth0 and the server will receive the packet on VLAN, and to send it to a concerned VLAN client should parse on which command line VLAN will receive it?
Usually there is nothing to do in the application to work with a VLAN. The VLAN is realized using a virtual network interface with its own IP address. From the perspective of the application this is not different from a real network interface with own IP address. The OS will take care about routing and encapsulation of packets and there is nothing to do from the application itself.
I have a dual port ethernet NIC and let's say I have connected 2 ports in a loop and assigned the following IPs to the 2 ethernet interfaces:
eth2 -> 192.168.2.1
eth3 -> 192.168.3.1
I want to send traffic from 1 port to another over the physical network, e.g. ping 192.168.3.1 from 192.168.2.1. However, the TCP/IP stack in the Linux kernel recognizes that these two addresses are local and instead sends the traffic to the loopback adapter, so the traffic never hits the physical network.
The closest I have to a solution is Anastasov's send-to-self patch, which unfortunately, has been discontinued since kernel 3.6 so it won't work on Ubuntu 13.10 (kernel 3.11) for me. I've tried finding rewriting the patch for 3.11, but I can't seem to locate these in the Ubuntu distro:
include/linux/inetdevice.h
net/ipv4/devinet.c
net/ipv4/fib_frontend.c
net/ipv4/route.c
Documentation/networking/ip-sysctl.txt
Is there a way I can get the send-to-self patch to work, or an alternative?
You can use network namespaces for this purpose.
As ip-netns's manpage says:
A network namespace is logically another copy of the network stack,
with its own routes, firewall rules, and network devices.
Following is just a copy of this answer:
Create a network namespace and move one of interfaces into it:
ip netns add test
ip link set eth1 netns test
Start a shell in the new namespace:
ip netns exec test bash
Then proceed as if you had two machines. When finished exit the shell and delete the namespace:
ip netns del test
you can try configuring route table, by running "ip" command:
ip route add to unicast 192.168.3.1 dev eth2
ip route add to unicast 192.168.2.1 dev eth3
new route would be added into route table, and it should be able to take effect before egress routing lookup hit the host-local route between "192.168.3.1" and "192.168.2.1", therefore, the traffic should be sent through physical interface "eth2" and "eth3", instead of loopback "lo"
Never tried myself, but should work.
i'm triying to imagine how to do:
(with Linux Debian based distro)
I have PC with 4 NIC:
eth0 = Internet Access (connect to router WAN)
eth1 = Local lan
eth2 = OUT NIC
eth3 = IN NIC
I need to send all traffic from eth1 (local lan) to eth2, receive the same traffic from eth3 and route to eth0.
The idea is send all eth1 traffic to external device over eth2, the external device inspect the packets and send to PC again on eth3, then my PC Linux route traffic to eth0
Is posible to do that ?
You're running linux on a PC? We need to know the version first off. Second you are looking into IProutes if you want to redirect traffic from one NIC to another.
I have a VPS on which eth0 is configured , i want to configure a interface eth0.1 but i want to know if i will configure this new interface the data flow will be divided between eth0 and eth0.1 ?
I want to use eth0 Ip address for all the data flow on server like custom written scripts and eth0.1 Ip address to access it from browser as i have web-server on it.
Linux, by default, will send all packets out the default interface for the subnet, which is most likely eth0.
iproute2 attempts to solve this problem by redirecting packets out on the same interface on which they have been received.
http://www.linuxfoundation.org/collaborate/workgroups/networking/iproute2
So, to answer your question, most packets on your system will probably already go out eth0 (assuming it's the same subnet).
If you set up an alias interface, eth0.1 (from your example), any programs listening on either all interfaces, or specifically, to eth0.1 will be able to receive packets on that IP address.
To add a secondary IP address you use the : separator on the interface name. Suppose you have eth0 assigned with 11.22.33.44 and you also want it to work with 11.22.33.55. Then you would just do:
ifconfig eth0:1 11.22.33.55
If you don't touch routing through the ip route command, 11.22.33.55 won't ever be used as an outbound interface, unless you're answering a request that points to 11.22.33.55 itself, so there are two more things to do.
The first is setting up your webserver's listening address to 11.22.33.55 instead of 'any' IP or 11.22.33.44. This depends on your webserver, in the case of apache check out the Listen directive.
The second thing, if you use a domain, to do is setting up a DNS record to point to 11.22.33.55 instead of 11.22.33.44. Take care because a domain name can't be resolved to a different address depending on the destination port, so you'll need a domain name for each interface. The alternative is directly using the IP address 11.22.33.44 for the script stuff and using the domain name for the webserver only.
After you've done this you can safely use tcpdump, iptables & friends on both the physical and the virtual interface.
I'm trying to test a ethernet bridging device. I have multiple ethernet ports on a linux box. I would like to send packets out one interface, say eth0 with IP 192.168.1.1, to another interface, say eth1 with IP 192.168.1.2, on the same subnet.
I realize that normally you don't configure two interfaces on the same subnet, and if you do the kernel routes directly to each interface, rather than over the wire. How can I override this behavior, so that traffic to 192.168.1.2 goes out the 192.168.1.1 interface, and visa-versa?
Thanks in advance!
This is a guess, but I hope it is in the right direction.
Make more-specific routing table entries, along the lines of:
route add -host 192.168.1.2 dev eth0
route add -host 192.168.1.1 dev eth1
You may also need to fiddle with the accept_local configuration for both interfaces -- or the all setting. (Turning this on may make your machine more susceptible to IP source spoofing attacks; be sure you have good ingress firewall rules elsewhere to prevent trouble.) (See sysctl -a | grep accept_local for what I'm talking about.)
I think you need something like Mac-Vlan in your Linux. This cannot be done with NAT only. Read this: http://www.linuxjournal.com/article/7268.