Mikrotik Script – Send Webhook when Power Fails on PSU

The goal for this script is to alert us if a remote site looses power. We can do this using a Mikrotik that has two PSUs. One is plugged into battery backup and the other in the non battery plug.

In this example, we are using PSU2 “number 8” We can find the number using

/system/health/print

We can now create a new scheduler entry with the following. Change out the number 8 to your PSU number, and change the webhook to your Teams webhook.

:local curState [system/health/get value-name=value  number=8]
:local name [/system/identity/get value-name=name]
:local webhook "https://teams.webhook.microsoft.com/webhook/more"

if ($curState != $lastState) do={
if ($curState = "ok") do={
/tool fetch http-method=post http-header-field="Content-Type: application/json" http-data="{\"text\": \"$name : Power is on.\"}" url="$webhook"
}
if ($curState != "ok") do={
/tool fetch http-method=post http-header-field="Content-Type: application/json" http-data="{\"text\": \"$name : Power is off.  On battery backup\"}" url="$webhook"
}
:global lastState $curState
}

Set to the appropriate interval (i.e. 5 minutes). The script will only alert once when the power state changes. This minimizes receiving an alert every 5 minutes while the power is off.

Mikrotik DHCP Scripts

The purpose of these scripts is to update the local DHCP lease table with a remote IP Address Management (IPAM) system.

Scheduler Script

This little script is added to the scheduler and goes through the entire DHCP lease table and uploads each MAC address and IP address pair to a website.

Change out the top three variables. May also need to change out the URL depending on how the website receives data.

:local url "upload.incredigeek.com"
:local username "myapiuser"
:local password "passwordforapiuserwebsite"

/ip/dhcp-server/lease/
:foreach i in=[find] do={ :put ([get $i address]." ".[get $i mac-address])
:local ipaddress ([get $i address])
:local macaddress ([get $i mac-address])
/tool fetch url="https://$url/api/v1/network/ipam/dynamic_ip_assignment?ip_address=$ipaddress&mac_address=$macaddress&expired=0" mode=https keep-result=no user=$username password=$password
:delay 1s;
}

DHCP Script

This script is to be used on the DHCP server script. Can add it by going to DHCP Server -> DHCP -> Double Click Server -> Script

Any time a new DHCP lease is obtained, this script is fired. Note that some of the variables like $leaseBound are specific to the script being used by the “DHCP server”

Also helpful to note that the script only runs if a new lease is obtained, or a lease expires and it disappears from the leases page. A DHCP renew does not trigger the script.

:local username "myapiuser"
:global password "myapipassword"
:global url "upload.incredigeek.com"

# The maximum retries
:local max 60
:local attempts 0
:local success 0
:do {
  :set attempts ($attempts+1);
  :if ($leaseBound = 0) do {
    :do {
      /tool fetch url="https://$url/api/v1/network/ipam/dynamic_ip_assignment?ip_address=$leaseActIP&mac_address=$leaseActMAC&expired=1" mode=https keep-result=no user=$username password=$password
      :set success 1;
    } on-error={
      :log error "DHCP FAILED to send unassignment to $url on attempt $attempts out of $max for $leaseActMAC / $leaseActIP";
      :delay 10s;
    }
  } else {
    :delay 1s;
    # see note below
    :local remoteID [/ip dhcp-server lease get [find where address=$leaseActIP] agent-remote-id];
    :do {
      /tool fetch url="https://$url/api/v1/network/ipam/dynamic_ip_assignment?ip_address=$leaseActIP&mac_address=$leaseActMAC&expired=0" mode=https keep-result=no user=$username password=$password
      :set success 1;
    } on-error={
      :log error "DHCP FAILED to send assignment to $url on attempt $attempts out of $max for $leaseActMAC / $leaseActIP";
      :delay 10s;
    }
  }
  :if ($success) do {
    :log info "DHCP lease message successfully sent $leaseActMAC / $leaseActIP to $url";
    :set attempts $max;  # break out of the do..while loop
  }
} while ( $attempts < $max )
}

Send Post Webhook Message to Teams from Mikrotik RouterOS

The following is the correct syntax needed to send a message to Microsoft Teams from a Mikrotik router. You will need a valid Teams webhook to send to.

Change “Test Message” out for your message. You should receive a “status: finished” response.

/tool fetch http-method=post http-header-field="Content-Type: application/json" http-data="{\"text\": \"Test Message\"}" url=https://domain.webhook.office.com/webhook/long/string

https://help.mikrotik.com/docs/display/ROS/Fetch

