World of networks and [Mikrotik](https://mikrotik.com) devices

Transparent Mikrotik

Wyze Base Station created an interesting conundrum for my network. Unlike most IoT devices, it requires a cable connection. Place where I wanted to place it didn’t have any. So, the choice was to either bring a new cable or figure some other method. Of course, some other method it is.

As often, my hammer for those situation was Mikrotik device. In this case mAP lite. Idea was to create a transparent bridge (or as close to it as possible) between the Base Station and my network. Ideally, it would even keep MAC address of base station.

This is what I ended up going with:

/interface wireless
set [ find default-name=wlan1 ] ssid=^^SSID^^ mode=station-pseudobridge frequency=auto 

/interface wireless security-profiles
set [ find default=yes ] authentication-types=wpa2-psk wpa2-pre-shared-key=^^key^^

/interface bridge
add name=bridge1 protocol-mode=none

/interface bridge port
add bridge=bridge1 interface=wlan1
add bridge=bridge1 interface=ether1

First step was to switch wireless into station-pseudobridge mode. While it has a lot of warnings (mostly due to L2 bridging being tricky with wireless), it’s actually ideal for this situation as one device it connects to will be the sole user of it.

Once wireless security has been setup, all remaining is to create a bridge with both wireless and wired interface.

And that’s it.

Configuring HTTP/2 for WordPress on Ubuntu

Last year I wrote this exact article only to find out it’s no longer current. So, as I rebuilt my web server on a new VM, I decided to bring it a bit of update for PHP 7.4

The first step, of course, is enabling HTTP/2 module:

a2enmod http2

Second step is adding HTTP/2 protocol definition to /etc/apache2/apache2.conf:

Protocols h2 h2c http/1.1
H2Direct on
H2ModernTLSOnly on

Followed by Apache’s restart:

systemctl restart apache2

In ideal world this would be it. But, despite Apache starting without error, a check via Developer Tools will show HTTP 1.1 is still in use. So we need an additional PHP with FastCGI support:

apt-get install php7.4-fpm

Furthermore, we need some modules enabled and disabled:

a2dismod php7.4
a2dismod mpm_prefork
a2enmod mpm_event
a2enmod proxy_fcgi
a2enconf php7.4-fpm

Of course, addition to /etc/apache2/apache2.conf is needed too:

<Files "*.php">
   SetHandler "proxy:unix:/var/run/php/php7.4-fpm.sock|fcgi://localhost/"
</Files>

If you configured prefork before, you also need to remove it’s configuration. In my case StartServers, MinSpareServers, MaxSpareServers, MaxClients, and MaxRequestsPerChild settings had to go.

Of course, another Apache restart is upon us:

systemctl restart apache2

Congratulations! HTTP/2 should be working now.

Automatic Mangling

Mikrotik routers give you a lot of control over traffic. If you stick with IPv4, it’s possible to nicely subdivide your network and use queues to traffic-shape any user’s bandwidth based on IP address. But things are not as easy when you allow IPv6. Suddenly your simple queues are essentially broken and tracking users becomes quite a lot more difficult.

For exactly that purpose, you have firewall mangle rules. In its simplest form, you just use MAC address as a condition to mark your connection and then you use that connection mark to mark each packet. In Mikrotik’s lingo, that would be something like this:

/ip firewall mangle add
    chain=forward
    src-mac-address=^^12:34:56:78:90:12^^
    connection-state=new
    action=mark-connection
    new-connection-mark=^^some-mark^^

/ip firewall mangle add
    chain=forward
    connection-mark=^^some-mark^^
    action=mark-packet
    new-packet-mark=^^some-mark^^
    passthrough=no

Illustration

Now you can use this packet mark in a simple queue as a condition instead of the subnet or IP. If you go further and create these mange rules in /ipv6 section as you did for /ip, you have yourself an easy way to track traffic even on per-MAC resolution.

The real challenge then becomes entering all these rules into the router. In order to fill this, it’s best to have a script as executing all these commands manually is really error prone. I like to keep this in a file looking something like this:

12:34:56:78:90:ab user1-mark
23:45:67:89:0a:bc user1-mark
34:56:78:90:ab:cd user2-mark

Using this I don’t necessarily track or limit traffic per device but per user. As long as all user’s MAC addresses result in the same mark, queue doesn’t really care.

I mark all automatic entries with !AUTO! in the comment field. Any time I want to update firewall rules, I make sure to delete the old ones first:

OLD_V4_ENTRIES=`ssh router.home "/ip firewall mangle print without-paging" | grep ";;; !AUTO!" | awk '{print $1}' | xargs | tr ' ' ','`
if [[ "$OLD_V4_ENTRIES" != "" ]]; then
    ssh router.home "/ip firewall mangle remove numbers=$OLD_V4_ENTRIES"
fi

OLD_V6_ENTRIES=`ssh router.home "/ipv6 firewall mangle print without-paging" | grep ";;; !AUTO!" | awk '{print $1}' | xargs | tr ' ' ','`
if [[ "$OLD_V6_ENTRIES" != "" ]]; then
    ssh router.home "/ipv6 firewall mangle remove numbers=$OLD_V6_ENTRIES"
fi

With old entries gone, we can add new entries using something like this:

cat ^^~/MAC.dat^^ | grep -v '^#' | while read ENTRY; do
    MAC=`echo "$ENTRY" | xargs | cut -sd' ' -f1`
    MARK=`echo "$ENTRY" | xargs | cut -sd' ' -f2`
    if [[ "$MAC" != "" ]] && [[ "$MARK" != "" ]]; then
        echo "$MAC $MARK"
        ssh -n router.home "/ip firewall mangle add chain=forward src-mac-address=$MAC connection-state=new action=mark-connection new-connection-mark=$MARK comment=\"!AUTO!\""
        ssh -n router.home "/ip firewall mangle add chain=forward connection-mark=$MARK action=mark-packet new-packet-mark=$MARK passthrough=no comment=\"!AUTO!\""
        ssh -n router.home "/ipv6 firewall mangle add chain=forward src-mac-address=$MAC connection-state=new action=mark-connection new-connection-mark=$MARK comment=\"!AUTO!\""
        ssh -n router.home "/ipv6 firewall mangle add chain=forward connection-mark=$MARK action=mark-packet new-packet-mark=$MARK passthrough=no comment=\"!AUTO!\""
    fi
done

Script above will go over the whole file, skipping all the comments, and assuming the first field in line is MAC address and the second is the mark you want to assign it. Then it will just add mangle pair to both IPv4 and the IPv6 firewall rules.

The last step is to force firewall to clear the existing connections so it can mark them with the new marks.

ssh -n router.home "/ip firewall connections remove [find]"
ssh -n router.home "/ipv6 firewall connections remove [find]"

Only thing now is to create simple queue based on each mark. And yes, that can be automated too. :)

