RouterOS Howto (1) - Part 4

From RaySoft

This is Part 4 of the RouterOS Howto for MikroTik hEX S.

Configure the Firewall

Documentation:

[RouterOS CLI]: Define ruleset version

:global rulesetVersion "v001"

[RouterOS CLI]: Configure several IP related Kernel parameters

/ip settings
    set ip-forward="yes" send-redirects="yes" accept-source-route="yes" \
        accept-redirects="no" secure-redirects="yes" rp-filter="strict" \
        tcp-syncookies="yes" route-cache="yes" allow-fast-path="no"
    print

[RouterOS CLI]: Disable all service ports except tftp

/ip firewall service-port
    enable "tftp"
    disable [find where name!="tftp"]
    print detail

Configure address lists

[RouterOS CLI]: Configure address lists for the internal network segments

/ip firewall address-list
    add list="lan-router"     address="192.168.1.0/28"
    add list="lan-network"    address="192.168.1.16/28"
    add list="lan-tools"      address="192.168.1.32/28"
    add list="lan-server"     address="192.168.1.48/28"
    add list="lan-kubernetes" address="192.168.1.64/28"
    add list="lan-client"     address="192.168.1.128/28"
    add list="lan-multimedia" address="192.168.1.144/28"
    add list="lan-gaming"     address="192.168.1.160/28"
    add list="lan-guest"      address="192.168.1.240/28"
    print detail where list~"^lan"

[RouterOS CLI]: Configure address lists for the Init7 network segments

/ip firewall address-list
    add list="init7-center" address="212.51.141.0/24"
    add list="init7-dcm"    address="77.109.129.16/30"
    print detail where list~"^init7"
NOTE:
My Init7 center is 790scw1.fiber7.init7.net (212.51.141.0/24)
NOTE:
DCM stands for Digital Content Management

[RouterOS CLI]: Configure an address list for Multicast

/ip firewall address-list
    add list="multicast" address="224.0.0.0/4"
    print detail where list="multicast"

[RouterOS CLI]: Configure an address list for bogons addresses

:global listName "bogons"

/ip firewall address-list
    add list="$listName" address="0.0.0.0/8"
    add list="$listName" address="10.0.0.0/8" disabled="yes"
    add list="$listName" address="100.64.0.0/10"
    add list="$listName" address="127.0.0.0/8"
    add list="$listName" address="169.254.0.0/16"
    add list="$listName" address="172.16.0.0/12"
    add list="$listName" address="192.0.0.0/24"
    add list="$listName" address="192.0.0.0/29"
    add list="$listName" address="192.0.2.0/24"
    add list="$listName" address="192.88.99.0/24"
    add list="$listName" address="192.168.0.0/16"
    add list="$listName" address="198.18.0.0/15"
    add list="$listName" address="198.51.100.0/24"
    add list="$listName" address="203.0.113.0/24"
    add list="$listName" address="224.0.0.0/4" disabled="yes"
    print detail where list="$listName"
NOTE:
The bogons address list is derived from RFC 6890 “Special-Purpose IP Address Registries”.

Configure rules for known connections

[RouterOS CLI]: Configure rules for known connections

:global groupName "PRE"

:global getLogPrefix do={ :return "$groupName ($ruleName)" }
:global getComment   do={ :return "$groupName ($ruleName) $rulesetVersion" }

/ip firewall filter
    :foreach chain in={"forward"; "output"; "input"} do={
        :global ruleName "Fasttrack"
        add chain="$chain" action="fasttrack-connection" \
            connection-state="established,related" \
            log="no" log-prefix=[$getLogPrefix] comment=[$getComment]

        :global ruleName "State"
        add chain="$chain" action="accept" \
            connection-state="established,related" \
            log="no" log-prefix=[$getLogPrefix] comment=[$getComment]
    }

Configure rules for unwanted connections

[RouterOS CLI]: Configure rules for unwanted connections

:global groupName "PRE"

