Transparent Proxy Routing

I'm running a VPN client on my Rpi, which has been set up to act as a transparent proxy. However, when I static route to Rpi, connection breaks entirely.

After doing traceroute, I assumed it's due to a different return route where Rpi simply ARPs and send packets back to clients directly instead of going through the router, and set up a NAT rule as band aid.

It worked, but multi NAT probably isn't optimal, so I'm looking for other methods. Perhaps I can move Rpi to a different subnet?

My router is fairly old and has limited processing power so sadly I can't just run everything on it.

It would be best if you provided us with:

  • A topology diagram that shows how things are connected and from where (and to where) you are running the tests
  • Your configuration (see below)
  • And the type of setup you are trying to achieve (i.e. a commercial VPN connection, a road-warrior type VPN, something else)?
  • Also, when you say "transparent proxy" -- do you mean you've setup a true proxy, or just the function that the VPN serves?

Please connect to your OpenWrt device using ssh and copy the output of the following commands and post it here using the "Preformatted text </> " button:
grafik
Remember to redact passwords, MAC addresses and any public IP addresses you may have:

ubus call system board
cat /etc/config/network
cat /etc/config/wireless
cat /etc/config/dhcp
cat /etc/config/firewall
1 Like

I'm trying to make all my devices access internet through my vpn relay, even devices without vpn support(e.g. nintendo switch).

The term "transparent proxy" originates from iptables tproxy which seems like it's made for my use case. I don't know if it's correct or not.

ubus call system board

{
        "kernel": "5.15.137",
        "hostname": "Router",
        "system": "Qualcomm Atheros QCA956X ver 1 rev 0",
        "model": "TP-Link Archer C6 v2 (US) / A6 v2 (US/TW)",
        "board_name": "tplink,archer-c6-v2-us",
        "rootfs_type": "squashfs",
        "release": {
                "distribution": "OpenWrt",
                "version": "23.05.2",
                "revision": "r23630-842932a63d",
                "target": "ath79/generic",
                "description": "OpenWrt 23.05.2 r23630-842932a63d"
        }
}

cat /etc/config/network

config interface 'loopback'
        option device 'lo'
        option proto 'static'
        option ipaddr '127.0.0.1'
        option netmask '255.0.0.0'

config globals 'globals'
        option ula_prefix 'fd6c:6510:4124::/48'
        option packet_steering '1'

config device
        option name 'br-lan'
        option type 'bridge'
        list ports 'lan2'
        list ports 'lan3'
        list ports 'lan4'
        [REDACTED]

config interface 'lan'
        option device 'br-lan'
        option proto 'static'
        option ipaddr '192.168.1.1'
        option netmask '255.255.255.0'
        option ip6assign '60'
        option ip6ifaceid '::1234'

config device
        option name 'wan'
        [REDACTED]

config interface 'wan'
        option device 'wan'
        [REDACTED]
        option ipv6 'auto'

config device
        option name 'eth0'
        [REDACTED]

config device
        option name 'lan2'
        [REDACTED]

config device
        option name 'lan3'
        [REDACTED]

config device
        option name 'lan4'
        [REDACTED]

config route
        option interface 'lan'
        option target '0.0.0.0/0'
        option table 'VPN'
        option gateway '192.168.1.50'

config route6
        option interface 'lan'
        option target '::/0'
        option gateway 'fd6c:6510:4124::1050'
        option table 'VPN'

config rule
        option lookup 'main'
        option mark '9991'

config rule
        option lookup 'VPN'
        option mark '9990'

config rule6
        option lookup 'main'
        option mark '9991'

config rule6
        option lookup 'VPN'
        option mark '9990'


config wifi-device 'radio0'
        option type 'mac80211'
        [REDACTED]

config wifi-iface 'wifinet0'
        option device 'radio0'
        option network 'lan'
        option mode 'ap'
        option encryption 'psk2'
        [REDACTED]

config wifi-device 'radio1'
        option type 'mac80211'
        [REDACTED]

config wifi-iface 'wifinet1'
        option device 'radio1'
        option network 'lan'
        option mode 'ap'
        option encryption 'psk2'
        [REDACTED]

