Implementing PPPoE half-bridge/ip-passthrough to suit IPSec VPN firewall appliance with Linux
(I'm editing my own question and posting an answer for anyone else who finds themselves in a similar position.)
I would like a firewall appliance that requires a public static IP on its external interface to be used with an ISP-approved ADSL modem. (This setup isn't recommended as the ADSL service and modem are consumer-grade, but we need to save money.)
The modem can act as a router, which means it will NAT all traffic and use the service's 1 public static IP on its external interface. We can't use a public subnet behind this NAT as this isn't supported by this ADSL service.
The other option is that this modem can act as a full bridge, but the firewall appliance is not capable of terminating a PPP link.
There is one modem (DrayTek Vigor 120) that I could acquire that is capable of half-bridge mode (DrayTek calls this "True-DMZ"), where one device behind the modem is assigned the ADSL link's one public static IP address. This worked, but unfortunately we had unrelated problems with the ADSL line and were not able to receive any support from our ISP while using this modem.
How do I configure a Linux PC so that it terminates the PPP link in half-bridge mode?
Solution 1:
I used Debian on a PC with three NICs (1 for management, 1 to connect to the modem, 1 to connect to the firewall). I ended up with eth0=management, eth1=modem, eth2=firewall, ppp0=ADSL service and lo.
- Prepare PC with ppp (and pppoeconf if desired) [note: this PC will lose its connection to the internet when this is all set up]
- Put modem into full-bridge mode
- Configure ppp and connect, test connection, etc.
- Configure eth1 and eth2 as "auto ethx" and "iface ethx" in /etc/network/interfaces
-
Add the following to /etc/ppp/ip-up (just before the "run-parts" line):
ifconfig ppp0 an IP in a subnet you'll never use/that subnet's CIDR
ifconfig eth2 up
ifconfig eth2 your public IP/your public subnet
ip route delete default
ip route add default dev ppp0
ip route flush cache
You should end up with a route table that looks like this:
- 0.0.0.0/0 ppp0
- your public IP's network/your public IP's subnet eth2
- network you don't care about/subnet ppp0
The way this works:
- eth1 doesn't need an IP address, as PPPoE is a frame protocol
- eth2 gets another IP in the same subnet as your public IP
- ppp0 gets an IP you don't care about (but doesn't clash with anything you do care about)
- when a packet arrives from ADSL, its source will be some other public IP and its destination will be your public IP: it will egress eth2 (due to route #2)
- when a packet arrives from the firewall, its source will be your public IP and its destination will be some other public IP: it will egress ppp0 (due to default route)
Example:
Say your public IP is 1.1.1.100/24 and your gateway is 1.1.1.1 (our ISP assigned us something like this; the way I understand it, you would normally get 1.1.1.100/32 with no gateway). Say also that 172.16.1.0/24 is a network you'll never use anywhere. So:
ifconfig ppp0 172.16.1.1/24
ifconfig eth2 up
ifconfig eth2 1.1.1.101/24
ip route delete default
ip route add default dev ppp0
ip route flush cache
Your route table:
- 0.0.0.0/0 ppp0
- 1.1.1.0/24 eth2
- 172.16.1.0/24 ppp0
Note that you are assigning eth2 1.1.1.101 and not 1.1.1.100. Eth2 needs to be on the same subnet as your public IP, but not the public IP itself.
Caveat:
You'll need to use either the real subnet used by your ISP (e.g., 1.1.1.0/24) or make up a pretend one (and use /30 to keep it as small as possible). Other IPs (typically other customers of your ISP) in this subnet on the internet will become unreachable to you.