I am relatively new to networking, so please bear with me. For a purely educational project, I've set up a network where the Raspberry Pi 3 running Raspbian Stretch is to function both as a router and a DHCP server. The intention is to have a private network that shares an internet connection. Here's the network topology:
+----------+
| Internet |
+-----+----+
| (wlan0)
+-----+----------+
| Raspberry Pi 3 | (router + DHCP server)
+-----+----------+
| (eth0)
+-----+--+
| Switch | (TP-Link 5-Port Desktop Switch TL-SF1005D)
+-----+--+
|
+-----+-------+
| My Computer |
+-------------+
The private network is to be 10.0.0.0/24
, with the Raspberry Pi (which is the router and DHCP server) having the 10.0.0.1
address (through eth0).
Routing Configuration on Raspberry Pi
For Raspberry Pi to route packets between wlan0
and eth0
, I did sudo sysctl -w net.ipv4.ip_forward=1
(and edited /etc/sysctl.conf
to make the change permanent).
Next, on initially empty iptables tables, I did:
# iptables -P INPUT ACCEPT
# iptables -P OUTPUT ACCEPT
# iptables -P FORWARD DROP
# iptables -t nat -A POSTROUTING -o wlan0 -j MASQUERADE
# iptables -A FORWARD -i wlan0 -o eth0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# iptables -A FORWARD -i eth0 -o wlan0 -j ACCEPT
Network Interface Configuration on Raspberry Pi
Because Raspbian Stretch uses /etc/dhcpcd.conf
instead of /etc/network/interfaces
to automatically configure network interfaces, I editied /etc/dhcpcd.conf
to look like this (see the MY SETTINGS
section):
# /etc/dhcpcd.conf on Raspberry Pi (router + DHCP server).
# Inform the DHCP server of our hostname for DDNS.
hostname
# Use the hardware address of the interface for the Client ID.
clientid
# Persist interface configuration when dhcpcd exits.
persistent
# Rapid commit support.
option rapid_commit
# A list of options to request from the DHCP server.
option domain_name_servers, domain_name, domain_search, host_name
option classless_static_routes
# Most distributions have NTP support.
option ntp_servers
# Respect the network MTU. This is applied to DHCP routes.
option interface_mtu
# A ServerID is required by RFC2131.
require dhcp_server_identifier
# Generate Stable Private IPv6 Addresses instead of hardware based ones
slaac private
# MY SETTINGS:
interface eth0
static ip_address=10.0.0.1/24
static broadcast_address=10.0.0.255
static domain_name_servers=8.8.8.8 8.8.4.4
DHCP Configuration on Raspberry Pi
I've installed isc-dhcp-server
and configured it like this:
# /etc/dhcp/dhcpd.conf on Raspberry Pi (router + DHCP server).
# Configuration file for ISC dhcpd
# Use Google Public DNS.
option domain-name-servers 8.8.4.4, 8.8.8.8;
default-lease-time 600;
max-lease-time 7200;
ddns-update-style none;
authoritative;
subnet 10.0.0.0 netmask 255.255.255.0 {
range 10.0.0.10 10.0.0.254;
option routers 10.0.0.1;
option broadcast-address 10.0.0.255;
}
Configuration for serving eth0
only:
# /etc/default/isc-dhcp-server on Raspberry Pi (router + DHCP server).
INTERFACESv4="eth0"
INTERFACESv6=""
Then I rebooted the Raspberry Pi, and ensured that isc-dhcp-server
is started.
An Observation of the Problem
Excited about the new network, I took a computer (My Computer
in the network diagram above), and connected an ethernet cable to its ethernet port. The computer does not connect, so I take a look at /var/log/syslog
on the computer. There, I see these lines:
home dhclient[14783]: DHCPDISCOVER on enp3s0 to 255.255.255.255 port 67 interval 3 (xid=0xcab1222)
home dhclient[14783]: DHCPDISCOVER on enp3s0 to 255.255.255.255 port 67 interval 5 (xid=0xcab1222)
home dhclient[14783]: DHCPDISCOVER on enp3s0 to 255.255.255.255 port 67 interval 14 (xid=0xcab1222)
home dhclient[14783]: DHCPDISCOVER on enp3s0 to 255.255.255.255 port 67 interval 16 (xid=0xcab1222)
## etc.
Curious about whether or not the Raspberry Pi (router + DHCP server) is receiving these requests, I looked at /var/log/syslog
on the Raspberry Pi:
rpi dhcpd[9685]: DHCPDISCOVER from f4:8e:38:e9:88:d7 (home) via eth0
rpi dhcpd[9685]: DHCPOFFER on 10.0.0.11 to f4:8e:38:e9:88:d7 (home) via eth0
rpi dhcpd[9685]: DHCPDISCOVER from f4:8e:38:e9:88:d7 (home) via eth0
rpi dhcpd[9685]: DHCPOFFER on 10.0.0.11 to f4:8e:38:e9:88:d7 (home) via eth0
rpi dhcpd[9685]: DHCPDISCOVER from f4:8e:38:e9:88:d7 (home) via eth0
rpi dhcpd[9685]: DHCPOFFER on 10.0.0.11 to f4:8e:38:e9:88:d7 (home) via eth0
## etc.
Indeed the Raspberry Pi is sending DHCPOFFER
s but the client computer is somehow not receiving them (or ignoring them).
A Strange Observation
Wanting to probe further, I ran tcpdump
on My Computer
. After connecting the ethernet cable to My Computer
, I ran sudo tcpdump -n udp port 68 -v
. And... it connects! My Computer
gets an IP address (10.0.0.11
) from the DHCP server. And I can use the connection to successfully browse stackoverflow.com
without any problems.
Curious, I unplugged and replugged the ethernet cable, and then ran tcpdump
slightly differently: sudo tcpdump -n udp port 68 --no-promiscuous-mode -v
. Unfortunately, back to square one: no connection, no assigned IP address.
So it seems that My Computer
can receive the DHCPOFFER
, but only in promiscuous mode? I don't think the NIC is to blame; I am able to use wired ethernet successfully outside this experiment.
Another observation: I tried to connect My Computer
to the network again, but this time without the switch (i.e. direct ethernet connection from My Computer
to the RPi). Exact same problem. Exact same observation in the logs and with the tcpdump
behavior.
Questions
- Is my network topology correct?
- Is my network hardware correct?
- What is wrong with the network configuration?
I've been trying to solve this problem by reading up a lot, and I've learned a lot from that, but I think it's time for me to get some pointers.