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"
:global ruleName "Dummy"

[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" 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 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="192.168.1.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

[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 "Drop"
    add chain="$chain" action="drop" \
        in-interface-list="$inInterface" \
        log="no" log-prefix=[$getLogPrefix] comment=[$getComment]

WAN 2 LAN-STD connections

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

: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 "Drop"
    add chain="$chain" action="drop" \
        in-interface-list="$inInterface" out-interface-list="$outInterface" \
        log="no" log-prefix=[$getLogPrefix] comment=[$getComment]

WAN 2 LAN-STD-GW connections

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

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

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

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

LAN-STD 2 WAN connections

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

:global chain "forward"
: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/filter
    :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-GW 2 WAN connections

[RouterOS CLI]: Configure IP masquerade from LAN-STD-GW to WAN

:global chain "srcnat"
: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/nat
    :global ruleName "Masquerade"
    add chain="$chain" action="masquerade" \
        out-interface-list="$outInterface" \
        log="no" log-prefix=[$getLogPrefix] comment=[$getComment]
Src Dst Src Port Dst Port
TCP any SSH (22, 2121), SMTP (25), HTTP (80), HTTPS (443, 8443), Submission (587), IMAPS (993), HKP (11371)
lan-gaming TCP any any
UDP any IPsec (500,4500), OpenVPN (1194), Reolink (9999), WireGuard (51820)
lan-gaming UDP any any
ICMP - -

[RouterOS CLI]: Configure rules for connections from LAN-STD-GW 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 "TCP Gaming"
    add chain="$chain" action="accept" \
        in-interface-list="$inInterface" out-interface-list="$outInterface" \
        src-address-list="lan-gaming" \
        protocol="tcp" \
        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 "UDP Gaming"
    add chain="$chain" action="accept" \
        in-interface-list="$inInterface" out-interface-list="$outInterface" \
        src-address-list="lan-gaming" \
        protocol="udp" \
        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"
    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), HTTP (80), HTTPS (443)
lan-router multicast VRRP - -
ICMP - -

[RouterOS CLI]: Configure rules for connections from LAN-STD 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,80,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"
    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)
ICMP - -

[RouterOS CLI]: Configure rules for connections from LAN-STD-GW 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 "ICMP"
    add chain="$chain" action="accept" \
        in-interface-list="$inInterface" \
        protocol="icmp" \
        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)
ICMP - -
WARNING:
Only activate the TCP & UDP rules on the passive firewall.

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

: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 "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]

FW 2 LAN-STD-GW connections

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

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

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

/ip/firewall/filter
    :global ruleName "Drop"
    add chain="$chain" action="drop" \
        out-interface-list="$outInterface" \
        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), DDNS (15252)
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,15252" \
        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~\"v001\"] \
    "]
}

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 "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 "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"]'