:global getLogPrefix do={ :return "$groupName ($ruleName)" }
:global getComment   do={ :return "$groupName ($ruleName) $rulesetVersion" }

/ip firewall filter
    :foreach chain in={"forward"; "input"} do={
        :global ruleName "Drop invalid"
        add chain="$chain" action="drop" \
            connection-state="invalid,untracked" \
            log="no" log-prefix=[$getLogPrefix] comment=[$getComment]

        :global ruleName "Drop Bogons"
        add chain="$chain" action="drop" \
            dst-address-list="bogons" \
            log="no" log-prefix=[$getLogPrefix] comment=[$getComment]
    }

WAN 2 FW connections

Src Dst Src Port Dst Port
init7-center multicast IGMP - -

[RouterOS CLI]: Configure rules for connections from WAN to Firewall

:global chain "input"
:global inInterface "WAN"
:global groupName "$inInterface 2 FW"

:global getLogPrefix do={ :return "$groupName ($ruleName)" }
:global getComment   do={ :return "$groupName ($ruleName) $rulesetVersion" }

/ip firewall filter
    :global ruleName "IGMP"
    add chain="$chain" action="accept" disabled="yes" \
        in-interface-list="$inInterface" \
        src-address-list="init7-center" dst-address-list="multicast" \
        protocol="igmp" \
        log="no" log-prefix=[$getLogPrefix] comment=[$getComment]

    :global ruleName "Drop"
    add chain="$chain" action="drop" \
        in-interface-list="$inInterface" \
        log="no" log-prefix=[$getLogPrefix] comment=[$getComment]

WAN 2 LAN-STD connections

WARNING:
The following rules only work if there are appropriate port forwardings.
Src Dst Src Port Dst Port
init7-dcm multicast UDP 5000 5000

[RouterOS CLI]: Configure rules for connections from WAN to LAN

:global chain "forward"
:global inInterface "WAN"
:global outInterface "LAN-STD"
:global groupName "$inInterface 2 $outInterface"

:global getLogPrefix do={ :return "$groupName ($ruleName)" }
:global getComment   do={ :return "$groupName ($ruleName) $rulesetVersion" }

/ip firewall filter
    :global ruleName "DCM UDP"
    add chain="$chain" action="accept" disabled="yes" \
        in-interface-list="$inInterface" out-interface-list="$outInterface" \
        src-address-list="init7-dcm" dst-address-list="multicast" \
        protocol="udp" src-port="5000" dst-port="5000" \
        log="no" log-prefix=[$getLogPrefix] comment=[$getComment]

    :global ruleName "Drop"
    add chain="$chain" action="drop" \
        in-interface-list="$inInterface" out-interface-list="$outInterface" \
        log="no" log-prefix=[$getLogPrefix] comment=[$getComment]

Masquerade WAN connections

[RouterOS CLI]: Configure IP masquerade

:global chain "srcnat"
:global inInterface "LAN-STD"
:global outInterface "WAN"
:global groupName "$inInterface 2 $outInterface"

:global getLogPrefix do={ :return "$groupName ($ruleName)" }
:global getComment   do={ :return "$groupName ($ruleName) $rulesetVersion" }

/ip firewall nat
    :global ruleName "Masquerade"
    add chain="$chain" action="masquerade" \
        out-interface-list="$outInterface" \
        log="no" log-prefix=[$getLogPrefix] comment=[$getComment]

LAN-STD-GW 2 WAN connections

WARNING:
The following rules only work if there is a corresponding IP masquerade.
Src Dst Src Port Dst Port
TCP any SSH (22, 2121), SMTP (25), HTTP (80), HTTPS (443, 8443), Submission (587), IMAPS (993), HKP (11371)
UDP any IPsec (500,4500), OpenVPN (1194), Reolink (9999), WireGuard (51820)
ICMP - -

[RouterOS CLI]: Configure rules for connections from LAN to WAN

:global chain "forward"
:global inInterface "LAN-STD-GW"
:global outInterface "WAN"
:global groupName "$inInterface 2 $outInterface"