Rebooting RB1100HAx4 via Reset Button

One thing that annoyed me about my Mikrotik RB1100HAx4 router was the need to unplug darn thing when I wanted to reboot it. It does have reset button but the darn thing is just there for resetting configuration. Simple reboot was not the part of the repertoire.

Well, that changed with RouterOS 6.47. As of them there is a few more options under settings - most notably reset button configuration. Now action on reset button can be configured.

And it’s easy enough.

/system routerboard reset-button
set enabled=yes on-event="/log info message=(\"Reset button\")\r\n/system reboot"

PS: This works with vast majority of Mikrotik routers and switches. But not all so your mileage may wary.

Multiple IPv6 Networks with Mikrotik

Illustration

Setting up IPv6 for home network is simple enough with Mikrotik. I actually already wrote about it and that IPv6 guide is still perfectly valid. However, what if you have multiple bridges and a single IPv6 address won’t do (e.g. home and guest network)?

Well, first you need to be lucky enough to have provider willing to give you multiple /64 prefixes as stateless address autoconfiguration (SLAAC) cannot work with prefix longer than that.

For this to work you need a prefix hint to let your provider know you want something bigger. Despite RIPE recommending at least /56 prefix length, my Comcast-provided connection gives /60 at most even if you request a shorter prefix.

