Wireless AP with udhcpd and NAT: Difference between revisions

From Alpine Linux
(Guide to setting up a home router)
 
(replace /etc/init.d with rc-service)
 
(15 intermediate revisions by 7 users not shown)
Line 2: Line 2:
Setting up a wireless AP with udhcpd and NAT
Setting up a wireless AP with udhcpd and NAT


(baseed largley on the [http://elinux.org/RPI-Wireless-Hotspot raspberry pi wireless router howto])
(based largely on the [https://elinux.org/RPI-Wireless-Hotspot raspberry pi wireless router howto])


= Dependencies =
= Dependencies =


{{Cmd|apk add hostapd udhcpd iptables}}
Install the hostapd access point software, busybox-extras (for the udhcpd DHCP server),
and the iptables firewall manager.


hostapd provides the AP.
{{Cmd|apk add hostapd busybox-extras iptables}}
udhcpd is the dhcp server.


If you want to connect clients to the internet, you need to provide some way
If you want to connect clients to the internet, you need to provide some way
of redirecting traffic from the AP to the rest of the internet.
of redirecting traffic from the AP to the internet.
There are two main possibilities:
There are two main possibilities:
*setting up a bridge
*A bridge
*using NAT (network address translation).
*Network Address Translation


If you use a bridge and get your IP via DHCP, you may have a hard time
If you use a bridge and get your IP via DHCP, you may have a hard time
configuring it so that the bridge gets an ip without screwing up your
configuring it such that the bridge gets an IP address without screwing up your
local internet connection.
local internet connection.
This guide only covers NAT; see [[Bridge]] for more on the alternative.
 
This guide only covers NAT. See [[Bridge]] for more info.


= Configure hostapd =
= Configure hostapd =
You need to write a configuration file; Alpine ships with a sample one in
You need to write a configuration file. Alpine ships with a sample file in
/etc/hostapd/hostapd.conf, but it didn't work for me (possibly because I
/etc/hostapd/hostapd.conf, but it didn't work for me (possibly because I
used a pre wireless-N card, supported by ath5k?).
used a pre-wireless-N card, supported by ath5k?).


Here's a sample one based on something that did work for me  
Here's a sample based on something that did work for me  
(I've changed ssid & wpa_passphrase):
(I've changed ssid & wpa_passphrase):
  ctrl_interface=/var/run/hostapd
  ctrl_interface=/var/run/hostapd
Line 52: Line 53:


Change "interface" to match your wireless interface.
Change "interface" to match your wireless interface.
Change "ssid" and "wpa_passphrase" to suit your desires.
Change "ssid" and "wpa_passphrase" as necessary.
Set "wpa" to 3 if you want plain wpa and wpa2. or 1 for plain WPA1 only.
Set "wpa" to 3 if you want plain wpa and wpa2. or 1 for plain WPA1 only.


The example in the package uses wpa_psk_file (needed for WPS) instead of a
The example in the package uses wpa_psk_file (needed for WPS) instead of a
static passphrase; this does not enable WPS.
static passphrase. That does not enable WPS.


You may want to change the channel to avoid collision with other local APs.
You may want to change the channel to avoid collisions with other local APs.
Unfortunately, the automatic channnel selection (channel=0) is *not*
Unfortunately, the automatic channnel selection (channel=0) is *not*
currently enabled at compile time, so we can't use it; scan for channels
currently enabled at compile time, so we can't use it. Scan for channels
in use with {{Cmd|iwlist wlan0 scanning}} or equivalent before setup.
in use with {{Cmd|iwlist wlan0 scanning}} or equivalent, before setup.


max_num_sta is a limit to the number of clients connecting to your AP.
max_num_sta sets a limit on the number of clients that can connect to your AP.
Set it higher than you think you could have, but not much higher.
Set it higher than you think you might have, but not much higher.


If you don't put this in /etc/hostapd/hostapd.conf, you will need to change
If you don't put this in /etc/hostapd/hostapd.conf, you will need to change
the CONFIGS line in /etc/conf.d/hostapd to point at it.
the CONFIGS line in /etc/conf.d/hostapd to point at it.
I prefer doing that, so that the default is available for reference.
I prefer doing that, so that the default is available for reference.


= Configure udhcpd =
= Configure udhcpd =


Edit /etc/udhcpd.conf.
Edit /etc/udhcpd.conf.
The default is very well-commented, but not perfectly ready to use.
The default is very well-commented, but not really ready to use.
Here's a skeleton, loosely based on mine:
Here's a skeleton, loosely based on mine:
  start 192.168.2.2
  start 192.168.2.2
Line 87: Line 87:


Note the following:
Note the following:
*max_leases should be set to at least as many clients as you might have in
*max_leases should be set to at least as many clients as you might have in the lifetime of a lease. If you have any clients connecting via bridges, note that the bridge itself gets a DHCP address.
the lifetime of a lease; if you have any clients connecting via bridges,
*interface is the interface clients will be connecting to (wlan0 or your wireless interface in this example)
note that the bridge itself gets a dhcp address.
*router should be the static IP address you assign to your wireless interface.
*interface is the interface clients will be connecting to (wlan0 or your
*start and end should be within the same subnet as the IP address you configure wlan0 with, but the address for wlan0 should be outside the range.
wireless interface in our example)
(e.g. 192.168.2.1 and 192.168.2.255 are both suitable for the router address)
*router should be the static IP address you give to your wireless interface.
*set the DNS option to point to any nameservers you want. You can repeat it, but the limit is 3 nameservers.
*start and end should be within the same subnet as the IP you configure
*static_lease takes two arguments: a MAC address designating a specific network adaptor, and the IP address that should be assigned to it.
wlan0 with, but the IP for wlan0 should be outside the range.
It can be repeated multiple times, to assign different addresses to different users.
(For example: 192.168.2.1 and 192.168.2.255 are both suitable for the router
This comes in handy for printers, if you can trust network users to not do MAC spoofing.
IP in this example.)
*set the dns option to point to any nameservers you want; you can repeat it,
but there's a maximum of 3 nameservers.
*static_lease takes two arguments: a MAC address designating a specific
network adaptor, and the IP address that should be assigned to it.
It can be repeated multiple times, to assign different IPs to different
users.
This comes in handy for printers, if you can trust those who connect to
the network to not do MAC spoofing.


= Configure iptables =
= Configure iptables =
Line 111: Line 102:
{{Cmd|iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
{{Cmd|iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
iptables -A FORWARD -i eth0 -o wlan0 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i eth0 -o wlan0 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT
iptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT}}
# this saves the state somewhere that the service can restore it from
# this saves the state in a location the service can restore it from
service iptables save}}
<code>
service iptables save
</code>


= Test =
= Test =
{{Cmd|/etc/init.d/hostapd start
<code>
/etc/init.d/udhcpd start
rc-service hostapd start
sysctl net.ipv4.ip_forward=1}}
 
and try connecting from another computer
rc-service udhcpd start
 
sysctl net.ipv4.ip_forward=1
</code>
and try connecting from another computer.


= Make changes permanent =
= Make the changes permanent =


{{Cmd|rc-update add hostapd
{{Cmd|rc-update add hostapd
Line 130: Line 127:
Now, the odd parts:
Now, the odd parts:
iptables tries to set net.ipv4.ip_forward to 1 when it's started, but in
iptables tries to set net.ipv4.ip_forward to 1 when it's started, but in
my experience, this cannot be relied upon.
my experience, this is not reliable.
You do *not* want to enable the "iptables" service; it starts before
You do *not* want to enable the "iptables" service. It starts before
networking, and may result in your wireless interface not getting configured.
networking, and may result in your wireless interface not getting configured.
(Apparently, ifup thinks that wlan0 is up and skips it. This was not something I expected, but it's the only explanation I have for how things worked...)
(Apparently, ifup thinks that wlan0 is up and skips it. This was not something I expected, but it's the only explanation I have for how things worked...)


Rather, modify /etc/network/interfaces, commenting out any configuration for
Rather, modify /etc/network/interfaces, commenting out any configuration for
your wireless interface. Then add this:
your wireless interface. Then add:


<pre>
<pre>
Line 143: Line 140:
address 192.168.2.1
address 192.168.2.1
netmask 255.255.255.0
netmask 255.255.255.0
up /etc/init.d/iptables start
up rc-service iptables start
up sysctl net.ipv4.ip_forward=1
up sysctl net.ipv4.ip_forward=1
down /etc/init.d/iptables stop
down rc-service iptables stop
</pre>
</pre>


(It would be possible to set everything up so that hostapd and udhcpd get
(It's possible to set up everything so that hostapd and udhcpd get
started and stopped from the wlan0 stanza; I didn't bother doing that.)
started and stopped from the wlan0 stanza. I didn't bother doing that.)
 


= Finishing touches =
= Finishing touches =


(See [[Setting_up_a_ssh-server]] for alternatives and more information)
(See [[Setting up a SSH server]] for alternatives and more information)
Add dropbear SSH server, configure it to run on only the wireless interface:
Add dropbear SSH server, configure it to run on only the wireless interface:
{{Cmd|setup-sshd -c dropbear}}
{{Cmd|setup-sshd -c dropbear}}
Line 161: Line 157:
  DROPBEAR_OPTS="-p 192.168.2.1:22"
  DROPBEAR_OPTS="-p 192.168.2.1:22"


(assuming that the wireless interface has the IP 192.168.2.1 and you
(assuming the wireless interface has the IP address 192.168.2.1 and you
want SSH on port 22).
want SSH on port 22).
This is optional, but if you're using a wireless router it helps to be able
This is optional, but if you're using a wireless router it helps to be able
to administer it, and listening on all addresses is rather risky.
to administer it, and listening on all addresses is rather risky.


= Things this doesn't cover but it would be nice to =
= Things this doesn't cover but it would be nice to =

Latest revision as of 10:31, 17 November 2023

Setting up a wireless AP with udhcpd and NAT

(based largely on the raspberry pi wireless router howto)

Dependencies

Install the hostapd access point software, busybox-extras (for the udhcpd DHCP server), and the iptables firewall manager.

apk add hostapd busybox-extras iptables

If you want to connect clients to the internet, you need to provide some way of redirecting traffic from the AP to the internet. There are two main possibilities:

  • A bridge
  • Network Address Translation

If you use a bridge and get your IP via DHCP, you may have a hard time configuring it such that the bridge gets an IP address without screwing up your local internet connection.

This guide only covers NAT. See Bridge for more info.

Configure hostapd

You need to write a configuration file. Alpine ships with a sample file in /etc/hostapd/hostapd.conf, but it didn't work for me (possibly because I used a pre-wireless-N card, supported by ath5k?).

Here's a sample based on something that did work for me (I've changed ssid & wpa_passphrase):

ctrl_interface=/var/run/hostapd
ctrl_interface_group=0
interface=wlan0
driver=nl80211
logger_syslog=-1
logger_syslog_level=2
logger_stdout=-1
logger_stdout_level=2
ssid=alpine-test
hw_mode=g
channel=6
max_num_sta=32
rts_threshold=2347
fragm_threshold=2346
macaddr_acl=0
auth_algs=3
ignore_broadcast_ssid=0
wpa=2
wpa_passphrase=supertopsecret
wpa_key_mgmt=WPA-PSK WPA-PSK-SHA256
wpa_pairwise=TKIP CCMP

Change "interface" to match your wireless interface. Change "ssid" and "wpa_passphrase" as necessary. Set "wpa" to 3 if you want plain wpa and wpa2. or 1 for plain WPA1 only.

The example in the package uses wpa_psk_file (needed for WPS) instead of a static passphrase. That does not enable WPS.

You may want to change the channel to avoid collisions with other local APs. Unfortunately, the automatic channnel selection (channel=0) is *not* currently enabled at compile time, so we can't use it. Scan for channels

in use with

iwlist wlan0 scanning

or equivalent, before setup.

max_num_sta sets a limit on the number of clients that can connect to your AP. Set it higher than you think you might have, but not much higher.

If you don't put this in /etc/hostapd/hostapd.conf, you will need to change the CONFIGS line in /etc/conf.d/hostapd to point at it. I prefer doing that, so that the default is available for reference.

Configure udhcpd

Edit /etc/udhcpd.conf. The default is very well-commented, but not really ready to use. Here's a skeleton, loosely based on mine:

start		192.168.2.2
end		192.168.2.254
max_leases	64
interface	wlan0
static_lease	00:1b:de:ad:be:ef	192.168.2.100
opt	dns	192.168.0.1 8.8.8.8
opt	subnet	255.255.255.0
opt	router	192.168.2.1
opt	lease	864000

Note the following:

  • max_leases should be set to at least as many clients as you might have in the lifetime of a lease. If you have any clients connecting via bridges, note that the bridge itself gets a DHCP address.
  • interface is the interface clients will be connecting to (wlan0 or your wireless interface in this example)
  • router should be the static IP address you assign to your wireless interface.
  • start and end should be within the same subnet as the IP address you configure wlan0 with, but the address for wlan0 should be outside the range.

(e.g. 192.168.2.1 and 192.168.2.255 are both suitable for the router address)

  • set the DNS option to point to any nameservers you want. You can repeat it, but the limit is 3 nameservers.
  • static_lease takes two arguments: a MAC address designating a specific network adaptor, and the IP address that should be assigned to it.

It can be repeated multiple times, to assign different addresses to different users. This comes in handy for printers, if you can trust network users to not do MAC spoofing.

Configure iptables

I used raw iptables, configuring it thus:

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

  1. this saves the state in a location the service can restore it from

service iptables save

Test

rc-service hostapd start

rc-service udhcpd start

sysctl net.ipv4.ip_forward=1 and try connecting from another computer.

Make the changes permanent

rc-update add hostapd rc-update add udhcpd rc-update add sysctl

Configuring ifup

Now, the odd parts: iptables tries to set net.ipv4.ip_forward to 1 when it's started, but in my experience, this is not reliable. You do *not* want to enable the "iptables" service. It starts before networking, and may result in your wireless interface not getting configured. (Apparently, ifup thinks that wlan0 is up and skips it. This was not something I expected, but it's the only explanation I have for how things worked...)

Rather, modify /etc/network/interfaces, commenting out any configuration for your wireless interface. Then add:

auto wlan0
iface wlan0 inet static
	address 192.168.2.1
	netmask 255.255.255.0
	up rc-service iptables start
	up sysctl net.ipv4.ip_forward=1
	down rc-service iptables stop

(It's possible to set up everything so that hostapd and udhcpd get started and stopped from the wlan0 stanza. I didn't bother doing that.)

Finishing touches

(See Setting up a SSH server for alternatives and more information) Add dropbear SSH server, configure it to run on only the wireless interface:

setup-sshd -c dropbear

edit /etc/conf.d/dropbear to add

DROPBEAR_OPTS="-p 192.168.2.1:22"

(assuming the wireless interface has the IP address 192.168.2.1 and you want SSH on port 22). This is optional, but if you're using a wireless router it helps to be able to administer it, and listening on all addresses is rather risky.

Things this doesn't cover but it would be nice to

This would require:

    • acf-core, acf-alpine-conf, acf-apk-tools
    • acf-iptables, or acf-awall + rewrite
    • acf-ssh + switch to openssh, or new acf-dropbear
    • acf-dhcp + switch to dhcp, or new acf-udhcpd
    • new acf-hostapd (probably hardest part!)
    • acf-tinydns after adding tinydns