Hardening SSH on Mikrotik Routers

Here are the commands you’ll need to harden SSH on your Mikrotik Routers. It looks like it still can use SSH-RSA, but it does get rid of most of the weaker crytpo algorithms.

/ip/ssh/set strong-crypto=yes allow-none-crypto=no always-allow-password-login=no host-key-size=4096

We’ll want to regenerate the Host Key now that the settings have been changed.

/ip/ssh/regenerate-host-key

It will prompt to enter [y/N] to confirm that you actually want to regenerate the host key. Hit y

After your done, you can use something like ssh-audit to check your equipment.
https://www.ssh-audit.com/

Further hardening information is available at the following link.
https://wiki.mikrotik.com/wiki/Manual:Securing_Your_Router

Bulk Update SNMP v3 Settings for Devices in LibreNMS

With support for DES being dropped, you may be faced with having to upgrade device settings to AES. In this post we’ll explore changing the settings in LibreNMS for all Mikrotik devices and then touch on making changes to a group of Mikrotik devices.

Upgrading SNMP Settings for Devices in LibreNMS

In LibreNMS, we can go to Device -> Device Settings (Gear on the right hand side) -> SNMP, to set the SNMP settings for that device.

Since this would get rather boring to change on multiple devices, and these settings are all in a MySQL database, we can skip using the mouse and use a few MySQL commands to update multiple devices at once.

Log into the LibreNMS server over ssh and then connect to the MySQL database

mysql -u librenms -p librenms

First we can get a list of all the devices (Mikrotik routers in this example) and show the hostname with the SNMP authentication and cryptography algorithms.

select hostname,authalgo,cryptoalgo from devices where os="routeros";

Now if we want to update the cryptography settings for all of our Mikorotik devices, we can do the following.

update devices cryptoalgo set cryptoalgo="AES"  where os="routeros";

This will set all of the devices to use AES for the cryptography algorithm.

We can also change the authentication algorithm to SHA with this

update devices authalgo set authalgo="SHA"  where os="routeros";
LibreNMS update device SNMP settings

Bulk updating of Network Devices

The bottom “script” can be used for changing SNMP settings on multiple Mikrotik devices.

Create a mikrotik.lst file with all the IP addresses of all the devices you need to update. Can you use the above MySQL commands to get a list from LibreNMS.

Change the following options in the script

  • routerpassword to the Mikrotik password
  • admin to your username
  • encryptionpassword to your SNMP encryption password
  • authpassword to your authentication password
  • addresses=192.168.0.0/16 to the list of IP addresses that should be able to access SNMP info on the mikrotik device. AKA your LibreNMS server.
  • SNMPname to your SNMP username
for ip in `cat mikrotik.lst` 
do 
echo $ip 
timeout 15 sshpass -p 'routerpassword' ssh -o StrictHostKeyChecking=no admin@${ip} -p1022 '/snmp community set addresses=192.168.0.0/16 authentication-protocol=SHA1 authentication-password=authpassword encryption-protocol=AES encryption-password=encryptionpassword security=private read-access=yes write-access=no SNMPname'
done

Copy and paste the above “code” in a shell script file.

nano mikrotik.sh
chmod +x mikrotik.sh 
./mikrotik.sh

The script should run and update all the SNMP settings on all the devices in mikrotik.lst

Configure MikroTik Router as WireGuard VPN Appliance

You may need to upgrade your MikroTik if the WireGuard options are not available.

Quick overview of setting up a MikroTik Router as a VPN appliance.

  1. Configure WireGuard Interface on MikroTik Router
    1. Copy interface public key
    2. Add IP address on WireGuard interface
  2. Create WireGuard client config
    1. Use above interface public key
    2. Copy the client Public Key
  3. Create a WireGuard Peer on the MikroTik Router
    1. Use client Public Key
    2. Assign proper IP address

Configure WireGuard on Router

First we need to create a WireGuard interface to use.

/interface/wireguard add listen-port=51820 mtu=1420 name=wireguard1

We’ll need to copy the public key, shown in the following command, for use in the client config.

/interfaces/wireguard print

Next we’ll configure an IP address/range for the new WireGuard interface.

/ip/address add address=192.168.1.1/24 network=192.168.1.0 interface=wireguard1

Configure WireGuard Client

Download and install the WireGuard application on your computer or phone.

Create an empty config (Ctrl +N), click edit, add the following.

Address = 192.168.1.2/24
DNS = 9.9.9.9

[Peer]
PublicKey = ReplaceWithInterfacePublicKeyFromMikrotik
AllowedIPs = 0.0.0.0/0
Endpoint = endpointip:51820

