ip route add by specifying source address in the same network - linux

I have 4 pc´s and another pc, call it proxy, all being in the same network: 172.16.96.0/20 . I can ping between each other.
But, I want to separate them into 2. That is:
pc1 is directly connected to pc2
pc3 is directly connected to pc4
But,
all traffic from pc1 or pc2 to pc3 or pc4 has to go through proxy and
all traffic from pc3 or pc4 to pc1 or pc2 has to go through proxy
pc1 pc3
| -proxy- |
pc2 pc4
pc1 IP: 172.16.97.24
pc3 IP: 172.16.97.27
proxy IP: 172.16.97.2
To do that on pc1 I added:
ip route add 172.16.97.27 via 172.16.97.2
But, when I do traceroute 172.16.97.27, 172.16.97.2 does not appear as a hop..I am not sure if it should..
On proxy the routing table looks like:
default via 172.16.111.254 dev eth0
172.16.96.0/20 dev eth0 proto kernel scope link src 172.16.97.2
I think I should add another source that is pc1 172.16.97.24.
And to be able to forward the traffic received from pc1 (172.16.97.24) to its destination(either pc3 or pc4), I used this:
ip route add 172.16.96.0/20 via 0.0.0.0 src 172.16.97.24
Error: RTNETLINK answers: No such device
ip route add 172.16.96.0/20 dev eth0:0 via 0.0.0.0 src 172.16.97.24
Error: RTNETLINK answers: Invalid argument
and:
ip route add 172.16.96.0/20 src 172.16.97.24
Error: RTNETLINK answers: No such device
I am not sure if I am going on the right path to do this configuration. Please tell me if not. Thank you!

I managed to solve the problem by adding on the proxy the following:
# sysctl net.ipv4.ip_forward=1 or add net.ipv4.ip_forward=1 in /etc/sysctl.conf (to keep it after you close the terminal)
# iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
-A POSTROUTING Append a rule to the POSTROUTING chain
-o eth0 this rule is valid for packets that leave on the eth0 network interface (-o stands for "output")
-j MASQUERADE the action that should take place is to 'masquerade' packets, i.e. replacing the sender's address by the router's address.
And I added on pc1,pc2,pc3,pc4:
ip route add pcDestIP via proxy
Where pcDest ip is pc3 and pc4 in case I am writing the rule on pc1.
More info : http://www.karlrupp.net/en/computer/nat_tutorial
and here: https://serverfault.com/questions/306024/how-to-route-network-traffic-of-a-host-via-another-host

Related

Is there a python function to catch UDP traffic a machine is forwarding

I am running a system with the following configuration:
NODE A <-> PROXY <-> SWITCH <-> PROXY <-> NODE B
Where node A and its proxy share a common private network, node b and its proxy share a common private network, and the proxy's are connected to the switch.
I have configured each as such:
#nodeA
#!/bin/sh
#Aliases
alias ip='sudo ip'
alias iptables='sudo iptables'
#interfaceconfiguration
ip link set enp0s8 up
ip addr add 192.168.0.1/29 dev enp0s8
iptables -t nat --flush
sudo route add default gw 192.168.0.2 enp0s8
iptables --policy INPUT ACCEPT
iptables --policy FORWARD ACCEPT
iptables --policy OUTPUT ACCEPT
#proxy a
#!/bin/sh
#Aliases
alias ip='sudo ip'
alias iptables='sudo iptables'
#interfaceconfiguration
ip link set enp0s8 up
ip link set enp0s9 up
ip addr add 192.167.0.1/26 dev enp0s9
ip addr add 192.168.0.2/29 dev enp0s8
sudo sysctl net.ipv4.ip_forward=1
iptables -t nat --flush
sudo route add default gw 192.167.0.2 enp0s9
sudo ip route add 192.168.0.0/29 via 192.168.0.2 dev enp0s8
iptables --policy INPUT ACCEPT
iptables --policy FORWARD ACCEPT
iptables --policy OUTPUT ACCEPT
#proxy B
#!/bin/sh
#Aliases
alias ip='sudo ip'
alias iptables='sudo iptables'
#interfaceconfiguration
ip link set enp0s8 up
ip link set enp0s9 up
ip addr add 192.167.0.2/26 dev enp0s9
ip addr add 192.168.0.10/29 dev enp0s8
sudo sysctl net.ipv4.ip_forward=1
iptables -t nat --flush
sudo route add default gw 192.167.0.1 enp0s9
sudo ip route add 192.168.0.8/29 via 192.168.0.10 dev enp0s8
iptables --policy INPUT ACCEPT
iptables --policy FORWARD ACCEPT
#node B
#!/bin/sh
#Aliases
alias ip='sudo ip'
alias iptables='sudo iptables'
#interfaceconfiguration
ip link set enp0s8 up
ip addr add 192.168.0.9/29 dev enp0s8
iptables -t nat --flush
sudo route add default gw 192.168.0.10 enp0s8
iptables --policy INPUT ACCEPT
iptables --policy FORWARD ACCEPT
iptables --policy OUTPUT ACCEPT
iptables --policy OUTPUT ACCEPT
I then have this simple server client code running on NODE A and NODE B just to have some traffic going through the network:
import socket
import sys
#NODE A - SERVER
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server_address = ('192.168.0.1', 10000)
sock.bind(server_address)
while True:
data, address = sock.recvfrom(4096)
print(data.decode())
import socket
import sys
#NODE B - CLIENT
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server_address = ('192.168.0.1', 10000)
while True:
sock.sendto(input("Message to send:").encode(), server_address)
My question is, how can I, at the proxy level intercept these messages to bring them up to the application level so that I can work with them as to add a layer of encryption for example then send them back out to their destination so that the proxy on the other side can decrypt the message.
Thank you
This is a perfectly good debugging loop:
while True:
data, address = sock.recvfrom(4096)
print(data.decode())
Once you see that the right datagrams are arriving,
that loop will be a natural place to forward datagrams
to your favorite destination.
Ensuring that your listening socket was properly bound can be a tricky thing,
given that you have several addresses and interfaces to worry about.
Consider using $ sudo tcpdump -i en0 udp port 10000 to examine
datagrams in flight, before you even run that debugging loop.
You can use the command on the sending host,
on an intermediate transit host,
and on the destination host.
By viewing $ ifconfig -a you may find that an interface besides en0,
perhaps a tunnel interface, is relevant for reading the packets you're interested in.
Once you know certain packets are flowing,
that tends to make it easier to correctly specify the bind() parameters.
I think you're approaching this from the wrong way around. Namely, if you want to "work with" packets on the proxy, then you don't want to be telling the kernel to do any IP level forwarding
the Linux tun/tap interface would let you do this, see here for an example of how this is used with a VPN. although there are Python packages that help if you really want Python code to be doing the work
as a minor side note, I've generally found it an anti-pattern to put sudo onto basically every line of a script as you have. I'd just run the entire script via sudo and just have the code in it assume this is the case.

