World of networks

Adding WinBox to Ubuntu Applications Menu

Illustration

If you need to run Mikrotik’s WinBox under Ubuntu, solution is wine and 64-bit WinBox download. It works, as far as I can tell, flawlessly. However, I found dropping to command line every time I want to run it, a bit annoying.

Adding WinBox to activities is a two step process. The first step being creation of winbox.desktop file. In its simplest form it can look something like this

[Desktop Entry]
Type=Application
Name=WinBox
Exec=wine ^^/home/user/Apps/winbox64.exe^^

Then, to get application officially registered, we just need to let system know about it:

sudo desktop-file-install winbox.desktop

And this is all it takes for WinBox to find it’s home among other applications.

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.

DNS Conundrum

DNS, known as the phone book of the Internet, is often something you get from your ISP provider with your IP address. And quite often people continue using those automatically given values without ever looking back as such DSN will serve its basic function just fine. But what if you want a bit more privacy, performance, or sometime stability? Enter the world of public DNS resolvers.

One of the first projects to bring DNS to people was OpenNIC. It’s a community driven project with its members providing DNS service on their own hardware similar to how NTP pool works. You select any server close to you and off you go. There are anycast addresses too but their usage is not encouraged albeit I find them much more practical - especially as individual servers can go down at any time. For this service you definitely want to fill secondary DNS server. There are no special privacy features it supports and whether you request is logged or not depends on server’s operator. Support for DNSCrypt is spotty and depends on the exact server you use.

Then came OpenDNS. It’s more centralized service and I found it often has the fastest response of all tested. DNSCrypt is fully supported but privacy is questionable. Enterprise users even have option of getting the logs themselves. If you are only interested in the speed and stability, you won’t go wrong if you select it but don’t expect you’ll know where your data goes.

The first DNS server that started the trend of memorable IP addresses was Google’s. I can almost bet most of its early adoption came from easily memorable 8.8.8.8 IP. Strangely DNSCrypt is not supported yet but privacy is decent. While temporary logs are kept, they are usually deleted within 48 hours. Limited information kept in permanent log is anonymized.

IBM didn’t want to lag behind Google much so they offered Quad9 DNS resolver to the world continuing the trend of easy to remember IP addresses. Privacy is a touch better than Google’s as IP address is not stored even in temporary logs. They do not support DNSCrypt and they do filter content for known phishing sites but supposedly there is no censorship involved. Those willing to deal with slightly more difficult-to-remember IP addresses can get unfiltered access and that’s really nice.

The latest to the party are Cloudflare and APNIC with their DNS. Unfortunately, DNSCrypt is not supported but it does support alternative DNS over HTTPS. While I have small preference toward more usual DNSCrypt, DoH seems to be a reasonable alternative. Most of the logged information is cleared after 24 hours and IP address is not logged in the first place so privacy should not be the issue. Information saved in permanent log does not contain personally identifiable data and it’s even further anonymized. In return for APNIC letting them use awesome 1.1.1.1 IP address, they do share some anonymous log data with them but only for research purposes.

For my personal network I decided to go with Cloudflare and non-filtered Quad9. While their DNS uptime has been impeccable so far, having them both configured does allow a bit of resilience if one network ever goes down. As my network setup unfortunately doesn’t allow me to make encrypted DNS queries I didn’t really take that into account when deciding. However, their claim that IP addresses are not logged did have a measurable impact. I know, there is a great deal of trust involved here but, as both companies do have decent reputation, I do believe their statements.

In the end, everybody values different things and all these choices are valid for one purpose or another. Here are IP addresses for public DNS services in my order of preference:

ProviderPrimary IPSecondary IP
Cloudflare1.1.1.11.0.0.1
2606:4700:4700::11112606:4700:4700::1001
Quad99.9.9.10149.112.112.10
2620:fe::10
Google8.8.8.88.8.4.4
2001:4860:4860::88882001:4860:4860::8844
Quad99.9.9.9149.112.112.112
2620:fe::fe2620:fe::9
OpenNIC185.121.177.177169.239.202.202
2a05:dfc7:5::532a05:dfc7:5::5353
OpenDNS208.67.222.222208.67.220.220
2620:0:ccc::22620:0:ccd::2

Slow Ansible Response Using External IP

As I was playing with Ansible’s ad-hoc commands, I’ve noticed that one host was struggling. Any command I tried took 15 seconds more for it than for any other host.

ansible all -a date

Adding IP to /etc/hosts actually solved that trouble which strongly indicated toward issue actually being connected to DNS setup. But, why the hell was my temporary lab even using DNS? It was just a bunch of virtual machines and I definitely didn’t want to add all hosts by name. I needed another solution…

