0

I'm trying to set up a raspberry pi as a network bridge between a wireless access point and a router (the reason for this being that I'd like to connect a device to the AP and use tc on the pi to simulate a poor network). The router is wired to the pi at eth0 and the AP is wired to the pi at eth1 (usb to ethernet adapter).

I'm using dhcpcd and dnsmasq to try accomplish this. However, even though I can connect a device to the AP and it is provided with an ip address (within the range specified in dhcpcd.conf), all pings (whether to domains or ip address) time out (I can't even ping the pi when connected to the AP).

I have enabled ipv4 forwarding in /etc/sysctl.conf:
net.ipv4.ip_forward=1

To the default dhcpcd.conf I've added:

# eth1 is connected to the AP
interface eth1
# This is the ip address of the Raspberry Pi
static ip_address=10.0.0.100/24
# This is the ip address of the router
static routers=10.0.0.1

My dnsmasq.conf looks like this (I'm not entirely sure the interface is correct, I've set it to be the interface connected to the AP but changing it to eth0 doesn't seem to make any difference):

interface=eth1
listen-address=10.0.0.100
bind-interfaces
server=8.8.8.8
server=8.8.4.4
domain-needed
bogus-priv
dhcp-range=10.0.0.110,10.0.0.130,4h

I ran these commands to add iptable rules (I then saved iptables to a file and am restoring them on boot via rc.local):

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

From what I've read, the rules above should be correctly forwarding traffic through the pi, but this doesn't seem to be the case.

I checked the status of the dhcpcd and dnsmasq services but didn't see anything that looks like an error.

dhcpcd status:

● dhcpcd.service - dhcpcd on all interfaces
   Loaded: loaded (/lib/systemd/system/dhcpcd.service; enabled; vendor preset: enabled)
  Drop-In: /etc/systemd/system/dhcpcd.service.d
           └─wait.conf
   Active: active (running) since Tue 2019-02-26 12:02:43 GMT; 29min ago
 Main PID: 368 (dhcpcd)
   CGroup: /system.slice/dhcpcd.service
           └─368 /sbin/dhcpcd -q -w

Feb 26 12:02:43 raspberrypi dhcpcd[368]: eth0: offered 10.0.0.140 from 10.0.0.1
Feb 26 12:02:43 raspberrypi dhcpcd[368]: eth0: probing address 10.0.0.140/24
Feb 26 12:02:47 raspberrypi dhcpcd[368]: eth0: using IPv4LL address 169.254.202.179
Feb 26 12:02:47 raspberrypi dhcpcd[368]: eth0: adding route to 169.254.0.0/16
Feb 26 12:02:48 raspberrypi dhcpcd[368]: eth0: leased 10.0.0.140 for 86400 seconds
Feb 26 12:02:48 raspberrypi dhcpcd[368]: eth0: adding route to 10.0.0.0/24
Feb 26 12:02:48 raspberrypi dhcpcd[368]: eth0: adding default route via 10.0.0.1
Feb 26 12:02:49 raspberrypi dhcpcd[368]: eth0: deleting route to 169.254.0.0/16
Feb 26 12:02:50 raspberrypi dhcpcd[368]: eth0: no IPv6 Routers available
Feb 26 12:02:50 raspberrypi dhcpcd[368]: eth1: no IPv6 Routers available

dnsmasq status:

● dnsmasq.service - dnsmasq - A lightweight DHCP and caching DNS server
   Loaded: loaded (/lib/systemd/system/dnsmasq.service; enabled; vendor preset: enabled)
   Active: active (running) since Tue 2019-02-26 12:02:43 GMT; 33min ago
 Main PID: 401 (dnsmasq)
   CGroup: /system.slice/dnsmasq.service
           └─401 /usr/sbin/dnsmasq -x /run/dnsmasq/dnsmasq.pid -u dnsmasq -r /run/dnsmasq/resolv.conf -7 /etc/dnsmasq.d,.dpkg-dist,.dpkg-old,.dpkg-new --local-service --trust-anchor=.,19036,8,2,49aac11d7b6f6446702e54a1607371607a1a41855200fd2ce1cdde32f24e8fb5 --trust-anchor=.,20326,8,2,e06d44b80b8f1d39a95c0b0d7c65d0

Feb 26 12:02:50 raspberrypi dnsmasq-dhcp[401]: DHCPDISCOVER(eth1) a0:f3:c1:6d:2f:1b
Feb 26 12:02:50 raspberrypi dnsmasq-dhcp[401]: DHCPOFFER(eth1) 10.0.0.129 a0:f3:c1:6d:2f:1b
Feb 26 12:02:50 raspberrypi dnsmasq-dhcp[401]: DHCPDISCOVER(eth1) a0:f3:c1:6d:2f:1b
Feb 26 12:02:50 raspberrypi dnsmasq-dhcp[401]: DHCPOFFER(eth1) 10.0.0.129 a0:f3:c1:6d:2f:1b
Feb 26 12:02:58 raspberrypi dnsmasq-dhcp[401]: DHCPDISCOVER(eth1) a0:f3:c1:6d:2f:1b
Feb 26 12:02:58 raspberrypi dnsmasq-dhcp[401]: DHCPOFFER(eth1) 10.0.0.129 a0:f3:c1:6d:2f:1b
Feb 26 12:02:58 raspberrypi dnsmasq-dhcp[401]: DHCPREQUEST(eth1) 10.0.0.129 a0:f3:c1:6d:2f:1b
Feb 26 12:02:58 raspberrypi dnsmasq-dhcp[401]: DHCPACK(eth1) 10.0.0.129 a0:f3:c1:6d:2f:1b TL-WR702N
Feb 26 12:35:05 raspberrypi dnsmasq-dhcp[401]: DHCPREQUEST(eth1) 10.0.0.124 f4:5c:89:8e:aa:a1
Feb 26 12:35:05 raspberrypi dnsmasq-dhcp[401]: DHCPACK(eth1) 10.0.0.124 f4:5c:89:8e:aa:a1 george

In this status, TL-WR702N is the AP and george is a device connected to the AP.

I'm stumped as to where I went wrong. I was following a tutorial for setting up a pi as bridge and have tried to debug this issue by referring to the man pages for dnsmasq, dhcpcd and iptables to no avail.

The pi has been rebooted since setting this up.

  • Be careful with the vocabulary: the question and tags say "bridge" (please hover on the tag's description), but the description says "routing" and has not a single bridge reference. This is not the same. The tutorial uses the word "bridge" but doesn't describe a bridge. A comment notices it: "Also, important to note that this setup is a wifi client NAT router, not technically a bridge". Can you clarify your goal? Can't you just plug the AP to the router without the RPi if your really want a bridge (the AP is already a bridge between wireless and ethernet) ? – A.B Feb 26 at 18:53
  • My goal is indeed to use the Pi as a bridge, and to use the kernel's traffic control to make the network unreliable for devices connected to the AP (but not for devices connected directly to the router). I hadn't noticed the comment about it being a NAT router and not a bridge; I'll do some more research. I may have to go about this a completely different way... – Alex Meuer Feb 26 at 19:10
  • 1
    try this: wiki.debian.org/BridgeNetworkConnections . Don't look for a RPi tutorial, because it will surely assume the RPi is the AP (which it is not). Also note the wiki is a bit outdated and that brctl as well as ifconfig are obsolete commands, and should be replaced with ip link + ip address (and less frequently also with bridge ... ), but anyway it's hidden in the /etc/network/ config – A.B Feb 26 at 19:19
  • You were absolutely right. Following the debian wiki was much more straightforward and actually worked like a charm, no fiddling about with iptables or dnsmasq. Thank you. If you want to write that in an answer, I'd be happy to accept it. – Alex Meuer Feb 27 at 12:40
  • Just realized I didn't write the answer. It's done. Also added some more information (especially a link to a netem question similar to your own goal) – A.B Mar 15 at 22:57
2

After looking at the linked tutorial ( https://pimylifeup.com/raspberry-pi-wifi-bridge/ ), I could conclude that this is not a bridge tutorial, but a NAT/router tutorial. Even a comment in it also states:

Also, important to note that this setup is a wifi client NAT router, not technically a bridge.

So to actually use a bridge, follow a bridge tutorial. Since it's Raspbian, Debian's BridgeNetworkConnections should be good enough. The bridge-utils package mentionned isn't really needed for its (obsolete) brctl command which could be completely replaced with modern iproute2's ip link and (if actually needed) bridge, but for its bridge-utils-interfaces plugin for ifupdown's configuration.

So in the end the configuration can be done with something similar to:

iface eth0 inet manual

iface eth1 inet manual

auto br0
iface br0 inet dhcp
    bridge_ports eth0 eth1

Don't put any IP on the real interfaces, because they now become bridge ports and their layer 3 settings will be ignored. Also not vital but the bridge should inherit its first's interface MAC address. So if it really matters and you'd rather have eth1's MAC used, put it first in the bridge_ports command (this would probably also change the router's DHCP offer).

Now change any reference to eth0 in various settings that would state an interface into br0 instead, but chances are you don't even need this, since for example you don't need anymore dnsmasq. That's it.

Some extra informations:

  • If you ever use iptables instead or in addition of ebtables to try to do filtering between the two interfaces (hint: you should probably not, it's a bridge now, not a router, but it's needed for a stateful transparent firewalling bridge), please be aware, if activating br-netfilter of the special interactions between the bridge filtering and the IP filtering layers: ebtables/iptables interaction on a Linux-based bridge. This can lead to hard-to-debug results when not knowing about it.

  • Many tc qdisc effects (like netem) work on the outgoing direction (egress) only. Since you're between both interfaces eth0 and eth1 , you could ponder that you can always find an egress interface for a specific intended action, but if it's done on eth0 then the RPi itself can be affected on the internet side, which is probably not what is wished. You can avoid this by attaching an Intermediate Functional Block device (ifb0) to eth1: this artificially inserts an interface between the ingress and the rest of the network code. This interface is thus now an egress interface from the point of view of eth1's incoming data flow, and can happily accept egress features like netem. For any other interpretation it's part of the ingress flow. You can now then apply TC to eth1 and ifb0 and leave eth0 undisturbed. More informations in my answer there: Simulation of packet loss on bridged interface using netem

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.