dns configuration for wireless access point

I am trying to implement wireless access point on my embedded platform. I have implemented some parts like running wireless card as access point, dhcp server and some forwarding rules (via iptables).
I have tried several iptables commands. results of all are the same. The last one I decided to use is:
iptables -t nat -F
iptables -F
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT
echo '1' > /proc/sys/net/ipv4/ip_forward
Access point runs successfully, clients can connect to it and get ip address. However there is DNS problem. Clients could not resolve the hostnames but they can connect via ip addresses.
DHCP configuration is as below:
interface wlan0
start 192.168.7.11
end 192.168.7.20
max_leases 10
option subnet 255.255.255.0
option router 192.168.7.1
#option dns 192.168.7.2 192.168.7.4
option domain local
option lease 864000
lease_file /conf/udhcpd.leases
#pidfile /tmp/udhcpd.pid
For this configuration, If I use 'option dns 8.8.8.8 8.8.4.4' I can resolve the problem but I need to use the dns of the network. Is there any way to forward the dns address 192.168.7.2 to the dns address of the wired network (eg. 192.168.0.2).
I could not find the DNS routing (eg. 192.168.7.2 to 192.168.0.2). But I have found a way to use the DNS address of the embedded platform on clients.
in DHCP server configuration, I used this option:
option dns 192.168.0.2 192.168.0.4 (conf file are generated when access point is started, so the dns addresses are obtained from the system )
after DHCP server is run, I have run these commands to forward dns addresses:
iptables -A FORWARD --in-interface eth1 -m tcp --sport 53 -j ACCEPT
iptables -A FORWARD --in-interface eth1 -m udp --sport 53 -j ACCEPT

LXC Container as VPS

I've been looking into LXC containers and I was wondering as to whether or not it is possible to use an LXC container like an ordinary VPS?
What I mean is;
How do I assign an external IP address to an LXC container?
How do I ssh into an LXC container directly?
I'm quite new to LXC containers so please let me know if there are any other differences I should be aware of.
lxc-create -t download -n cn_name
lxc-start -n cn_name -d
lxc-attach -n cn_name
then in container cn_name install openssh server so you can use ssh then reboot it or restart ssh service.
To make any container "services" available to the world configure port forwarding from the host to the container.
For instance if you had a web server in a container, to forward port 80 from the host ip 192.168.1.1 to a container with ip 10.0.3.1 you can use the iptables rule below.
iptables -t nat -I PREROUTING -i eth0 -p TCP -d 191.168.1.1/32 --dport 80 -j DNAT --to-destination 10.0.3.1:80
now the web server on port 80 of the container will be available via port 80 of the host OS.
It sounds like what you want is to bridge the host NIC to the container. In that case, the first thing you need to do is create a bridge. Do this by first ensuring bridge-utils is installed on the system, then open /etc/networking/interfaces for editing and change this:
auto eth0
iface eth0 inet dhcp
to this:
auto br0
iface br0 inet dhcp
bridge-interfaces eth0
bridge-ports eth0
up ifconfig eth0 up
iface eth0 inet manual
If your NIC is not named eth0, you should replace eth0 with whatever your NIC is named (mine is named enp5s0). Once you've made the change, you can start the bridge by issuing the command
sudo ifup br0
Assuming all went well, you should maintain internet access and even your ssh session should stay online during the process. I recommend you have physical access to the host because messing up the above steps could block the host from internet access. You can verify your setup is correct by running ifconfig and checking that br0 has an assigned IP address while eth0 does not.
Once that's all set up, open up /etc/lxc/default.conf and change
lxc.network.link = lxcbr0
to
lxc.network.link = br0
And that's it. Any containers that you launch will automatically bridge to eth0 and will effectively exist on the same LAN as the host. At this point, you can install ssh if it's not already and ssh into the container using its newly assigned IP address.
"Converting eth0 to br0 and getting all your LXC or LXD onto your LAN"

