MikroTik Solutions

Isolated Guest WiFi Sans VLANs
Login

Motivation

I despise VLANs. They’re unreasonably complicated1 to set up under RouterOS, and once you’ve done so, it’s distressingly common to find cause to make special-case exceptions, justifying hole after hole punched through that barrier until the resulting Swiss-cheese makes you ask, “Why did I do this again?”

Here I show one way to get an effect that is often done with VLANs, but which needn’t be when your requirements are simple,2 as in a typical home LAN case, where you have a lone Internet gateway that is also providing this guest WiFi service. The purpose of this configuration is to replicate the simple checkbox you find in consumer-grade all-in-one router/WiFi gateway devices without taking on the burden of VLANs, which tend to ripple out from the border into the core of the network. This scheme allows the private LAN to remain flat and simple, as I like it.

I characterize this configuration as creating a “guest” network, but it could equally be a dedicated IoT network or whatever else covers your needs.

There have been other articles of this type, but a good many are now at least partially obsolete due to one or more of:

I built and tested this configuration under 7.14 using one of MikroTik’s 802.11ax routers, forcing me down the “wave2” path. It is unlikely to apply directly to older hardware and OS releases.

Our starting assumption is that you began with one of the Quick Set Home AP configurations3, where you set up the basics like your country’s channel allocation rules, the SSID, WiFi Passphrase, and so forth. We’re going to use the default MikroTik network 192.168.88.0/24 for the private LAN and relegate guests to a new 192.168.99.0/24 network.

Slave Interface

First, we must create one or more new “slaves” of our existing WiFi interfaces. Although I did all this atop a hAP ax³, with its dual-band radios, I chose to restrict guests to the 2.4 GHz side (wifi2) for a couple of reasons:

Therefore, we say:

/interface wifi configuration add
name=guestcfg ssid="Guest" \
datapath.client-isolation=yes \
security.authentication-types=wpa2-psk \
.passphrase=yourGuestPSKgoesHere

/interface wifi add
name=wifi2g configuration=guestcfg \
master-interface=wifi2

The “wifi2g” interface name means it is the guest side of the 2.4 GHz network. You are free to call it anything you like.

Although the master interface (wifi2) is on the router’s main bridge, it is important that this new slave not be on any bridge. This not only adds an L2 isolation layer between the guest and private LANs, forcing all intercommunication attempts through the routing layer where we can trap it with firewall rules, it sidesteps a few restrictions in RouterOS that would otherwise bite us below.

The client isolation setting keeps multiple guests from seeing each other even though they’re using a shared RF communication medium. Preventing the smart TV apps from snooping on the doorbell camera stream is all to the good, but equally, there is no reason to allow houseguests to send commands to the smart power plugs. If there is any case where two hosts should interoperate, they don’t belong on this “guest” network.

We’re overriding the default authentication mode of WPA2+WPA3 PSK because IoT devices rarely support WPA3 these days, and when they do, we’re not especially concerned with using it in preference to WPA2. The whole point of this setup is to limit the damage any individual client can do on this network, right?

IP Configuration

We assign a separate IP scheme for our guests thus:

/ip address add address=192.168.99.1/24 interface=wifi2g
/ip pool add name=pool2 ranges=192.168.99.2-192.168.99.254
/ip dhcp-server add name=dhcp2 address-pool=pool2 interface=wifi2g
network add address=192.168.99.0/24 dns-server=1.1.1.1 gateway=192.168.99.1

The first line gives a guest-side IP to the router even though we don’t want to allow guests to access the router itself. We must, because without a local gateway IP, routing won’t work. We’ll block guests from trying to reconfigure our router and such separately with firewall rules, below.

The pool and network configurations parallel ones you likely have for your private LAN already. The main thing to be aware of here is that we don’t reserve any room for static IP allocations in this setup. Only the router itself gets a static IP, .1. The only legitimate way for any other client on the guest network to get an IP is to go through DHCP.

The choice to give out an external DNS address was carefully considered. You may well have the router acting as a caching DNS server and be thinking now, “Why not have it listen on the guest side as well, then give that IP out instead?” The reason is, you might also have that server acting as a local source of host names, with A, AAAA, and CNAME records, and you don’t want guests to be able to dig through all that to discover what’s on the other side of the network. It is for this same reason that we also don’t provide the private side’s domain name to guests via DHCP, nor local NTP server addresses, nor anything else private. If you do anything else here, it would be to set up a separate caching DNS server for the guest side of the network, having no information from the private side.

Firewall

We might as well take full advantage of the fact that all guest network traffic is forced to cross the CPU in this configuration. It lets us be more paranoid about our firewall rules than we otherwise might be when we’re operating under a stricture to get the traffic back into the hardware-accelerated regime as fast as possible, as is common with “switch” class MikroTik hardware.

