Skip to content

Instantly share code, notes, and snippets.

Last active Nov 20, 2021
What would you like to do?
NAT/DHCP/DNS on a Raspberry Pi 1B

Blog 2020/2/4

<- previous | index | next ->

NAT/DHCP/DNS on a Raspberry Pi 1B

This is a tutorial on how setup a Raspberry Pi as a NAT router, with custom local DNS.

system diagram


This tutorial is using a Raspberry Pi 1 Model B and a USB-Ethernet dongle.

raspberry pi

usb-ethernet dongle

(Search amazon for "usb ethernet raspberry pi".)

Note: plugging in the Ethernet dongle may reboot the Pi. I recommend you insert the dongle before booting up your Pi.

Install Raspbian

Grab the latest Raspbian Lite from and burn it to an SD card.

On my Linux box, that's pv 2019-09-26-raspbian-buster-lite.img > /dev/mmcblk0.

Configure Raspbian

  • Boot the Pi
  • Login as pi, password raspberry
  • sudo raspi-config
    • Localisation Options -> Change Locale (to en_US.UTF-8)
    • Localisation Options -> Change Timezone (to America / Chicago)
    • Localisation Options -> Keyboard Layout (to Generic 104, Other -> English US)
    • Interfacing Options -> SSH (enable)
  • Make note of the IP address (ifconfig eth0)
  • Logout
  • Login via ssh as pi, then sudo -i
  • Change root's password (run passwd)
  • Append your ~/.ssh/ to /root/.ssh/authorized_keys
  • Logout
  • Login via ssh as root
  • deluser pi && rm -rf /home/pi

Configure network interfaces

Disable systemd's DHCP:

systemctl disable dhcpcd.service

Note: on systems which predated systemd, this would have been update-rc.d dhcpcd disable.

Configure both interfaces in /etc/network/interfaces:

# eth0: LAN connection to local network
auto eth0
iface eth0 inet static

# eth1 is the WAN connection to cable modem and is handled by systemd.
auto eth1
iface eth1 inet dhcp

Set up NAT

Install iptables:

apt-get install iptables

Create /usr/local/sbin/


# this script adapted from

set -e



# delete all existing rules.
iptables -F
iptables -t nat -F
iptables -t mangle -F
iptables -X

# Always accept loopback traffice
iptables -A INPUT -i lo -j ACCEPT

# Allow established connections, and those not coming from the outside.
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -m state --state NEW ! -i $WAN -j ACCEPT
iptables -A FORWARD -i $WAN -o $LAN -m state --state ESTABLISHED,RELATED -j ACCEPT

# Allow outgoing connections from the LAN side
iptables -A FORWARD -i $LAN -o $WAN -j ACCEPT

# Masquerade
iptables -t nat -A POSTROUTING -o $WAN -j MASQUERADE

# Don't forward from the outside to the inside.
iptables -A FORWARD -i $WAN -o $WAN -j REJECT

# Enable routing.
echo 1 > /proc/sys/net/ipv4/ip_forward
chmod u+x /usr/local/sbin/

Edit /etc/rc.local and add a call to this script:


Note: if there is an exit 0 line in your rc.local, ensure this call comes before that line!

Set up local DHCP and DNS

apt-get install dnsmasq

Edit /etc/dnsmasq.conf:

# Set the domain for dnsmasq. this is optional, but if it is set, it
# does the following things.
# 1) Allows DHCP hosts to have fully qualified domain names, as long
#     as the domain part matches this setting.
# 2) Sets the "domain" DHCP option thereby potentially setting the
#    domain of all systems configured by DHCP
# 3) Provides the domain part for "expand-hosts"
# Note: only a few domains are safe from conflict with public TLD's.
# In particular, '.local' causes problems.
# See

# Add local-only domains here, queries in these domains are answered
# from /etc/hosts or DHCP only.

# Set this (and domain: see below) if you want to have a domain
# automatically added to simple names in a hosts-file.

# Thanks to
# Use /etc/hosts.dnsmasq rather than /etc/hosts for local DNS.

# Use /etc/ethers to map MAC addresses to hostnames.

# Override the default route supplied by dnsmasq, which assumes the
# router is the same machine as the one running dnsmasq.

# The range of IP addresses to use for DHCP "guests" (machines not listed
# in /etc/ethers).

# The DNS cache size (number of records, hard limit is 10000).

# Set the DHCP server to authoritative mode. This avoids long timeouts
# when a machine wakes up on a new network.
# See

# Never forward plain names (without a dot or domain part).

# Never forward addresses in the non-routed address spaces.

# Send an empty WPAD option. This may be REQUIRED to get windows 7 to behave.

# Set the DHCP server to enable DHCPv4 Rapid Commit Option per RFC 4039.
# In this mode it will respond to a DHCPDISCOVER message including a Rapid Commit
# option with a DHCPACK including a Rapid Commit option and fully committed address
# and configuration information. This must only be enabled if either the server is 
# the only server for the subnet, or multiple servers are present and they each
# commit a binding for all clients.

# For debugging purposes, log each DNS query as it passes through
# dnsmasq.
# Note: leaving this enabled will wear out your SD card.

# Log lots of extra information about DHCP transactions.
# Note: leaving this enabled will wear out your SD card.

Fill out /etc/hosts.dnsmasq: larry curly moe

Fill out /etc/ethers:

01:23:45:67:89:AB larry
01:23:45:67:89:AC curly
01:23:45:67:89:AD moe

Disable unused services

systemctl disable avahi-daemon

Reduce swappiness

This will save a bit of wear-and-tear on your SD card. Add this to /etc/sysctl.conf:


Update Raspbian

apt-get update
apt-get dist-upgrade


apt-get install openntpd
Copy link

thomaswesenberg commented Aug 28, 2021

There's an error in /usr/local/sbin/
iptables -A FORWARD -i $WAN -o $WAN -j REJECT
should be
iptables -A FORWARD -i $WAN -o $LAN -j REJECT

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment