4
5
I have a Raspberry Pi, running Raspbian (Debian Based), with 2 network interfaces.
One of the interfaces is the WAN, coming from a Satellite Modem. The other is the Customer Router, which the Pi is providing the internet for.
The problem is that I'm only dealing with a /30, and the Satellite Modem already has one of the two IPs on that /30, so I only have one IP left (1.1.1.2/30), and 2 devices that want it (my Raspberry Pi, and the Customer Router).
I know I can easily do NAT, and give the customer a LAN IP. I don't want that. I need the customer to have a public IP. I also know that I can configure the Pi to just be a switch, with no IP of its own, but then the Pi won't have internet access. I don't want that either. I need both the Pi, and the customer router to have internet.
I know this is possible, because I've used MicroHard cell modems in the past which do this exact thing. The Cell Modem gets a public IP when it connects to the cell tower, and when you enable IP passthrough mode on it, a router plugged into that cell modem will also get the same public IP.
If you hit that public IP from the internet on port 80, 443, or 22, you'll be talking to the cell modem, but if you hit any other port, you'll be talking to the router behind the cell modem. That's exactly what I want to do. I'm just not sure exactly how they do it, and how I replicate it in Linux. MicroHard Cell Modems are linux-based, so it's possible on Linux.
So far, this is my plan:
- Static IP of 1.1.1.2/30 on Raspberry Pi's eth0 (Sat Modem Interface)
- Static IP of 1.1.1.254/24 on Raspberry Pi's eth1 (Customer Router Interface)
- DHCP server on eth1 giving the Customer Router:
- 1.1.1.2/24
- DG: 1.1.1.254
- Enabled net.ipv4.ip_forward
- Because the 2 subnets on the 2 interfaces obviously overlap, use policy based routing rules to tell the Pi when and where it should send traffic
It now looks like this:
I've been trying to get this working, but that last bullet point is obviously the hard part. Everything else (DHCP Router, Static IPs, IP Forwarding) is all done, and working.
I've done this:
# Rules to prevent ARP from going out the wrong interface
$ sudo arptables -A INPUT -i eth0 --destination-ip ! 1.1.1.2 -j DROP
$ sudo arptables -A INPUT -i eth1 --destination-ip ! 1.1.1.254 -j DROP
# Create custom routing tables
$ sudo vim /etc/iproute2/rt_tables
190 to_sat_modem
200 to_customer_router
# Add rules to tables
$ sudo ip route add default dev eth0 table to_sat_modem
$ sudo ip route add default dev eth1 table to_customer_router
# Add policy based routing rules
$ sudo ip rule add fwmark 0x1 lookup to_sat_modem
$ sudo ip rule add fwmark 0x2 lookup to_customer_router
# Add masq rule
$ sudo iptables -t nat -A POSTROUTING -o eth0 ! -s 1.1.1.2 -j SNAT --to 1.1.1.2
# Add rules for when to use these routing tables
$ sudo iptables -t mangle -N TO_CUSTOMER_ROUTER
$ sudo iptables -t mangle -N TO_SAT_MODEM
$ sudo iptables -t mangle -A OUTPUT -d 1.1.1.2 -j TO_CUSTOMER_ROUTER # From localhost
$ sudo iptables -t mangle -A PREROUTING -i eth0 -d 1.1.1.2 -p udp -j TO_CUSTOMER_ROUTER # All UDP ports
$ sudo iptables -t mangle -A PREROUTING -i eth0 -d 1.1.1.2 -p tcp --match multiport ! --dports 22,80 -j TO_CUSTOMER_ROUTER # Most TCP ports
$ sudo iptables -t mangle -A TO_CUSTOMER_ROUTER -j MARK --set-xmark 0x2
$ sudo iptables -t mangle -A TO_CUSTOMER_ROUTER -j ACCEPT
$ sudo iptables -t mangle -A OUTPUT -d 1.1.1.1 -j TO_SAT_MODEM # From localhost
$ sudo iptables -t mangle -A PREROUTING -i eth1 -d 1.1.1.1 -j TO_SAT_MODEM
$ sudo iptables -t mangle -A TO_SAT_MODEM -j MARK --set-xmark 0x1
$ sudo iptables -t mangle -A TO_SAT_MODEM -j ACCEPT
It feels like I'm on the right track, but I can't seem to get it to work. Any ideas?
PS. Yes, I know that most of my rules won't survive a reboot. I'll fix that once I have a working solution
PPS. This is trying to achieve one-way transparency. The Sat Modem will only see a single device behind it (1.1.1.2), while the Customer Router will be able to talk to the Pi (1.1.1.254) and the Sat modem (1.1.1.1). This should work, but has the problem of masking an entire /24 of real public IPs. I can change the /24 to a /29 to reduce the effect, but it'll still happen. Eventually, I'll want 2-way transparency so that I can just reuse the /30 IPs on both ends of the Pi, but I figured this would be easier to start with
PPPS. I'm aware that the obvious answer to this question is
Don't do this. Do something else. Give the customer a LAN IP, or put your Pi behind the customer router and give it a LAN IP, or put the pi in bridge mode, or ...
I don't want to write a 10 page explanation for why this needs to be done this way, but trust me, it needs to be done this way, if at all possible, which, like I said, I'm pretty sure is possible because I've seen it done
Comments are not for extended discussion; this conversation has been moved to chat.
– DavidPostill – 2019-12-01T21:41:22.883