/ip firewall address-list
add address=192.168.99.2-192.168.99.254 list="Guest WiFi"
/ip firewall filter
add action=drop chain=input dst-address=192.168.99.1 
add action=drop chain=forward dst-address=192.168.88.0/24 src-address-list="Guest WiFi"
add action=drop chain=forward out-interface-list=!WAN src-address=192.168.99.0/24

In order, these rules prevent guests from…

  1. …directly accessing the router itself
  2. …using the router to access the private side of the LAN by IP
  3. …sneaking packets past the prior rule somehow; the only legitimate forwarding path for guest-side traffic is out to the Internet.

The “input” chain rule needs to go above the default “drop” rule in that chain to be effective. Likewise, the “forward” chain rules need to be somewhere in the middle. I’ve got mine above the “defconf: accept established,related, untracked” rule.

Going Beyond

One thing that would significantly improve this scheme is to tunnel4 all guest network traffic from wifi2g outside the LAN so that it emerges directly onto the public Internet. This effectively adds your home router’s border firewall to the layers of protection already provided above.

One of the benefits this would provide is to allow multi-AP networks, where each AP creates a separate tunnel for guest traffic so that it can safely transit the private LAN without interacting with it.

All that gets me beyond the scope of what I’d like to cover here, though, so consider the solution an exercise for the reader. 😉

The Quick Set Alternative

Despite its limitations,3 it’s worth mentioning that Quick Set has a “guest network” feature of its own, which takes an entirely different approach to the one above. If we reuse our network names above instead of its generated ones to aid in drawing the parallel, the Quick Set approach to guest WiFi networking boils down to this:

/interface wifi add … master-interface=wifi2 name=wifi2g …
/interface bridge filter add action=drop chain=forward in-interface=wifi2g
/interface bridge filter add action=drop chain=forward out-interface=wifi2g
/interface bridge port add bridge=bridge interface=wifi2g

That is, it uses bridge filtering instead of IP filtering, and instead of client isolation via the datapath feature, it denies forwarding between the guests and anyone else on that network. This last may be a saving grace when it comes to the fact that it puts everything onto a single L2 domain, not breaking it off as in my configuration above. Surprisingly, it allows the single bridge DHCP server to autoconfigure guests, handing out IP addresses from the same pool. Here again the restriction on forwarding should prevent the guests from interacting with the private LAN at L3, but it feels icky to me.

I took my path because I didn’t want to return to QS and wreck my other custom configurations, but now that I know about this other approach, I’m left without any strong opinion on which approach is objectively better. My subjective opinion is that mine is better, but that may purely be a matter of chef’s prerogative; the soup tastes better after you stir it with your own finger.

Conclusion

I hope this guide has been helpful.

License

This work is © 2024 by Warren Young and is licensed under CC BY-NC-SA 4.0


  1. ^ I point to that series of articles purely to demonstrate the complexity I speak of, not to denigrate @pcunite’s work. Even if you limit your reading to one of the first three articles as a starting point and ignore the other options, you must then add the generic “Security” article below them, then fold in a bunch more of the advice below it from other writers, if only to track the changes in RouterOS 7. My article here is for people who look at all that and “nope” right on out of there. I am not trying to claim that VLANs are useless, merely that they’re over-applied, and in the specific situation covered by this article, unnecessary. They’re the proverbial hammer in everyone’s toolbox, making every isolation problem look like a nail.
  2. ^ The solution this article presents breaks down when you want multiple WiFi APs, and one or more of those edge APs needs to carry the guest network. Short of tunneling the guest network traffic out to the Internet and dumping it there to keep it from interacting with the private LAN, it is at this point that VLANs begin to justify their complexity by providing a tagged channel for the guest traffic, which the intervening switches and routers can use to keep the streams separate.
  3. ^ a b You will find many people online who will tell you that Quick Set is terrible, but I find it quite useful as a starting step. It has only one primary problem: on subsequent visits, it can only reimport the subset of configuration change types it knows how to handle; everything else it tends to overwrite or erase wholesale. Once you’ve got a working configuration, it is far better to modify it in place with either the CLI as we show here or with one of the RouterOS GUIs — WinBox, WebFig, or the mobile apps. The only time you should return to Quick Set to modify a working configuration is when iterating on those first steps, before you get into customization options not covered by Quick Set.
  4. ^ My default choice for this type of task is WireGuard, but any of RouterOS’s other VPN and tunneling technologies should work for this. There are plusses and minuses to each choice, but the important thing they share in common is that they prevent the two networks from interacting at any but the physical layer. If there is no interaction at L2 and above, the guest-side traffic slips right on past the private traffic even as it is carried on the same physical media.