After a bit of investigation, I discovered the actual culprit - SSH daemon was trying to resolve IP address. For which purpose you ask? Just to write host name to its log.

The final solution was easy - just adding UseDNS no to /etc/ssh/sshd_config:

echo -e "\nUseDNS no" | sudo tee -a /etc/ssh/sshd_config'
sudo systemctl restart sshd

VPN-only Internet Access on Linux Mint 18.3 Via Private Internet Access

Setting up Private Internet Access VPN is usually not a problem these days as Linux version is readily available among the supported clients. However, such installation requires GUI. What if we don’t want or need one?

For setup to work independently of GUI, one approach is to use OpenVPN client usually installed by default. Also needed are PIA’s IP-based OpenVPN configuration files. While this might cause issues down the road if that IP changes, it does help a lot with security as we won’t need to poke an unencrypted hole (and thus leak information) for DNS.

From the downloaded archive extract .crt and .pem files followed by your choice of .ovpn file (usually going with the one physically closest to you). Copy them all to your desktop to be used later. Yes, you can use any other directory - this is just the one I’ll use in example commands below.

Rest of the VPN configuration needs to be done from the Bash (replacing username and password with actual values):

sudo mv ~/Desktop/*.crt /etc/openvpn/
sudo mv ~/Desktop/*.pem /etc/openvpn/
sudo mv ~/Desktop/*.ovpn /etc/openvpn/client.conf

sudo sed -i "s*ca *ca /etc/openvpn/*" /etc/openvpn/client.conf
sudo sed -i "s*crl-verify *crl-verify /etc/openvpn/*" /etc/openvpn/client.conf

sudo echo "auth-user-pass /etc/openvpn/client.login" >> /etc/openvpn/client.conf
sudo echo "mssfix 1400" >> /etc/openvpn/client.conf
sudo echo "dhcp-option DNS 209.222.18.218" >> /etc/openvpn/client.conf
sudo echo "dhcp-option DNS 209.222.18.222" >> /etc/openvpn/client.conf
sudo echo "script-security 2" >> /etc/openvpn/client.conf
sudo echo "up /etc/openvpn/update-resolv-conf" >> /etc/openvpn/client.conf
sudo echo "down /etc/openvpn/update-resolv-conf" >> /etc/openvpn/client.conf

unset HISTFILE
echo '^^username^^' | sudo tee -a /etc/openvpn/client.login
echo '^^password^^' | sudo tee -a /etc/openvpn/client.login
sudo chmod 500 /etc/openvpn/client.login

To test VPN connection execute:

sudo openvpn --config /etc/openvpn/client.conf

Assuming test was successful (i.e. resulted in Initialization Sequence Completed message), we can further make sure data is actually traversing VPN. I’ve found whatismyipaddress.com quite helpful here. Just check if IP detected is different then IP you usually get without VPN.

Stop the test connection using Ctrl+C and proceed to configure OpenVPN’s auto-startup:

echo "AUTOSTART=all" | sudo tee -a /etc/default/openvpn
sudo reboot

Once computer has booted and no further VPN issues have been observed, you can also look into disabling the default interface when VPN is not active. Essentially this means traffic is either going through VPN or not going at all.

Firewall rules are to allow data flow only via VPN’s tun0 interface with only encrypted VPN traffic being allowed on port 1198.

sudo ufw reset
sudo ufw default deny incoming
sudo ufw default deny outgoing
sudo ufw allow out on tun0
sudo ufw allow out on `route | grep '^default' | grep -v "tun0$" | grep -o '[^ ]*$'` proto udp to `cat /etc/openvpn/client.conf | grep "^remote " | grep -o ' [^ ]* '` port 1198
sudo ufw enable

This should give you quite secure setup without the need for GUI.

MAC Address Anatomy

While most people understand the structure behind IPv4 and even IPv6 address, MAC address is usually just assumed as something unique enough not to cause routing issues. But did you ever think whether there is any non-random meaning behind those 48 bits usually expressed as 12 hexadecimal digits?

First bit that gets transmitted is determining if given MAC is for individual device (0) or for a group (1). Most of the time we just care about individual type with group support mostly being used for multicast albeit historically a few more usages were known.

Next transmitted bit controls whether MAC is intended to be globally unique (0) or its intended to be unique only on local level (1). If properly manufactured, all physical network devices will have that bit set to 0 and you can count on it being unique. That being said, I have once personally experienced duplicate MAC on cheap network (ISA) card. However, that is unlikely scenario and hopefully one will never need to troubleshoot it these days.

While one would think locally administered addresses would be an awesome match for virtualization platforms, most don’t take advantage of it and have their addresses instead (incorrectly) allocated from globally unique pool. One major exception is KVM which by default does take care to set bit correctly. Realistically there is no difference in behavior for either choice but I find it nice that someone is actually paying attention.

Further 22 bits are identifier for the organization. Together with aforementioned 2 bits this makes total of 24 bits, also known as three bytes (or octets if you are a stickler). These identifiers are assigned by IEEE and it is easy to check which entity assigned your MAC address. If you despise manual search, you can also check one of the many OUI lookup web sites.

And finally the last 24 bits (the other 3 bytes) are assigned either sequentially or randomly - doesn’t really matter - by manufacturer within their OUI number. The only real requirement is to keep it unique so some manufacturers might have multiple assignments (e.g. almost 500 for Intel Corporations) while others might have just one.

While this covers all 48 bits, there is one piece of puzzle still missing - order of bits. Notice how I said that Individual/Group bit is the one first transmitted. Well, its not the first written. Bits on network get transmitted in least-significant first order.

If we take some imaginary MAC address 9C-DA-3E-E2-34-EB we can express this in binary as 10011100 11011010 00111110 11100010 00110100 11101011. When looking at binary form the Local/Group bit is actually at position 8 while at position 7 you can see the Unique/Local bit.

Those playing with blade servers can now also understand why their network adapters seem to have MAC addresses spaced by 4 - with the lowest two bits set to 0 that decision is forced by math and not some evil plan to waste already small MAC address space.

Setting IPv6 on Mikrotik

If your ISP offers IPv6 and you have Mikrotik router, it would be shame not to make use of it. My setup assumes you get /64 prefix from your ISP (Comcast in my case) via DHCPv6. Also assumed is empty IPv6 configuration.

First I like to disable default neighbor discovery interface. Blasting IPv6 router advertisements on all intefaces is not necessarily a good idea:

/ipv6 nd
set [ find default=yes ] disabled=yes

Next step is to setup DHCP client. Withing a few seconds, you should see the prefix being allocated:

/ipv6 dhcp-client
add add-default-route=yes interface=ether1 pool-name=^^general-pool6^^ request=prefix
:delay 5s
print
 Flags: D - dynamic, X - disabled, I - invalid
  #    INTERFACE             STATUS        REQUEST             PREFIX
  0    ether1                bound         prefix              ^^2601:600:9780:ee2c::/64^^, 3d14h41m41s

At this time I love to allocate address ending with ::1 to the router itself:

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

Now it should be possible to ping its address from external computer (in this example address would be 2601:600:9780:ee2c::1). If this doesn’t work, do check if you have link-local addresses. If none are present, reboot the router and they will be regenerated.

With router reachable, it is time to delegate IPv6 prefix to internal machines too. For this purpose, setup RA (router announcement) over the bridge. While default interval settings are just fine, I like to make them a bit shorter (20-60 seconds):

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

And that’s all. Now your computers behind the router will have direct IPv6 route to the Internet. Do not forget to setup both router firewall and firewall of individual devices. There is no NAT to save your butt here.

PS: Here is the basic IPv6 firewall allowing all connections out while allowing only established back in:

/ipv6 firewall filter
add chain=input action=drop connection-state=invalid comment="Drop (invalid)"
add chain=input action=accept connection-state=established,related comment="Accept (established, related)"
add chain=input action=accept in-interface=ether1 protocol=udp src-port=547 limit=10,20:packet comment="Accept DHCP (10/sec)"
add chain=input action=drop in-interface=ether1 protocol=udp src-port=547 comment="Drop DHCP (>10/sec)"
add chain=input action=accept in-interface=ether1 protocol=icmpv6 limit=10,20:packet comment="Accept external ICMP (10/sec)"
add chain=input action=drop in-interface=ether1 protocol=icmpv6 comment="Drop external ICMP (>10/sec)"
add chain=input action=accept in-interface=!ether1 protocol=icmpv6 comment="Accept internal ICMP"
add chain=input action=drop in-interface=ether1 comment="Drop external"
add chain=input action=reject comment="Reject everything else"
add chain=output action=accept comment="Accept all"
add chain=forward action=drop connection-state=invalid comment="Drop (invalid)"
add chain=forward action=accept connection-state=established,related comment="Accept (established, related)"
add chain=forward action=accept in-interface=ether1 protocol=icmpv6 limit=20,50:packet comment="Accept external ICMP (20/sec)"
add chain=forward action=drop in-interface=ether1 protocol=icmpv6 comment="Drop external ICMP (>20/sec)"
add chain=forward action=accept in-interface=!ether1 comment="Accept internal"
add chain=forward action=accept out-interface=ether1 comment="Accept outgoing"
add chain=forward action=drop in-interface=ether1 comment="Drop external"
add chain=forward action=reject comment="Reject everything else"