Here is a screenshot as an example. We need to copy the public key. We’ll use that when we create the peer.

Configure WireGuard Client

Create WireGuard Peer

Now lets create a peer. Back on the MikroTik, run the following command. Change the allowed address and public key.

/interface/wireguard/peers add allowed-address=192.128.1.2/32 interface=wireguard1 public-key="PublicKeyFromClientCreatedInNextStep"

Note that the 192.168.1.2/32 is important. If you have multiple clients connected and one of them is setup with a /24 instead of a /32, it will cause issues. I think this is because WireGuard tries to route the whole /24 over that peer.

Also note that you can not use DHCP with WireGuard. Each client will have a static IP address assigned in the config. In this example, 192.168.1.2.

You should now be all set up and able to connect from your device.

Troubleshooting

Some issues you may run into.

Unable to have two devices connected at the same time.

First, you’ll need to have one Peer per Client connection. Either that, or do not connect at the same time.

Second, check and verify that each peer has the ClientIP/32 in the Allowed Address.

For example, if the WireGuard interface is using 192.168.1.0/24, and one of the peers has 192.168.1.4/24 in the Allowed Address option, then only one client will work. It appears that the MikroTik will attempt to route all 192.168.1.0/24 request to 192.168.1.4.

Identify “Magic Bytes” for Mikroitk Backup File

the “magic bytes” are the first few bytes of a file that can tell you what format the file is.

https://en.wikipedia.org/wiki/List_of_file_signatures

Mikrotik Backup file magic bytes

File typeMagic bytes
RC4 EncryptedEFA89172
AES EncryptedEFA89173
Not Encrypted88ACA1B1

Using the above list, we can view a Mikrotik .backup file in a hex editor like GHex or dump it with xxd.

Get list of IP DHCP Leases from Mikrotik RouterOS Command Line

Sometimes it is nice to have a list of just the IP addresses and the hostname or mac address. Can be especially helpful when you are trying to get a list of devices to do a bulk update in LibreNMS. Helpful LibreNMS links for renaming and showing down devices

we are going to run the command to pull the DHCP information and then use Unix utilities to parse the data out.

Replace dhcp8 with the correct dhcp server in the mikrotik.

First, SSH into your Mikrotik router.

ssh user@mikrotik

Next we’ll want to go to the ip dhcp-server lease directory

/ip dhcp-server lease

Now we can run the following command to loop through and pull out all the info we need.
You can change the info like “mac-address” for something like “status”. You can use Tab to see what options are available. Just delete mac-address and hit tab twice.

:foreach i in=[find] do={ :put ([get $i address].",".[get $i mac-address].",".[get $i server].",".[get $i host-name ])}

Found the above helpful info from the following pdf file.

https://mum.mikrotik.com/presentations/PH18/presentation_5113_1516612695.pdf

Troubleshooting DNS CPU Usage on Mikrotik Router

Problem : Lots of CPU utilization. Profile shows a good bit of it is DNS related.

DNS eating CPU on Router

The router is setup to allow DNS to pass through to web servers so rDNS and other records can be looked up and resolved. This is a specific IP block that gets it’s addresses from the router. The firewall rules explicitly allow this address range. We’ll say 192.168.88.0/24, and blocks everything else. This works for the web servers. But why are we still getting a bunch of CPU utilization with DNS?

As it turns out, the firewall rule that allows the server address range also includes routers own address! So we have unintentionally whitelisted DNS access to our router.

To resolve the issue we can add another firewall rule that explicitly blocks DNS traffic to the routers IP address. We are using two rules, one to block TCP and the other UDP.

ip firewall filter add chain=input dst-address=192.168.88.1 protocol=6 dst-port=53 in-interface-list=WAN action=drop
ip firewall filter add chain=input dst-address=192.168.88.1 protocol=17 dst-port=53 in-interface-list=WAN action=drop

Rules 6 & 7 are the two new rules we just applied. 14 & 15 block input to the router, however rules 8 & 9 inadvertently allowed access to the router’s public IP.

Firewall Rules for Router

The Result? Our CPU usage dropped!

CPU Usage dropped after adding DNS firewall rules.

Quite dramatically too as the following LibreNMS screenshot shows.

LibreNMS CPU graph showing the overall CPU utilization improvement

For more information about DNS Amplification attacks, refer to the following links.

https://ask.wireshark.org/question/6865/dns-amplification-attack/
https://security.stackexchange.com/questions/237127/why-would-hackers-attack-a-dns-server-with-a-dos