cat /etc/config/dhcp

config dnsmasq
        option domainneeded '1'
        option localise_queries '1'
        option rebind_protection '0'
        option local '/lan/'
        option domain 'lan'
        option expandhosts '1'
        option cachesize '1000'
        option authoritative '1'
        option readethers '1'
        option leasefile '/tmp/dhcp.leases'
        option resolvfile '/tmp/resolv.conf.d/resolv.conf.auto'
        option localservice '1'
        option ednspacket_max '1232'
        option port '54' // I'm using a different dns resolver
        list server '127.0.0.1'

config dhcp 'lan'
        option interface 'lan'
        option start '100'
        option limit '150'
        option leasetime '12h'
        option dhcpv4 'server'
        list dhcp_option '3,192.168.1.1'
        list dhcp_option '6,192.168.1.50'
        option ra 'server'
        list ra_flags 'managed-config'
        list ra_flags 'other-config'
        option dhcpv6 'server'
        option dns_service '0'

config dhcp 'wan'
        option interface 'wan'
        option ignore '1'
        option start '100'
        option limit '150'
        option leasetime '12h'

config odhcpd 'odhcpd'
        option maindhcp '0'
        option leasefile '/tmp/hosts/odhcpd'
        option leasetrigger '/usr/sbin/odhcpd-update'
        option loglevel '4'

config host
        option name 'Rpi'
        option ip '192.168.1.50'
        [REDACTED]

config host
        option name 'PC'
        option ip '192.168.1.2'
        [REDACTED]

cat /etc/config/firewall

config defaults
        option input 'DROP'
        option output 'ACCEPT'
        option forward 'DROP'

config zone
        option name 'lan'
        option input 'ACCEPT'
        option output 'ACCEPT'
        option forward 'ACCEPT'
        list network 'lan'

config zone
        option name 'wan'
        option input 'DROP'
        option output 'ACCEPT'
        option forward 'DROP'
        option mtu_fix '1'
        option masq '1'
        list network 'wan'

config forwarding
        option src 'lan'
        option dest 'wan'

config rule
        option name 'Allow-DHCP-Renew'
        option src 'wan'
        option proto 'udp'
        option dest_port '68'
        option target 'ACCEPT'
        option family 'ipv4'

config rule
        option name 'Allow-Ping'
        option src 'wan'
        option proto 'icmp'
        option icmp_type 'echo-request'
        option family 'ipv4'
        option target 'ACCEPT'

config rule
        option name 'Allow-IGMP'
        option src 'wan'
        option proto 'igmp'
        option family 'ipv4'
        option target 'ACCEPT'

config rule
        option name 'Allow-DHCPv6'
        option src 'wan'
        option proto 'udp'
        option dest_port '546'
        option family 'ipv6'
        option target 'ACCEPT'

config rule
        option name 'Allow-MLD'
        option src 'wan'
        option proto 'icmp'
        option src_ip 'fe80::/10'
        list icmp_type '130/0'
        list icmp_type '131/0'
        list icmp_type '132/0'
        list icmp_type '143/0'
        option family 'ipv6'
        option target 'ACCEPT'

config rule
        option name 'Allow-ICMPv6-Input'
        option src 'wan'
        option proto 'icmp'
        list icmp_type 'echo-request'
        list icmp_type 'echo-reply'
        list icmp_type 'destination-unreachable'
        list icmp_type 'packet-too-big'
        list icmp_type 'time-exceeded'
        list icmp_type 'bad-header'
        list icmp_type 'unknown-header-type'
        list icmp_type 'router-solicitation'
        list icmp_type 'neighbour-solicitation'
        list icmp_type 'router-advertisement'
        list icmp_type 'neighbour-advertisement'
        option limit '1000/sec'
        option family 'ipv6'
        option target 'ACCEPT'