:global getLogPrefix do={ :return "$groupName ($ruleName)" }
:global getComment   do={ :return "$groupName ($ruleName) $rulesetVersion" }

/ip firewall filter
    :global ruleName "TCP"
    add chain="$chain" action="accept" \
        in-interface-list="$inInterface" out-interface-list="$outInterface" \
        protocol="tcp" dst-port="22,25,80,443,587,993,2121,8443,11371" \
        log="no" log-prefix=[$getLogPrefix] comment=[$getComment]

    :global ruleName "UDP"
    add chain="$chain" action="accept" \
        in-interface-list="$inInterface" out-interface-list="$outInterface" \
        protocol="udp" dst-port="500,1194,4500,9999,51820" \
        log="no" log-prefix=[$getLogPrefix] comment=[$getComment]

    :global ruleName "ICMP"
    add chain="$chain" action="accept" \
        in-interface-list="$inInterface" out-interface-list="$outInterface" \
        protocol="icmp" \
        log="no" log-prefix=[$getLogPrefix] comment=[$getComment]

    :global ruleName "Drop known TCP"
    add chain="$chain" action="drop" \
        in-interface-list="$inInterface" out-interface-list="$outInterface" \
        protocol="tcp" dst-port="5222-5224" \
        log="no" log-prefix=[$getLogPrefix] comment=[$getComment]

    :global ruleName "Drop"
    add chain="$chain" action="drop" \
        in-interface-list="$inInterface" out-interface-list="$outInterface" \
        log="yes" log-prefix=[$getLogPrefix] comment=[$getComment]

LAN-STD 2 FW connections

Src Dst Src Port Dst Port
TCP any SSH (22), HTTPS (443)
lan-router multicast VRRP - -
ICMP - -

[RouterOS CLI]: Configure rules for connections from LAN to Firewall

:global chain "input"
:global inInterface "LAN-STD"
:global groupName "$inInterface 2 FW"

:global getLogPrefix do={ :return "$groupName ($ruleName)" }
:global getComment   do={ :return "$groupName ($ruleName) $rulesetVersion" }

/ip firewall filter
    :global ruleName "TCP"
    add chain="$chain" action="accept" \
        in-interface-list="$inInterface" \
        protocol="tcp" dst-port="22,443" \
        log="no" log-prefix=[$getLogPrefix] comment=[$getComment]

    :global ruleName "VRRP"
    add chain="$chain" action="accept" \
        in-interface-list="$inInterface" \
        src-address-list="lan-router" dst-address-list="multicast" \
        protocol="vrrp" \
        log="no" log-prefix=[$getLogPrefix] comment=[$getComment]

    :global ruleName "ICMP"
    add chain="$chain" action="accept" \
        in-interface-list="$inInterface" \
        protocol="icmp" \
        log="no" log-prefix=[$getLogPrefix] comment=[$getComment]

    :global ruleName "Drop known UDP"
    add chain="$chain" action="drop" \
        in-interface-list="$inInterface" \
        protocol="udp" dst-port="67,137,10001" \
        log="no" log-prefix=[$getLogPrefix] comment=[$getComment]

    :global ruleName "Drop"
    add chain="$chain" action="drop" \
        in-interface-list="$inInterface" \
        log="yes" log-prefix=[$getLogPrefix] comment=[$getComment]

LAN-STD-GW 2 FW connections

Src Dst Src Port Dst Port
TCP any DNS (53)
UDP any DNS (53), BOOTP (67), TFTP (69), NTP (123)
multicast IGMP - -
ICMP - -

[RouterOS CLI]: Configure rules for connections from LAN to Firewall

:global chain "input"
:global inInterface "LAN-STD-GW"
:global groupName "$inInterface 2 FW"

:global getLogPrefix do={ :return "$groupName ($ruleName)" }
:global getComment   do={ :return "$groupName ($ruleName) $rulesetVersion" }

