Wireless Guest Network, Client Isolation- Under The Hood
Wireless Guest Network is a very common feature for an Access Point device. In this article, I’ll explain why do we need such network and how exactly it is implemented in a typical access point.
As the name suggests Guest Network is for the guest. Now a days, almost all, if not all, organisation provides wireless network in the office for their employees to connect and access various network resources. However when some external customers, employee’s friend, relatives, interviewee etc comes to visit the office, how the organisation can provide internet connectivity to them? Of Course not, it’s a grave security concern. We need to find a way to allow guest internet access, at the same time deny any access to LAN resources.
Let’s consider above topology. Real office topology can be way more complex or simpler depending on the size of organisation. My intention here is is just make it complex enough to demonstrate the concept.
Employee connected to emp_ssid should be able to reach to server1, server2, server3, server4 as well as internet. Firewall can do routing when server2 or server3 are accessed Or there can be an L3 switch in the mix or some router also can be there for routing. Let’s assume some magic box is there to route between resources on switch1 & switch2 side and switch3 side. With this assumption, let’s put the requirements for Guest Network (guest_ssid).
- Guest should be able to connect to guest_ssid network with authentication configured in the guest_ssid.
- Guest shouldn’t be able to reach out to any resources on the LAN (server1, server2, server3 , server4 or any other employees devices that are connected to emp_ssid).
- If admin wants, may provide access to specific IP:Port on the LAN. Let’s say server4:port1111 made accessible.
- Guest should be able to get internet connection.
- One Guest Device shouldn’t be able to reach another Guest Device.
Ways to achieve the requirements:
VLAN:
Whenever we think about traffic isolation, the default option come to our mind is VLAN. We can isolate guest traffic using VLAN without using guest network feature of access point. Most, if NOT all, access point supports VLAN configuration for a specific network (a.k.a SSID). We can put guest_ssid network on a specific VLAN other than the ones where LAN resources are . But there is a catch here. We have to be very careful about routing part in the magic box. We have to make sure that routing for guest VLAN subnet must not happen to switch3 side.
Also what happens to requirement no 5 ? VLAN won’t stop that.
Guest Network Feature in AP:
Even though VLAN can handle the Guest, it requires a certain level of competency. But most of the access point provides a very simple, one click solution for the same.
Single click fulfils all of the requirements, but let’s see how all of those requirements are achieved. I have seen two kind of implementation in the access points.
Kernel Patch:
In the kernel wireless driver packet path, we can put up a patch to drop a packet before pushing to the kernel networking stack. Here is a sample code snippet that achieve same. This function allows all the white listed IP and Ports and drops all other traffic to any private subnet.
//If this API returns 0, packet should be processed further or else should be dropped
int does_packet_needs_to_be_dropped(wlan_if_t vap ,struct sk_buff *skb)
{
struct iphdr *ip;
struct ethhdr *eth = (struct ethhdr *)skb_mac_header(skb);
int16_t ip_hlen;
ip = (struct iphdr *)(skb_mac_header(skb) + sizeof(struct ethhdr));
ip_hlen = ip->ihl * 4;
if ( ip_is_whitelisted(ip) ) // If IPs are white Listed
return 0;
if ( port_is_whitelisted(ip) ) // If ports are white listed
return 0;
// Drop any other private network IP
if (((ip->daddr & htonl(0xFF000000)) == htonl(0x0A000000)) || /* class A private address 10.0.0.0/8 */
((ip->daddr & htonl(0xFFF00000)) == htonl(0XAC100000)) || /* class B private address 172.16.0.0/12 */
((ip->daddr & htonl(0xFFFF0000)) == htonl(0xC0A80000)) || /* class C private address 192.168.0.0/16 */
((ip->daddr & htonl(0xF0000000)) == htonl(0xE0000000)) || /* class D private address 224.0.0.0/4 */
((ip->daddr & htonl(0xF1000000)) == htonl(0xF0000000)) /* class E private address 240.0.0.0/5 */
) return 1;
return 0;
}But this a bit tricky, you need to figure out where exactly to call this function, probably as soon as you receive SKB. Also for requirement 3, you need a mechanism to pass on whitelisted IP:PORT to driver and driver needs to maintain those whitelisted IP Ports. Req.5 might or might NOT be fulfilled based on where exactly we inject this patch. Also this is NOT very portable and generic solution. None the less, I have seen this implementation.
Using ebtables or iptables:
More generic way to achieve those requirements would be to use ebtables or iptables rules to meet those requirements. Here is sample ebtable rules.
ebtables -t nat -A PREROUTING --in-interface ath9 -p IPv4 --ip-proto udp --ip-dport 67:68 -j ACCEPTAbove rule allows DHCP traffic so that guest can get IP address. Here ath9 is my wireless interface which should work as guest network. Usually iwconfig commands shows your wifi interface name for your network.
You should replace ath9 with whatever interface name name matches with your SSID name
ebtables -t nat -A PREROUTING --in-interface ath9 -p IPv4 --ip-proto udp --ip-dport 53 -j ACCEPT
ebtables -t nat -A PREROUTING --in-interface ath9 -p IPv4 --ip-proto tcp --ip-dport 53 -j ACCEPTAbove rules allows DNS traffic so that address to IP resolution happens. Two rules are for TCP and UDP. Similar rule can be applied for any whitelisted port.
ebtables -t nat -A PREROUTING --in-interface ath9 -p IPv4 --ip-proto tcp --ip-dst 192.168.1.29 --ip-dport 1111 -j ACCEPTAbove rule is for white listed IP. It may be required or may not be based on if any whitelisted network or IP is required or NOT. For our requirement 4 , 192.168.1.29 is server4 IP and port 1111 . Rule can be used for a network as well. Also if you have a captive portal on this SSID, you have to whitelist captive portal IP and port so that captive portal is reachable by client.
ebtables -t nat -A PREROUTING --in-interface ath9 -p IPv4 --ip-dst 10.0.0.0/8 -j DROP
ebtables -t nat -A PREROUTING --in-interface ath9 -p IPv4 --ip-dst 172.16.0.0/12 -j DROP
ebtables -t nat -A PREROUTING --in-interface ath9 -p IPv4 --ip-dst 192.168.0.0/16 -j DROPFinally Drop all other packets that has destination IP in private IP subnet range.
Note that iptable rules will only work if your AP is running a dhcp server to issue IPs to the client and AP behaves like a gateway. AP must must put some NAT rules for outgoing traffic. If you AP is working purly like a bridge where clients gets IP from the network, packets won’t hit iptables rule in AP as packet won’t reach to APs L3 layer. In such case ebtables is the only option.
Similarly iptables rules also can be applied like below. But I haven’t tested with iptables rule, but tested with ebtable rules and worked fine. I think iptables rule also should work fine. Here are sample rules.
iptables -t nat -A PREROUTING -i ath9 -p udp --dport 67:68 -j ACCEPT
iptables -t nat -A PREROUTING -i ath9 -p udp --dport 53 -j ACCEPT
iptables -t nat -A PREROUTING -i ath9 -p tcp --dport 53 -j ACCEPT
iptables -t nat -A PREROUTING -i ath9 -p tcp -d 192.168.1.29 --dport 1111 -j ACCEPT
iptables -t nat -A PREROUTING -i ath9 -p tcp -d 10.0.0.0/8 -j DROP
iptables -t nat -A PREROUTING -i ath9 -p tcp -d 172.16.0.0/12 -j DROP
iptables -t nat -A PREROUTING -i ath9 -p tcp -d 192.168.0.0/16 -j DROPiptables or ebtables needs kernel built with those support and also corresponding kernel modules (ebtable_nat.ko, iptable_nat.ko)are needed to be inserted.
If you want to experiment, you can create a simple SSID, apply above rules and that’ll become your guest SSID.
But above rules still can’t satisfy Req.5. Why ?
When two device are connected to same wireless network, traffic from one device to another doesn’t hit the filters we set. There is one more feature that all access point usually provides comes handy here.
Client Isolation:
This feature makes sure that clients connected to same AP, can’t talk to each other. Typically, it’s a single click and when guest network is chosen, this is also chosen by default.
Underlying implementation is done at the wireless driver level. I have found some wireless driver code in github and providing link of the same. Client Isolation selection results in setting up IEEE80211_F_NOBRIDGE flag in the driver. At wireless driver data delivery path there is a check if this flag is set or not. If not set (i.e. client isolation is disabled) then that means bridging within the wirless interface will be attempted. If destination is connected to same interface, data is retransmitted to same, without pushing the packets to network stack. If destination is doesn’t belong to same interface or IEEE80211_F_NOBRIDGE flag is set, packets are pushed to kernel network stack.
Now the biggest question is which method to use for securing the network so that guest can’t access network ?
VLAN is the fundamental element in networking, used for traffic isolation, but it requires a some technical competency. If competency is available, one must use VLAN to isolate guest traffic. On the other hand Guest network, combined with Client Isolation is also a robust mechanism to restrict guest for any other access and configuration is just few clicks and a layman can do it. Any attempt to access private network will be dropped at access point itself.
One must use guest network and if competency is there, guest network with VLAN is the best option.
