Linux – How to route all traffic from one interface to another interface and keep the same ports

iptableslinuxnetworking

since I am fairly new to networking in general, but need to implement a specific scenario I would like to ask for support. Thanks for everything in advance.

I have a following scenario, on my machine A I have a software running which is usually connected to machine B via an ethernet cable.
What I would like to do now is to connect to machine B remotely via an in-between router/device from machine A, lets call this new device machine C. I believe that I will need to work with IP routing using iptables.

Note: machine A is not in the same subnet as machine B

So the scenario will look like this:

  192.168.20.X machine A 10.8.0.55  <--tap0--> 10.8.0.50 machine C 192.168.27.1 <--eth0--> 192.168.27.100 machine B

How I believe iptables will do the job:

So for example when machine A would like to connect to machine B it has to connect with its tap0 interface using 10.8.0.50:12345. Machine C will alter the IP packets (via iptables) from tap0 and send it to its eth0 connection using the same port 192.X.X:12345. Machine B will reply to machine C, which is then sending it back to machine A.

So some of my questions are:

  1. If machine C is unaware of machine B's ip address, but I know it is connected with its eth0 interface, can I still route traffic to its eth0 ip address under the condition that machine A is sending packets destined to machine B? For example using the gateway tap0?
  2. If machine A and C are unaware of machine B's ip address, is it possible to route traffic to B's eth0 ip address? Or would that packet be discarded because it doesnt contain the destination IP address?
  3. Can I forward packets in machine C to different interfaces and keep the same ports?

I was following this guide without implementing the firewall rules, but I was unable to connect properly because it was using hardcoded IP address which I would like to avoid, I would like to forward the traffic from tap0 to eth0 in machine C and in best case not need to know machine B's ip address.

I was trying to use these rules in machine C but to be honest I am not understanding them very well.

sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE  
sudo iptables -A FORWARD -i eth0 -o tap0 -m state --state RELATED,ESTABLISHED -j ACCEPT
sudo iptables -A FORWARD -i tap0 -o eth0 -j ACCEPT

If you could reference me to some easy to understand resources, I would check them out as well. Thank you.

Also checked out:

this question
this question


EDIT:
I have added a simplified layout of the scenario.
I was figuring out that I possible need to use NAT.

From machine A I tried to send packets to machine C using ping 10.8.0.50
where machine B has ip address: 192.168.27.106.
When I send packets from machine A to C I want it to change the packets source and destination address, so I've applied:

sudo iptables -t nat -A PREROUTING -i tap0 -j DNAT --to 192.168.27.100
sudo iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to 10.8.0.55

Using sudo tcpdump -i eth0 on machine B I got a correct ICMP request.
However, the echo didnt go back to machine A. Naturally I thought I'd need to apply the iptables rule back again to machine A. So I've applied:

sudo iptables -t nat -A PREROUTING -i eth0 -j DNAT --to 10.8.0.55
sudo iptables -t nat -A POSTROUTING -o tap0 -j SNAT --to 192.168.27.100

I was able to send the packets through to machine B, but didnt get the reply back to A. I feel like something is missing.
Any ideas?

enter image description here

Best Answer

Machine C has only one address and can not be changed. - but on your picture it has 2 addresses in both A and B subnetworks and 2 network interfaces tap0 and eth0.

Also, your picture and your text for IPs differs. What is 192.168.27.106 really? Machine B IP on the eth0? But your picture shows it's as 192.168.27.100. You are doing SNAT to 10.8.0.55, but that's a Machine A IP according to your picture. That way the Machine C will send ICMP reply to that IP according to it's routing table. You need to SNAT to your Machine B IP on the eth0 side, i.e. 192.168.27.1 if your picture has correct IPs noted. I.e. something like this:

sudo iptables -t nat -A PREROUTING -i tap0 -j DNAT --to 192.168.27.100
sudo iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to 192.168.27.1

You don't usually need a "reverse" NAT rules, as conntracking should resolve it back again on remembered packets.