Gateway - ether42/bootable-usb GitHub Wiki

LXC

The LXC needs access to the ppp device and the bridged connection.

lxc.cgroup.devices.allow = c 108:0 rwm
lxc.hook.autodev = sh -c 'mknod "$LXC_ROOTFS_MOUNT"/dev/ppp c 108 0'

lxc.network.2.type = veth
lxc.network.2.name = bridge
lxc.network.2.link = bridge
lxc.network.2.hwaddr = 02:00:0a:00:63:fe

Setup

On the rootfs:

apt-get install ppp iptables ulogd2
systemctl disable ulogd ulogd2 # yup, two .service are installed, only enable back ulogd2...
systemctl disable pppd-dns # no need to enable it afterward

ULOGD 2 is needed for proper log forwarding in the LXC.

Minimal /etc/ulogd.conf:

[global]
logfile="syslog"
loglevel=3

plugin="/usr/lib/x86_64-linux-gnu/ulogd/ulogd_inppkt_NFLOG.so"
plugin="/usr/lib/x86_64-linux-gnu/ulogd/ulogd_raw2packet_BASE.so"
plugin="/usr/lib/x86_64-linux-gnu/ulogd/ulogd_filter_IFINDEX.so"
plugin="/usr/lib/x86_64-linux-gnu/ulogd/ulogd_filter_IP2STR.so"
plugin="/usr/lib/x86_64-linux-gnu/ulogd/ulogd_filter_PRINTPKT.so"
plugin="/usr/lib/x86_64-linux-gnu/ulogd/ulogd_output_SYSLOG.so"

stack=log3:NFLOG,base1:BASE,ifi1:IFINDEX,ip2str1:IP2STR,print1:PRINTPKT,sys1:SYSLOG

Add the DSL provider, /etc/ppp/peers/ovh:

plugin rp-pppoe.so bridge
user USERNAME
noauth
hide-password

persist
maxfail 0
holdoff 5

mtu 1492
mru 1492

default-asyncmap

noipdefault
defaultroute
replacedefaultroute

lcp-echo-interval 10
lcp-echo-failure 5

updetach
#nodetach
#debug

The DSL provider secret may be stored in /etc/ppp/chap-secrets and/or in /etc/ppp/pap-secrets depending on your provider (both may be valid):

# client server  secret   IP addresses
USERNAME *       PASSWORD *

Change USERNAME and PASSWORD.

Even if the forwarding state is set in the interface configuration, pppd may reestablish the connection (for example, after it has been dropped or if the daemon is killed with SIGHUP) and the forwarding sysctl will be reset. To correct this, chmod +x /etc/ppp/ip-up.d/forwarding:

#!/usr/bin/env bash

set -eux

sysctl -w net.ipv4.conf."$1".forwarding=1

Configure the bridging interface, /etc/network/interfaces.d/bridge:

auto bridge
iface bridge inet ppp
  # /etc/ppp/peers/$provider
  provider ovh

  # up the corresponding interface
  pre-up ip link set dev bridge up
  post-down ip link set dev bridge down

  # setup logging chains
  pre-up iptables -N LOG_ACCEPT
  pre-up iptables -A LOG_ACCEPT -j NFLOG --nflog-prefix "INPUT ACCEPT"
  pre-up iptables -A LOG_ACCEPT -j ACCEPT
  pre-up iptables -N LOG_DROP
  pre-up iptables -A LOG_DROP -j NFLOG --nflog-prefix "INPUT DROP"
  pre-up iptables -A LOG_DROP -j DROP

  # block incoming connections unless established
  post-up iptables -A INPUT -i ppp0 -m state --state RELATED,ESTABLISHED -j LOG_ACCEPT
  post-down iptables -D INPUT -i ppp0 -m state --state RELATED,ESTABLISHED -j LOG_ACCEPT
  post-up iptables -A INPUT -i ppp0 -j LOG_DROP
  post-down iptables -D INPUT -i ppp0 -j LOG_DROP

  # clamp the MSS corresponding to the MTU
  post-up iptables -A FORWARD -o ppp0 -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
  post-down iptables -D FORWARD -o ppp0 -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

  # masquerade the outgoing traffic to ppp0
  post-up iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE
  post-down iptables -t nat -D POSTROUTING -o ppp0 -j MASQUERADE

  # mark traffic having for destination the external ip
  post-up iptables -t nat -A PREROUTING --destination 109.190.107.125 -j MARK --set-mark 0x1
  post-down iptables -t nat -D PREROUTING --destination 109.190.107.125 -j MARK --set-mark 0x1

  # dns port forwarding
  post-up iptables -t nat -A PREROUTING -p udp -m mark --mark 0x1 --dport 53 -j DNAT --to-destination 10.0.101.253:53
  post-down iptables -t nat -D PREROUTING -p udp -m mark --mark 0x1 --dport 53 -j DNAT --to-destination 10.0.101.253:53
  post-up iptables -t nat -A PREROUTING -p tcp -m mark --mark 0x1 --dport 53 -j DNAT --to-destination 10.0.101.253:53
  post-down iptables -t nat -D PREROUTING -p tcp -m mark --mark 0x1 --dport 53 -j DNAT --to-destination 10.0.101.253:53

  # http port forwading
  post-up iptables -t nat -A PREROUTING -p tcp -m mark --mark 0x1 --dport 80 -j DNAT --to-destination 10.0.101.16:80
  post-down iptables -t nat -D PREROUTING -p tcp -m mark --mark 0x1 --dport 80 -j DNAT --to-destination 10.0.101.16:80
  post-up iptables -t nat -A PREROUTING -p tcp -m mark --mark 0x1 --dport 443 -j DNAT --to-destination 10.0.101.16:443
  post-down iptables -t nat -D PREROUTING -p tcp -m mark --mark 0x1 --dport 443 -j DNAT --to-destination 10.0.101.16:443

  # ssh port forwading
  post-up iptables -t nat -A PREROUTING -p tcp -m mark --mark 0x1 --dport 22 -j DNAT --to-destination 10.0.101.13:22
  post-down iptables -t nat -D PREROUTING -p tcp -m mark --mark 0x1 --dport 22 -j DNAT --to-destination 10.0.101.13:22

  # port forwarding for local networks
  post-up iptables -t nat -A POSTROUTING -s 10.0.0.0/8 -m mark --mark 0x1 -j SNAT --to-source 109.190.107.125
  post-down iptables -t nat -D POSTROUTING -s 10.0.0.0/8 -m mark --mark 0x1 -j SNAT --to-source 109.190.107.125

  # allow IP forwarding
  post-up sysctl -w net.ipv4.conf.ppp0.forwarding=1
  pre-down sysctl -w net.ipv4.conf.ppp0.forwarding=0

  # cleanup logging chains
  post-down iptables -F LOG_ACCEPT
  post-down iptables -X LOG_ACCEPT
  post-down iptables -F LOG_DROP
  post-down iptables -X LOG_DROP

Marking the packets having for destination the external IP address has two uses:

  • less repetitions
  • in case of internal traffic, the internal IP has to be rewritten as the external IP to be sent back through the gateway

Note that for external traffic, the destination IP could be replaced by -i ppp0 to avoid the hardcoded IP, but this would break the internal traffic destinated to the external IP.

The other interfaces could be set to DHCP (unusual for a gateway but less hardcoded configuration), /etc/network/interfaces.d/service:

auto service
iface service inet dhcp
  # allow IP forwarding
  post-up sysctl -w net.ipv4.conf.service.forwarding=1
  pre-down sysctl -w net.ipv4.conf.service.forwarding=0

However the administrative interface shouldn't allow forwading.