/ip firewall filter
    :global ruleName "TCP"
    add chain="$chain" action="accept" \
        in-interface-list="$inInterface" \
        protocol="tcp" dst-port="53" \
        log="no" log-prefix=[$getLogPrefix] comment=[$getComment]

    :global ruleName "UDP"
    add chain="$chain" action="accept" \
        in-interface-list="$inInterface" \
        protocol="udp" dst-port="53,67,69,123" \
        log="no" log-prefix=[$getLogPrefix] comment=[$getComment]

    :global ruleName "DCM IGMP"
    add chain="$chain" action="accept" disabled="yes" \
        in-interface-list="$inInterface" \
        dst-address-list="multicast" \
        protocol="igmp" \
        log="no" log-prefix=[$getLogPrefix] comment=[$getComment]

    :global ruleName "ICMP"
    add chain="$chain" action="accept" \
        in-interface-list="$inInterface" \
        protocol="icmp" \
        log="no" log-prefix=[$getLogPrefix] comment=[$getComment]

    :global ruleName "Drop known UDP"
    add chain="$chain" action="drop" \
        in-interface-list="$inInterface" \
        protocol="udp" dst-port="137,10001" \
        log="no" log-prefix=[$getLogPrefix] comment=[$getComment]

    :global ruleName "Drop"
    add chain="$chain" action="drop" \
        in-interface-list="$inInterface" \
        log="yes" log-prefix=[$getLogPrefix] comment=[$getComment]

FW 2 LAN-STD connections

Src Dst Src Port Dst Port
TCP any DNS (53), HTTP (80), HTTPS (443)
UDP any DNS (53), NTP (123)
multicast IGMP - -
ICMP - -
NOTE:
These TCP & UDP rules are disabled by default & are on ly needed if the firewall is passive and connected to the LAN.

[RouterOS CLI]: Configuring rules for connections from Firewall to LAN

:global chain "output"
:global outInterface "LAN-STD"
:global groupName "FW 2 $outInterface"

:global getLogPrefix do={ :return "$groupName ($ruleName)" }
:global getComment   do={ :return "$groupName ($ruleName) $rulesetVersion" }

/ip firewall filter
    :global ruleName "TCP"
    add chain="$chain" action="accept" disabled="yes" \
        out-interface-list="$outInterface" \
        protocol="tcp" dst-port="53,80,443" \
        log="no" log-prefix=[$getLogPrefix] comment=[$getComment]

    :global ruleName "UDP"
    add chain="$chain" action="accept" disabled="yes" \
        out-interface-list="$outInterface" \
        protocol="udp" dst-port="53,123" \
        log="no" log-prefix=[$getLogPrefix] comment=[$getComment]

    :global ruleName "DCM IGMP"
    add chain="$chain" action="accept" disabled="yes" \
        out-interface-list="$outInterface" \
        dst-address-list="multicast" \
        protocol="igmp" \
        log="no" log-prefix=[$getLogPrefix] comment=[$getComment]

    :global ruleName "ICMP"
    add chain="$chain" action="accept" \
        out-interface-list="$outInterface" \
        protocol="icmp" \
        log="no" log-prefix=[$getLogPrefix] comment=[$getComment]

    :global ruleName "Drop"
    add chain="$chain" action="drop" \
        out-interface-list="LAN" \
        log="yes" log-prefix=[$getLogPrefix] comment=[$getComment]

FW 2 WAN connections

Src Dst Src Port Dst Port
TCP any DNS (53), HTTP (80), HTTPS (443), Submission (587)
UDP any DNS (53), NTP (123)
init7-center multicast IGMP - -
ICMP - -

[RouterOS CLI]: Configure rules for connections from Firewall to WAN

:global chain "output"
:global outInterface "WAN"
:global groupName "FW 2 $outInterface"

:global getLogPrefix do={ :return "$groupName ($ruleName)" }
:global getComment   do={ :return "$groupName ($ruleName) $rulesetVersion" }