/ipv6 dhcp-client
add interface=^^ether1^^ pool-name=general-pool6 request=prefix prefix-hint=::/48 add-default-route=yes

Once you receive IP allocation, check on Status tab you indeed got something shorter than /64. If you got only /64 allocation, you will not be able to have two independent networks. In my case, /60 enables me up to 16 networks.

Next we add additional router address to use for advertisement.

/ipv6 address
add address=::1 from-pool=general-pool6 interface=^^bridge2^^ advertise=yes

Lastly, we need to setup router announcements.

/ipv6 nd
add interface=^^bridge2^^ ra-interval=20s-60s

And that’s it. Now your guests can enjoy IPv6 too.

Curious Case of Missing DHCP Renewal

Most of my network is based on Mikrotik routers and they serve me well. Even though I have decent mix of different operating systems present and I never had any issues. Until I got Ubuntu 19.10 Server up and running.

At the first glance, all worked perfectly and then suddenly machine would stop responding. Quick check from console interface pointed toward the culprit - there was no IP address present. Check on Mikrotik for DHCP leases was showing “waiting” state. Manually running dhclient on Ubuntu did temporarily resolve problem only to have address gone at the next DHCP expiration interval.

For some reason Ubuntu 19.10 Server would do DHCP once and then give up on further renewals. It was as if dhclient was crashing. Check of the syslog has shown curious entries:

systemd-networkd: eno1: DHCPv4 address 192.168.1.103/24 via 192.168.1.1
systemd-networkd: eno1: Could not set DHCPv4 route: Network is unreachable
systemd-networkd: eno1: Failed

I had DHCP classless static route option set on my Mikrotik and it seems dhclient really didn’t like my setup with multiple CIDRs. As soon as I removed all entries except for the default one, it started working properly.

On a hunch, I tried changing the network order to have default route as the first one and it worked. What also worked was omitting default gateway altogether and only having narrower CIDR definitions.

There is nothing in RFC3442 forcing this order and either ordering works for all other clients - including non-server Ubuntu 19.10. I guess something in Ubuntu Server configuration is making dhclient misbehave when things are not exactly how it wants it.

However, considering either ordering is perfectly valid, I decided to take a simpler route and update my classless route definition.

Checking XigmaNAS Network Speed

If your XigmaNAS server is a bit slow, it’s often beneficial to see what is your network speed before changing settings - especially if you are on wireless. If your network cannot handle more than 50 Mbps, you cannot complain when you have only 5 MB/s Samba transfer rate.

While there are many ways you can check the speed, I usually find iperf3 the best choice. Not only it comes preinstalled on XigmaNAS, but you can also download precompiled binaries for Windows, Linux, and BSD to start with. If that’s not enough, you can always use freely available source and compile it yourself.

My approach is first starting server on XigmaNAS (or FreeNAS if that’s your NAS platform of choice):

iperf3 -s

Once server is listening I run the following commands on client, giving it IP address of that server:

iperf3 -c ^^192.168.0.1^^

And that’s it. This command will send data for 10 seconds toward server and receive back the same from it.

Armed with the number you can now deal with that pesky SMB3 performance.

Attacking WPA2 PSK And Mikrotik Fix

Illustration

With everybody awaiting WPA3, it’s easy to miss improved WPA2 attacks. Up until recently cracking the WPA2 with pre-shared key required online attack. Well, not anymore.

This new attack doesn’t even require waiting for 4-way handshake - essentially all you need is a few minutes of passive traffic, minimal amount of luck, and a bit of alone time to crack the key - offline. If you are willing to go active capture time goes down to a second and no luck is involved. The only real challenge is offline cracking - and there is no time pressure here.

