In a previous post, I have shown a configuration using Hostapd, Ubuntu and a Belkin USB dongle allowing me to have Wi-Fi access.
This work reasonably well but the speed of the dongle was 54 Mbps only. So I decided to buy a Panda PAU06 Wireless N USB adapter.
The reason was that Panda claimed it was Linux compatible and it will operate at 150 Mbps. I know 150 Mbps is so slow nowadays, but I do not need that much speed on the WLAN, all my devices are wired with Gigabit speed.
I do not have several people competing for bandwidth also.
If I need to stream something I use, the media center connected to a big-screen TV.
This setup actually worked fairly well, using Fedora 29 on VMWARE Workstation.
The setup used routing and that created some issues with the “/64” prefixes I am given by my provider that you can read in that post.
Well, I accidentally deleted the VM guest the other day, yes I had no backup but I am always careful, this time it bit me in the behind.
Thus this time I decided to re-do the setup but instead use bridging to connect the LAN and WLAN interfaces. This is working rather well, so read on.
Initial Plan and Requirements
The idea is to use a wireless dongle to provide Wi-Fi access to devices. The dongle will act as an access point running on a Linux server.
My network connects to an ISP via a modem provided by them. However, it just provides me with an internet IP address, both IPv4 and IPv6.
Instead of a router, I use a Linux distro to provide firewalling and services inside, including DHCP and IPv6 addresses. This server also acts as a router for devices in my LAN.
So in my case, the server with the dongle will be my wireless router.
- A wireless dongle interface. Since I plan to use Linux, a compatible dongle should be used. In my case, I am using a Panda PAU06 USB adapter.
- A suitable server. I am using Fedora Core 29. This is a virtual machine created using VMWARE Workstation on a Fedora Core server (my file server). You can use a physical server if you have one or a fanless mini-pc as long as you can install Linux. Any Linux distro will do, but it needs to be the latest so the dongle will be recognized.
- Hostapd, to enable the dongle to act as an access point.
- Bridge Tools, although on Fedora 29 they are installed by default. Also, you can create bridging interfaces using the IP utility.
- Iptables and Ip6tables.
You may ask why I need a firewall if my devices are inside and they will no be exposed to the internet?
Below are some of the reasons:
- Limit connections to your SSID by some means.
- Allow only known devices to obtain an IP address. You achieve this by filtering MAC addresses. This does not prevent MAC spoofing.
- You can also hide your SSID (security through obscurity). Done by Hostpad, not the firewall, though.
If someone wants to hack you, they will but you can minimize the risk.
If you are really paranoid, you can use software that will alert you if someone joins your SSID and if you do not recognize the device, have the ability to drop it.
- If you have your server, a physical or virtual install FC 29.
- Install bridge-utils if not installed already.
- Plug the dongle and see if the OS recognizes it.
At a shell prompt issue:
sudo cat /var/log/messages | grep -A5 -B5 wlan
You should see the following:
Oct 22 04:18:46 wifi systemd: Reached target Sound Card. Oct 22 04:18:46 wifi kernel: ieee80211 phy0: rt2x00_set_rt: Info - RT chipset 5392, rev 0223 detected Oct 22 04:18:47 wifi kernel: ieee80211 phy0: rt2x00_set_rf: Info - RF chipset 5372 detected Oct 22 04:18:47 wifi kernel: usbcore: registered new interface driver rt2800usb Oct 22 04:18:47 wifi systemd-udevd: link_config: autonegotiation is unset or enabled, the speed and duplex are not writable. Oct 22 04:18:47 wifi kernel: rt2800usb 1-1:1.0 wls36u1: renamed from wlan0 Oct 22 04:18:47 wifi wireless: setting regulatory domain to US based on timezone (America/Los_Angeles)
Bring the interface up using:
sudo ifconfig wls36u1 up
Notice that wls36u1 is the name given to the interface in my case, the name given to your dongle will be different. You also need to be root or use “sudo.”
Test that Hostapd can be used as an access point.
Create the following file and named it hostapd-minimal.conf:
#change wlan0 to your wireless device interface=wlan0 driver=nl80211 ssid=test channel=1
Now run it:
sudo hostapd ./hostapd-minimal.conf Configuration file: ./hostapd-minimal.conf Line 2: invalid/unknown driver 'nl80211' 1 errors found in configuration file './hostapd-minimal.conf'
If you see errors as above then your wireless card is not supported by Hostapd.
The solution you need a different dongle.
A word of advice. Select the correct dongle that your Linux distro supports.
In general, the RALINK chipset or the Atheros chipset have broad Linux support.
However, the Realtek family of chipsets has spotty support. You will be able to compile the drivers using drivers from the aircrack-ng website.
If you do not feel comfortable compiling drivers for the kernel then stick with the USB that provides support.
The only drawback is that some of the newest dual-band adapters using the 5-GHz band use the Realtek chipset that can do 300+ Mbps.
Create The Bridge
Create the bridge using the IP utility, add your LAN interface to it and show the bridge has the interface, bring the bridge up. Issue the following commands:
sudo ip link add br0 type bridge ip link show br0 sudo brctl addif br0 "your LAN interface(eth0, ensxx, etc.)" brctl show bridge br0 sudo ifconfig br0 up
You should see the bridge named “br0” and your LAN interface added to it.
Configure The Network
Now you need to set the interfaces, so they keep their configuration at boot time.
Network configuration varies from distro to distro.
Since I am using Fedora, the instructions are for it. Others consult your documentation.
At a shell prompt issue:
The network-scripts directory contains text files that are read by NetworkManager and executed at boot time.
As a precaution make a copy of the file ifcfg-ifname, where ifname is the name of the LAN interface in my case ens33, this will be different on your system.
Named the copy whatever you what remembering that if you need to restore it, it has to have the original name.
Copy the file with the interface name to ifcfg-br0. Now edit both files using your favorite editor, vi or nano.
The ifcfg-ifname should look like:
TYPE="Ethernet" PROXY_METHOD="none" BROWSER_ONLY="no" BOOTPROTO="none" DEFROUTE="yes" NAME="Your LAN interface name" DEVICE="Your LAN interface name" ONBOOT="yes" IPV6INIT="yes" IPV6_AUTOCONF="yes" IPV6_DEFROUTE="yes" IPV6_FAILURE_FATAL="no" IPV6_ADDR_GEN_MODE="stable-privacy" BRIDGE=br0"
The IPv6 statements are only necessary if you use IPv6. If not you can delete them.
The bridge interface ifcfg-br0 should look like:
TYPE="Bridge" PROXY_METHOD="none" BROWSER_ONLY="no" BOOTPROTO="none" IPV6INIT="yes" IPV6_AUTOCONF="yes" IPV6_DEFROUTE="yes" IPV6_FAILURE_FATAL="no" IPV6_ADDR_GEN_MODE="stable-privacy" DEFROUTE="yes" IPADDR="192.168.1.x" (or whatever your lan is) NETMASK="255.255.255.0" DEVICE="br0" ONBOOT="yes"
Notice that a static IPv4 IP has been given, this IP should be in the range of your current LAN.
For example, if your router uses 192.168.1.1 then use 192.168.1.x (use the same netmask.)
One note regarding IPv6, you need to have the IPv6 statements for IPv6 support on both interfaces. If not you will not obtain an IPv6 via SLAAC from your router.
Fort testing purposes add the IP that you set above.
sudo ip add add 10.192.168.x/24 dev br0
Finally, add the appropriate default route:
/usr/sbin/ip add add 192.168.1.1/24 dev br0
Once again use the appropriate IP, this is normally the IP of the main router on your LAN. This will be made permanent later by using rc.local.
Test by pinging. If you get replies your bridge is working.
Notice we did not add a file for the wireless adapter, this is because the adapter will not allow you to add it to the bridge.
Hostpad will be able to do so when it starts.
Now create a file hostapd.conf, with an editor, fill it so it looks like the following:
interface="Your wireless interface" bridge=br0 driver=nl80211 ssid="The name you want to identify your WLAN" hw_mode=g channel=11 macaddr_acl=0 auth_algs=1 ignore_broadcast_ssid=0 wpa=3 wpa_passphrase="A passphrase the more complicated the better" wpa_key_mgmt=WPA-PSK wpa_pairwise=TKIP rsn_pairwise=CCMP ieee80211n=1
The above will work with a 2.4 GHz adapter (g mode), for 2.5/5.0 GHz use n mode.
Copy the file to /etc/hostapd/.
Now start it by issuing the following:
sudo systemctl enable hostapd sudo systemctl restart hostapd
Check that Hostapd has started:
sudo systemctl status hostapd
Now you will be able to see your SSID and connect to it.
Of course, by now you would have run into a Hostapd bug has had for at least 10 years.
When you start Hostapd, it wipes out the network configuration.
The solution after starting Hostapd is to re-add the IP configuration. This can be done with rc.local.
Putting It All Together
Every time you reboot, your configuration should stay. To do this we will use rc.local.
First, enable the ability to use rc.local:
sudo systemctl enable rc-local
Now create the following file rc.local, put it in /etc/rc.d/rc.local.
It should look like:
#!/bin/bash # # ---------------------------------------------------------- # # IMPORTANT! # # Enable the firewalls. Otherwise any client on the WLAN will # be able to request an address via DHCP or NDP. # # Only hosts with particular MAC addresses are allowed to # traverse the FW (FORWARD chain). This is enough to block # such requests. # # Of course this does not protect you against MAC address # spoffing but it is good enough for most purposes. # # END. # --------------------------------------------------------- # # Enable WiFi /usr/sbin/ifconfig wls36u1 up # /usr/sbin/ifconfig br0 up # # Restart Hostapd /usr/bin/systemctl restart hostapd # # Sleep for 5 seconds to give time for hostapd to finish. /usr/sbin/sleep 5 # # Hostapd deletes the IPV4 address from br0. This is a known bug. # Re-add ens33 to bridge and give an IP. Add routing also. # # Add ens33 to bridge br0 /usr/sbin/brctl addif br0 ens33 # # Make sure bro is up. /usr/sbin/ifconfig br0 up # /usr/sbin/ip add add 10.1.1.100/24 dev br0 # # Add default route /usr/sbin/route add default gw 10.1.1.1 # # Enable IPV4 FW /usr/sbin/iptables-restore < /home/ipv4-restore.txt # # Enable IPV6 FW /usr/sbin/iptables-restore < /home/ipv6-restore.txt #
A few points.
- Use the correct interfaces for your system.
- Use the correct IP addressing for your system.
- Finally, use Iptables.
For Iptables, you need to craft your own rules; this because is up to you what you want to allow, block and log.
Having said that, you can take advantage of the ability of Iptables to filter by MAC address.
The syntax you will use will be:
-A FORWARD -m mac --mac-source XX:XX:XX:XX:XX -m physdev --physdev-in wls36u1 --physdev-out ens33 -m sta te --state NEW -j ACCEPT
The above will work for either IPv4 or IPv6.
You can have as many entries as devices you want to filter. Notice that the filter is not applied to br0.
Instead, we use the ability to use the physical device, in this case for input your LAN interface and for output the WLAN interface.
Notice also that this is applied to the FORWARD chain.
Of course, you will also need rules to allow established connections and allow new connections on the INPUT chain so you can manage the router.
Finally, you will need to allow new connections out via the OUTPUT chain.
You have now a working access point using Linux, a USB adapter and Hostpad.
A few remarks:
- We are using a 150 Mbps dongle. A dual-band dongle will give you more speed.
- Make sure the dongle is supported by your Linux distro.
- If not then you will have to compile the drivers yourself. This is not that difficult.
I have been using this setup now for a few months and it is very stable.