config rule
        option name 'Allow-ICMPv6-Forward'
        option src 'wan'
        option dest '*'
        option proto 'icmp'
        list icmp_type 'echo-request'
        list icmp_type 'echo-reply'
        list icmp_type 'destination-unreachable'
        list icmp_type 'packet-too-big'
        list icmp_type 'time-exceeded'
        list icmp_type 'bad-header'
        list icmp_type 'unknown-header-type'
        option limit '1000/sec'
        option family 'ipv6'
        option target 'ACCEPT'

config rule
        option name 'Allow-IPSec-ESP'
        option src 'wan'
        option dest 'lan'
        option proto 'esp'
        option target 'ACCEPT'
        option enabled '0'

config rule
        option name 'Allow-ISAKMP'
        option src 'wan'
        option dest 'lan'
        option dest_port '500'
        option proto 'udp'
        option target 'ACCEPT'
        option enabled '0'

config ipset
        option name 'LAN4'
        option family 'ipv4'
        list match 'dest_net'
        list entry '10.0.0.0/8'
        list entry '127.16.0.0/12'
        list entry '192.168.0.0/16'

config ipset
        option name 'LAN6'
        option family 'ipv6'
        list match 'dest_net'
        list entry 'fc00::/7'
        list entry 'fd00::/8'

config rule
        option name 'Mark-VPN'
        option src 'lan'
        option dest '*'
        option target 'MARK'
        option set_mark '9990'
        list proto 'all'
        list src_mac '[REDACTED] My Devices'

config rule
        option name 'Mark-LAN4'
        option family 'ipv4'
        option src 'lan'
        option ipset 'LAN4'
        option dest '*'
        option target 'MARK'
        option set_mark '9991'
        option mark '9990'
        list proto 'all'

config rule
        option name 'Mark-LAN6'
        option family 'ipv6'
        option src 'lan'
        option ipset 'LAN6'
        option dest '*'
        option target 'MARK'
        option set_mark '9991'
        option mark '9990'
        list proto 'all'

config nat
        option name 'VPN-NAT4'
        option src 'lan'
        option target 'MASQUERADE'
        option mark '9990'
        option family 'ipv4'
        list proto 'all'

config nat
        option name 'VPN-NAT6'
        option src 'lan'
        option target 'MASQUERADE'
        option mark '9990'
        option family 'ipv6'
        list proto 'all'

The NAT could be necessary as this traffic could be classified as INVALID.
The Traffic starts running via the main router but return traffic is going directly.

If you allow invalid traffic on the interfaces it might work without NAT.

For this make sure you did not enable DROP invalid traffic and also you have to Allow invalid traffic on the LAN interface under CONNTRACK settings (I am not sure about the latter)

P.S. if you want all traffic to run via the Pi could you not simply add a static route for all traffic with an exception for the Pi's address?

1 Like

Firewall mark is for device whitelist, I don't want to disrupt other people using the same network.

With NAT I can't monitor each device's traffic since for Pi everything comes from the router.

Allowing invalid connections seems like it's breaking standards so I'd prefer to avoid that.

What about using g policy based routing? You can send the vpn bound traffic to the pi (as the gateway) based on the client devices that should use the tunnel.

1 Like

The PBR package does the same thing as I did, it generates fwmarks and routes. And the last time I checked, it only supports routing to different interfaces.

Iā€™m not a PBR expert, so that may be true (or maybe it has more features now). That said, you could put the pi on another subnet such that you can use PBR via an interface to get to the pi. There is no reason that the pi really needs to be on the same l2 subnet as your client devices.

Another approach could be to make your pi into the main router and then your c6 could be a dumb ap. This will greatly simplify the routing as it will all be handled by a single gateway.

1 Like

Having different subnets for clients and gateways is what I'm looking into, but I'm having trouble setting it up on LuCI, particularly with dhcp and ipv6 prefixes.

The main thing is to ensure the network isn't completely dependent on a device I'm regularly tinkering with, hence this setup.

I'm confused. Why can you just route via the tunnel instead of complex proxying via firewall rules?

Most firewall rules are on the pi itself to ensure the main out-facing firewall stays simple.

Anyway, I think I'll set up two VLANs for this. Although I'm still not sure how to limit the prefixes dhcp delegates to downstream clients.