/ip firewall filter
    :global ruleName "TCP"
    add chain="$chain" action="accept" \
        out-interface-list="$outInterface" \
        protocol="tcp" dst-port="53,80,443,587" \
        log="no" log-prefix=[$getLogPrefix] comment=[$getComment]

    :global ruleName "UDP"
    add chain="$chain" action="accept" \
        out-interface-list="$outInterface" \
        protocol="udp" dst-port="53,123" \
        log="no" log-prefix=[$getLogPrefix] comment=[$getComment]

    :global ruleName "DCM IGMP"
    add chain="$chain" action="accept" disabled="yes" \
        out-interface-list="$outInterface" \
        src-address-list="init7-center" dst-address-list="multicast" \
        protocol="igmp" \
        log="no" log-prefix=[$getLogPrefix] comment=[$getComment]

    :global ruleName "ICMP"
    add chain="$chain" action="accept" \
        out-interface-list="$outInterface" \
        protocol="icmp" \
        log="no" log-prefix=[$getLogPrefix] comment=[$getComment]

    :global ruleName "Drop"
    add chain="$chain" action="drop" \
        out-interface-list="$outInterface" \
        log="yes" log-prefix=[$getLogPrefix] comment=[$getComment]

Final Drop rules

[RouterOS CLI]: Configure final drop rules

:global groupName "POST"
:global ruleName "Drop any"

:global getLogPrefix do={ :return "$groupName ($ruleName)" }
:global getComment   do={ :return "$groupName ($ruleName) $rulesetVersion" }

/ip firewall filter
    :foreach chain in={"forward"; "output"; "input"} do={
        add chain="$chain" action="drop" \
            log="yes" log-prefix=[$getLogPrefix] comment=[$getComment]
    }

Remove default rules

[RouterOS CLI]: Delete all rules that start with defconf or contain an old version number vXXX

:foreach table in={"filter"; "nat"} do={
    [:parse " \
        /ip firewall $table remove \
            [find comment~\"^defconf\" or comment~\"vXXX\"] \
    "]
}

Show all rules

[RouterOS CLI]: Show the rules from the chains filter & nat

:foreach table in={"filter"; "nat"} do={
    [:parse "/ip firewall $table print without-paging"]
}

Monitor the Firewall logs

[RouterOS CLI]: Monitor the Firewall logs

/log print follow where topics~"^firewall"

Reset all Firewall counters

[RouterOS CLI]: Reset the Firewall counters for the chains filter, nat, mangle & raw

:foreach table in={"filter"; "nat"; "mangle", "raw"} do={
    [:parse "/ip firewall $table reset-counters-all"]
}

Create Backups

Documentation:

[UNIX shell]: Define environment

  • for tellurium.raysoft.loc
host_name='tellurium'
  • for palladium.raysoft.loc
host_name='palladium'

[RouterOS CLI]: Create a backup & show the file

/system backup save dont-encrypt="yes"
/file print where type="backup"

[UNIX shell]: Download the backup file

scp "admin@${host_name}.raysoft.loc:/flash/${host_name}-DATE-COUNTER.backup" \
    "${HOME}/Documents/41-maschinen/${host_name}.raysoft.loc/backup"

[RouterOS CLI]: Remove all backup files

/file remove [find type="backup"]

Create Backups automatically

[UNIX shell]: Define environment

  • for tellurium.raysoft.loc
host_name='tellurium'
  • for palladium.raysoft.loc
host_name='palladium'
  • all machines
host="admin@${host_name}.raysoft.loc"

[UNIX shell]: Create a backup remotely

ssh "${host}" '/system backup save dont-encrypt="yes"'

[UNIX shell]: Download all available backup files

while read -r file; do
  scp "${host}:/${file}" "${HOME}/Documents/41-maschinen/${host##*@}/backup"
done < <(ssh "${host}" '/file print terse where type="backup"' \
         | sed '/^\s*$/d; s/.*name=\([^ ]*\).*/\1/')

[UNIX shell]: Remove all backup files remotely

ssh "${host}" '/file remove [find type="backup"]'