how to route 2 Nics with 2 public IP on same subnet running with same gateway

I'm newbie in networking field. I have trouble with my web server Network configuration (OS is Centos).
I have 2 NICs (eth0 + eth2 - physically) running 2 public IP which have the same subnet, same gateway.
When I configure nginx to listen on these 2 NICs, everything works just fine. But when I monitor the traffic, all traffic is on the eth0 only, nothing on eth2.
My question is: How can I configure so that traffic goes in a NIC, go out on that NIC, too?
This is my ethernet card config:
DEVICE="eth0"
ONBOOT=yes
BOOTPROTO=static
IPADDR=x.x.x.38
PREFIX=27
GATEWAY=x.x.x.x.33
DNS1=8.8.8.8
DNS2=8.8.4.4
NAME="System eth0"
DEVICE="eth2"
ONBOOT=yes
BOOTPROTO=static
IPADDR=x.x.x.39
PREFIX=27
GATEWAY=x.x.x.33
DNS1=8.8.8.8
DNS2=8.8.4.4
NAME="System eth2"
This is my route -n result
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
10.14.8.0 0.0.0.0 255.255.255.0 U 0 0 0 eth1
y.z.0.0 0.0.0.0 255.255.0.0 U 1002 0 0 eth0
y.z.0.0 0.0.0.0 255.255.0.0 U 1003 0 0 eth1
y.z.0.0 0.0.0.0 255.255.0.0 U 1004 0 0 eth2
0.0.0.0 x.x.x.33 0.0.0.0 UG 0 0 0 eth0
Hope you can help, thanks in advanced!
In Linux, routing is performed by looking at the destination address only, so a packet will follow whichever route can be used to reach the packet's destination, with no regard to the source address.
The behaviour you want requires choosing a route depending not only on the destination address, but also on the source address — this is sometimes called source-sensitive routing or SADR (source-address dependent routing). The most portable way of implementing source-sensitive routing under Linux is to define routing rules across multiple routing tables using the ip rule and ip route ... table ... commands.
This is described in detail in Section 4 of the Linux Advanced Routing and Traffic Control HOWTO
Probably, the problem can be solved even with NAT.
ip tuntap add dev tap0 mode tap
ip tuntap add dev tap1 mode tap
Then you can assign separate ip addresses to these devices:
ifconfig tap0 10.10.10.1 netmask 255.255.255.255
ifconfig tap1 10.10.10.2 netmask 255.255.255.255
And finally - redirect incoming traffic to specific virtual device
iptables -t nat -A PREROUTING -i eth0 -j DNAT --to-destination 10.10.10.1
iptables -t nat -A PREROUTING -i eth2 -j DNAT --to-destination 10.10.10.2
In this case, all traffic will be routed definetely to the interface it came from.

How do I route a packet to use localhost as a gateway?

I'm trying to test a gateway I wrote(see What's the easiest way to test a gateway? for context). Due to an issue I'd rather not get into, the gateway and "sender" have to be on the same machine. I have a receiver(let's say 9.9.9.9) which the gateway is able to reach.
So I'll run an application ./sendStuff 9.9.9.9 which will send some packets to that IP address.
The problem is: how do I get the packets destined for 9.9.9.9 to go to the gateway on localhost? I've tried:
sudo route add -host 9.9.9.9 gw 127.0.0.1 lo
sudo route add -host 9.9.9.9 gw <machine's external IP address> eth0
but neither of those pass packets through the gateway. I've verified that the correct IPs are present in sudo route. What can I do?
Per request, here is the route table, after running the second command(IP addresses changed to match the question. x.y.z.t is the IP of the machine I'm running this on):
Destination Gateway Genmask Flags Metric Ref Use Iface
9.9.9.9 x.y.z.t 255.255.255.255 UGH 0 0 0 eth0
x.y.z.0 0.0.0.0 255.255.254.0 U 0 0 0 eth0
0.0.0.0 <gateway addr> 0.0.0.0 UG 100 0 0 eth0
127.0.0.1 is probably picking up the packets, then forwarding them on their merry way if ipv4 packet forwarding is enabled. If it's not enabled, it will drop them.
If you are trying to forward packets destined to 9.9.9.9 to 127.0.0.1, look into iptables.
Edit: try this:
iptables -t nat -A OUTPUT -d 9.9.9.9 -j DNAT --to-destination 127.0.0.1
That should redirect all traffic to 9.9.9.9 to localhost instead.

Resources