Without going into too many details, issue is in optional PMKID field that does come in handy for roaming support. Unfortunately, for most routers, PMKID gets sent even if roaming option is off.

There are two “fixes” for this. The obvious one is to increase complexity of your pre-shared key while avoiding ones present in the precalculated SHA-1 tables. We are still talking about brute forcing SHA-1 hash - a non-trivial task if you have long and random password.

Second approach is to disable PMKID field and that would require you to upgrade router’s firmware. Fortunately for me, Mikrotik already has a fix available and thus avoiding it as easy as selecting to Disable PMKID.

Mind you, that’s not absolute protection as weak passwords are still vulnerable no matter how you cut it. But this does prevent offline attack.

Wireless X-Box 360

My only console - X-Box 360 - is a bit aged by any standard. I don’t find that too bothersome except in one aspect - network connection. Being aged means it has only wired ethernet. Considering I “bought it” for actual cost of $0, paying $50 for wireless adapter would be a bit of a premium.

Fortunately, I had Mikrotik mAP Lite lying around. It’s a small device with 2.4 GHz and a single 100 Mbps RJ-45 Ethernet connector. While not obviously designed to be a wireless client, its powerful software does allow for this.

The very first step is not only resetting Mikrotik mAP lite configuration but actually deleting it fully. Either using System, Reset Configuration, and selecting No Default Configuration or going via terminal is equally good:

/system
reset-configuration no-defaults=yes

Starting with the blank slate would be problematic for many devices, but not Mikrotik as one can always use WinBox and its neighbor search option to connect using MAC address.

On the empty device, the first step is creating the security profile and connecting to the wireless via the bridge. In my case I used WPA2 and with n-only wireless. While default of b/g/n (2.4ghz-b/g/n) does offer a bit more flexibility when it comes to compatibility with other devices, using n-only does help with network’s speed (e.g. beacons are always transmitted at the slowest speed standard allows). Of course, you will also need to know the wireless SSID.

In the Mikrotik’s language these steps can be expressed with the following commands:

/interface wireless security-profiles
add name=security-profile authentication-types=wpa2-psk mode=dynamic-keys \
    wpa2-pre-shared-key=^^KEY^^

/interface wireless
set [ find default-name=wlan1 ] disabled=no band=^^2ghz-onlyn^^ frequency=auto \
    mode=station-pseudobridge security-profile=security-profile ssid=^^SSID^^

The only thing remaining is creating the bridge and putting all devices into it.

/interface bridge
add name=local-bridge

/interface bridge port
add bridge=local-bridge interface=wlan1
add bridge=local-bridge interface=ether1

Connecting Mikrotik’s mAP to X-Box via RJ45 and USB cable (for power) will now dutifully transfer all the packets via the wireless interface.

Supermicro's IPMI Firewall Rules

Illustration

If your internal firewall is very restrictive or you need to expose IPMI to the outside world, you might be presented with a bit of a challenge due to quite varied port selection.

The first ports you have to allow are of course TCP 80 and 443 for web management interface. Almost all IPMI implementations have it and quite often it’s the interface with the most features. For example, Supermicro’s implementation only allows BIOS update and port number changes over web interface. This interface unfortunately stops just short of allowing console access.

To get access via IPMI tool (I use Supermicro’s IPMI View) you need to have UDP port 623 allowed through. This will allow logging into the IPMI interface and seeing machine’s status. Unfortunately, this too stops short of console access.

The key to the console (aka KVM) access is in TCP ports 3520 and 5900. These will allow you to see and type into. And only if you ever ran IPMI in nonrestrictive network would you notice something missing.

The missing piece is the menu, allowing you to mount virtual media and similar. For this you need to enable TCP port 623. This will finally allow full control over the hardware.

It’s a bit of annoyance that so many ports are needed but in general this doesn’t present the problem. Unless there are special circumstances, you shouldn’t access IPMI from the outside via port forwarding. What you should do is use VPN and then use IPMI via it.