Need a forward rule

I have the following config:

FIOS → RB5009 → ax3

LAN is 192.168.2.0/24

RB5009 is 192.168.2.2

ax3 is 192.168.2.5

ax3 has its own DHCP server for its guest wifi clients at 10.0.0.0/24 that provides guests access only to the internet.

It seems to work very well but I am discovering surprising log entries coming from the RB5009’s rule:

/ip firewall filter add action=drop chain=forward log=yes log-prefix="drop forward (all else)"

such as:

drop forward (all else) forward: in:bridge out:bridge, connection-state:new src-mac 48:a9:8a:0f:04:8f, proto TCP (ACK,PSH), 17.57.144.54:5223->10.0.0.236:54877, len 685

I believe that this is a new incoming connection (from 17.57.144.54) to an iphone connected to this ax3’s guest wifi.

My question is: Should I attempt to allow this? Why would Apple (17.57.144.54) try to initiate a connection to my iphone?

If I should create a rule that allows these types of connections, what should it be?

Happy to post the entire config, but I thought it might be better to describe the situation and discuss on a more abstract level instead.

Do not allow. If everything seems to be working do not touch that rule. It could be a leftover of any unexpectedly closed connections etc.
It is not suprising that your router is scanned by Apple. I have an issue that my router cut me off the Google services as there were scans initiated from 8.8.8.8 and my prevention rules did what they were supposed to do and put 8.8.8.8 on a blacklist.
Why and what that scans were initiated from 8.8.8.8 for … only Google and IT-God knows.

Thanks for the assurance.

I admit to having an ongoing urge to find problems to fix that don’t exist.

To be precise, it actually is a problem, but for sure adding a permissive rule would not be a solution to it.

As in IPv4, the majority of user endpoints have private addresses, there are not many useful scenarios where endpoints in the internet would initiate connections to them, as they could only reach the minority of user endpoints that are on public addresses. The exceptions are user endpoints that control the routers that connect them to the internet using UPnP or similar mechanisms, and those that use STUN and similar techniques to predict the NAT behavior rather than controlling it. But even these exceptions are typically used when two user endpoints, both behind a NAT, want to set up a direct communication with each other, in order to reduce the transport delay and conserve resources on dedicated traffic forwarders that have to be used if the direct connection cannot be established.

So the most typical case where you get an unsolicited packet whose source address belongs to some big company is when the packet actually came from a different source whose aim is to overload the device that listens at the source address of that packet - the attacker sends a small packet to many devices that he knows or expects to respond it, and chooses packets that cause a huge response. So using a relatively small bandwidth from himself to multiple (thousands of) destinations he can generate a much larger influx of “unsolicited responses” to the target/victim.

Another type of scenarios lacks the evil intention and can be explained by firewall behavior alone. E.g., the firewal labels a late UDP DNS response packet as a connection-state=new because the tracked connection initiated by the query packet has timed out before the response came. Another example is that the firewall drops a tracked TCP connection as soon as it has received and forwarded a RST packet from one endpoint towards the other, so it marks whatever packet comes from the other endpoint afterwards (because its sender has sent it already before receiving the RST) with connection-state=invalid or connection-state=new depending on the loose-tcp-tracking setting in ip firewall connection tracking. The default setting is yes, which means that the firewall does not check the internal state of the TCP that is expresses using the TCP flags.

So the packet from your example, which is a mid-session TCP packet, would seemingly match best to the last example (mid-session TCP packet received after a RST for that session has already passed through the firewall), as it has no potential of inducing a huge response nor it can break an existing session from any other address than your public one, if it wasn’t for the facts that it came in and left via the same interface and that it has been dstnated. A post-RST packet from the Apple address would not make it to a private address because once the tracked connection gets removed, the “un-src-nat” of packets belonging to that connection not possible any more. So it suggests that use-ip-firewall under interface bridge settings is set to yes in your configuration, causing even pakets forwarded between ports of the same bridge to be handled by the IP firewall. Is that indeed the case? If yes, what was the reason to set it like that?

@sindy – that is such a fantastic explanation and analysis! Thank you very much.

use-ip-firewall is set to no

# 2024-10-05 08:16:12 by RouterOS 7.14.2
# software id = 2KBD-7ZZB
#
# model = RB5009UPr+S+
# serial number = HDA0xxxxxH

/interface bridge settings
set allow-fast-path=yes use-ip-firewall=no use-ip-firewall-for-pppoe=no use-ip-firewall-for-vlan=no

It sure seems like it is your #2 explanation: timed out connection resulting in connection-state=new

I will make no changes to the firewall configs, as has been recommended (except maybe turning logging off so I don’t have to see them in the log).

Thank you.

Unfortunately, your conclusion suggests that the explanation wasn’t as fantastic as I would like it to be :slight_smile:

Let me reiterate - since the source address of that packet is a public one and the destination one is private, a dstnat operation changing the destination address from the public one of your home to the private one in the guest network must have taken place. So the router/firewall that has performed that dst-nat operation must either have a dst-nat rule installed (but the source and destination ports of the packet do not support this assumption) or the dstnat operation was actually an “un-src-nat” one, which implies that the tracked connection still existed on that router. So it would require a very tight timing that the router where you have seen this public->private packet would have just forwarded a RST one (and removed the connection) whilst the next router in your home would have sent that public->private packet before processing the received RST one. It is not impossible, it is just unlikely that it would happen so frequently.

The other remarkable thing about the packet is that it has been set for being sent out via the same IP interface (the one named bridge) through which it got in. This is very rare for routed packets if the network topology is properly designed and the routing properly configured. So given that use-ip-firewall is set to no, you either have multiple subnets attached to the bridge or there is an even more unusual reason why it happened. One possibility is that the upstream router has the one where you’ve caught the packet configured as a gateway to 10.0.0.0/24 but the router where you’ve caught it has yet another router in the same subnet configured as a gateway to 10.0.0.0/24. So if it receives a packet for 10.0.0.0/24, it delivers it but notifies the sender that there is a better gateway in the same subnet. Such a notification makes the sending device update its routing tables temporarily, so for some time after, it uses the “better gateway”, but once the lifetime of the notification expires, it starts using the configured gateway again and the cycle repeats.

So most likely what needs a review are not firewall rules but routing and network topology.

You’ve picked up that I don’t 100% understand – thank you for your perserverence in helping.

Here are the configs for the RB5009 and the ax3. I removed what I believe are the non-relevant sections. Does anything look the routing or gateway is misconfigured?

# 2024-10-05 10:02:13 by RouterOS 7.16
# software id = 5NRD-V1QF
#
# model = C53UiG+5HPaxD2HPaxD
# serial number = HDG08xxxx
/interface bridge
add admin-mac=48:A9:8A:xx:xx:xx auto-mac=no comment=defconf name=bridge \
    port-cost-mode=short
	
/interface ethernet
set [ find default-name=ether1 ] comment="To RB5009" poe-out=off
set [ find default-name=ether3 ] comment=TV
set [ find default-name=ether4 ] comment=TV

/interface wifi
set [ find default-name=wifi1 ] channel.band=5ghz-ax .frequency=5250-5330 \
    .skip-dfs-channels=all .width=20/40/80mhz configuration.antenna-gain=0 \
    .country=Russia .mode=ap .ssid=Upstairs5g-0F0493 .tx-power=21 disabled=no \
    security.authentication-types=wpa2-psk .disable-pmkid=yes .ft=yes \
    .ft-over-ds=yes .passphrase=<password>
set [ find default-name=wifi2 ] channel.band=2ghz-g .skip-dfs-channels=\
    disabled .width=20mhz configuration.country="United States" .mode=ap \
    .ssid=Upstairs-2G-0F0494 disabled=no security.authentication-types=\
    wpa2-psk .disable-pmkid=yes .ft=yes .ft-over-ds=yes .passphrase=\
    <password>

/interface wifi
add configuration.mode=ap .ssid=2point4 disabled=no mac-address=\
    4A:A9:8A:0F:04:93 master-interface=wifi2 mtu=1500 name=2point4 \
    security.authentication-types=wpa2-psk .disable-pmkid=yes .ft=yes \
    .ft-over-ds=yes .passphrase=<password>
	
/interface list
add comment=defconf name=WAN
add comment=defconf name=LAN
add include=all name=TRUSTED

/interface wifi configuration
add datapath.client-isolation=yes disabled=no name=guestcfg \
    security.authentication-types=wpa2-psk .disable-pmkid=yes .ft=yes \
    .ft-over-ds=yes .passphrase=blueberry ssid=GuestWifi
	
/interface wifi
add configuration=guestcfg configuration.mode=ap disabled=no mac-address=\
    4A:A9:8A:0F:04:94 master-interface=wifi2 name=Guest2g
add configuration=guestcfg configuration.mode=ap disabled=no mac-address=\
    4A:A9:8A:0F:04:95 master-interface=wifi1 name=Guest5g
	
/ip pool
add name=pool-guest ranges=10.0.0.10-10.0.0.252

/ip dhcp-server
add address-pool=pool-guest interface=Guest2g name=dhcp-guest2g
add address-pool=pool-guest interface=Guest5g name=dhcp-guest5g

/interface bridge port
add bridge=bridge comment=defconf interface=ether2 internal-path-cost=10 \
    path-cost=10
add bridge=bridge comment=defconf interface=ether3 internal-path-cost=10 \
    path-cost=10
add bridge=bridge comment=defconf interface=ether4 internal-path-cost=10 \
    path-cost=10
add bridge=bridge comment=defconf interface=ether5 internal-path-cost=10 \
    path-cost=10
add bridge=bridge comment=defconf interface=*6 internal-path-cost=10 \
    path-cost=10
add bridge=bridge comment=defconf interface=wifi2 internal-path-cost=10 \
    path-cost=10
add bridge=bridge interface=ether1 internal-path-cost=10 path-cost=10
add bridge=bridge interface=2point4 internal-path-cost=10 path-cost=10
add bridge=bridge interface=wifi1

/interface list member
add comment=defconf interface=bridge list=LAN
add comment=defconf interface=ether1 list=WAN
add interface=bridge list=TRUSTED
add interface=ether1 list=TRUSTED
add interface=*6 list=TRUSTED
add interface=wifi2 list=TRUSTED


/ip address
add address=192.168.2.5/24 comment=defconf interface=bridge network=\
    192.168.2.0
add address=10.0.0.1/24 interface=Guest2g network=10.0.0.0
add address=10.0.0.1/24 interface=Guest5g network=10.0.0.0

/ip dhcp-server network
add address=10.0.0.0/24 dns-server=1.1.1.1 gateway=10.0.0.1

/ip dns
set allow-remote-requests=yes cache-max-ttl=4w cache-size=32768KiB \
    query-server-timeout=5s servers=1.1.1.1,8.8.8.8,9.9.9.9,8.8.4.4

/ip route
add disabled=no distance=1 dst-address=0.0.0.0/0 gateway=192.168.2.2 \
    pref-src="" routing-table=main scope=30 suppress-hw-offload=no \
    target-scope=10



# 2024-10-05 10:02:23 by RouterOS 7.14.2
# software id = 2KBD-7ZZB
#
# model = RB5009UPr+S+
# serial number = HDA0xxx

/interface bridge
add admin-mac=18:FD:74:xx:xx:xx auto-mac=no comment=defconf name=bridge \
    port-cost-mode=short

/interface ethernet
set [ find default-name=ether1 ] comment=WAN poe-out=off
set [ find default-name=ether2 ] comment="Switch CSS 24" poe-out=off
set [ find default-name=ether3 ] comment="JRS PC port 3" poe-out=off
set [ find default-name=ether4 ] comment="hAP 16" poe-out=off
set [ find default-name=ether5 ] comment="15 wall port 5 -- Proxmox" poe-out=\
    off
set [ find default-name=ether6 ] comment="MOCA adapter" poe-out=off
set [ find default-name=ether7 ] poe-out=off
set [ find default-name=ether8 ] poe-out=off

/ip pool
add name=dhcp ranges=192.168.2.100-192.168.2.200

/ip dhcp-server
add address-pool=dhcp interface=bridge 

/interface bridge port
add bridge=bridge comment=defconf ingress-filtering=no interface=ether2 \
    internal-path-cost=10 path-cost=10
add bridge=bridge comment=defconf ingress-filtering=no interface=ether3 \
    internal-path-cost=10 path-cost=10
add bridge=bridge comment=defconf ingress-filtering=no interface=ether4 \
    internal-path-cost=10 path-cost=10
add bridge=bridge comment=defconf ingress-filtering=no interface=ether5 \
    internal-path-cost=10 path-cost=10
add bridge=bridge interface=ether6 internal-path-cost=10 path-cost=10
add bridge=bridge interface=ether7 internal-path-cost=10 path-cost=10
add bridge=bridge interface=ether8 internal-path-cost=10 path-cost=10

/interface list member
add comment=defconf interface=bridge list=LAN
add comment=defconf interface=ether1 list=WAN
add interface=bridge list=MANAGE
add disabled=yes interface=ether1 list=MANAGE
add interface=212-Wireguard list=LAN
add interface=212-Wireguard list=MANAGE
add interface=212-Wireguard list=DHCPdisabled

/ip address
add address=192.168.2.2/24 comment=defconf interface=bridge network=\
    192.168.2.0
add address=10.10.100.1/24 interface=212-Wireguard network=10.10.100.0

/ip dhcp-server network
add address=192.168.2.0/24 comment=defconf dns-server=192.168.2.2 gateway=\
    192.168.2.2 netmask=24

/ip route
add disabled=no distance=1 dst-address=0.0.0.0/0 gateway=192.168.2.2 \
    pref-src="" routing-table=main scope=30 suppress-hw-offload=no \
    target-scope=10
add disabled=no distance=1 dst-address=10.0.0.0/24 gateway=192.168.2.5 \
    pref-src="" routing-table=main scope=30 suppress-hw-offload=no \
    target-scope=10

In case the firewall mangle and nat rules might help:

RB5009:

# 2024-10-05 10:02:23 by RouterOS 7.14.2
# software id = 2KBD-7ZZB
#
# model = RB5009UPr+S+

/ip firewall mangle
add action=mark-connection chain=prerouting comment=\
    "Mark connection for hairpin" disabled=yes dst-address-list=dynamic-WANIP \
    log=yes new-connection-mark="Hairpin NAT" passthrough=yes src-address=\
    192.168.2.0/24
add action=mark-connection chain=prerouting comment=\
    "Mark connection for hairpin" disabled=yes dst-address-list=dynamic-WANIP \
    log=yes new-connection-mark="Hairpin NAT" passthrough=yes src-address=\
    192.168.2.0/24
add action=mark-connection chain=prerouting comment=\
    "Mark connection for hairpin" disabled=yes dst-address-list=dynamic-WANIP \
    log=yes new-connection-mark="Hairpin NAT" passthrough=yes src-address=\
    192.168.2.0/24

/ip firewall nat
add action=masquerade chain=srcnat comment="Hairpin NAT" connection-mark=\
    "Hairpin NAT" dst-address=192.168.2.0/24 src-address=192.168.2.0/24
add action=dst-nat chain=dstnat comment=mtdale.dyndns.org:81 \
    dst-address-list=mtdale dst-port=81 log-prefix=\
    "NAT FW destination mtdale port 81" protocol=tcp to-addresses=\
    192.168.0.101 to-ports=81
add action=dst-nat chain=dstnat comment=mtdale.dyndns.org:8123 \
    dst-address-list=mtdale dst-port=8123 protocol=tcp to-addresses=\
    192.168.0.162 to-ports=8123
add action=masquerade chain=srcnat comment="NEW defconf: masquerade" \
    out-interface-list=WAN
add action=dst-nat chain=dstnat dst-address-list=dynamic-WANIP dst-port=8123 \
    protocol=tcp to-addresses=192.168.2.176
add action=masquerade chain=srcnat comment="Hairpin NAT" connection-mark=\
    "Hairpin NAT" disabled=yes dst-address=192.168.2.0/24 src-address=\
    192.168.2.0/24
add action=masquerade chain=srcnat comment="NEW defconf: masquerade" \
    disabled=yes out-interface-list=WAN
add action=dst-nat chain=dstnat disabled=yes dst-address-list=dynamic-WANIP \
    dst-port=8123 protocol=tcp to-addresses=192.168.2.176
add action=dst-nat chain=dstnat disabled=yes dst-address-list=dynamic-WANIP \
    dst-port=5911 log=yes protocol=tcp to-addresses=192.168.2.139
add action=dst-nat chain=dstnat disabled=yes dst-port=51833 protocol=udp \
    to-addresses=192.168.2.50
add action=masquerade chain=srcnat comment="Hairpin NAT" connection-mark=\
    "Hairpin NAT" disabled=yes dst-address=192.168.2.0/24 src-address=\
    192.168.2.0/24
add action=masquerade chain=srcnat comment="NEW defconf: masquerade" \
    disabled=yes out-interface-list=WAN
add action=dst-nat chain=dstnat disabled=yes dst-address-list=dynamic-WANIP \
    dst-port=8123 protocol=tcp to-addresses=192.168.2.176
add action=dst-nat chain=dstnat disabled=yes dst-address-list=dynamic-WANIP \
    dst-port=5911 log=yes protocol=tcp to-addresses=192.168.2.139
add action=dst-nat chain=dstnat disabled=yes dst-port=51833 protocol=udp \
    to-addresses=192.168.2.50

ax3:

# 2024-10-05 10:02:13 by RouterOS 7.16
# software id = 5NRD-V1QF
#
# model = C53UiG+5HPaxD2HPaxD

/ip firewall nat
add action=masquerade chain=srcnat comment="defconf: masquerade" \
    ipsec-policy=out,none out-interface-list=WAN

In general, doing so is actually a bad idea - more often than not, the issue is caused by something in those parts of the configuration that one deems irrelevant.


I don’t understand how comes your routing actually works at all. On the 5009, there are just two routes - one to 10.0.0.0/24 via 192.168.2.5 (the address of the hAP ax³, which is fine per se), and another one to 0.0.0.0/0 (i.e. the default one), whose gateway is set to the address of the 5009 itself (192.168.2.2). So I’ve got no clue how a packet towards the internet can ever escape from the 5009 - the only explanation that comes to my mind is that the address of the FIOS is also 192.168.2.2 and it sometimes wins the race. Or you’ve tried to obfuscate something, or maybe you’ve removed something “irrelevant”, hard to say. Other than this, it seems that the 5009 is configured as a gateway towards 10.0.0.0/24 on the FIOS, and as the default gateway on the hAP ax³, so when the FIOS sends a packet to a client in 10.0.0.0/24, the 5009 forwards the packet to the hAP ax³ but tells FIOS to use the hAP ax³ next time, and similarly in the reverse direction - i.e. exactly what I have suggested in the previous post. But given that it is not clear to me how it works at all, the actual behavior may be still different.

There’s a mistake also on the hAP ax³, you’ve got two overlapping subnets attached to different interfaces there, so it is also surprising that the guest devices work on both the 2.4 GHz SSID and on the 5 GHz one. Either use a different subnet for each of the two guest WiFi interfaces (including the DHCP server etc.), or make both of them member ports of the same separate bridge (until you make friends with VLANs) and move all the IP configuration to that bridge. But this is not related to the occurrence of the mysterious packet on the 5009.

Instead of blindly posting bits of a config and asking is the config okay,
Start from the beginning.
a. network diagram
b. identify all users ( devices, users (external, internal, admin)
c. identify all the traffic they should be able to execute
d. provide enough details on wan side for type of ISP, type of connection, vpns etc. ( static/dynamic public IP, CGNAT etc…)

Okay, here are the full configs. I sure hope I redacted all sensitive info – there are many, many instances of mac address, email addresses, dynmanic dns names, passwords, wireguard keys, etc. that have to be manually removed.


RB5009

# 2024-10-05 10:02:23 by RouterOS 7.14.2
# software id = 2KBD-7ZZB
#
# model = RB5009UPr+S+
# serial number = HDA08A
/interface bridge
add admin-mac=18:FD:74: auto-mac=no comment=defconf name=bridge \
    port-cost-mode=short
/interface ethernet
set [ find default-name=ether1 ] comment=WAN poe-out=off
set [ find default-name=ether2 ] comment="Switch CSS 24" poe-out=off
set [ find default-name=ether3 ] comment="JRS PC port 3" poe-out=off
set [ find default-name=ether4 ] comment="hAP 16" poe-out=off
set [ find default-name=ether5 ] comment="15 wall port 5 -- Proxmox" poe-out=\
    off
set [ find default-name=ether6 ] comment="MOCA adapter" poe-out=off
set [ find default-name=ether7 ] poe-out=off
set [ find default-name=ether8 ] poe-out=off
/interface eoip
add allow-fast-path=no disabled=yes ipsec-secret=xxxxx mac-address=\
    02:DE:0 name=eoip-tunnel-to-76 remote-address=\
    <host>.sn.mynetname.net tunnel-id=76
add allow-fast-path=no disabled=yes ipsec-secret=xxx  mac-address=\
    02:DE  name=eoip-tunnel-to-125 remote-address=\
    xxxx.dyndns.org tunnel-id=125
add disabled=yes mac-address=02:68:43 name=eoip-tunnel-to-212-ax3 \
    remote-address=192.168.2.5 tunnel-id=101
add allow-fast-path=no disabled=yes ipsec-secret=xxxx  mac-address=\
    02:DE  name=eoip-tunnel-to-255 remote-address=\
    <host>.sn.mynetname.net tunnel-id=255
add allow-fast-path=no disabled=yes ipsec-secret=xxx mac-address=\
    02:54: 6 name=eoip-tunnel-to-355 remote-address=\
    <host>.sn.mynetname.net tunnel-id=355
add allow-fast-path=no disabled=yes ipsec-secret=xxx mac-address=\
    02:DE name=eoip-tunnel-to-371 remote-address=<host>.dydns.org \
    tunnel-id=371
add allow-fast-path=no disabled=yes ipsec-secret=xxx mac-address=\
    02:6  name=eoip-tunnel-to-629 remote-address=<host>.dydns.org \
    tunnel-id=629
/interface wireguard
add listen-port=51820 mtu=1420 name=212-Wireguard private-key=\
    "WIPj L0A="
/interface list
add comment=defconf name=WAN
add comment=defconf name=LAN
add name=MANAGE
add name=DHCPdisabled
/iot lora servers
add address=eu.mikrotik.thethings.industries name=TTN-EU protocol=UDP
add address=us.mikrotik.thethings.industries name=TTN-US protocol=UDP
add address=eu1.cloud.thethings.industries name="TTS Cloud (eu1)" protocol=\
    UDP
add address=nam1.cloud.thethings.industries name="TTS Cloud (nam1)" protocol=\
    UDP
add address=au1.cloud.thethings.industries name="TTS Cloud (au1)" protocol=\
    UDP
add address=eu1.cloud.thethings.network name="TTN V3 (eu1)" protocol=UDP
add address=nam1.cloud.thethings.network name="TTN V3 (nam1)" protocol=UDP
add address=au1.cloud.thethings.network name="TTN V3 (au1)" protocol=UDP
/iot mqtt brokers
add address=192.168.0.103 client-id=192.168.2.2 name=HA password=<password> \
    username=mqtt
add address=192.168.0.162 auto-connect=yes name="Home Assistant" password=\
    <password> username=mqtt
/ip kid-control
add fri=0s-1d mon=0s-1d name=Monitor sat=0s-1d sun=0s-1d thu=0s-1d tue=0s-1d \
    wed=0s-1d
/ip pool
add name=dhcp ranges=192.168.2.100-192.168.2.200
/ip dhcp-server
add address-pool=dhcp interface=bridge lease-script="\r\
    \n/system\r\
    \n:local cdate [clock get date] \r\
    \n:local yyyy  [:pick \$cdate 0  4]\r\
    \n:local MM    [:pick \$cdate 5  7]\r\
    \n:local dd    [:pick \$cdate 8 10]\r\
    \n\r\
    \n:local thistime [/system clock get time]\r\
    \n:local thishour [:pick \$thistime 0 2]\r\
    \n:local thisminute [:pick \$thistime 3 5]\r\
    \n:local thissecond [:pick \$thistime 6 8]\r\
    \n:local identitydatetime \"\$[identity get name]_\$yyyy-\$MM-\$dd_\$thish\
    our:\$thisminute:\$thissecond\"\r\
    \n:local datetime \"\$yyyy-\$MM-\$dd_\$thishour:\$thisminute:\$thissecond\
    \"\r\
    \n:local systemname \"\$[identity get name]\"\r\
    \n\r\
    \n#:if (\$leaseBound=1) do={\r\
    \n\r\
    \n#  :log info \"testing after condition BOUND\" }\r\
    \n\r\
    \n#:if  ([/ip dhcp-server lease find where dynamic mac-address=\$leaseActM\
    AC]!=\"\") do={\r\
    \n\r\
    \n#  :log info \"testing after condition DYNAMIC\"}\r\
    \n\r\
    \n\r\
    \n:if  ((\$leaseBound=1)  && ([/ip dhcp-server lease find where dynamic ma\
    c-address=\$leaseActMAC]!=\"\") && ([/ip dhcp-server lease find where comm\
    ent mac-address=\$leaseActMAC]=\"\")) do={\r\
    \n\r\
    \n#    :log info \"testing after conditions BOUND and DYNAMIC and EMPTY CO\
    MMENT\" \r\
    \n\r\
    \n:local recipient \"j@xxx.com\"\r\
    \n\r\
    \n #   :tool e-mail send to=\$recipient subject=\"\$systemname DHCP Lease \
    Assigned to \$leaseActMAC\" body=\"MAC address \$leaseActMAC received IP a\
    ddress \$leaseActIP with a hostname of \$[/ip/dhcp-server/lease/get value-\
    name=host-name [find where mac-address=\$leaseActMAC]] from DHCP Server \$\
    leaseServerName on \$datetime from \$systemname with comment \$[/ip/dhcp-s\
    erver/lease/get value-name=comment [find where mac-address=\$leaseActMAC]]\
    \"\r\
    \n\r\
    \n\r\
    \n#    :log info \"Sent DHCP alert for MAC \$leaseActMAC\"\r\
    \n\r\
    \n}\r\
    \n\r\
    \n\r\
    \n\r\
    \n\r\
    \n" lease-time=1d name=defconf
/ip smb users
set [ find default=yes ] disabled=yes
/system logging action
set 3 remote=192.168.0.13
add name=logserver remote=192.168.0.112 remote-port=51400 target=remote
/zerotier
set zt1 comment="ZeroTier Central controller - https://my.zerotier.com/" \
    disabled=yes disabled=yes name=zt1 port=9993
/container config
set registry-url=https://registry-1.docker.io tmpdir=disk1/pull
/interface bridge filter
add action=drop chain=forward disabled=yes dst-port=67-68 in-interface-list=\
    DHCPdisabled ip-protocol=udp log-prefix=Bridge-Filter-Forward \
    mac-protocol=ip out-interface-list=DHCPdisabled src-port=67-68
add action=drop chain=input disabled=yes dst-port=67-68 in-interface-list=\
    DHCPdisabled ip-protocol=udp log-prefix=Bridge-Filter-Input mac-protocol=\
    ip src-port=67-68
/interface bridge port
add bridge=bridge comment=defconf ingress-filtering=no interface=ether2 \
    internal-path-cost=10 path-cost=10
add bridge=bridge comment=defconf ingress-filtering=no interface=ether3 \
    internal-path-cost=10 path-cost=10
add bridge=bridge comment=defconf ingress-filtering=no interface=ether4 \
    internal-path-cost=10 path-cost=10
add bridge=bridge comment=defconf ingress-filtering=no interface=ether5 \
    internal-path-cost=10 path-cost=10
add bridge=bridge interface=ether6 internal-path-cost=10 path-cost=10
add bridge=bridge interface=ether7 internal-path-cost=10 path-cost=10
add bridge=bridge interface=ether8 internal-path-cost=10 path-cost=10
/ip firewall connection tracking
set udp-timeout=10s
/ip neighbor discovery-settings
set discover-interface-list=all
/ipv6 settings
set accept-redirects=no accept-router-advertisements=no disable-ipv6=yes \
    forward=no max-neighbor-entries=8192
/interface list member
add comment=defconf interface=bridge list=LAN
add comment=defconf interface=ether1 list=WAN
add interface=bridge list=MANAGE
add disabled=yes interface=ether1 list=MANAGE
add interface=212-Wireguard list=LAN
add interface=212-Wireguard list=MANAGE
add interface=212-Wireguard list=DHCPdisabled
add interface=eoip-tunnel-to-76 list=DHCPdisabled
add interface=eoip-tunnel-to-125 list=DHCPdisabled
add interface=eoip-tunnel-to-212-ax3 list=DHCPdisabled
add interface=eoip-tunnel-to-255 list=DHCPdisabled
add interface=eoip-tunnel-to-355 list=DHCPdisabled
add interface=eoip-tunnel-to-371 list=DHCPdisabled
add interface=eoip-tunnel-to-629 list=DHCPdisabled
/interface wireguard peers
add allowed-address=10.10.100.8/32 comment="JRS Laptop" interface=\
    212-Wireguard public-key="b9iypJX8="
add allowed-address=\
    10.10.100.2/32,192.168.88.0/24,10.10.100.40/32,192.168.40.0/24 comment=\
    371 endpoint-address=<host>.dydns.org endpoint-port=52820 interface=\
    212-Wireguard persistent-keepalive=40s public-key=\
    "zoZtilohI="
add allowed-address=10.10.100.9/32 comment="JRS iPhone" interface=\
    212-Wireguard public-key="PypF8="
add allowed-address=10.10.100.12/32,192.168.20.0/24 comment=629 \
    endpoint-address=<host>.dydns.org endpoint-port=51821 interface=\
    212-Wireguard persistent-keepalive=40s public-key=\
    "q28DzCXo="
add allowed-address=10.10.100.50/32,192.168.0.0/24,192.168.5.0/24 comment=355 \
    endpoint-address=<host>.dydns.org endpoint-port=51833 interface=\
    212-Wireguard persistent-keepalive=40s public-key=\
    "Q8mLZq3g="
add allowed-address=10.10.100.60/32,192.168.1.0/24 comment=255 \
    endpoint-address=<host>.dydns.org endpoint-port=51835 interface=\
    212-Wireguard persistent-keepalive=40s public-key=\
    "6E3qiwbRc="
add allowed-address=10.10.100.30/32,192.168.30.1/24 comment=76 \
    endpoint-address=<host>.dydns.org endpoint-port=51830 interface=\
    212-Wireguard persistent-keepalive=40s public-key=\
    "EJu6Uic="
add allowed-address=10.10.90.0/24 comment="BI PC WG APP" endpoint-port=51820 \
    interface=212-Wireguard public-key=\
    "R5SjZucV4="
add allowed-address=10.10.100.1/32,192.168.2.2/24 comment=\
    "212 (local, just for reference);   192.168.2.2" disabled=yes \
    endpoint-address=<host>.dydns.org endpoint-port=51820 interface=\
    212-Wireguard public-key="xx271ODs="
add allowed-address=10.10.100.100/32 comment="JRS Laptop 201" disabled=yes \
    interface=212-Wireguard public-key=\
    "QJCXZaAI75udeqsSFk="
add allowed-address=10.10.100.101/32 endpoint-port=51840 interface=\
    212-Wireguard public-key="N/t6/86S/qTZsW8="
add allowed-address=10.10.100.70/32,192.168.70.0/24 comment=125 \
    endpoint-address=<host>.dydns.org endpoint-port=51870 interface=\
    212-Wireguard persistent-keepalive=40s public-key=\
    "Otpb8="
add allowed-address=10.10.100.99/32,192.168.2.0/24 comment="JRS Laptop 2023" \
    interface=212-Wireguard private-key=\
    "ED8p2Q=" public-key=\
    "w9XFndCHiU="
add allowed-address=10.10.100.53/32,192.168.0.0/24 client-listen-port=51840 \
    comment="WG Proxmox Win11" endpoint-address=<host>.dydns.org \
    endpoint-port=51844 interface=*12 public-key=\
    "WutDGRDk="
add allowed-address=10.10.100.15/32 comment=AX endpoint-address=10.0.0.1 \
    endpoint-port=51860 interface=212-Wireguard persistent-keepalive=40s \
    public-key="C6fh04="
/ip address
add address=192.168.2.2/24 comment=defconf interface=bridge network=\
    192.168.2.0
add address=10.10.100.1/24 interface=212-Wireguard network=10.10.100.0
/ip cloud
set ddns-enabled=yes ddns-update-interval=1h
/ip dhcp-client
add comment=defconf interface=ether1 use-peer-dns=no
/ip dhcp-server alert
add alert-timeout=12h disabled=no interface=bridge on-alert="/system script ad\
    d name=rogue-dhcp source=\94:log warning message=\\\94Rogue DHCP server de\
    tected!\\\94\94"
add alert-timeout=30m interface=bridge on-alert=rogue-dhcp
/ip dhcp-server lease
add address=192.168.2.100 comment=TV15 mac-address=78:6AC8 server=\
    defconf

/ip dhcp-server network
add address=192.168.2.0/24 comment=defconf dns-server=192.168.2.2 gateway=\
    192.168.2.2 netmask=24
/ip dns
set allow-remote-requests=yes cache-max-ttl=2d cache-size=4096KiB servers=\
    8.8.4.4,8.8.8.8,9.9.9.9,1.1.1.1
/ip dns static
add address=192.168.2.8 name=212-rb5009.212.local
add address=192.168.2.2 name=RB5009.212.local ttl=9w6d10h40m
add address=10.10.100.1 name=212.10.10.100.1.local ttl=9w6d10h40m
add address=192.168.2.100 comment="automatic-from-comment (magic comment)" \
    name=TV15.212.local ttl=1h
add address=192.168.2.121 comment="automatic-from-comment (magic comment)" \
    name="Ipad SRN.212.local" ttl=9w6d10h40m
add address=192.168.2.138 comment="automatic-from-comment (magic comment)" \
    name=MFCL3770CDW.212.local ttl=9w6d10h40m
add address=192.168.2.141 comment="automatic-from-comment (magic comment)" \
    name="JRS iPhone.212.local" ttl=9w6d10h40m
add address=192.168.2.109 comment="automatic-from-comment (magic comment)" \
    name="Vizio on 15.212.local" ttl=9w6d10h40m
add address=192.168.2.122 comment="automatic-from-comment (magic comment)" \
    name=Homepod.212.local ttl=9w6d10h40m
add address=192.168.2.199 comment="automatic-from-comment (magic comment)" \
    name=Playstation.212.local ttl=9w6d10h40m
add address=192.168.2.142 comment="automatic-from-comment (magic comment)" \
    name=SRNAppleWatch.212.local ttl=9w6d10h40m
add address=192.168.2.22 name=JRS-PC.212.local
add address=192.168.2.102 comment="automatic-from-dhcp (magic comment)" name=\
    Master-Bedroom.212.local ttl=1h40m
add address=192.168.2.103 comment="automatic-from-dhcp (magic comment)" name=\
    Family-Room.212.local ttl=1h40m
add address=192.168.2.138 comment="automatic-from-dhcp (magic comment)" name=\
    MFC-L3770.212.local ttl=1h40m
add address=192.168.2.147 comment="automatic-from-dhcp (magic comment)" name=\
    212LR.212.local ttl=1h40m
add address=192.168.2.191 comment="automatic-from-dhcp (magic comment)" name=\
    SRNOffice.212.local ttl=1h40m
add address=192.168.2.128 comment="automatic-from-dhcp (magic comment)" name=\
    212MBR.212.local ttl=1h40m
add address=192.168.2.200 comment="automatic-from-dhcp (magic comment)" name=\
    HarmonyHub.212.local ttl=1h40m
add address=192.168.2.124 comment="automatic-from-dhcp (magic comment)" name=\
    BRW2C6FC95FBCEB.212.local ttl=1h40m
add address=192.168.2.173 comment="automatic-from-dhcp (magic comment)" name=\
    NC-LT-SN20.212.local ttl=1h40m
add address=192.168.2.137 comment="automatic-from-dhcp (magic comment)" name=\
    tasmota-E37677-5751.212.local ttl=1h40m
add address=192.168.2.117 comment="automatic-from-dhcp (magic comment)" name=\
    BRNB4220095598A.212.local ttl=1h40m
add address=192.168.2.127 comment="automatic-from-dhcp (magic comment)" name=\
    Debian.212.local ttl=1h40m
add address=192.168.2.110 comment="automatic-from-dhcp (magic comment)" name=\
    JRS-Laptop-2023.212.local ttl=1h40m
add address=192.168.2.108 comment="automatic-from-dhcp (magic comment)" name=\
    0005CD193C07.212.local ttl=1h40m
add address=x.x.x.x name=<host>.dyndns.org
/ip firewall address-list
add address=<host>.dydns.org list=dynamic-WANIP
add address=192.168.0.0/16 list=Authorized
add address=10.10.100.0/24 list=Authorized
add address=<host>.dydns.org list=mtdale
/ip firewall filter
add action=accept chain=input comment=\
    "defconf: accept established,related,untracked" connection-state=\
    established,related,untracked
add action=drop chain=input comment="defconf: drop invalid" connection-state=\
    invalid
add action=accept chain=input comment="defconf: accept ICMP" protocol=icmp
add action=accept chain=input comment="Loopback allow" dst-address=127.0.0.1
add action=drop chain=input comment="DROP DHCP on DHCPdisabled" dst-port=\
    67-68 in-interface-list=DHCPdisabled log=yes protocol=udp src-port=67-68
add action=accept chain=input comment="Allow GRE for EoIP" protocol=gre
add action=accept chain=input comment="Allow incoming WG connections" \
    dst-port=51820 protocol=udp
add action=accept chain=input comment="Allow Authorized" src-address-list=\
    Authorized
add action=accept chain=input comment="Allow LAN" in-interface-list=LAN
add action=drop chain=input comment="drop all else"
add action=fasttrack-connection chain=forward comment="defconf: fasttrack" \
    connection-state=established,related hw-offload=yes
add action=accept chain=forward comment=\
    "defconf: accept established,related, untracked" connection-state=\
    established,related,untracked
add action=accept chain=forward comment="Allow LAN to WAN" in-interface-list=\
    LAN out-interface-list=WAN
add action=accept chain=forward comment="allow port forwarding" \
    connection-nat-state=dstnat
add action=accept chain=forward comment="Allows cross peer subnet traffic" \
    in-interface=212-Wireguard out-interface=212-Wireguard
add action=accept chain=forward comment="Allow WG to subnet" dst-address=\
    192.168.2.0/24 in-interface=212-Wireguard
add action=accept chain=forward comment="Allow all traffic out WG iface" \
    out-interface=212-Wireguard
add action=drop chain=forward log=yes log-prefix="drop forward (all else)"
/ip firewall mangle
add action=mark-connection chain=prerouting comment=\
    "Mark connection for hairpin" disabled=yes dst-address-list=dynamic-WANIP \
    log=yes new-connection-mark="Hairpin NAT" passthrough=yes src-address=\
    192.168.2.0/24
add action=mark-connection chain=prerouting comment=\
    "Mark connection for hairpin" disabled=yes dst-address-list=dynamic-WANIP \
    log=yes new-connection-mark="Hairpin NAT" passthrough=yes src-address=\
    192.168.2.0/24
add action=mark-connection chain=prerouting comment=\
    "Mark connection for hairpin" disabled=yes dst-address-list=dynamic-WANIP \
    log=yes new-connection-mark="Hairpin NAT" passthrough=yes src-address=\
    192.168.2.0/24
/ip firewall nat
add action=masquerade chain=srcnat comment="Hairpin NAT" connection-mark=\
    "Hairpin NAT" dst-address=192.168.2.0/24 src-address=192.168.2.0/24
add action=dst-nat chain=dstnat comments=<host>.dydns.org:81 \
    dst-address-list=mtdale dst-port=81 log-prefix=\
    "NAT FW destination mtdale port 81" protocol=tcp to-addresses=\
    192.168.0.101 to-ports=81
add action=dst-nat chain=dstnat comments=<host>.dydns.org:8123 \
    dst-address-list=mtdale dst-port=8123 protocol=tcp to-addresses=\
    192.168.0.162 to-ports=8123
add action=masquerade chain=srcnat comment="NEW defconf: masquerade" \
    out-interface-list=WAN
add action=dst-nat chain=dstnat dst-address-list=dynamic-WANIP dst-port=8123 \
    protocol=tcp to-addresses=192.168.2.176
add action=masquerade chain=srcnat comment="Hairpin NAT" connection-mark=\
    "Hairpin NAT" disabled=yes dst-address=192.168.2.0/24 src-address=\
    192.168.2.0/24
add action=masquerade chain=srcnat comment="NEW defconf: masquerade" \
    disabled=yes out-interface-list=WAN
add action=dst-nat chain=dstnat disabled=yes dst-address-list=dynamic-WANIP \
    dst-port=8123 protocol=tcp to-addresses=192.168.2.176
add action=dst-nat chain=dstnat disabled=yes dst-address-list=dynamic-WANIP \
    dst-port=5911 log=yes protocol=tcp to-addresses=192.168.2.139
add action=dst-nat chain=dstnat disabled=yes dst-port=51833 protocol=udp \
    to-addresses=192.168.2.50
add action=masquerade chain=srcnat comment="Hairpin NAT" connection-mark=\
    "Hairpin NAT" disabled=yes dst-address=192.168.2.0/24 src-address=\
    192.168.2.0/24
add action=masquerade chain=srcnat comment="NEW defconf: masquerade" \
    disabled=yes out-interface-list=WAN
add action=dst-nat chain=dstnat disabled=yes dst-address-list=dynamic-WANIP \
    dst-port=8123 protocol=tcp to-addresses=192.168.2.176
add action=dst-nat chain=dstnat disabled=yes dst-address-list=dynamic-WANIP \
    dst-port=5911 log=yes protocol=tcp to-addresses=192.168.2.139
add action=dst-nat chain=dstnat disabled=yes dst-port=51833 protocol=udp \
    to-addresses=192.168.2.50
/ip route
add comment=371 disabled=yes distance=1 dst-address=192.168.88.0/24 gateway=\
    *B pref-src="" routing-table=main scope=30 suppress-hw-offload=no \
    target-scope=10
add comment=355 disabled=yes distance=1 dst-address=192.168.0.0/24 gateway=*B \
    pref-src="" routing-table=main scope=30 suppress-hw-offload=no \
    target-scope=10
add comment=255 disabled=yes distance=1 dst-address=192.168.1.0/24 gateway=*B \
    pref-src="" routing-table=main scope=30 suppress-hw-offload=no \
    target-scope=10
add disabled=yes distance=1 dst-address=192.168.5.0/24 gateway=*B pref-src="" \
    routing-table=main scope=30 suppress-hw-offload=no target-scope=10
add comment=629 disabled=yes distance=1 dst-address=192.168.20.0/24 gateway=\
    *B pref-src="" routing-table=main scope=30 suppress-hw-offload=no \
    target-scope=10
add disabled=no distance=1 dst-address=0.0.0.0/0 gateway=192.168.2.2 \
    pref-src="" routing-table=main scope=30 suppress-hw-offload=no \
    target-scope=10
add comment=355 disabled=no distance=1 dst-address=192.168.0.0/24 gateway=\
    212-Wireguard pref-src="" routing-table=main scope=30 \
    suppress-hw-offload=no target-scope=10
add comment=255 disabled=no distance=1 dst-address=192.168.1.0/24 gateway=\
    212-Wireguard pref-src="" routing-table=main scope=30 \
    suppress-hw-offload=no target-scope=10
add comment=355-Cameras disabled=no distance=1 dst-address=192.168.5.0/24 \
    gateway=212-Wireguard pref-src="" routing-table=main scope=30 \
    suppress-hw-offload=no target-scope=10
add comment=629 disabled=no distance=1 dst-address=192.168.20.0/24 gateway=\
    212-Wireguard pref-src="" routing-table=main scope=30 \
    suppress-hw-offload=no target-scope=10
add disabled=no distance=1 dst-address=192.168.60.0/24 gateway=192.168.2.8 \
    pref-src="" routing-table=main scope=30 suppress-hw-offload=no \
    target-scope=10
add comment=76 disabled=no distance=1 dst-address=192.168.30.0/24 gateway=\
    212-Wireguard pref-src="" routing-table=main scope=30 \
    suppress-hw-offload=no target-scope=10
add comment=371 disabled=no distance=1 dst-address=192.168.40.0/24 gateway=\
    212-Wireguard pref-src="" routing-table=main scope=30 \
    suppress-hw-offload=no target-scope=10
add comment=125 disabled=no distance=1 dst-address=192.168.70.0/24 gateway=\
    212-Wireguard pref-src="" routing-table=main scope=30 \
    suppress-hw-offload=no target-scope=10
add disabled=no distance=1 dst-address=10.0.0.0/24 gateway=192.168.2.5 \
    pref-src="" routing-table=main scope=30 suppress-hw-offload=no \
    target-scope=10
/ip service
set www-ssl disabled=no
/ip smb shares
set [ find default=yes ] directory=/pub
/ip ssh
set always-allow-password-login=yes forwarding-enabled=both
/snmp
set enabled=yes trap-version=2
/system clock
set time-zone-name=America/New_York
/system identity
set name=212RB5009
/system logging
set 0 topics=info,!script
add topics=account
add topics=watchdog
add action=logserver prefix="serial=HDA08A4MAZH MikroTik" topics=hotspot
add action=logserver prefix="serial=HDA08A4MAZH MikroTik" topics=\
    !debug,!packet,!snmp
add action=remote prefix="192.168.2.2 " topics=info
/system note
set show-at-login=no
/system ntp client
set enabled=yes
/system ntp server
set enabled=yes
/system ntp client servers
add address=216.239.35.4
add address=104.16.132.229
/system scheduler
add disabled=yes interval=1d name=Daily on-event=dyndns policy=\
    ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon \
    start-date=2022-10-18 start-time=02:00:00
add disabled=yes interval=10m name=Route355255371 on-event=\
    "355 255 371 route status" policy=\
    ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon \
    start-date=2022-11-24 start-time=04:42:54
add interval=2d name=export-download on-event=export-download policy=\
    ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon \
    start-date=2022-12-14 start-time=04:47:33
add disabled=yes interval=1h name="355 255 371 629 Route Status" on-event=\
    "355 255 371 629 Route Status" policy=\
    ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon \
    start-date=2023-01-23 start-time=16:22:48
add interval=2w name=dynamic-data-rextended on-event=dynamic-data-rextended \
    policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon \
    start-date=2023-09-30 start-time=02:58:29
add interval=30m name=Netwatch on-event=Netwatch policy=\
    ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon \
    start-date=2023-01-23 start-time=16:22:48
add disabled=yes interval=30m name=WG-iface-restart on-event=WG-iface-restart \
    policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon \
    start-date=2023-03-13 start-time=06:41:55
add interval=5d name=IPlist on-event=IPlist policy=\
    ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon \
    start-date=2023-04-10 start-time=06:54:16
add disabled=yes name="Hassio Firmware Entity Publish" on-event=\
    "Hassio Firmware Entity Publish" policy=read,test start-time=startup
add disabled=yes interval=6h name="Hassio Firmware State Publish" on-event=\
    "Hassio Firmware State Publish" policy=read,write,policy,test start-time=\
    startup
add disabled=yes name=HassioSensorHealthEntityPublish on-event=\
    HassioSensorHealthEntityPublish policy=read,write,test start-time=startup
add disabled=yes interval=1h name=HassioSensorHealthStatePublish on-event=\
    HassioSensorHealthStatePublish policy=read,write,test start-time=startup
add disabled=yes name=HassioSensorPoeEntityPublish on-event=\
    HassioSensorPoeEntityPublish policy=read,write,test start-time=startup
add disabled=yes interval=1h name=HassioSensorPoeStatePublish on-event=\
    HassioSensorPoeStatePublish policy=read,test start-time=startup
add interval=2w name=dhcpleasesftp on-event=dhcpleasesftp policy=\
    ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon \
    start-date=2022-12-14 start-time=04:47:33
add disabled=yes interval=30m name=WG-iface-restart-log-lasthandshake \
    on-event=WG-iface-restart-log-lasthandshake policy=\
    ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon \
    start-date=2024-03-18 start-time=05:25:18
add interval=1d name=DynDNS on-event=DynDNS policy=\
    ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon \
    start-date=2022-10-18 start-time=02:00:00
add interval=1m name=UPSonline on-event=UPSonline policy=\
    ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon \
    start-date=2024-04-05 start-time=08:08:58
add interval=5m name=Data_to_Splunk on-event=Data_to_Splunk_using_Syslog \
    policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon \
    start-date=2024-09-06 start-time=18:27:54
/system script
add dont-require-permissions=no name=Netwatch-JRS owner=admin policy=\
    ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="{\
    \r\
    \n:global prevstatus355;\r\
    \n:global updown355;\r\
    \n:global status355 [:ip route get value-name=active [:ip route find comme\
    nt=\"355\"]]\r\
    \n\r\
    \n#:log info (\"status355 is \$status355\");\r\
    \n#:log info (\"prevstatus355 is \$prevstatus355\");\r\
    \n\r\
    \n:if ( \"\$status355\" = true ) do={:set updown355 UP} else= {:set updown\
    355 DOWN}\r\
    \n\r\
    \n#:log info (\"updown355 is \$updown355\");\r\
    \n\r\
    \n:if ( \"\$status355\" != \"\$prevstatus355\" ) do={ \r\
    \n\r\
    \n#:log warn \"355 connectivity is now \\\"\$updown355\\\" \";\r\
    \n:tool e-mail send to=j@xxx.com subject=\"355 Connectivity n\
    ow \\\"\$updown355\\\"\" body=( [ :system clock get date ] . \" \" . [ :sy\
    stem clock get time ] . \" SENT FROM 212hEX:  355 connectivity changed sta\
    tus from \\\"\$prevstatus355\\\" -> \\\"\$updown355\\\" \" )\r\
    \n\r\
    \n:set prevstatus355 \$status355\r\
    \n\r\
    \n}\r\
    \n\r\
    \n\r\
    \n:global prevstatus371;\r\
    \n:global updown371;\r\
    \n:global status371 [:ip route get value-name=active [:ip route find comme\
    nt=\"371\"]]\r\
    \n\r\
    \n#:log info (\"status371 is \$status371\");\r\
    \n#:log info (\"prevstatus371 is \$prevstatus371\");\r\
    \n\r\
    \n:if ( \"\$status371\" = true ) do={:set updown371 UP} else= {:set updown\
    371 DOWN}\r\
    \n\r\
    \n#:log info (\"updown371 is \$updown371\");\r\
    \n\r\
    \n:if ( \"\$status371\" != \"\$prevstatus371\" ) do={ \r\
    \n\r\
    \n#:log warn \"371 connectivity is now \\\"\$updown371\\\" \";\r\
    \n:tool e-mail send to=j@xxx.com subject=\"371 Connectivity n\
    ow \\\"\$updown371\\\"\" body=( [ :system clock get date ] . \" \" . [ :sy\
    stem clock get time ] . \" SENT FROM 212hEX:  371 connectivity changed sta\
    tus from \\\"\$prevstatus371\\\" -> \\\"\$updown371\\\" \" )\r\
    \n\r\
    \n:set prevstatus371 \$status371\r\
    \n\r\
    \n}\r\
    \n\r\
    \n\r\
    \n:global prevstatus255;\r\
    \n:global updown255;\r\
    \n:global status255 [:ip route get value-name=active [:ip route find comme\
    nt=\"255\"]]\r\
    \n\r\
    \n#:log info (\"status255 is \$status255\");\r\
    \n#:log info (\"prevstatus255 is \$prevstatus255\");\r\
    \n\r\
    \n:if ( \"\$status255\" = true ) do={:set updown255 UP} else= {:set updown\
    255 DOWN}\r\
    \n\r\
    \n#:log info (\"updown255 is \$updown255\");\r\
    \n\r\
    \n:if ( \"\$status255\" != \"\$prevstatus255\" ) do={ \r\
    \n\r\
    \n#:log warn \"255 connectivity is now \\\"\$updown255\\\" \";\r\
    \n:tool e-mail send to=j@xxx.com subject=\"255 Connectivity n\
    ow \\\"\$updown255\\\"\" body=( [ :system clock get date ] . \" \" . [ :sy\
    stem clock get time ] . \" SENT FROM 212hEX:  255 connectivity changed sta\
    tus from \\\"\$prevstatus255\\\" -> \\\"\$updown255\\\" \" )\r\
    \n\r\
    \n:set prevstatus255 \$status255\r\
    \n\r\
    \n}\r\
    \n\r\
    \n\r\
    \n\r\
    \n:global prevstatus629;\r\
    \n:global updown629;\r\
    \n:global status629 [:ip route get value-name=active [:ip route find comme\
    nt=\"629\"]]\r\
    \n\r\
    \n#:log info (\"status629 is \$status629\");\r\
    \n#:log info (\"prevstatus629 is \$prevstatus629\");\r\
    \n\r\
    \n:if ( \"\$status629\" = true ) do={:set updown629 UP} else= {:set updown\
    629 DOWN}\r\
    \n\r\
    \n#:log info (\"updown629 is \$updown629\");\r\
    \n\r\
    \n:if ( \"\$status629\" != \"\$prevstatus629\" ) do={ \r\
    \n\r\
    \n#:log warn \"629 connectivity is now \\\"\$updown629\\\" \";\r\
    \n:tool e-mail send to=j@xxx.com subject=\"629 Connectivity n\
    ow \\\"\$updown629\\\"\" body=( [ :system clock get date ] . \" \" . [ :sy\
    stem clock get time ] . \" SENT FROM 212hEX:  629 connectivity changed sta\
    tus from \\\"\$prevstatus629\\\" -> \\\"\$updown629\\\" \" )\r\
    \n\r\
    \n:set prevstatus629 \$status629\r\
    \n\r\
    \n}\r\
    \n\r\
    \n\r\
    \n\r\
    \n\r\
    \n\r\
    \n:global prevstatus76;\r\
    \n:global updown76;\r\
    \n:global status76 [:ip route get value-name=active [:ip route find commen\
    t=\"76\"]]\r\
    \n\r\
    \n#:log info (\"status76 is \$status76\");\r\
    \n#:log info (\"prevstatus76 is \$prevstatus76\");\r\
    \n\r\
    \n:if ( \"\$status76\" = true ) do={:set updown76 UP} else= {:set updown76\
    \_DOWN}\r\
    \n\r\
    \n#:log info (\"updown76 is \$updown76\");\r\
    \n\r\
    \n:if ( \"\$status76\" != \"\$prevstatus76\" ) do={ \r\
    \n\r\
    \n#:log warn \"629 connectivity is now \\\"\$updown629\\\" \";\r\
    \n:tool e-mail send to=j@xxx.com subject=\"76 Connectivity no\
    w \\\"\$updown76\\\"\" body=( [ :system clock get date ] . \" \" . [ :syst\
    em clock get time ] . \" SENT FROM 212hEX:  76 connectivity changed status\
    \_from \\\"\$prevstatus76\\\" -> \\\"\$updown76\\\" \" )\r\
    \n\r\
    \n:set prevstatus76 \$status76\r\
    \n\r\
    \n}\r\
    \n\r\
    \n\r\
    \n}\r\
    \n"
add dont-require-permissions=no name=GetIP owner=admin policy=\
    ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="/\
    interface bridge host\r\
    \n:foreach item in=[find] do={\r\
    \n    :local iface  [get \$item interface]\r\
    \n    :local macadd [get \$item mac-address]\r\
    \n    :local idmac  [/ip arp find where mac-address=\$macadd]\r\
    \n    :if ([:len \$idmac] = 1) do={\r\
    \n        :local ifip [/ip arp get \$idmac address]\r\
    \n        :put   \"interface=\$iface mac=\$macadd ip=\$ifip\"\r\
    \n    }\r\
    \n}"
add dont-require-permissions=no name="New route UP" owner=admin policy=\
    ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source=":\
    global prevstatus355\r\
    \n{\r\
    \n    /ip route\r\
    \n    :local status355 [get [find where comment=\"355\"] active]\r\
    \n    :if (\$status355) do={:set status355 \"UP\"} else={:set status355 \"\
    DOWN\"}\r\
    \n    :log info \"status355 is \$status355 and prevstatus355 is \$prevstat\
    us355\"\r\
    \n    :if (\$status355 != \$prevstatus355) do={ \r\
    \n        :log warning \"355 connectivity is now \$status355\"\r\
    \n        /tool e-mail send to=j@xxx.com subject=\"355 Connec\
    tivity is now \$status355\" \\\r\
    \n                     body=\"\$[/system clock get date] \$[/system clock \
    get time] 355 connectivity changed status \$prevstatus355 -> \$status355\"\
    \r\
    \n        :set prevstatus355 \$status355\r\
    \n    }\r\
    \n}\r\
    \n"
add dont-require-permissions=no name=export-download owner=admin policy=\
    ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="\
    \r\
    \n\r\
    \n/system\r\
    \n:local cdate [clock get date] \r\
    \n:local yyyy  [:pick \$cdate 0  4]\r\
    \n:local MM    [:pick \$cdate 5  7]\r\
    \n:local dd    [:pick \$cdate 8 10]\r\
    \n:local identitydate \"\$[identity get name]_\$yyyy-\$MM-\$dd\"\r\
    \n/export show-sensitive file=\"\$identitydate\"\r\
    \n\r\
    \n/tool fetch upload=yes mode=ftp ascii=no src-path=\"/\$[\$identitydate].\
    rsc\" dst-path=\"/mikrotik-backups/\$[\$identitydate].rsc\" address=192.16\
    8.2.22 port=21 user=mikrotik password=<password>\r\
    \n\r\
    \n/file remove \"\$identitydate.rsc\"\r\
    \n\r\
    \n# /system logging set 0 topics=info\r\
    \n# /system logging add action=remote prefix=192.168.0.13 topics=info\r\
    \n\r\
    \n:log info (\"Uploaded rsc backup to 192.168.2.22 as \".\$identitydate)\r\
    \n\r\
    \n# /system logging set 0 topics=info,!script\r\
    \n# /system logging add action=remote prefix=192.168.0.13 topics=info,!scr\
    ipt"
add dont-require-permissions=yes name=WG-iface-restart owner=admin policy=\
    ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source=":\
    foreach i in=[/interface/wireguard/peers/find where disabled=no endpoint-a\
    ddress~\"[a-z]\\\$\"] do={\r\
    \n  :local LastHandshake [/interface/wireguard/peers/get \$i last-handshak\
    e]\r\
    \n  :if (([:tostr \$LastHandshake] = \"\") or (\$LastHandshake > [:totime \
    \"5m\"])) do={\r\
    \n   \r\
    \n     :log info \"WG-iface-restart script found WG peers with last handsh\
    ake greater than 5 minutes; then reset the endpoint-address to reload dns \
    of endpoint\"\r\
    \n\r\
    \n    /interface/wireguard/peers/set \$i endpoint-address=[/interface/wire\
    guard/peers/get \$i endpoint-address]\r\
    \n\r\
    \n   :local endpoint [/interface/wireguard/peers/get \$i endpoint-address]\
    \r\
    \n   :log info \"WG-iface-restart script found WG peer with last handshake\
    \_greater than 5 minutes; then reset the endpoint-address to reload dns of\
    \_endpoint:  \$endpoint\"\r\
    \n\r\
    \n  }\r\
    \n}\r\
    \n\r\
    \n"
add dont-require-permissions=no name=IPlist owner=admin policy=\
    ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="#\
    \_Export public IP and mail it\r\
    \n\r\
    \n/ip/address print file=\"212-IP-\$[\$nowdate]\"\r\
    \n\r\
    \n/tool fetch upload=yes mode=ftp ascii=no src-path=\"212-IP-\$[\$nowdate]\
    .txt\" dst-path=\"/mikrotik-backups/212-IP-\$[\$nowdate].txt\" address=192\
    .168.2.22 port=21 user=mikrotik password=<password>\r\
    \n\r\
    \n/file remove \"212-IP-\$[\$nowdate].txt\""
add dont-require-permissions=no name="DHCP to DNS" owner=admin policy=\
    ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="#\
    \_SPDX-License-Identifier: CC0-1.0\
    \n\r\
    \n\r\r\r\r\
    \n\r\
    \n\r\r:local domains [:toarray \"212.local\"]\
    \n\r\
    \n\r\r:local dnsttl \"100m\"\
    \n\r\
    \n\r\r\
    \n\r\
    \n\r\r:local magiccomment \"automatic-from-dhcp (magic comment)\"\
    \n\r\
    \n\r\r:local activehosts [:toarray \"\"]\
    \n\r\
    \n\r\r\
    \n\r\
    \n\r\r:foreach lease in [/ip dhcp-server lease find] do={\
    \n\r\
    \n\r\r  :local hostname [/ip dhcp-server lease get value-name=host-name \$\
    lease]\
    \n\r\
    \n\r\r  :local hostaddr [/ip dhcp-server lease get value-name=address \$le\
    ase]\
    \n\r\
    \n\r\r\
    \n\r\
    \n\r\r  :if ([:len \$hostname] > 0) do={\
    \n\r\
    \n\r\r    :foreach domain in \$domains do={\
    \n\r\
    \n\r\r      :local regdomain \"\$hostname.\$domain\"\
    \n\r\
    \n\r\r      :set activehosts (\$activehosts, \$regdomain)\
    \n\r\
    \n\r\r\
    \n\r\
    \n\r\r      :if ([:len [/ip dns static find where name=\$regdomain]] = 0) \
    do={\
    \n\r\
    \n\r\r        /ip dns static add name=\$regdomain address=\$hostaddr comme\
    nt=\$magiccomment ttl=\$dnsttl\
    \n\r\
    \n\r\r      } else={\
    \n\r\
    \n\r\r        :if ([:len [/ip dns static find where name=\$regdomain comme\
    nt=\$magiccomment]] = 1) do={\
    \n\r\
    \n\r\r          /ip dns static set address=\$hostaddr [/ip dns static find\
    \_name=\$regdomain comment=\$magiccomment]\
    \n\r\
    \n\r\r        }\
    \n\r\
    \n\r\r      }\
    \n\r\
    \n\r\r    }\
    \n\r\
    \n\r\r  }\
    \n\r\
    \n\r\r}\
    \n\r\
    \n\r\r\
    \n\r\
    \n\r\r:foreach dnsentry in [/ip dns static find where comment=\$magiccomme\
    nt] do={\
    \n\r\
    \n\r\r  :local hostname [/ip dns static get value-name=name \$dnsentry]\
    \n\r\
    \n\r\r  :if ([:type [:find \$activehosts \$hostname]] = \"nil\") do={\
    \n\r\
    \n\r\r    /ip dns static remove \$dnsentry\
    \n\r\
    \n\r\r  }\
    \n\r\
    \n\r\r}\
    \n\r\
    \n\r\r"
add dont-require-permissions=no name="Comment to DNS" owner=admin policy=\
    ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="#\
    \_SPDX-License-Identifier: CC0-1.0\
    \n\r\
    \n\r\r\r\r\
    \n\r\
    \n\r\r:local domains [:toarray \"212.local\"]\
    \n\r\
    \n\r\r:local dnsttl \"15m\"\
    \n\r\
    \n\r\r\
    \n\r\
    \n\r\r:local magiccomment \"automatic-from-comment (magic comment)\"\
    \n\r\
    \n\r\r:local activehosts [:toarray \"\"]\
    \n\r\
    \n\r\r\
    \n\r\
    \n\r\r:foreach lease in [/ip dhcp-server lease find] do={\
    \n\r\
    \n\r\r  :local hostname [/ip dhcp-server lease get value-name=comment \$le\
    ase]\
    \n\r\
    \n\r\r  :local hostaddr [/ip dhcp-server lease get value-name=address \$le\
    ase]\
    \n\r\
    \n\r\r\
    \n\r\
    \n\r\r  :if ([:len \$hostname] > 0) do={\
    \n\r\
    \n\r\r    :foreach domain in \$domains do={\
    \n\r\
    \n\r\r      :local regdomain \"\$hostname.\$domain\"\
    \n\r\
    \n\r\r      :set activehosts (\$activehosts, \$regdomain)\
    \n\r\
    \n\r\r\
    \n\r\
    \n\r\r      :if ([:len [/ip dns static find where name=\$regdomain]] = 0) \
    do={\
    \n\r\
    \n\r\r        /ip dns static add name=\$regdomain address=\$hostaddr comme\
    nt=\$magiccomment ttl=\$dnsttl\
    \n\r\
    \n\r\r      } else={\
    \n\r\
    \n\r\r        :if ([:len [/ip dns static find where name=\$regdomain comme\
    nt=\$magiccomment]] = 1) do={\
    \n\r\
    \n\r\r          /ip dns static set address=\$hostaddr [/ip dns static find\
    \_name=\$regdomain comment=\$magiccomment]\
    \n\r\
    \n\r\r        }\
    \n\r\
    \n\r\r      }\
    \n\r\
    \n\r\r    }\
    \n\r\
    \n\r\r  }\
    \n\r\
    \n\r\r}\
    \n\r\
    \n\r\r\
    \n\r\
    \n\r\r:foreach dnsentry in [/ip dns static find where comment=\$magiccomme\
    nt] do={\
    \n\r\
    \n\r\r  :local hostname [/ip dns static get value-name=name \$dnsentry]\
    \n\r\
    \n\r\r  :if ([:type [:find \$activehosts \$hostname]] = \"nil\") do={\
    \n\r\
    \n\r\r    /ip dns static remove \$dnsentry\
    \n\r\
    \n\r\r  }\
    \n\r\
    \n\r\r}\
    \n\r\
    \n\r\r"
add dont-require-permissions=no name="Get dhcp-client gatewat" owner=admin \
    policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon \
    source="\r\
    \n:local dhcpclientGW  [/ip dhcp-client get [find interface=ether1] gatewa\
    y]\r\
    \n\r\
    \n:log info \$dhcpclientGW\r\
    \n"
add dont-require-permissions=no name=dynamic-data-rextended owner=admin \
    policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon \
    source="/system\r\
    \n:local identitydate \"\$[identity get name]_\$[clock get date]\"\r\
    \n:local stringexec   \"/system iden print; :put \\\"\\\\r\\\\n\\\"; /ip c\
    loud pri; :put \\\"\\\\r\\\\n\\\";  /ip dhcp-server lease pri det; :put \\\
    \"\\\\r\\\\n\\\"; /int bridge host pri det\"\r\
    \n\r\
    \n:if ([:len [/system package find where name=\"wifiwave2\"]] > 1) do={\r\
    \n    :set stringexec \"\$stringexec; :put \\\"\\\\r\\\\n\\\" /int wifiwav\
    e2 reg pri det\"\r\
    \n} \r\
    \n\r\
    \n:if ([:len [/system package find where name=\"wifiwave2\"]] > 1) do={\r\
    \n    :set stringexec \"\$stringexec; :put \\\"\\\\r\\\\n\\\" /int wireles\
    s reg pri det\"\r\
    \n}\r\
    \n\r\
    \n\r\
    \n/file remove [find where name=tmpresults.txt]\r\
    \n:delay 1s\r\
    \n:execute \$stringexec file=tmpresults.txt\r\
    \n:delay 2s\r\
    \n\r\
    \n/tool fetch upload=yes mode=ftp ascii=no address=192.168.2.22 port=21 us\
    er=mikrotik password=<password> \\\r\
    \n    src-path=tmpresults.txt dst-path=\"/mikrotik-backups/\$identitydate-\
    dynamicdata.txt\"\r\
    \n\r\
    \n/file remove [find where name=tmpresults.txt]"
add dont-require-permissions=no name="mqtt to HA" owner=admin policy=\
    ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="/\
    system script add dont-require-permissions=no name=mqttpublish owner=admin\
    \_policy=\\\r\
    \n    ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon sou\
    rce=\"#\\\r\
    \n    \\_Required packages: iot\\r\\\r\
    \n    \\n\\r\\\r\
    \n    \\n################################ Configuration ##################\
    #######\\\r\
    \n    #######\\r\\\r\
    \n    \\n# Name of an existing MQTT broker that should be used for publish\
    ing\\r\\\r\
    \n    \\n:local broker \\\"broker\\\"\\r\\\r\
    \n    \\n\\r\\\r\
    \n    \\n# MQTT topic where the message should be published\\r\\\r\
    \n    \\n:local topic \\\"my/test/topic\\\"\\r\\\r\
    \n    \\n\\r\\\r\
    \n    \\n#################################### System #####################\
    #######\\\r\
    \n    #######\\r\\\r\
    \n    \\n:put (\\\"[*] Gathering system info...\\\")\\r\\\r\
    \n    \\n:local cpuLoad [/system resource get cpu-load]\\r\\\r\
    \n    \\n:local freeMemory [/system resource get free-memory]\\r\\\r\
    \n    \\n:local usedMemory ([/system resource get total-memory] - \\\$free\
    Memory)\\r\\\r\
    \n    \\n:local rosVersion [/system package get value-name=version \\\\\\r\
    \\\r\
    \n    \\n\\A0 \\A0 [/system package find where name ~ \\\"^routeros\\\"]]\
    \\r\\\r\
    \n    \\n:local model [/system routerboard get value-name=model]\\r\\\r\
    \n    \\n:local serialNumber [/system routerboard get value-name=serial-nu\
    mber]\\r\\\r\
    \n    \\n:local upTime [/system resource get uptime]\\r\\\r\
    \n    \\n\\r\\\r\
    \n    \\n#################################### MQTT #######################\
    #######\\\r\
    \n    #######\\r\\\r\
    \n    \\n:local message \\\\\\r\\\r\
    \n    \\n\\A0 \\A0 \\\"{\\\\\\\"model\\\\\\\":\\\\\\\"\\\$model\\\\\\\",\\\
    \\\\r\\\r\
    \n    \\n\\A0 \\A0 \\A0 \\A0 \\A0 \\A0 \\A0 \\A0 \\\\\\\"sn\\\\\\\":\\\\\\\
    \"\\\$serialNumber\\\\\\\",\\\\\\r\\\r\
    \n    \\n\\A0 \\A0 \\A0 \\A0 \\A0 \\A0 \\A0 \\A0 \\\\\\\"ros\\\\\\\":\\\\\
    \\\"\\\$rosVersion\\\\\\\",\\\\\\r\\\r\
    \n    \\n\\A0 \\A0 \\A0 \\A0 \\A0 \\A0 \\A0 \\A0 \\\\\\\"cpu\\\\\\\":\\\$c\
    puLoad,\\\\\\r\\\r\
    \n    \\n\\A0 \\A0 \\A0 \\A0 \\A0 \\A0 \\A0 \\A0 \\\\\\\"umem\\\\\\\":\\\$\
    usedMemory,\\\\\\r\\\r\
    \n    \\n\\A0 \\A0 \\A0 \\A0 \\A0 \\A0 \\A0 \\A0 \\\\\\\"fmem\\\\\\\":\\\$\
    freeMemory,\\\\\\r\\\r\
    \n    \\n\\A0 \\A0 \\A0 \\A0 \\A0 \\A0 \\A0 \\A0 \\\\\\\"uptime\\\\\\\":\\\
    \\\\\"\\\$upTime\\\\\\\"}\\\"\\r\\\r\
    \n    \\n\\r\\\r\
    \n    \\n:log info \\\"\\\$message\\\";\\r\\\r\
    \n    \\n:put (\\\"[*] Total message size: \\\$[:len \\\$message] bytes\\\
    \")\\r\\\r\
    \n    \\n:put (\\\"[*] Sending message to MQTT broker...\\\")\\r\\\r\
    \n    \\n/iot mqtt publish broker=\\\$broker topic=\\\$topic message=\\\$m\
    essage\\r\\\r\
    \n    \\n:put (\\\"[*] Done\\\")\""
add dont-require-permissions=no name=mqttpublish owner=admin policy=\
    ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="#\
    \_Required packages: iot\r\
    \n\r\
    \n################################ Configuration #########################\
    #######\r\
    \n# Name of an existing MQTT broker that should be used for publishing\r\
    \n:local broker \"broker\"\r\
    \n\r\
    \n# MQTT topic where the message should be published\r\
    \n:local topic \"my/test/topic\"\r\
    \n\r\
    \n#################################### System ############################\
    #######\r\
    \n:put (\"[*] Gathering system info...\")\r\
    \n:local cpuLoad [/system resource get cpu-load]\r\
    \n:local freeMemory [/system resource get free-memory]\r\
    \n:local usedMemory ([/system resource get total-memory] - \$freeMemory)\r\
    \n:local rosVersion [/system package get value-name=version \\\r\
    \n\A0 \A0 [/system package find where name ~ \"^routeros\"]]\r\
    \n:local model [/system routerboard get value-name=model]\r\
    \n:local serialNumber [/system routerboard get value-name=serial-number]\r\
    \n:local upTime [/system resource get uptime]\r\
    \n\r\
    \n#################################### MQTT ##############################\
    #######\r\
    \n:local message \\\r\
    \n\A0 \A0 \"{\\\"model\\\":\\\"\$model\\\",\\\r\
    \n\A0 \A0 \A0 \A0 \A0 \A0 \A0 \A0 \\\"sn\\\":\\\"\$serialNumber\\\",\\\r\
    \n\A0 \A0 \A0 \A0 \A0 \A0 \A0 \A0 \\\"ros\\\":\\\"\$rosVersion\\\",\\\r\
    \n\A0 \A0 \A0 \A0 \A0 \A0 \A0 \A0 \\\"cpu\\\":\$cpuLoad,\\\r\
    \n\A0 \A0 \A0 \A0 \A0 \A0 \A0 \A0 \\\"umem\\\":\$usedMemory,\\\r\
    \n\A0 \A0 \A0 \A0 \A0 \A0 \A0 \A0 \\\"fmem\\\":\$freeMemory,\\\r\
    \n\A0 \A0 \A0 \A0 \A0 \A0 \A0 \A0 \\\"uptime\\\":\\\"\$upTime\\\"}\"\r\
    \n\r\
    \n:log info \"\$message\";\r\
    \n:put (\"[*] Total message size: \$[:len \$message] bytes\")\r\
    \n:put (\"[*] Sending message to MQTT broker...\")\r\
    \n/iot mqtt publish broker=\$broker topic=\$topic message=\$message\r\
    \n:put (\"[*] Done\")"
add dont-require-permissions=no name="DHCP to DNS -- NEW" owner=admin policy=\
    ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="#\
    \_SPDX-License-Identifier: CC0-1.0\r\
    \n\r\
    \n:local domains [:toarray \"212.local\"]\r\
    \n:local dnsttl \"100m\"\r\
    \n:local magiccomment \"automatic-from-dhcp (magic comment)\"\r\
    \n:local activehosts [:toarray \"\"]\r\
    \n\r\
    \n:foreach lease in [/ip dhcp-server lease find] do={\r\
    \n  :local hostname [/ip dhcp-server lease get value-name=host-name \$leas\
    e]\r\
    \n  :local hostaddr [/ip dhcp-server lease get value-name=address \$lease]\
    \r\
    \n  :local macaddr [/ip dhcp-server lease get value-name=mac-address \$lea\
    se]\r\
    \n\r\
    \n  :if ([:len \$hostname] > 0) do={\r\
    \n\r\
    \n    :foreach domain in \$domains do={\r\
    \n\r\
    \n      :local regdomain \"\$hostname.\$domain\"\r\
    \n      :set activehosts (\$activehosts, \$regdomain)\r\
    \n\r\
    \n      :if ([:len [/ip dns static find where name=\$regdomain]] = 0) do={\
    \r\
    \n        /ip dns static add name=\$regdomain address=\$hostaddr comment=\
    \$magiccomment ttl=\$dnsttl\r\
    \n      } else={\r\
    \n        :if ([/ip dns static find where name=\$regdomain] = \$hostname) \
    | ([/ip dhcp-server lease find where address=\$hostaddr] = \$macaddr) do=(\
    \r\
    \n\t\t  :set regdomain=(\"\$hostname\", \"-1\")       \r\
    \n          :/ip dns static add name=\$regdomain address=\$hostaddr commen\
    t=\$magiccomment ttl=\$dnsttl\r\
    \n        }  \r\
    \n          else={\r\
    \n          /ip dns static add name=\$regdomain address=\$hostaddr comment\
    =\$magiccomment ttl=\$dnsttl\r\
    \n          }\r\
    \n\r\
    \n\r\
    \n        :if ([:len [/ip dns static find where name=\$regdomain comment=\
    \$magiccomment]] = 1) do={\r\
    \n          /ip dns static set address=\$hostaddr [/ip dns static find nam\
    e=\$regdomain comment=\$magiccomment]\r\
    \n        \r\
    \n      }\r\
    \n    }\r\
    \n  }\r\
    \n\r\
    \n\r\
    \n"
add dont-require-permissions=no name=rogue-dhcp owner=admin policy=\
    ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source=\
    ":log warning message=\"Rogue DHCP server detected!\""
add dont-require-permissions=no name=HassioLib_DeviceString owner=admin \
    policy=read source="# Use\r\
    \n# local DeviceString [parse [system/script/get \"HassioLib_DeviceString\
    \" source]]\r\
    \n# \$DeviceString\r\
    \n#\r\
    \nlocal ID\r\
    \nlocal connections\r\
    \nlocal hwversion\r\
    \nlocal LowercaseHex [parse [system/script/get \"HassioLib_LowercaseHex\" \
    source]]\r\
    \n# Get serial\r\
    \nif ([/system/resource/get board-name] != \"CHR\") do={\r\
    \n    set ID (\"\\\"\".[/system/routerboard get serial-number].\"\\\"\");#\
    ID\r\
    \n    set \$hwversion [[:parse \"[system/routerboard/get revision]\"]]\r\
    \n    if ([len \$hwversion] >0) do={\r\
    \n        set \$hwversion (\"\\\"hw_version\\\":\\\"\".\$hwversion.\"\\\",\
    \")\r\
    \n    }\r\
    \n} else={\r\
    \n    set ID (\"\\\"\".[system/license/get system-id ].\"\\\"\")\r\
    \n}\r\
    \n\r\
    \nlocal Name [/system/identity/get name];       #Name\r\
    \nlocal Model [system/resource/get board-name]; #Mode\r\
    \nlocal CSW   [/system/resource/get version ];  #SW\r\
    \nlocal Manu [/system/resource/get platform];   #Manufacturer\r\
    \n\r\
    \n\r\
    \n# Get Ethernet MAC addresses\r\
    \nforeach iface in=[interface/ethernet/find ] do={\r\
    \n    set \$connections (\$connections.\"[\\\"mac\\\",\\\"\".\\\r\
    \n        [\$LowercaseHex input=[/interface/ethernet/get \$iface mac-addre\
    ss]].\\\r\
    \n        \"\\\"],\")\r\
    \n}\r\
    \n\r\
    \n# Get Wi-Fi MAC addresses\r\
    \nif ([len [system/package/find name=\"wifiwave2\"]]  =0 ) do={\r\
    \n    local Action [parse \"local a [interface/wireless/get \\\$1 mac-addr\
    ess];return \\\$a\"]\r\
    \n    foreach iface in=[[parse \"/interface/wireless/ find interface-type!\
    =\\\"virtual\\\"\"]] do={\r\
    \n        set \$connections (\$connections.\"[\\\"mac\\\",\\\"\".\\\r\
    \n            [\$LowercaseHex input=[\$Action \$iface]].\\\r\
    \n            \"\\\"],\")\r\
    \n    }\r\
    \n}\\\r\
    \n# Get Wi-Fi Wave2 MAC Addresses\r\
    \nelse={\r\
    \n    local Action [parse \"local a [/interface/wifiwave2/radio/get \\\$1 \
    radio-mac];return \\\$a\"]\r\
    \n    foreach iface in=[[parse \"/interface/wifiwave2/radio/find\"]] do={\
    \r\
    \n        set \$connections (\$connections.\"[\\\"mac\\\",\\\"\".\\\r\
    \n            [\$LowercaseHex input=[\$Action \$iface]].\\\r\
    \n            \"\\\"],\")\r\
    \n    }\r\
    \n}\r\
    \nset \$connections [pick \$connections -1 ([len \$connections]-1)]; #Remo\
    ve trailing comma\r\
    \n\r\
    \n# Find a reasonable link to WebFig if enabled.\r\
    \nlocal urldomain\r\
    \nlocal ipaddress\r\
    \n\r\
    \nforeach bridge in=[/interface/bridge/find] do={\r\
    \n    foreach AddressIndex in=[ip/address/find where interface=[/interface\
    /bridge/get \$bridge name]] do={\r\
    \n        set ipaddress [/ip/address/get \$AddressIndex address]\r\
    \n        set \$ipaddress [:pick \$ipaddress 0 [:find \$ipaddress \"/\"]]\
    \r\
    \n       foreach UrlIndex in=[/ip/dns/static/ find address=\$ipaddress nam\
    e] do={\r\
    \n            set \$urldomain [/ip/dns/static/ get \$UrlIndex name  ]\r\
    \n        }\r\
    \n    }\r\
    \n}\r\
    \nif ([len \$ipaddress]=0) do={\r\
    \n    foreach addr in=[/ip/address/find] do={\r\
    \n        local TempAddress [/ip/address/get \$addr address]\r\
    \n        set \$TempAddress [:pick \$TempAddress 0 [:find \$TempAddress \"\
    /\"]]\r\
    \n        foreach UrlIndex in=[/ip/dns/static/find address=\$TempAddress] \
    do={\r\
    \n            local TempUrlDomain [ip/dns/static/get \$UrlIndex name]\r\
    \n            if ([len \$TempUrlDomain]>0) do={set \$urldomain \$TempUrlDo\
    main}\r\
    \n        }\r\
    \n    }\r\
    \n}\r\
    \nif ([len \$urldomain]>0) do={set \$ipaddress \$urldomain}\r\
    \n\r\
    \nlocal url\r\
    \nif ([len \$ipaddress] >0) do={\r\
    \n    :if (! [/ip/service/get www-ssl disabled ]) \\\r\
    \n        do={:set \$url \",\\\"cu\\\":\\\"https://\$ipaddress/\\\"\"} \\\
    \r\
    \n    else={if (! [/ip/service/get www disabled]) \\\r\
    \n        do={:set \$url \",\\\"cu\\\":\\\"http://\$ipaddress/\\\"\"}}\r\
    \n}\r\
    \n        #-------------------------------------------------------\r\
    \n        #Build device string\r\
    \n        #-------------------------------------------------------\r\
    \n        local dev \"\\\"dev\\\":{\\\r\
    \n            \\\"ids\\\":[\$ID],\\\r\
    \n            \\\"connections\\\":[\$connections],\\\r\
    \n            \\\"name\\\":\\\"\$Name\\\",\\\r\
    \n            \\\"mdl\\\":\\\"\$Model\\\",\$hwversion\\\r\
    \n            \\\"sw\\\":\\\"\$CSW\\\",\\\r\
    \n            \\\"mf\\\":\\\"\$Manu\\\"\$url}\"\r\
    \n\r\
    \n\r\
    \nreturn \$dev"
add dont-require-permissions=no name=HassioLib_JsonEscape owner=admin policy=\
    read source="# local JsonEscape [parse [system/script/get \"HassioLib_Json\
    Escape\" source]]\
    \n# \$JsonEscape input=\$a4\
    \n#\
    \n#global JsonEscape do= {\
    \n    #:global SearchReplace\
    \n    local SearchReplace [parse [system/script/get \"HassioLib_SearchRepl\
    ace\" source]]\
    \n    :local escchars   {\"\\\\\";\"\\\"\";\"/\";\"\\08\";\"\\0C\";\"\\0A\
    \";\"\\0D\";\"\\08\"};\
    \n    :local escReplace {\"\\\\\\\\\";\"\\\\\\\"\";\"\\\\/\";\"\\\\b\";\"\
    \\\\f\";\"\\\\n\";\"\\\\r\";\"\\\\t\"}\
    \n    foreach k,escchar in=\$escchars do={\
    \n        set \$input [\$SearchReplace input=\$input search=\$escchar repl\
    ace=(\$escReplace->(\$k))]\
    \n    }\
    \n    return \$input\
    \n\
    \n#}"
add dont-require-permissions=no name=HassioLib_JsonPick owner=admin policy=\
    read source="# Use\r\
    \n# local JsonPick [parse [system/script/get \"HassioLib_JsonPick\" source\
    ]]\r\
    \n# \$JsonPick input=\$a2 len=255\r\
    \n#\r\
    \n#global JsonPick do= {\r\
    \n    set \$input [pick \$input -1 \$len]\r\
    \n    local length [len \$input]\r\
    \n    if (([pick \$input (\$length-1)] = \"\\\\\") && ([pick \$input (\$le\
    ngth-2)] != \"\\\\\")) do= {\r\
    \n        set \$input [:pick (\$input) -1 (\$length-1)]\r\
    \n    }\r\
    \n    return \$input\r\
    \n#}"
add dont-require-permissions=no name=HassioLib_LowercaseHex owner=admin \
    policy=read source="# Use\r\
    \n# local LowercaseHex [parse [system/script/get \"HassioLib_LowercaseHex\
    \" source]]\r\
    \n# \$LowercaseHex input=\$a4\r\
    \n#\r\
    \n#global LowercaseHex do= {\r\
    \n    #:global SearchReplace\r\
    \n    local SearchReplace [parse [system/script/get \"HassioLib_SearchRepl\
    ace\" source]]\r\
    \n    :local escchars {\"A\";\"B\";\"C\";\"D\";\"E\";\"F\"}\r\
    \n    :local escReplace {\"a\";\"b\";\"c\";\"d\";\"e\";\"f\"}\r\
    \n    foreach k,escchar in=\$escchars do={\r\
    \n        set \$input [\$SearchReplace input=\$input search=\$escchar repl\
    ace=(\$escReplace->(\$k))]\r\
    \n    }\r\
    \n    return \$input\r\
    \n\r\
    \n#}"
add dont-require-permissions=no name=HassioLib_SearchReplace owner=admin \
    policy=read source="# Use\r\
    \n# local SearchReplace [parse [system/script/get \"HassioLib_SearchReplac\
    e\" source]]\r\
    \n# \$SearchReplace input=\"abc\" search=\"a\" replace=\"b\"\r\
    \n#\r\
    \n#global SearchReplace do= {\r\
    \n    :local out \"\"\r\
    \n    :local index 0\r\
    \n    :local length [:len \$input]\r\
    \n    :local findex\r\
    \n\r\
    \n    set \$findex [find \$input \$search (\$index-1) ]\r\
    \n    while ([len \$findex] != \"0\") do={\r\
    \n        set \$out (\$out.[pick \$input \$index \$findex ].\$replace)\r\
    \n        set \$index (\$findex+[len \$search])\r\
    \n        set \$findex [find \$input \$search (\$index-1) ]\r\
    \n    }\r\
    \n    set \$out (\$out.[pick \$input (\$index) \$length ])\r\
    \n    :return \$out\r\
    \n#}\r\
    \n"
add dont-require-permissions=no name="Hassio Firmware Entity Publish" owner=\
    admin policy=read,test source="if ([len [system/package/find name=\"iot\"]\
    ]=0) do={ ; # If IOT packages is  not installed\r\
    \n    log/error message=\"HassioMQTT: IOT package not installed.\"\r\
    \n} else={\r\
    \n    if ([len [iot/mqtt/brokers/find name=\"Home Assistant\"]]=0) do={ ;#\
    \_If Home assistant broker does not exist\r\
    \n        log/error message=\"HassioMQTT: Broker does not exist.\"\r\
    \n    } else={\r\
    \n        while (![/iot/mqtt/brokers/get [/iot/mqtt/brokers/find name=\"Ho\
    me Assistant\"] connected ]) do={ ;# If Home assistant broker is not conne\
    cted\r\
    \n            log/info message=\"HassioMQTT: Broker not connected reattemp\
    ting connection...\"\r\
    \n            delay 1m; # Wait and attempt reconnect\r\
    \n            iot/mqtt/connect broker=\"Home Assistant\"\r\
    \n        }\r\
    \n\r\
    \n\r\
    \n        local discoverypath \"homeassistant/\"\r\
    \n        local domainpath \"update/\"\r\
    \n\r\
    \n        #-------------------------------------------------------\r\
    \n        #Get variables to build device string\r\
    \n        #-------------------------------------------------------\r\
    \n\r\
    \n        local ID\r\
    \n        if ([/system/resource/get board-name] != \"CHR\") do={\r\
    \n        set ID [/system/routerboard get serial-number];#ID\r\
    \n        } else={\r\
    \n        set ID [system/license/get system-id ]\r\
    \n        }\r\
    \n        #-------------------------------------------------------\r\
    \n        #Build device string\r\
    \n        #-------------------------------------------------------\r\
    \n        local DeviceString [parse [system/script/get \"HassioLib_DeviceS\
    tring\" source]]\r\
    \n        local dev [\$DeviceString]\r\
    \n        local buildconfig do= {\r\
    \n\r\
    \n            #build config for Hassio\r\
    \n            local config \"{\\\"~\\\":\\\"\$discoverypath\$domainpath\$I\
    D/\$name\\\",\\\r\
    \n                \\\"name\\\":\\\"\$name\\\",\\\r\
    \n                \\\"stat_t\\\":\\\"~/state\\\",\\\r\
    \n                \\\"uniq_id\\\":\\\"\$ID_\$name\\\",\\\r\
    \n                \\\"obj_id\\\":\\\"\$ID_\$name\\\",\\\r\
    \n                \$dev\\\r\
    \n            }\"\r\
    \n            /iot/mqtt/publish broker=\"Home Assistant\" message=\$config\
    \_topic=\"\$discoverypath\$domainpath\$ID/\$name/config\" retain=yes      \
    \_       \r\
    \n        }\r\
    \n        #-------------------------------------------------------\r\
    \n        #Handle routerboard firmware for non CHR\r\
    \n        #-------------------------------------------------------\r\
    \n        if ([/system/resource/get board-name] != \"CHR\") do={\r\
    \n            \$buildconfig name=\"RouterBOARD\" ID=\$ID discoverypath=\$d\
    iscoverypath domainpath=\$domainpath dev=\$dev\r\
    \n        }\r\
    \n\r\
    \n        #-------------------------------------------------------\r\
    \n        #Handle RouterOS\r\
    \n        #-------------------------------------------------------\r\
    \n        \$buildconfig name=\"RouterOS\" ID=\$ID discoverypath=\$discover\
    ypath domainpath=\$domainpath dev=\$dev\r\
    \n\r\
    \n        #-------------------------------------------------------\r\
    \n        #Handle LTE interfaces\r\
    \n        #-------------------------------------------------------\r\
    \n        :foreach iface in=[/interface/lte/ find] do={\r\
    \n        local ifacename [/interface/lte get \$iface name]\r\
    \n\r\
    \n        #Get manufacturer and model for LTE interface\r\
    \n        local lte [ [/interface/lte/monitor [/interface/lte get \$iface \
    name] once as-value] manufacturer]\r\
    \n            if (\$lte->\"manufacturer\"=\"\\\"MikroTik\\\"\") do={\r\
    \n                {\r\
    \n                #build config for LTE\r\
    \n                local modemname [:pick (\$lte->\"model\")\\\r\
    \n                    ([:find (\$lte->\"model\") \"\\\"\" -1] +1)\\\r\
    \n                    [:find (\$lte->\"model\") \"\\\"\" [:find (\$lte->\"\
    model\") \"\\\"\" -1]]]\r\
    \n                \$buildconfig name=\$modemname ID=\$ID discoverypath=\$d\
    iscoverypath domainpath=\$domainpath dev=\$dev\r\
    \n                }\r\
    \n            }\r\
    \n        }\r\
    \n    }\r\
    \n}"
add dont-require-permissions=no name="Hassio Firmware State Publish" owner=\
    admin policy=read,write,policy,test source="if ([len [system/package/find \
    name=\"iot\"]]=0) do={ ; # If IOT packages is  not installed\r\
    \n    log/error message=\"HassioMQTT: IOT package not installed.\"\r\
    \n} else={\r\
    \n    if ([len [iot/mqtt/brokers/find name=\"Home Assistant\"]]=0) do={ ;#\
    \_If Home assistant broker does not exist\r\
    \n        log/error message=\"HassioMQTT: Broker does not exist.\"\r\
    \n    } else={\r\
    \n        local Ctr 0\r\
    \n        while ((![/iot/mqtt/brokers/get [/iot/mqtt/brokers/find name=\"H\
    ome Assistant\"] connected ])&&(Ctr<12)) do={ ;# If Home assistant broker \
    is not connected\r\
    \n            log/info message=\"HassioMQTT: Broker not connected reattemp\
    ting connection...\"\r\
    \n            delay 1m; # Wait and attempt reconnect\r\
    \n            set \$Ctr (\$Ctr+1)\r\
    \n            iot/mqtt/connect broker=\"Home Assistant\"\r\
    \n        }\r\
    \n        local discoverypath \"homeassistant/\"\r\
    \n        local domainpath \"update/\"\r\
    \n        :global HassioReleaseNote\r\
    \n        #-------------------------------------------------------\r\
    \n        #Get variables to build device string\r\
    \n        #-------------------------------------------------------\r\
    \n        #ID\r\
    \n        local ID\r\
    \n            if ([/system/resource/get board-name] != \"CHR\") do={\r\
    \n        set ID [/system/routerboard get serial-number];#ID\r\
    \n        } else={\r\
    \n            set ID [system/license/get system-id ]\r\
    \n        }\r\
    \n\r\
    \n        local poststate do= {\r\
    \n            if ((typeof \$url)!=nil) do={\r\
    \n            set \$url  \",\\\"release_url\\\":\\\"\$url\\\"\"\r\
    \n            }\r\
    \n\r\
    \n            if ((typeof \$note)!=nil) do={\r\
    \n            set \$note \",\\\"release_summary\\\":\\\"\$note\\\"\"\r\
    \n            }\r\
    \n\r\
    \n            local state \"{\\\"installed_version\\\":\\\"\$cur\\\",\\\r\
    \n                \\\"latest_version\\\":\\\"\$new\\\"\$url\$note}\"\r\
    \n            /iot/mqtt/publish broker=\"Home Assistant\" message=\$state \
    topic=\"\$discoverypath\$domainpath\$ID/\$name/state\" retain=yes\r\
    \n        }\r\
    \n        #-------------------------------------------------------\r\
    \n        #Handle routerboard firmware for non CHR\r\
    \n        #-------------------------------------------------------\r\
    \n        if ([/system/resource/get board-name] != \"CHR\") do={\r\
    \n            #Get routerboard firmware\r\
    \n            local Act [parse \"/system/routerboard/get current-firmware\
    \"]\r\
    \n            local cur [\$Act]\r\
    \n            local Act [parse \"/system/routerboard/get upgrade-firmware\
    \"]\r\
    \n            local new [\$Act]\r\
    \n            #post Routerboard firmware\r\
    \n            \$poststate name=\"RouterBOARD\" cur=\$cur new=\$new ID=\$ID\
    \_discoverypath=\$discoverypath domainpath=\$domainpath\r\
    \n        }\r\
    \n\r\
    \n        #-------------------------------------------------------\r\
    \n        #Handle RouterOS\r\
    \n        #-------------------------------------------------------\r\
    \n        #Get system software\r\
    \n        local versions [/system/package/update/check-for-updates as-valu\
    e ]\r\
    \n\r\
    \n        local cur (\$versions->\"installed-version\")\r\
    \n        local new (\$versions->\"latest-version\")\r\
    \n\r\
    \n        #Get release note:\r\
    \n        if ((\$HassioReleaseNote->\"version\")!=new) do={\r\
    \n            #:global HassioReleaseNote\r\
    \n\r\
    \n            :set (\$HassioReleaseNote->\"note\") ([/tool/fetch \"http://\
    upgrade.mikrotik.com/routeros/\$new/CHANGELOG\" output=user as-value]->\"d\
    ata\")\r\
    \n            :set (\$HassioReleaseNote->\"note\") [:pick (\$HassioRelease\
    Note->\"note\") -1 255]\r\
    \n\r\
    \n            #Text must be escaped before posting as JSON!\r\
    \n            local JsonEscape [parse [system/script/get \"HassioLib_JsonE\
    scape\" source]]\r\
    \n            set (\$HassioReleaseNote->\"note\") [\$JsonEscape input=(\$H\
    assioReleaseNote->\"note\")]\r\
    \n\r\
    \n            local JsonPick [parse [system/script/get \"HassioLib_JsonPic\
    k\" source]]\r\
    \n            set (\$HassioReleaseNote->\"note\") [\$JsonPick input=(\$Has\
    sioReleaseNote->\"note\") len=255]\r\
    \n            :set (\$HassioReleaseNote->\"version\") \$new\r\
    \n            /log/debug message=\"HassioMQTT: Release note fetched.\"\r\
    \n        } else={/log/debug message=\"HassioMQTT: Release note already ca\
    ched, not fetched.\"}\r\
    \n\r\
    \n        local urls {development=\"https://mikrotik.com/download/changelo\
    gs/development-release-tree\";\\\r\
    \n            long-term=\"https://mikrotik.com/download/changelogs/long-te\
    rm-release-tree\";\\\r\
    \n            stable=\"https://mikrotik.com/download/changelogs/stable-rel\
    ease-tree\";\\\r\
    \n            testing=\"https://mikrotik.com/download/changelogs/testing-r\
    elease-tree\"}\r\
    \n        set urls (\$urls->[system/package/update/get channel ])\r\
    \n\r\
    \n        \$poststate name=\"RouterOS\" cur=\$cur new=\$new url=\$urls not\
    e=(\$HassioReleaseNote->\"note\") ID=\$ID discoverypath=\$discoverypath do\
    mainpath=\$domainpath\r\
    \n\r\
    \n        #-------------------------------------------------------\r\
    \n        #Handle LTE interfaces\r\
    \n        #-------------------------------------------------------\r\
    \n        :foreach iface in=[/interface/lte/ find] do={\r\
    \n        local ifacename [/interface/lte get \$iface name]\r\
    \n\r\
    \n        #Get manufacturer and model for LTE interface\r\
    \n        local lte [ [/interface/lte/monitor [/interface/lte get \$iface \
    name] once as-value] manufacturer]\r\
    \n            if (\$lte->\"manufacturer\"=\"\\\"MikroTik\\\"\") do={\r\
    \n                {\r\
    \n                #build config for LTE\r\
    \n                local modemname [:pick (\$lte->\"model\")\\\r\
    \n                    ([:find (\$lte->\"model\") \"\\\"\" -1] +1)\\\r\
    \n                    [:find (\$lte->\"model\") \"\\\"\" [:find (\$lte->\"\
    model\") \"\\\"\" -1]]]\r\
    \n\r\
    \n                #Get firmware version for LTE interface\r\
    \n                local Firmware [/interface/lte firmware-upgrade [/interf\
    ace/lte get \$iface name] once as-value ]\r\
    \n                local cur (\$Firmware->\"installed\")\r\
    \n                local new (\$Firmware->\"latest\")\r\
    \n\r\
    \n                \$poststate name=\$modemname cur=\$cur new=\$new ID=\$ID\
    \_discoverypath=\$discoverypath domainpath=\$domainpath\r\
    \n                }\r\
    \n            }\r\
    \n        }\r\
    \n    }\r\
    \n}"
add dont-require-permissions=no name=HassioSensorHealthEntityPublish owner=\
    admin policy=read,test source="if ([len [system/package/find name=\"iot\"]\
    ]=0) do={ ; # If IOT packages is  not installed\r\
    \n    log/error message=\"HassioMQTT: IOT package not installed.\"\r\
    \n} else={\r\
    \n    if ([len [iot/mqtt/brokers/find name=\"Home Assistant\"]]=0) do={ ;#\
    \_If Home assistant broker does not exist\r\
    \n        log/error message=\"HassioMQTT: Broker does not exist.\"\r\
    \n    } else={\r\
    \n        while (![/iot/mqtt/brokers/get [/iot/mqtt/brokers/find name=\"Ho\
    me Assistant\"] connected ]) do={ ;# If Home assistant broker is not conne\
    cted\r\
    \n            log/info message=\"HassioMQTT: Broker not connected reattemp\
    ting connection...\"\r\
    \n            delay 1m; # Wait and attempt reconnect\r\
    \n            iot/mqtt/connect broker=\"Home Assistant\"\r\
    \n        }\r\
    \n\r\
    \n        local discoverypath \"homeassistant/\"\r\
    \n        local domainpath \"sensor/\"\r\
    \n\r\
    \n        #-------------------------------------------------------\r\
    \n        #Get variables to build device string\r\
    \n        #-------------------------------------------------------\r\
    \n\r\
    \n        local ID [/system/routerboard get serial-number];#ID\r\
    \n\r\
    \n        #-------------------------------------------------------\r\
    \n        #Build device string\r\
    \n        #-------------------------------------------------------\r\
    \n        local DeviceString [parse [system/script/get \"HassioLib_DeviceS\
    tring\" source]]\r\
    \n        local dev [\$DeviceString]\r\
    \n        local buildconfig do= {\r\
    \n            local SearchReplace [parse [system/script/get \"HassioLib_Se\
    archReplace\" source]]\r\
    \n            local jsonname (\"x\".[\$SearchReplace input=\$name search=\
    \"-\" replace=\"_\"])\r\
    \n\r\
    \n            #build config for Hassio\r\
    \n            local config \"{\\\"name\\\":\\\"\$name\\\",\\\r\
    \n                \\\"stat_t\\\":\\\"\$discoverypath\$domainpath\$ID/state\
    \\\",\\\r\
    \n                \\\"uniq_id\\\":\\\"\$ID_\$name\\\",\\\r\
    \n                \\\"obj_id\\\":\\\"\$ID_\$name\\\",\\\r\
    \n                \\\"suggested_display_precision\\\": 1,\\\r\
    \n                \\\"unit_of_measurement\\\": \\\"\$unit\\\",\\\r\
    \n                \\\"value_template\\\": \\\"{{ value_json.\$jsonname }}\
    \\\",\\\r\
    \n                \\\"expire_after\\\":70,\\\r\
    \n                \$dev\\\r\
    \n            }\"\r\
    \n            /iot/mqtt/publish broker=\"Home Assistant\" message=\$config\
    \_topic=\"\$discoverypath\$domainpath\$ID/\$name/config\" retain=yes      \
    \_       \r\
    \n        }\r\
    \n        foreach sensor in=[/system/health/find] do={\r\
    \n            local name [/system/health/get \$sensor name];#name\r\
    \n            local unit [/system/health/get \$sensor type];#unit\r\
    \n            if (\$unit=\"C\") do={set \$unit \"\\C2\\B0\\43\"}\r\
    \n            \$buildconfig name=\$name unit=\$unit ID=\$ID discoverypath=\
    \$discoverypath domainpath=\$domainpath dev=\$dev\r\
    \n        }\r\
    \n    }\r\
    \n}"
add dont-require-permissions=no name=HassioSensorHealthStatePublish owner=\
    admin policy=read,write,test source="if ([len [system/package/find name=\"\
    iot\"]]=0) do={ ; # If IOT packages is  not installed\r\
    \n    log/error message=\"HassioMQTT: IOT package not installed.\"\r\
    \n} else={\r\
    \n    if ([len [iot/mqtt/brokers/find name=\"Home Assistant\"]]=0) do={ ;#\
    \_If Home assistant broker does not exist\r\
    \n        log/error message=\"HassioMQTT: Broker does not exist.\"\r\
    \n    } else={\r\
    \n        local discoverypath \"homeassistant/\"\r\
    \n        local domainpath \"sensor/\"\r\
    \n\r\
    \n        #-------------------------------------------------------\r\
    \n        #Get variables to build device string\r\
    \n        #-------------------------------------------------------\r\
    \n        #ID\r\
    \n        local ID [/system/routerboard get serial-number] \r\
    \n\r\
    \n        local string \"{\"\r\
    \n        local SearchReplace [parse [system/script/get \"HassioLib_Search\
    Replace\" source]]\r\
    \n        foreach sensor in=[/system/health/find] do={\r\
    \n            set \$string ((\$string).(\"\\\"\").\\\r\
    \n                (\"x\").([\$SearchReplace input=[/system/health/get \$se\
    nsor name] search=\"-\" replace=\"_\"]).(\"\\\":\").\\\r\
    \n                ([/system/health/get \$sensor value]).(\",\"))\r\
    \n        }\r\
    \n        set \$string ([pick \$string -1 ([len \$string ]-1)].\"}\")\r\
    \n        \r\
    \n        /iot/mqtt/publish broker=\"Home Assistant\" message=\$string top\
    ic=\"\$discoverypath\$domainpath\$ID/state\" retain=no   \r\
    \n    }\r\
    \n}"
add dont-require-permissions=no name=HassioSensorPoeEntityPublish owner=admin \
    policy=read,test source="if ([len [system/package/find name=\"iot\"]]=0) d\
    o={ ; # If IOT packages is  not installed\
    \n    log/error message=\"HassioMQTT: IOT package not installed.\"\
    \n} else={\
    \n    if ([len [iot/mqtt/brokers/find name=\"Home Assistant\"]]=0) do={ ;#\
    \_If Home assistant broker does not exist\
    \n        log/error message=\"HassioMQTT: Broker does not exist.\"\
    \n    } else={\
    \n        while (![/iot/mqtt/brokers/get [/iot/mqtt/brokers/find name=\"Ho\
    me Assistant\"] connected ]) do={ ;# If Home assistant broker is not conne\
    cted\
    \n            log/info message=\"HassioMQTT: Broker not connected reattemp\
    ting connection...\"\
    \n            delay 1m; # Wait and attempt reconnect\
    \n            iot/mqtt/connect broker=\"Home Assistant\"\
    \n        }\
    \n\
    \n        local discoverypath \"homeassistant/\"\
    \n        local domainpath \"sensor/\"\
    \n\
    \n        #-------------------------------------------------------\
    \n        #Get variables to build device string\
    \n        #-------------------------------------------------------\
    \n\
    \n        local ID [/system/routerboard get serial-number];#ID\
    \n        #-------------------------------------------------------\
    \n        #Build device string\
    \n        #-------------------------------------------------------\
    \n        local DeviceString [parse [system/script/get \"HassioLib_DeviceS\
    tring\" source]]\
    \n        local dev [\$DeviceString]\
    \n        local buildconfig do= {\
    \n            local SearchReplace [parse [system/script/get \"HassioLib_Se\
    archReplace\" source]]\
    \n            local jsonname (\"x\".[\$SearchReplace input=\$name search=\
    \"-\" replace=\"_\"])\
    \n\
    \n            #build config for Hassio\
    \n            local config (\"{\\\"name\\\":\\\"\$name\".\" POE\".\"\\\",\
    \\\
    \n                \\\"stat_t\\\":\\\"\$discoverypath\$domainpath\$ID/state\
    \$NamePostfix\\\",\\\
    \n                \\\"uniq_id\\\":\\\"\$ID_\$name\$NamePostfix\\\",\\\
    \n                \\\"obj_id\\\":\\\"\$ID_\$name\$NamePostfix\\\",\\\
    \n                \\\"suggested_display_precision\\\": 1,\\\
    \n                \\\"unit_of_measurement\\\": \\\"\$unit\\\",\\\
    \n                \\\"value_template\\\": \\\"{{ value_json.\$jsonname | i\
    s_defined}}\\\",\\\
    \n                \\\"expire_after\\\":70,\\\
    \n                \$dev\\\
    \n            }\")\
    \n            /iot/mqtt/publish broker=\"Home Assistant\" message=\$config\
    \_topic=(\"\$discoverypath\$domainpath\$ID/\$name\$NamePostfix/config\") r\
    etain=yes        \
    \n        }\
    \n        foreach sensor in=[/interface/ethernet/poe/find] do={\
    \n            local name [/interface/ethernet/poe/get \$sensor name];#name\
    \n            \$buildconfig name=(\$name) unit=W NamePostfix=\"_poe\" ID=\
    \$ID discoverypath=\$discoverypath domainpath=\$domainpath dev=\$dev\
    \n        }\
    \n    }\
    \n}"
add dont-require-permissions=no name=HassioSensorPoeStatePublish owner=admin \
    policy=read,test source="local discoverypath \"homeassistant/\"\
    \nlocal domainpath \"sensor/\"\
    \nlocal ID [/system/routerboard get serial-number] \
    \n\
    \nlocal Out \"{\"\
    \n\
    \nforeach iface in=[/interface/ethernet/poe/ find] do={\
    \n    local InterfaceName [/interface/ethernet/poe/get \$iface name]\
    \n    local InterfaceValue [interface/ethernet/poe/monitor \$iface once as\
    -value ]\
    \n    if ([:len (\$InterfaceValue->\"poe-out-current\")]=0) do={set (\$Int\
    erfaceValue->\"poe-out-current\") 0}\
    \n    set \$Out (\$Out.\"\\\"x\$InterfaceName\\\":\".\\\
    \n    [([:tonum [(\$InterfaceValue->\"poe-out-current\")]]/10) ].\\\
    \n    \".\".\\\
    \n    ([:tonum [(\$InterfaceValue->\"poe-out-current\")]]%10).\\\
    \n    \",\")\
    \n}\
    \nset \$Out ([pick \$Out -1 ([len \$Out]-1)].\"}\")\
    \n/iot/mqtt/publish broker=\"Home Assistant\" message=\$Out topic=\"\$disc\
    overypath\$domainpath\$ID/state_poe\" retain=no"
add dont-require-permissions=no name=DHCP-LEASE-TEST2 owner=admin policy=\
    ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="/\
    system\r\
    \n:local identitydate \"\$[identity get name]_\$[clock get date]\"\r\
    \n\r\
    \n\r\
    \n:foreach i in=[/ip dhcp-server lease find] do={\r\
    \n:put ([get \$i comment].\",\".[get \$i address].\",\".[get \$i mac-addre\
    ss].\",\".[get \$i host-name])\r\
    \n\r\
    \nfile=\"test1.txt\"\r\
    \n}"
add dont-require-permissions=no name=dhcpleasesftp owner=admin policy=\
    ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="\
    \r\
    \n/file remove [find where name=temp3.txt]\r\
    \n\r\
    \n/system\r\
    \n\r\
    \n:local identitydate \"\$[identity get name]\"\r\
    \n\r\
    \n:local stringexec \"/ip dhcp-server lease; :foreach i in=[find] do={ :pu\
    t ([get \\\$i address].\\\",\\\".[get \\\$i comment].\\\",\\\",[get \\\$i \
    mac-address].\\\",\\\".[get \\\$i host-name]  ) }\"\r\
    \n\r\
    \n\r\
    \n:execute \$stringexec file=temp3\r\
    \n\r\
    \n:delay 60\r\
    \n\r\
    \n/tool fetch address=192.168.2.22 port=21 user=mikrotik password=<password>\
    \_src-path=temp3.txt mode=ftp dst-path=\"/mikrotik-backups/\$identitydate-\
    leases.txt\" upload=yes ascii=no\r\
    \n\r\
    \n\r\
    \n\r\
    \n\r\
    \n"
add dont-require-permissions=no name=script1 owner=admin policy=\
    ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="\
    \r\
    \n/file remove [find where name=temp2.txt]\r\
    \n\r\
    \n/system\r\
    \n\r\
    \n:local identitydate \"\$[identity get name]_\$[clock get date]\"\r\
    \n\r\
    \n:local stringexec \"/ip dhcp-server lease; :foreach i in=[find] do={ :pu\
    t ([get \\\$i address].\\\",\\\".[get \\\$i comment].\\\",\\\",[get \\\$i \
    mac-address].\\\",\\\".[get\r\
    \n \\\$i host-name]  ) }\"\r\
    \n\r\
    \n\r\
    \n:execute \$stringexec file=temp2.txt\r\
    \n\r\
    \n/tool fetch upload=yes mode=ftp ascii=no address=192.168.2.22 port=21 us\
    er=mikrotik password=<password> src-path=\"temp2.txt\" dst-path=\"/mikrotik-\
    backups/\$identitydate-leases.txt\"\r\
    \n\r\
    \n\r\
    \n\r\
    \n\r\
    \n\r\
    \n"
add dont-require-permissions=yes name=WG-iface-restart-log-lasthandshake \
    owner=admin policy=\
    ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source=":\
    foreach i in=[/interface/wireguard/peers/find where disabled=no endpoint-a\
    ddress~\"[a-z]\\\$\"] do={\r\
    \n  :local LastHandshake [/interface/wireguard/peers/get \$i last-handshak\
    e]\r\
    \n\r\
    \n#  :if (([:tostr \$LastHandshake] = \"\") or (\$LastHandshake > [:totime\
    \_\"2m\"])) do={\r\
    \n\r\
    \n  :if ((\$LastHandshake > [:totime \"2m\"])) do={\r\
    \n\r\
    \n#  :local lasthandshaketime [:totime]\r\
    \n  :local endpoint [/interface/wireguard/peers/get \$i endpoint-address]\
    \r\
    \n\r\
    \n  :log info \"WG-iface-restart-log-lasthandshake script found WG peer wi\
    th last handshake greater than 2 minutes: \$endpoint \$LastHandshake\"\r\
    \n    \r\
    \n#    /interface/wireguard/peers/set \$i endpoint-address=[/interface/wir\
    eguard/peers/get \$i endpoint-address]\r\
    \n\r\
    \n  }\r\
    \n}\r\
    \n\r\
    \n"
add dont-require-permissions=no name=DynDNS owner=admin policy=\
    ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="\
    \r\
    \n/system\r\
    \n:local cdate [clock get date] \r\
    \n:local yyyy  [:pick \$cdate 0  4]\r\
    \n:local MM    [:pick \$cdate 5  7]\r\
    \n:local dd    [:pick \$cdate 8 10]\r\
    \n:local identitydate \"\$[identity get name]_\$yyyy-\$MM-\$dd\"\r\
    \n#/export show-sensitive file=\"\$identitydate\"\r\
    \n\r\
    \n# Export public IP and mail it\r\
    \n\r\
    \n#/ip/address print file=\"\$identitydate-IP\"\r\
    \n\r\
    \n#/tool fetch upload=yes mode=ftp ascii=no src-path=\"\$[\$identitydate]-\
    IP.txt\" dst-path=\"/mikrotik-backups/\$[\$identitydate]-IP.txt\" address=\
    192.168.2.22 port=21 user=mikrotik password=<password>\r\
    \n\r\
    \n#/file remove \"\$identitydate-IP.txt\"\r\
    \n\r\
    \n# Set needed variables\r\
    \n\t:local username \"josxxx\"\r\
    \n\t:local clientkey \"9axxxxxaa78bc3\"\r\
    \n\t:local hostname \"jxxxx.dyndns.org\"\r\
    \n\r\
    \n\t:global dyndnsForce\r\
    \n\t:global previousIP\r\
    \n\r\
    \n# get the current IP address from the internet (in case of double-nat)\r\
    \n\t/tool fetch mode=http address=\"checkip.dyndns.org\" src-path=\"/\" ds\
    t-path=\"/dyndns.checkip.html\"\r\
    \n\t:delay 1\r\
    \n\t:local result [/file get dyndns.checkip.html contents]\r\
    \n\r\
    \n# parse the current IP result\r\
    \n\t:local resultLen [:len \$result]\r\
    \n\t:local startLoc [:find \$result \": \" -1]\r\
    \n\t:set startLoc (\$startLoc + 2)\r\
    \n\t:local endLoc [:find \$result \"</body>\" -1]\r\
    \n\t:local currentIP [:pick \$result \$startLoc \$endLoc]\r\
    \n\t:log info \"UpdateDynDNS: currentIP = \$currentIP\"\r\
    \n\r\
    \n# Remove the # on next line to force an update every single time - usefu\
    l for debugging,\r\
    \n# but you could end up getting blacklisted by DynDNS!\r\
    \n\r\
    \n#:set dyndnsForce true\r\
    \n\r\
    \n# Determine if dyndns update is needed\r\
    \n# more dyndns updater request details https://help.dyn.com/remote-access\
    -api/perform-update/\r\
    \n\t:log info \"UpdateDynDNS: previousIP = \$previousIP\"\r\
    \n\t:if (\$dyndnsForce = true) do={ :log warning \"UpdateDynDNS: Forced up\
    date on\" }\r\
    \n\r\
    \n\t:if ((\$currentIP != \$previousIP) || (\$dyndnsForce = true)) do={\r\
    \n\t\t:set dyndnsForce false\r\
    \n\t\t:set previousIP \$currentIP\r\
    \n\r\
    \n\t\t/tool fetch mode=https \\\r\
    \n\t\turl=\"https://\$username:\$clientkey@members.dyndns.org/v3/update\?h\
    ostname=\$hostname&myip=\$currentIP\" \\ \r\
    \n\t\tdst-path=\"/dyndns.txt\"\r\
    \n\r\
    \n\t\t:delay 1\r\
    \n\t\t:local result [/file get dyndns.txt contents]\r\
    \n\t\t:log info (\"UpdateDynDNS: Dyndns update needed\")\r\
    \n\t\t:log info (\"UpdateDynDNS: Dyndns Update Result: \".\$result)\r\
    \n\t\t:put (\"Dyndns Update Result: \".\$result)\r\
    \n\r\
    \n                                           /ip/address print file=\"\$id\
    entitydate-IP\"\r\
    \n\r\
    \n                                          /tool fetch upload=yes mode=ft\
    p ascii=no src-path=\"\$[\$identitydate]-IP.txt\" dst-path=\"/mikrotik-bac\
    kups/\$[\$identitydate]-IP.txt\" address=192.168.2.22 port=21 user=mikroti\
    k password=<password>\r\
    \n\r\
    \n                                          /file remove \"\$identitydate-\
    IP.txt\"\r\
    \n\r\
    \n\r\
    \n\r\
    \n\t} else={\r\
    \n\t\t:log info (\"UpdateDynDNS: No dyndns update needed\")\r\
    \n\t}\r\
    \n\r\
    \n"
add dont-require-permissions=no name=UPSonline owner=admin policy=\
    ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="\
    \r\
    \n\r\
    \n\r\
    \n:set curonline true\r\
    \n\r\
    \n/system up monitor 0 once\r\
    \n\r\
    \n:set curonline \$\"on-line\"\r\
    \n\r\
    \n:if (\$curonline=false) do={\r\
    \n :log info \"POWER FAIL.  POWER TO UPS IS OFF\"\r\
    \n}\r\
    \n\r\
    \n"
add dont-require-permissions=yes name=Netwatch owner=admin policy=\
    ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="#\
    ###################################\r\
    \n# Netwatch script\r\
    \n#\r\
    \n# Used as both up and down script\r\
    \n# Created Jotne 2021 v1.5\r\
    \n#\r\
    \n####################################\r\
    \n:local Host \$host\r\
    \n/tool netwatch\r\
    \n:local Status [get [find where host=\"\$Host\"] status]\r\
    \n:local Comment [get [find where host=\"\$Host\"] comment]\r\
    \n:local Interval [get [find where host=\"\$Host\"] interval]\r\
    \n:local Since [get [find where host=\"\$Host\"] since]\r\
    \n:log info \"script=netwatch watch_host=\$Host comment=\\\"\$Comment\\\" \
    status=\$Status interval=\$Interval since=\\\"\$Since\\\"\""
add dont-require-permissions=no name=Data_to_Splunk_using_Syslog owner=admin \
    policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon \
    source="# Collect information from Mikrotik RouterOS\r\
    \n# Jotne 2024\r\
    \n# Script name=Data_to_Splunk_using_Syslog\r\
    \n:log info message=\"script=version ver=5.6\"\r\
    \n# ----------------------------------\r\
    \n\r\
    \n# Auto update syslog server. 5.3-5.4.\r\
    \n# Change <your syslog dns name> to the dns of your syslog server.\r\
    \n# The update is disabled by default.  Remove the # from the two next lin\
    e to use it.\r\
    \n\r\
    \n#:local mySyslog [resolve <your syslog dns name>]\r\
    \n#/system/logging/action/set [find where name=\"logserver\"] remote=\$myS\
    yslog\r\
    \n\r\
    \n\r\
    \n# What data to collect.  Set to false to skip the section \r\
    \n# ----------------------------------\r\
    \n:local SystemResource true\r\
    \n:local SystemInformation true\r\
    \n:local SystemHealth true\r\
    \n:local TrafficData true\r\
    \n:local AccountData true\r\
    \n:local uPnP true\r\
    \n:local Wireless true\r\
    \n:local AddressLists true\r\
    \n:local DHCP true\r\
    \n:local Neighbor true\r\
    \n:local InterfaceData true\r\
    \n:local CmdHistory true\r\
    \n:local CAPsMANN false\r\
    \n\r\
    \n:local Routing true\r\
    \n:local OSPF false\r\
    \n:local BGP false\r\
    \n\r\
    \n:local PPP true\r\
    \n:local IPSEC true\r\
    \n\r\
    \n# Get RouterOS main version (used to run different script on different v\
    ersion)\r\
    \n:local train [:tonum [:pick [/system resource get version] 0 1]] \r\
    \n\r\
    \n# Collect system resource\r\
    \n# ----------------------------------\r\
    \n:if (\$SystemResource) do={\r\
    \n\t/system resource\r\
    \n\t:local cpuload [get cpu-load]\r\
    \n\t:local freemem ([get free-memory]/1048576)\r\
    \n\t:local totmem ([get total-memory]/1048576)\r\
    \n\t:local freehddspace ([get free-hdd-space]/1048576)\r\
    \n\t:local totalhddspace ([get total-hdd-space]/1048576)\r\
    \n\t:local up [get uptime]\r\
    \n\t:local sector [get write-sect-total]\r\
    \n\t:log info message=\"script=resource free_memory=\$freemem MB total_mem\
    ory=\$totmem MB free_hdd_space=\$freehddspace MB total_hdd_space=\$totalhd\
    dspace MB cpu_load=\$cpuload uptime=\$up write-sect-total=\$sector\"\r\
    \n}\r\
    \n\r\
    \n\r\
    \n# Make some part only run every hours\r\
    \n# ----------------------------------\r\
    \n:global Hour\r\
    \n:local run false\r\
    \n:local hour [:pick [/system clock get time] 0 2]\r\
    \n:if (\$Hour != \$hour) do={\r\
    \n\t:global Hour \$hour\r\
    \n\t:set run true\r\
    \n}\r\
    \n\r\
    \n\r\
    \n# Get NTP status\r\
    \n# ----------------------------------\r\
    \n:local ntpstatus \"\"\r\
    \n:if ([:len [/system package find where !disabled and name=ntp]] > 0 or [\
    :tonum [:pick [/system resource get version] 0 1]] > 6) do={\r\
    \n    :set ntpstatus [/system ntp client get status]\r\
    \n} else={\r\
    \n    :if ([:typeof [/system ntp client get last-update-from]] = \"nil\") \
    do={\r\
    \n        :set ntpstatus \"using-local-clock\"\r\
    \n    } else={\r\
    \n        :set ntpstatus \"synchronized\"\r\
    \n    }\r\
    \n}\r\
    \n:log info message=\"script=ntp status=\$ntpstatus\" \r\
    \n\r\
    \n\r\
    \n# Get interface traffic data for all interface\r\
    \n# ----------------------------------\r\
    \n:if (\$TrafficData) do={\r\
    \n\t:foreach id in=[/interface find] do={\r\
    \n\t\t:local output \"\$[/interface print stats as-value where .id=\$id]\"\
    \r\
    \n\t\t:set ( \"\$output\"->\"script\" ) \"if_traffic\"\r\
    \n\t\t:log info message=\"\$output\"\r\
    \n\t}\r\
    \n}\r\
    \n\r\
    \n\r\
    \n# Get traffic data v2 (Kid Control)\r\
    \n# ----------------------------------\r\
    \n:if (\$AccountData) do={\r\
    \n\t:foreach logline in=[/ip kid-control device find] do={\r\
    \n\t\t:local output \"\$[/ip kid-control device get \$logline]\"\r\
    \n\t\t:set ( \"\$output\"->\"script\" ) \"kids\"\r\
    \n\t\t:log info message=\"\$output\"\r\
    \n\t}\r\
    \n}\r\
    \n\r\
    \n\r\
    \n# Finding dynmaic lines used in uPnP\r\
    \n# ----------------------------------\r\
    \n:if (\$uPnP) do={\r\
    \n\t:foreach logline in=[/ip firewall nat find where dynamic=yes and comme\
    nt~\"^upnp \"] do={\r\
    \n\t\t:local output \"\$[/ip firewall nat print as-value from=\$logline]\"\
    \r\
    \n\t\t:set ( \"\$output\"->\"script\" ) \"upnp\"\r\
    \n\t\t:log info message=\"\$output\" \r\
    \n\t}\r\
    \n}\r\
    \n\r\
    \n\r\
    \n# Collect system information 5.5 added ID for non routerBoard 5.6 Remvoe\
    d serial\r\
    \n# ----------------------------------\r\
    \n:local model na\r\
    \n:local ffirmware na\r\
    \n:local cfirmware na\r\
    \n:local ufirmware na\r\
    \n:if (\$SystemInformation and \$run) do={\r\
    \n\t:local version ([/system resource get version])\r\
    \n\t:local board ([/system resource get board-name])\r\
    \n\t:local identity ([/system identity get name])\r\
    \n\t:do {\r\
    \n\t\t:if (\$board!=\"CHR\" OR \$board!=\"x86\") do={\r\
    \n\t\t\t/system routerboard\r\
    \n\t\t\t:set model ([get model])\r\
    \n\t\t\t:set ffirmware ([get factory-firmware])\r\
    \n\t\t\t:set cfirmware ([get current-firmware])\r\
    \n\t\t\t:set ufirmware ([get upgrade-firmware])\r\
    \n\t\t}\r\
    \n\t} on-error={}\r\
    \n\t:log info message=\"script=sysinfo version=\\\"\$version\\\" board-nam\
    e=\\\"\$board\\\" model=\\\"\$model\\\" identity=\\\"\$identity\\\" factor\
    y-firmware=\\\"\$ffirmware\\\" current-firmware=\\\"\$cfirmware\\\" upgrad\
    e-firmware=\\\"\$ufirmware\\\"\"\r\
    \n}\r\
    \n\r\
    \n\r\
    \n# Collect system health\r\
    \n# ----------------------------------\r\
    \n:if (\$train > 6 and \$SystemHealth) do={\r\
    \n\t# New version (RouterOS >6)\r\
    \n\t:foreach id in=[/system health find] do={\r\
    \n\t\t:local health \"\$[/system health get \$id]\"\r\
    \n\t\t:set ( \"\$health\"->\"script\" ) \"health\"\r\
    \n\t\t:log info message=\"\$health\"\r\
    \n\t}\r\
    \n} else={\r\
    \n\t# Old version (RouterOS 6 or older)\r\
    \n\t:if (!([/system health get]~\"(state=disabled|^\\\$)\")) do={\r\
    \n\t\t:local health \"\$[/system health get]\"\r\
    \n\t\t:set ( \"\$health\"->\"script\" ) \"health\"\r\
    \n\t\t:log info message=\"\$health\"\r\
    \n\t}\r\
    \n}\r\
    \n\r\
    \n\r\
    \n\r\
    \n# Sends wireless client data to log server \r\
    \n# ----------------------------------\r\
    \n:if (\$Wireless && [:len [/int find where type=wlan]]>0) do={\r\
    \n\t/interface wireless registration-table\r\
    \n\t:foreach i in=[find] do={\r\
    \n\t\t:log info message=\".id=\$i;ap=\$([get \$i ap]);interface=\$([get \$\
    i interface]);mac-address=\$([get \$i mac-address]);signal-strength=\$([ge\
    t \$i signal-strength]);tx-rate=\$([get \$i tx-rate]);uptime=\$([get \$i u\
    ptime]);script=wifi\"\r\
    \n\t}\r\
    \n}\r\
    \n\r\
    \n\r\
    \n# Count IP in address-lists\r\
    \n#----------------------------------\r\
    \n:if (\$AddressLists) do={\r\
    \n\t:local array [ :toarray \"\" ]\r\
    \n\t:local addrcntdyn [:toarray \"\"] \r\
    \n\t:local addrcntstat [:toarray \"\"] \r\
    \n\t:local test\r\
    \n\t:foreach id in=[/ip firewall address-list find] do={\r\
    \n\t\t:local rec [/ip firewall address-list get \$id]\r\
    \n\t\t:local listname (\$rec->\"list\")\r\
    \n\t\t:local listdynamic (\$rec->\"dynamic\")\r\
    \n\t\t:if (!(\$array ~ \$listname)) do={ :set array (\$array , \$listname)\
    \_}\r\
    \n\t\t:if (\$listdynamic = true) do={\r\
    \n\t\t\t:set (\$addrcntdyn->\$listname) (\$addrcntdyn->\$listname+1)\r\
    \n\t\t} else={\r\
    \n\t\t\t:set (\$addrcntstat->\$listname) (\$addrcntstat->\$listname+1)}\r\
    \n\t}\r\
    \n\t:foreach k in=\$array do={\r\
    \n\t\t:log info message=(\"script=address_lists list=\$k dynamic=\".((\$ad\
    drcntdyn->\$k)+0).\" static=\".((\$addrcntstat->\$k)+0))}\r\
    \n}\r\
    \n\r\
    \n\r\
    \n# Get MNDP (CDP) Neighbors\r\
    \n# ----------------------------------\r\
    \n:if (\$Neighbor and \$run) do={\r\
    \n\t:foreach neighborID in=[/ip neighbor find] do={\r\
    \n\t\t:local nb [/ip neighbor get \$neighborID]\r\
    \n\t\t:local id [:pick (\"\$nb\"->\".id\") 1 99]\r\
    \n\t\t:foreach key,value in=\$nb do={\r\
    \n\t\t\t:local newline [:find \$value \"\\n\"]\r\
    \n\t\t\t:if ([\$newline]>0) do={\r\
    \n\t\t\t\t:set value [:pick \$value 0 \$newline]\r\
    \n\t\t\t}\r\
    \n\t\t\t:log info message=\"script=neighbor nid=\$id \$key=\\\"\$value\\\"\
    \"\r\
    \n\t\t}\r\
    \n\t}\r\
    \n}\r\
    \n\r\
    \n\r\
    \n# Collect DHCP Pool information\r\
    \n# ----------------------------------\r\
    \n:if (\$DHCP and \$run) do={\r\
    \n\t/ip pool {\r\
    \n\t\t:local poolname\r\
    \n\t\t:local pooladdresses\r\
    \n\t\t:local poolused\r\
    \n\t\t:local minaddress\r\
    \n\t\t:local maxaddress\r\
    \n\t\t:local findindex\r\
    \n\r\
    \n# Iterate through IP Pools\r\
    \n\t\t:foreach pool in=[find] do={\r\
    \n\t\t\t:set poolname [get \$pool name]\r\
    \n\t\t\t:set pooladdresses 0\r\
    \n\t\t\t:set poolused 0\r\
    \n\r\
    \n# Iterate through current pool's IP ranges\r\
    \n\t\t\t:foreach range in=[:toarray [get \$pool range]] do={\r\
    \n\r\
    \n# Get min and max addresses\r\
    \n\t\t\t\t:set findindex [:find [:tostr \$range] \"-\"]\r\
    \n\t\t\t\t:if ([:len \$findindex] > 0) do={\r\
    \n\t\t\t\t\t:set minaddress [:pick [:tostr \$range] 0 \$findindex]\r\
    \n\t\t\t\t\t:set maxaddress [:pick [:tostr \$range] (\$findindex + 1) [:le\
    n [:tostr \$range]]]\r\
    \n\t\t\t\t} else={\r\
    \n\t\t\t\t\t:set minaddress [:tostr \$range]\r\
    \n\t\t\t\t\t:set maxaddress [:tostr \$range]\r\
    \n\t\t\t\t}\r\
    \n\r\
    \n# Calculate number of ip in one range\r\
    \n\t\t\t\t:set pooladdresses (\$maxaddress - \$minaddress)\r\
    \n\r\
    \n# /foreach range\r\
    \n\t\t\t}\r\
    \n\r\
    \n# Test if pools is used in DHCP or VPN and show leases used\r\
    \n\t\t\t:local dname [/ip dhcp-server find where address-pool=\$poolname]\
    \r\
    \n\t\t\t:if ([:len \$dname] = 0) do={\r\
    \n# No DHCP server found, assume VPN\r\
    \n\t\t\t\t:set poolused [:len [used find pool=[:tostr \$poolname]]]\r\
    \n\t\t\t} else={\r\
    \n# DHCP server found, count leases\r\
    \n\t\t\t\t:local dname [/ip dhcp-server get [find where address-pool=\$poo\
    lname] name]\r\
    \n\t\t\t\t:set poolused [:len [/ip dhcp-server lease find where server=\$d\
    name]]}\r\
    \n\r\
    \n# Send data\r\
    \n\t\t\t:log info message=(\"script=pool pool=\$poolname used=\$poolused t\
    otal=\$pooladdresses\")\r\
    \n\r\
    \n# /foreach pool\r\
    \n\t\t}\r\
    \n# /ip pool\r\
    \n\t}\r\
    \n}\r\
    \n\r\
    \n\r\
    \n# Get detailed command history RouterOS >= v7\r\
    \n# ----------------------------------\r\
    \n:if (\$train > 6 and \$CmdHistory) do={\r\
    \n\t:global cmd\r\
    \n\t:local f 0\r\
    \n\t:foreach i in=[/system history find] do={\r\
    \n\t\t:if (\$i = \$cmd) do={ :set f 1 }\r\
    \n\t\t:if (\$f != 1) do={\r\
    \n\t\t\t:log info message=\"StartCMD\"\r\
    \n\t\t\t:log info message=[/system history get \$i]\r\
    \n\t\t\t:log info message=\"EndCMD\"\r\
    \n\t\t}\r\
    \n\t}\r\
    \n\t:global cmd  [:pick [/system history find] 0]\r\
    \n}\r\
    \n\r\
    \n\r\
    \n# Test if CAPsMANN is installed and run script 5.5\r\
    \n# ----------------------------------\r\
    \n:if ( ([:len [/interface find where type=\"cap\"]] > 0) and \$CAPsMANN) \
    do={ \r\
    \n\t/system script run CAPsMANN\r\
    \n}\r\
    \n\r\
    \n\r\
    \n\r\
    \n# Collect routing information\r\
    \n# ----------------------------------\r\
    \n:if (\$Routing) do={\r\
    \n\t/ip route\r\
    \n\t:foreach id in=[find] do={\r\
    \n\t\t:local route \"\$[get \$id]\"\r\
    \n\t\t:set ( \"\$route\"->\"script\" ) \"route\"\r\
    \n\t\t:log info message=\"\$route\"\r\
    \n\t}\r\
    \n}\r\
    \n\r\
    \n:if (\$OSPF) do={\r\
    \n\t/routing ospf neighbor\r\
    \n\t:foreach id in=[find] do={\r\
    \n\t\t:local ospf \"\$[get \$id]\"\r\
    \n\t\t:set ( \"\$ospf\"->\"script\" ) \"ospf\"\r\
    \n\t\t:log info message=\"\$ospf\"\r\
    \n\t}\r\
    \n}\r\
    \n\r\
    \n:if (\$BGP) do={\r\
    \n\t/routing bgp session\r\
    \n\t:foreach id in=[find] do={\r\
    \n\t\t:local bgp \"\$[get \$id]\"\r\
    \n\t\t:set ( \"\$bgp\"->\"script\" ) \"bgp\"\r\
    \n\t\t:log info message=\"\$bgp\"\r\
    \n\t}\r\
    \n}\r\
    \n\r\
    \n\r\
    \n# Collect PPP/IPSEC\r\
    \n# ----------------------------------\r\
    \n:if (\$PPP) do={\r\
    \n\t/ppp active\r\
    \n\t:foreach id in=[find] do={\r\
    \n\t\t:local ppp \"\$[get \$id]\"\r\
    \n\t\t:set ( \"\$ppp\"->\"script\" ) \"ppp\"\r\
    \n\t\t:log info message=\"\$ppp\"\r\
    \n\t}\r\
    \n}\r\
    \n\r\
    \n:if (\$IPSEC) do={\r\
    \n\t/ip ipsec active-peers\r\
    \n\t:foreach id in=[find] do={\r\
    \n\t\t:local ipsec \"\$[get \$id]\"\r\
    \n\t\t:set ( \"\$ipsec\"->\"script\" ) \"ipsec\"\r\
    \n\t\t:log info message=\"\$ipsec\"\r\
    \n\t}\r\
    \n}\r\
    \n\r\
    \n# End Script\r\
    \n\r\
    \n"
add dont-require-permissions=yes name=Netwatch-JRS-small owner=admin policy=\
    ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source=":\
    local Host \$host\r\
    \n/tool netwatch\r\
    \n:local Status [get [find where host=\"\$Host\"] status]\r\
    \n:local Comment [get [find where host=\"\$Host\"] comment]\r\
    \n:local Interval [get [find where host=\"\$Host\"] interval]\r\
    \n:local Since [get [find where host=\"\$Host\"] since]\r\
    \n:local thisBox [/system identity get name];\r\
    \n:tool e-mail send to=j@xxx.com subject=\"\$thisBox DOWN to \
    \$Host\" body=( [ :system clock get date ] . \" \" . [ :system clock get t\
    ime ] . \"\$thisBox DOWN to \$Host\" )\r\
    \n"
add dont-require-permissions=yes name=script2 owner=admin policy=\
    ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="\
    \r\
    \n/system\r\
    \n:local cdate [clock get date] \r\
    \n:local yyyy  [:pick \$cdate 0  4]\r\
    \n:local MM    [:pick \$cdate 5  7]\r\
    \n:local dd    [:pick \$cdate 8 10]\r\
    \n:local identitydate \"\$[identity get name]_\$yyyy-\$MM-\$dd\"\r\
    \n/export show-sensitive file=\"\$identitydate\"\r\
    \n\r\
    \n/tool fetch upload=yes mode=ftp ascii=no src-path=\"/\$[\$identitydate].\
    rsc\" dst-path=\"/mikrotik-backups/\$[\$identitydate].rsc\" address=192.16\
    8.2.22 port=21 user=mikrotik password=<password>\r\
    \n\r\
    \n/file remove \"\$identitydate.rsc\"\r\
    \n\r\
    \n#:local logIDs [/system logging find where topics~\"info,!script\"]\r\
    \n\r\
    \n#/system logging set \$logIDs disabled=yes\r\
    \n\r\
    \n/system/logging/disable numbers=[/system logging/find where topics~\"inf\
    o\"] \r\
    \n\r\
    \n:log info \$logIDs\r\
    \n\r\
    \n:log info (\"Uploaded rsc backup to 192.168.2.22 as \".\$identitydate)\r\
    \n\r\
    \n/system/logging/enable numbers=[/system logging/find where topics~\"info\
    ,!script\"] \r\
    \n\r\
    \n#/system logging set \$logIDs disabled=no\r\
    \n\r\
    \n\r\
    \n# /system logging set 0 topics=info\r\
    \n# /system logging add action=remote prefix=192.168.0.13 topics=info\r\
    \n# :log info (\"Uploaded rsc backup to 192.168.2.22 as \".\$identitydate)\
    \r\
    \n# /system logging set 0 topics=info,!script\r\
    \n# /system logging add action=remote prefix=192.168.0.13 topics=info,!scr\
    ipt"
/system ups
add name=ups1 port=usbhid1
/system watchdog
set auto-send-supout=yes ping-start-after-boot=10m ping-timeout=10m \
    send-email-from=j@xxx.com send-email-to=\
    j@xxx.com watch-address=1.1.1.1
/tool bandwidth-server
set authenticate=no
/tool e-mail
set from=j@xxx.com password=<password> port=587 server=\
    smtp.gmail.com tls=starttls user=j@xxx.com
/tool graphing interface
add interface=bridge
add interface=bridge
add
add interface=bridge
add interface=bridge
add
/tool graphing queue
add
add
/tool graphing resource
add
add
/tool mac-server
set allowed-interface-list=MANAGE
/tool mac-server mac-winbox
set allowed-interface-list=MANAGE
/tool netwatch
add comment=Netwatch-8.8.4.4-Splunk disabled=no down-script=Netwatch host=\
    8.8.4.4 http-codes="" interval=30s name=Netwatch-8.8.4.4-Splunk \
    test-script="" type=simple up-script=Netwatch
add comment=Netwatch-192.168.0.11-Splunk disabled=no down-script=Netwatch \
    host=192.168.0.11 http-codes="" interval=30s name=\
    Netwatch-192.168.0.11-Splunk test-script="" type=simple up-script=\
    Netwatch
add comment=Netwatch-192.168.20.1-Splunk disabled=no down-script=Netwatch \
    host=192.168.20.1 http-codes="" interval=30s name=\
    Netwatch-192.168.20.1-Splunk test-script="" type=simple up-script=\
    Netwatch
add comment=Netwatch-192.168.30.2-Splunk disabled=no down-script=Netwatch \
    host=192.168.30.2 http-codes="" interval=20s name=\
    Netwatch-192.168.30.2-Splunk test-script="" type=simple up-script=\
    Netwatch
add comment=Netwatch-192.168.40.1-Splunk disabled=no down-script=Netwatch \
    host=192.168.40.1 http-codes="" interval=30s name=\
    Netwatch-192.168.40.1-Splunk test-script="" type=simple up-script=\
    Netwatch
add comment=Netwatch-192.168.70.1-Splunk disabled=no down-script=Netwatch \
    host=192.168.70.1 http-codes="" interval=30s name=\
    Netwatch-192.168.70.1-Splunk test-script="" type=simple up-script=\
    Netwatch
add comment=Netwatch-192.168.20.22-Splunk disabled=no down-script=Netwatch \
    host=192.168.20.22 http-codes="" interval=30s name=\
    Netwatch-192.168.20.22-Splunk test-script="" type=simple up-script=\
    Netwatch
add comment=Netwatch-192.168.1.2-Splunk disabled=no down-script=Netwatch \
    host=192.168.1.2 http-codes="" interval=30s name=\
    Netwatch-192.168.1.2-Splunk test-script="" type=simple up-script=Netwatch
add comment=Netwatch-JRS-small disabled=no down-script=Netwatch-JRS-small \
    host=1.1.1.1 http-codes="" interval=30s name=Netwatch-JRS-small \
    test-script="" type=simple up-script=Netwatch-JRS-small
add comment=Netwatch-192.168.0.80-Splunk disabled=no down-script=Netwatch \
    host=192.168.0.80 http-codes="" interval=30s name=\
    Netwatch-192.168.0.80-Splunk test-script="" type=simple up-script=\
    Netwatch
add comment=Netwatch-192.168.0.32-Splunk disabled=no down-script=Netwatch \
    host=192.168.0.32 http-codes="" interval=30s name=\
    Netwatch-192.168.0.32-Splunk test-script="" type=simple up-script=\
    Netwatch
add comment=Netwatch-192.168.0.31-Splunk disabled=no down-script=Netwatch \
    host=192.168.0.31 http-codes="" interval=30s name=\
    Netwatch-192.168.0.31-Splunk test-script="" type=simple up-script=\
    Netwatch
add comment=Netwatch-192.168.2.5-Splunk disabled=no down-script=Netwatch \
    host=192.168.2.5 http-codes="" interval=30s name=\
    Netwatch-192.168.2.5-Splunk test-script="" type=simple up-script=Netwatch
add comment=Netwatch-192.168.2.7-Splunk disabled=no down-script=Netwatch \
    host=192.168.2.7 http-codes="" interval=30s name=\
    Netwatch-192.168.2.7-Splunk test-script="" type=simple up-script=Netwatch
add comment=Netwatch-192.168.20.5-Splunk disabled=no down-script=Netwatch \
    host=192.168.20.5 http-codes="" interval=30s name=\
    Netwatch-192.168.20.5-Splunk test-script="" type=simple up-script=\
    Netwatch
add comment=Netwatch-192.168.20.21-Splunk disabled=no down-script=Netwatch \
    host=192.168.20.21 http-codes="" interval=30s name=\
    Netwatch-192.168.20.21-Splunk test-script="" type=simple up-script=\
    Netwatch
/tool romon
set enabled=yes
/tool sniffer
set file-limit=10000KiB filter-ip-address=10.0.0.0/16 memory-limit=10000KiB \
    streaming-server=192.168.2.22
/tool traffic-monitor
add disabled=yes interface=ether1 name=tmon1
add disabled=yes interface=ether3 name=tmon2 traffic=received trigger=always

ax3:

# 2024-10-05 10:02:13 by RouterOS 7.16
# software id = 5NRD-V1QF
#
# model = C53UiG+5HPaxD2HPaxD
# serial number = HDG08W
/interface bridge
add admin-mac=48:A9:8A:0F:04:8F auto-mac=no comment=defconf name=bridge \
    port-cost-mode=short
/interface ethernet
set [ find default-name=ether1 ] comment="To RB5009" poe-out=off
set [ find default-name=ether3 ] comment=TV
set [ find default-name=ether4 ] comment=TV
/interface wifi
set [ find default-name=wifi1 ] channel.band=5ghz-ax .frequency=5250-5330 \
    .skip-dfs-channels=all .width=20/40/80mhz configuration.antenna-gain=0 \
    .country=Russia .mode=ap .ssid=Upstairs5g-0F0493 .tx-power=21 disabled=no \
    security.authentication-types=wpa2-psk .disable-pmkid=yes .ft=yes \
    .ft-over-ds=yes .passphrase=<password>
set [ find default-name=wifi2 ] channel.band=2ghz-g .skip-dfs-channels=\
    disabled .width=20mhz configuration.country="United States" .mode=ap \
    .ssid=Upstairs-2G-0F0494 disabled=no security.authentication-types=\
    wpa2-psk .disable-pmkid=yes .ft=yes .ft-over-ds=yes .passphrase=\
    <password>
/interface eoip
add disabled=yes mac-address=02:88:47:EE:7A:47 name=eoip-tunnel-to-212-rb5009 \
    remote-address=192.168.2.2 tunnel-id=101
/interface wifi
add configuration.mode=ap .ssid=2point4 disabled=no mac-address=\
    4A:A9:8A:0F:04:93 master-interface=wifi2 mtu=1500 name=2point4 \
    security.authentication-types=wpa2-psk .disable-pmkid=yes .ft=yes \
    .ft-over-ds=yes .passphrase=<password>
/interface list
add comment=defconf name=WAN
add comment=defconf name=LAN
add include=all name=TRUSTED
/interface wifi configuration
add datapath.client-isolation=yes disabled=no name=guestcfg \
    security.authentication-types=wpa2-psk .disable-pmkid=yes .ft=yes \
    .ft-over-ds=yes .passphrase=blueberry ssid=GuestWifi
/interface wifi
add configuration=guestcfg configuration.mode=ap disabled=no mac-address=\
    4A:A9:8A:0F:04:94 master-interface=wifi2 name=Guest2g
add configuration=guestcfg configuration.mode=ap disabled=no mac-address=\
    4A:A9:8A:0F:04:95 master-interface=wifi1 name=Guest5g
/ip pool
add name=pool-guest ranges=10.0.0.10-10.0.0.252
/ip dhcp-server
add address-pool=pool-guest interface=Guest2g name=dhcp-guest2g
add address-pool=pool-guest interface=Guest5g name=dhcp-guest5g
/ip smb users
set [ find default=yes ] disabled=yes
/system logging action
set 3 remote=192.168.0.13
add name=logserver remote=192.168.0.112 remote-port=51400 target=remote
/interface bridge port
add bridge=bridge comment=defconf interface=ether2 internal-path-cost=10 \
    path-cost=10
add bridge=bridge comment=defconf interface=ether3 internal-path-cost=10 \
    path-cost=10
add bridge=bridge comment=defconf interface=ether4 internal-path-cost=10 \
    path-cost=10
add bridge=bridge comment=defconf interface=ether5 internal-path-cost=10 \
    path-cost=10
add bridge=bridge comment=defconf interface=*6 internal-path-cost=10 \
    path-cost=10
add bridge=bridge comment=defconf interface=wifi2 internal-path-cost=10 \
    path-cost=10
add bridge=bridge interface=ether1 internal-path-cost=10 path-cost=10
add bridge=bridge interface=2point4 internal-path-cost=10 path-cost=10
add bridge=bridge interface=wifi1
/ip firewall connection tracking
set udp-timeout=10s
/ip neighbor discovery-settings
set discover-interface-list=TRUSTED
/interface bridge vlan
add bridge=bridge disabled=yes vlan-ids=100
/interface list member
add comment=defconf interface=bridge list=LAN
add comment=defconf interface=ether1 list=WAN
add interface=bridge list=TRUSTED
add interface=ether1 list=TRUSTED
add interface=*6 list=TRUSTED
add interface=wifi2 list=TRUSTED
/interface wifi access-list
add action=accept comment=HarmonyHub disabled=no mac-address=\
    00:04:20:F9:31:D2
add action=accept comment=MFC-L3770 disabled=no mac-address=30:C9:AB:17:71:59
add action=accept comment="JRS iPhone" disabled=no mac-address=\
    FC:AA:81:2A:1F:B4
add action=accept comment="\?\?\?" disabled=no mac-address=96:4E:A5:1A:A9:74
add action=accept comment="\?\?\?" disabled=no mac-address=52:DA:D4:46:23:5B
add action=accept comment="Thomas iPhone" disabled=no mac-address=\
    46:B4:96:5E:1A:1B
add action=accept comment="SRN iPhone" disabled=no mac-address=\
    4A:11:46:2B:5B:78
add action=accept comment="\?\?\?" disabled=no mac-address=02:2A:61:8A:88:A7
add action=accept comment="SRN iPad" disabled=no mac-address=\
    16:31:50:11:6B:CF
add action=accept comment=DCP-L2550DW disabled=no mac-address=\
    2C:6F:C9:5F:BC:EB
add action=accept comment=Laptop-JRS-AN51 disabled=no mac-address=\
    94:E7:0B:29:30:E7
add action=accept comment="Tasmota switch" disabled=no mac-address=\
    C4:5B:BE:E3:76:77
add action=accept comment="JRS Laptop 2023" disabled=no mac-address=\
    64:49:7D:61:AE:2C
add action=accept comment="Living room (TV maybe)" disabled=no mac-address=\
    D4:90:9C:D8:66:99
add action=accept comment="49TCLRokuTV - Thomas" disabled=no mac-address=\
    0C:62:A6:1E:8B:18
add action=accept comment="SRN MS laptop" disabled=no mac-address=\
    24:EE:9A:54:9A:E8
add action=accept comment=MFC-L2550 disabled=no mac-address=B2:38:0C:90:FE:04
add action=accept comment="THR316 Thomas BR" disabled=no mac-address=\
    C8:F0:9E:E8:8A:E4
add action=accept comment="SRN iPhone" disabled=no mac-address=\
    EA:C1:05:82:99:7C
add action=accept comment="THS Acer Laptop" disabled=no mac-address=\
    54:6C:EB:7B:A2:C3
add action=accept comment="Screek Human Sensor 2A 16 LR" disabled=no \
    mac-address=EC:DA:3B:D1:92:3C
add action=accept comment="Shelly Button1 15 AV Equip" disabled=no \
    mac-address=48:55:19:F0:73:12
add action=accept comment="Beelink 212 DR" disabled=no mac-address=\
    70:D8:C2:4C:54:64
/ip address
add address=192.168.2.5/24 comment=defconf interface=bridge network=\
    192.168.2.0
add address=10.10.10.5/24 disabled=yes interface=bridge network=10.10.10.0
add address=172.16.0.1/24 disabled=yes interface=*C network=172.16.0.0
add address=10.0.0.1/24 interface=Guest2g network=10.0.0.0
add address=10.0.0.1/24 interface=Guest5g network=10.0.0.0
/ip cloud
set ddns-enabled=yes
/ip dhcp-server network
add address=10.0.0.0/24 dns-server=1.1.1.1 gateway=10.0.0.1
/ip dns
set allow-remote-requests=yes cache-max-ttl=4w cache-size=32768KiB \
    query-server-timeout=5s servers=1.1.1.1,8.8.8.8,9.9.9.9,8.8.4.4
/ip dns static
add address=192.168.2.5 comment=defconf name=hapax3.212.local type=A
add address=10.0.0.1 comment=defconf name=router.lan type=A
/ip firewall address-list
add address=10.0.0.2-10.0.0.254 list="Guest WiFi"
/ip firewall filter
add action=accept chain=input comment=\
    "defconf: accept established,related,untracked" connection-state=\
    established,related,untracked
add action=drop chain=input comment="defconf: drop invalid" connection-state=\
    invalid
add action=accept chain=input comment="defconf: accept ICMP" protocol=icmp
add action=accept chain=input comment="allow 67 68 to 10.0.0.1" dst-address=\
    10.0.0.1 dst-port=67,68 log-prefix="allow 67 68  to 10.0.0.1" protocol=\
    udp
add action=drop chain=input comment="drop all to 10.0.0.1" dst-address=\
    10.0.0.1 in-interface=!lo log=yes log-prefix="drop all to 10.0.0.1"
add action=accept chain=input
add action=drop chain=forward comment="drop all 10.0.0.0/24 to not-WAN" \
    disabled=yes log=yes log-prefix=drop-all-10-0-0-0-24-to-not-WAN \
    out-interface-list=!WAN src-address=10.0.0.0/24
add action=drop chain=forward comment="drop guest to 192.168.0.0/16" \
    dst-address=192.168.0.0/16 dst-port=!53,68,68 log=yes log-prefix=\
    drop-guest-to-192-168-0-0-16 protocol=udp src-address-list="Guest WiFi"
add action=accept chain=forward
add action=accept chain=input disabled=yes
add action=accept chain=input comment=\
    "defconf: accept to local loopback (for CAPsMAN)" disabled=yes \
    dst-address=127.0.0.1
add action=drop chain=input comment="defconf: drop all not coming from LAN" \
    disabled=yes in-interface-list=!LAN
add action=accept chain=forward disabled=yes in-interface-list=LAN log=yes
add action=accept chain=forward comment="defconf: accept out ipsec policy" \
    disabled=yes ipsec-policy=out,ipsec
add action=fasttrack-connection chain=forward comment="defconf: fasttrack" \
    connection-state=established,related disabled=yes hw-offload=yes
add action=accept chain=forward comment=\
    "defconf: accept established,related, untracked" connection-state=\
    established,related,untracked disabled=yes
add action=drop chain=forward comment="defconf: drop invalid" \
    connection-state=invalid disabled=yes
add action=drop chain=forward comment=\
    "defconf: drop all from WAN not DSTNATed" connection-nat-state=!dstnat \
    connection-state=new disabled=yes in-interface-list=WAN
/ip firewall nat
add action=masquerade chain=srcnat comment="defconf: masquerade" \
    ipsec-policy=out,none out-interface-list=WAN
/ip ipsec profile
set [ find default=yes ] dpd-interval=2m dpd-maximum-failures=5
/ip kid-control
add fri=0s-1d mon=0s-1d name=Monitor sat=0s-1d sun=0s-1d thu=0s-1d tue=0s-1d \
    wed=0s-1d
/ip route
add disabled=no distance=1 dst-address=0.0.0.0/0 gateway=192.168.2.2 \
    pref-src="" routing-table=main scope=30 suppress-hw-offload=no \
    target-scope=10
/ip service
set www-ssl disabled=no
/ip smb shares
set [ find default=yes ] directory=/pub
/snmp
set enabled=yes trap-version=2
/system clock
set time-zone-name=America/New_York
/system identity
set name=212hAP-Ax3
/system logging
set 0 topics=info,!script
add disabled=yes topics=wireless
add action=logserver prefix="serial=HDG08WM231C MikroTik" topics=hotspot
add action=logserver prefix="serial=HDG08WM231C MikroTik" topics=\
    !debug,!packet,!snmp
add topics=account
add action=remote prefix="192.168.2.5 " topics=info
/system note
set show-at-login=no
/system ntp client
set enabled=yes
/system ntp client servers
add address=192.168.2.2
add address=3.pool.ntp.org
add address=0.north-america.pool.ntp.org
/system scheduler
add interval=4d name=export-download on-event=export-download policy=\
    ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon \
    start-date=2023-02-01 start-time=16:44:58
add interval=2w name=dynamic-data-rextended on-event=dynamic-data-rextended \
    policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon \
    start-date=2023-09-30 start-time=02:58:29
add interval=5m name=Data_to_Splunk on-event=Data_to_Splunk_using_Syslog \
    policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon \
    start-date=2024-09-08 start-time=06:53:02
/system script
add dont-require-permissions=no name=export-download owner=admin policy=\
    ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="\
    \r\
    \n\r\
    \n/system\r\
    \n:local cdate [clock get date] \r\
    \n:local yyyy  [:pick \$cdate 0  4]\r\
    \n:local MM    [:pick \$cdate 5  7]\r\
    \n:local dd    [:pick \$cdate 8 10]\r\
    \n:local identitydate \"\$[identity get name]_\$yyyy-\$MM-\$dd\"\r\
    \n/export show-sensitive file=\"\$identitydate\"\r\
    \n\r\
    \n/tool fetch upload=yes mode=ftp ascii=no src-path=\"/\$[\$identitydate].\
    rsc\" dst-path=\"/mikrotik-backups/\$[\$identitydate].rsc\" address=192.16\
    8.2.22 port=21 user=mikrotik password=<password>\r\
    \n\r\
    \n/file remove \"\$[\$identitydate]\"\r\
    \n\r\
    \n:log info (\"Uploaded rsc backup to 192.168.2.22 as \".\$identitydate)\r\
    \n\r\
    \n"
add dont-require-permissions=yes name=dynamic-data-rextended owner=admin \
    policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon \
    source="/system\r\
    \n:local identitydate \"\$[identity get name]_\$[clock get date]\"\r\
    \n:local stringexec   \"/system iden print; :put \\\"\\\\r\\\\n\\\"; /ip c\
    loud pri; :put \\\"\\\\r\\\\n\\\";  /ip dhcp-server lease pri det; :put \\\
    \"\\\\r\\\\n\\\"; /int bridge host pri det\"\r\
    \n\r\
    \n:if ([:len [/system package find where name=\"wifiwave2\"]] > 1) do={\r\
    \n    :set stringexec \"\$stringexec; :put \\\"\\\\r\\\\n\\\" /int wifiwav\
    e2 reg pri det\"\r\
    \n} \r\
    \n\r\
    \n:if ([:len [/system package find where name=\"wifiwave2\"]] > 1) do={\r\
    \n    :set stringexec \"\$stringexec; :put \\\"\\\\r\\\\n\\\" /int wireles\
    s reg pri det\"\r\
    \n}\r\
    \n\r\
    \n\r\
    \n/file remove [find where name=tmpresults.txt]\r\
    \n:delay 1s\r\
    \n:execute \$stringexec file=tmpresults.txt\r\
    \n:delay 2s\r\
    \n\r\
    \n/tool fetch upload=yes mode=ftp ascii=no address=192.168.2.22 port=21 us\
    er=mikrotik password=<password>  src-path=tmpresults.txt dst-path=\"/mikroti\
    k-backups/\$identitydate-dynamicdata.txt\"\r\
    \n\r\
    \n/file remove [find where name=tmpresults.txt]"
add dont-require-permissions=no name=Data_to_Splunk_using_Syslog owner=admin \
    policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon \
    source="# Collect information from Mikrotik RouterOS\r\
    \n# Jotne 2024\r\
    \n# Script name=Data_to_Splunk_using_Syslog\r\
    \n:log info message=\"script=version ver=5.6\"\r\
    \n# ----------------------------------\r\
    \n\r\
    \n# Auto update syslog server. 5.3-5.4.\r\
    \n# Change <your syslog dns name> to the dns of your syslog server.\r\
    \n# The update is disabled by default.  Remove the # from the two next lin\
    e to use it.\r\
    \n\r\
    \n#:local mySyslog [resolve <your syslog dns name>]\r\
    \n#/system/logging/action/set [find where name=\"logserver\"] remote=\$myS\
    yslog\r\
    \n\r\
    \n\r\
    \n# What data to collect.  Set to false to skip the section \r\
    \n# ----------------------------------\r\
    \n:local SystemResource true\r\
    \n:local SystemInformation true\r\
    \n:local SystemHealth true\r\
    \n:local TrafficData true\r\
    \n:local AccountData true\r\
    \n:local uPnP true\r\
    \n:local Wireless true\r\
    \n:local AddressLists true\r\
    \n:local DHCP true\r\
    \n:local Neighbor true\r\
    \n:local InterfaceData true\r\
    \n:local CmdHistory true\r\
    \n:local CAPsMANN false\r\
    \n\r\
    \n:local Routing true\r\
    \n:local OSPF false\r\
    \n:local BGP false\r\
    \n\r\
    \n:local PPP true\r\
    \n:local IPSEC true\r\
    \n\r\
    \n# Get RouterOS main version (used to run different script on different v\
    ersion)\r\
    \n:local train [:tonum [:pick [/system resource get version] 0 1]] \r\
    \n\r\
    \n# Collect system resource\r\
    \n# ----------------------------------\r\
    \n:if (\$SystemResource) do={\r\
    \n\t/system resource\r\
    \n\t:local cpuload [get cpu-load]\r\
    \n\t:local freemem ([get free-memory]/1048576)\r\
    \n\t:local totmem ([get total-memory]/1048576)\r\
    \n\t:local freehddspace ([get free-hdd-space]/1048576)\r\
    \n\t:local totalhddspace ([get total-hdd-space]/1048576)\r\
    \n\t:local up [get uptime]\r\
    \n\t:local sector [get write-sect-total]\r\
    \n\t:log info message=\"script=resource free_memory=\$freemem MB total_mem\
    ory=\$totmem MB free_hdd_space=\$freehddspace MB total_hdd_space=\$totalhd\
    dspace MB cpu_load=\$cpuload uptime=\$up write-sect-total=\$sector\"\r\
    \n}\r\
    \n\r\
    \n\r\
    \n# Make some part only run every hours\r\
    \n# ----------------------------------\r\
    \n:global Hour\r\
    \n:local run false\r\
    \n:local hour [:pick [/system clock get time] 0 2]\r\
    \n:if (\$Hour != \$hour) do={\r\
    \n\t:global Hour \$hour\r\
    \n\t:set run true\r\
    \n}\r\
    \n\r\
    \n\r\
    \n# Get NTP status\r\
    \n# ----------------------------------\r\
    \n:local ntpstatus \"\"\r\
    \n:if ([:len [/system package find where !disabled and name=ntp]] > 0 or [\
    :tonum [:pick [/system resource get version] 0 1]] > 6) do={\r\
    \n    :set ntpstatus [/system ntp client get status]\r\
    \n} else={\r\
    \n    :if ([:typeof [/system ntp client get last-update-from]] = \"nil\") \
    do={\r\
    \n        :set ntpstatus \"using-local-clock\"\r\
    \n    } else={\r\
    \n        :set ntpstatus \"synchronized\"\r\
    \n    }\r\
    \n}\r\
    \n:log info message=\"script=ntp status=\$ntpstatus\" \r\
    \n\r\
    \n\r\
    \n# Get interface traffic data for all interface\r\
    \n# ----------------------------------\r\
    \n:if (\$TrafficData) do={\r\
    \n\t:foreach id in=[/interface find] do={\r\
    \n\t\t:local output \"\$[/interface print stats as-value where .id=\$id]\"\
    \r\
    \n\t\t:set ( \"\$output\"->\"script\" ) \"if_traffic\"\r\
    \n\t\t:log info message=\"\$output\"\r\
    \n\t}\r\
    \n}\r\
    \n\r\
    \n\r\
    \n# Get traffic data v2 (Kid Control)\r\
    \n# ----------------------------------\r\
    \n:if (\$AccountData) do={\r\
    \n\t:foreach logline in=[/ip kid-control device find] do={\r\
    \n\t\t:local output \"\$[/ip kid-control device get \$logline]\"\r\
    \n\t\t:set ( \"\$output\"->\"script\" ) \"kids\"\r\
    \n\t\t:log info message=\"\$output\"\r\
    \n\t}\r\
    \n}\r\
    \n\r\
    \n\r\
    \n# Finding dynmaic lines used in uPnP\r\
    \n# ----------------------------------\r\
    \n:if (\$uPnP) do={\r\
    \n\t:foreach logline in=[/ip firewall nat find where dynamic=yes and comme\
    nt~\"^upnp \"] do={\r\
    \n\t\t:local output \"\$[/ip firewall nat print as-value from=\$logline]\"\
    \r\
    \n\t\t:set ( \"\$output\"->\"script\" ) \"upnp\"\r\
    \n\t\t:log info message=\"\$output\" \r\
    \n\t}\r\
    \n}\r\
    \n\r\
    \n\r\
    \n# Collect system information 5.5 added ID for non routerBoard 5.6 Remvoe\
    d serial\r\
    \n# ----------------------------------\r\
    \n:local model na\r\
    \n:local ffirmware na\r\
    \n:local cfirmware na\r\
    \n:local ufirmware na\r\
    \n:if (\$SystemInformation and \$run) do={\r\
    \n\t:local version ([/system resource get version])\r\
    \n\t:local board ([/system resource get board-name])\r\
    \n\t:local identity ([/system identity get name])\r\
    \n\t:do {\r\
    \n\t\t:if (\$board!=\"CHR\" OR \$board!=\"x86\") do={\r\
    \n\t\t\t/system routerboard\r\
    \n\t\t\t:set model ([get model])\r\
    \n\t\t\t:set ffirmware ([get factory-firmware])\r\
    \n\t\t\t:set cfirmware ([get current-firmware])\r\
    \n\t\t\t:set ufirmware ([get upgrade-firmware])\r\
    \n\t\t}\r\
    \n\t} on-error={}\r\
    \n\t:log info message=\"script=sysinfo version=\\\"\$version\\\" board-nam\
    e=\\\"\$board\\\" model=\\\"\$model\\\" identity=\\\"\$identity\\\" factor\
    y-firmware=\\\"\$ffirmware\\\" current-firmware=\\\"\$cfirmware\\\" upgrad\
    e-firmware=\\\"\$ufirmware\\\"\"\r\
    \n}\r\
    \n\r\
    \n\r\
    \n# Collect system health\r\
    \n# ----------------------------------\r\
    \n:if (\$train > 6 and \$SystemHealth) do={\r\
    \n\t# New version (RouterOS >6)\r\
    \n\t:foreach id in=[/system health find] do={\r\
    \n\t\t:local health \"\$[/system health get \$id]\"\r\
    \n\t\t:set ( \"\$health\"->\"script\" ) \"health\"\r\
    \n\t\t:log info message=\"\$health\"\r\
    \n\t}\r\
    \n} else={\r\
    \n\t# Old version (RouterOS 6 or older)\r\
    \n\t:if (!([/system health get]~\"(state=disabled|^\\\$)\")) do={\r\
    \n\t\t:local health \"\$[/system health get]\"\r\
    \n\t\t:set ( \"\$health\"->\"script\" ) \"health\"\r\
    \n\t\t:log info message=\"\$health\"\r\
    \n\t}\r\
    \n}\r\
    \n\r\
    \n\r\
    \n\r\
    \n# Sends wireless client data to log server \r\
    \n# ----------------------------------\r\
    \n:if (\$Wireless && [:len [/int find where type=wlan]]>0) do={\r\
    \n\t/interface wireless registration-table\r\
    \n\t:foreach i in=[find] do={\r\
    \n\t\t:log info message=\".id=\$i;ap=\$([get \$i ap]);interface=\$([get \$\
    i interface]);mac-address=\$([get \$i mac-address]);signal-strength=\$([ge\
    t \$i signal-strength]);tx-rate=\$([get \$i tx-rate]);uptime=\$([get \$i u\
    ptime]);script=wifi\"\r\
    \n\t}\r\
    \n}\r\
    \n\r\
    \n\r\
    \n# Count IP in address-lists\r\
    \n#----------------------------------\r\
    \n:if (\$AddressLists) do={\r\
    \n\t:local array [ :toarray \"\" ]\r\
    \n\t:local addrcntdyn [:toarray \"\"] \r\
    \n\t:local addrcntstat [:toarray \"\"] \r\
    \n\t:local test\r\
    \n\t:foreach id in=[/ip firewall address-list find] do={\r\
    \n\t\t:local rec [/ip firewall address-list get \$id]\r\
    \n\t\t:local listname (\$rec->\"list\")\r\
    \n\t\t:local listdynamic (\$rec->\"dynamic\")\r\
    \n\t\t:if (!(\$array ~ \$listname)) do={ :set array (\$array , \$listname)\
    \_}\r\
    \n\t\t:if (\$listdynamic = true) do={\r\
    \n\t\t\t:set (\$addrcntdyn->\$listname) (\$addrcntdyn->\$listname+1)\r\
    \n\t\t} else={\r\
    \n\t\t\t:set (\$addrcntstat->\$listname) (\$addrcntstat->\$listname+1)}\r\
    \n\t}\r\
    \n\t:foreach k in=\$array do={\r\
    \n\t\t:log info message=(\"script=address_lists list=\$k dynamic=\".((\$ad\
    drcntdyn->\$k)+0).\" static=\".((\$addrcntstat->\$k)+0))}\r\
    \n}\r\
    \n\r\
    \n\r\
    \n# Get MNDP (CDP) Neighbors\r\
    \n# ----------------------------------\r\
    \n:if (\$Neighbor and \$run) do={\r\
    \n\t:foreach neighborID in=[/ip neighbor find] do={\r\
    \n\t\t:local nb [/ip neighbor get \$neighborID]\r\
    \n\t\t:local id [:pick (\"\$nb\"->\".id\") 1 99]\r\
    \n\t\t:foreach key,value in=\$nb do={\r\
    \n\t\t\t:local newline [:find \$value \"\\n\"]\r\
    \n\t\t\t:if ([\$newline]>0) do={\r\
    \n\t\t\t\t:set value [:pick \$value 0 \$newline]\r\
    \n\t\t\t}\r\
    \n\t\t\t:log info message=\"script=neighbor nid=\$id \$key=\\\"\$value\\\"\
    \"\r\
    \n\t\t}\r\
    \n\t}\r\
    \n}\r\
    \n\r\
    \n\r\
    \n# Collect DHCP Pool information\r\
    \n# ----------------------------------\r\
    \n:if (\$DHCP and \$run) do={\r\
    \n\t/ip pool {\r\
    \n\t\t:local poolname\r\
    \n\t\t:local pooladdresses\r\
    \n\t\t:local poolused\r\
    \n\t\t:local minaddress\r\
    \n\t\t:local maxaddress\r\
    \n\t\t:local findindex\r\
    \n\r\
    \n# Iterate through IP Pools\r\
    \n\t\t:foreach pool in=[find] do={\r\
    \n\t\t\t:set poolname [get \$pool name]\r\
    \n\t\t\t:set pooladdresses 0\r\
    \n\t\t\t:set poolused 0\r\
    \n\r\
    \n# Iterate through current pool's IP ranges\r\
    \n\t\t\t:foreach range in=[:toarray [get \$pool range]] do={\r\
    \n\r\
    \n# Get min and max addresses\r\
    \n\t\t\t\t:set findindex [:find [:tostr \$range] \"-\"]\r\
    \n\t\t\t\t:if ([:len \$findindex] > 0) do={\r\
    \n\t\t\t\t\t:set minaddress [:pick [:tostr \$range] 0 \$findindex]\r\
    \n\t\t\t\t\t:set maxaddress [:pick [:tostr \$range] (\$findindex + 1) [:le\
    n [:tostr \$range]]]\r\
    \n\t\t\t\t} else={\r\
    \n\t\t\t\t\t:set minaddress [:tostr \$range]\r\
    \n\t\t\t\t\t:set maxaddress [:tostr \$range]\r\
    \n\t\t\t\t}\r\
    \n\r\
    \n# Calculate number of ip in one range\r\
    \n\t\t\t\t:set pooladdresses (\$maxaddress - \$minaddress)\r\
    \n\r\
    \n# /foreach range\r\
    \n\t\t\t}\r\
    \n\r\
    \n# Test if pools is used in DHCP or VPN and show leases used\r\
    \n\t\t\t:local dname [/ip dhcp-server find where address-pool=\$poolname]\
    \r\
    \n\t\t\t:if ([:len \$dname] = 0) do={\r\
    \n# No DHCP server found, assume VPN\r\
    \n\t\t\t\t:set poolused [:len [used find pool=[:tostr \$poolname]]]\r\
    \n\t\t\t} else={\r\
    \n# DHCP server found, count leases\r\
    \n\t\t\t\t:local dname [/ip dhcp-server get [find where address-pool=\$poo\
    lname] name]\r\
    \n\t\t\t\t:set poolused [:len [/ip dhcp-server lease find where server=\$d\
    name]]}\r\
    \n\r\
    \n# Send data\r\
    \n\t\t\t:log info message=(\"script=pool pool=\$poolname used=\$poolused t\
    otal=\$pooladdresses\")\r\
    \n\r\
    \n# /foreach pool\r\
    \n\t\t}\r\
    \n# /ip pool\r\
    \n\t}\r\
    \n}\r\
    \n\r\
    \n\r\
    \n# Get detailed command history RouterOS >= v7\r\
    \n# ----------------------------------\r\
    \n:if (\$train > 6 and \$CmdHistory) do={\r\
    \n\t:global cmd\r\
    \n\t:local f 0\r\
    \n\t:foreach i in=[/system history find] do={\r\
    \n\t\t:if (\$i = \$cmd) do={ :set f 1 }\r\
    \n\t\t:if (\$f != 1) do={\r\
    \n\t\t\t:log info message=\"StartCMD\"\r\
    \n\t\t\t:log info message=[/system history get \$i]\r\
    \n\t\t\t:log info message=\"EndCMD\"\r\
    \n\t\t}\r\
    \n\t}\r\
    \n\t:global cmd  [:pick [/system history find] 0]\r\
    \n}\r\
    \n\r\
    \n\r\
    \n# Test if CAPsMANN is installed and run script 5.5\r\
    \n# ----------------------------------\r\
    \n:if ( ([:len [/interface find where type=\"cap\"]] > 0) and \$CAPsMANN) \
    do={ \r\
    \n\t/system script run CAPsMANN\r\
    \n}\r\
    \n\r\
    \n\r\
    \n\r\
    \n# Collect routing information\r\
    \n# ----------------------------------\r\
    \n:if (\$Routing) do={\r\
    \n\t/ip route\r\
    \n\t:foreach id in=[find] do={\r\
    \n\t\t:local route \"\$[get \$id]\"\r\
    \n\t\t:set ( \"\$route\"->\"script\" ) \"route\"\r\
    \n\t\t:log info message=\"\$route\"\r\
    \n\t}\r\
    \n}\r\
    \n\r\
    \n:if (\$OSPF) do={\r\
    \n\t/routing ospf neighbor\r\
    \n\t:foreach id in=[find] do={\r\
    \n\t\t:local ospf \"\$[get \$id]\"\r\
    \n\t\t:set ( \"\$ospf\"->\"script\" ) \"ospf\"\r\
    \n\t\t:log info message=\"\$ospf\"\r\
    \n\t}\r\
    \n}\r\
    \n\r\
    \n:if (\$BGP) do={\r\
    \n\t/routing bgp session\r\
    \n\t:foreach id in=[find] do={\r\
    \n\t\t:local bgp \"\$[get \$id]\"\r\
    \n\t\t:set ( \"\$bgp\"->\"script\" ) \"bgp\"\r\
    \n\t\t:log info message=\"\$bgp\"\r\
    \n\t}\r\
    \n}\r\
    \n\r\
    \n\r\
    \n# Collect PPP/IPSEC\r\
    \n# ----------------------------------\r\
    \n:if (\$PPP) do={\r\
    \n\t/ppp active\r\
    \n\t:foreach id in=[find] do={\r\
    \n\t\t:local ppp \"\$[get \$id]\"\r\
    \n\t\t:set ( \"\$ppp\"->\"script\" ) \"ppp\"\r\
    \n\t\t:log info message=\"\$ppp\"\r\
    \n\t}\r\
    \n}\r\
    \n\r\
    \n:if (\$IPSEC) do={\r\
    \n\t/ip ipsec active-peers\r\
    \n\t:foreach id in=[find] do={\r\
    \n\t\t:local ipsec \"\$[get \$id]\"\r\
    \n\t\t:set ( \"\$ipsec\"->\"script\" ) \"ipsec\"\r\
    \n\t\t:log info message=\"\$ipsec\"\r\
    \n\t}\r\
    \n}\r\
    \n\r\
    \n# End Script\r\
    \n\r\
    \n"
add dont-require-permissions=yes name=Netwatch owner=admin policy=\
    ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="#\
    ###################################\r\
    \n# Netwatch script\r\
    \n#\r\
    \n# Used as both up and down script\r\
    \n# Created Jotne 2021 v1.5\r\
    \n#\r\
    \n####################################\r\
    \n:local Host \$host\r\
    \n/tool netwatch\r\
    \n:local Status [get [find where host=\"\$Host\"] status]\r\
    \n:local Comment [get [find where host=\"\$Host\"] comment]\r\
    \n:local Interval [get [find where host=\"\$Host\"] interval]\r\
    \n:local Since [get [find where host=\"\$Host\"] since]\r\
    \n:log info \"script=netwatch watch_host=\$Host comment=\\\"\$Comment\\\" \
    status=\$Status interval=\$Interval since=\\\"\$Since\\\"\""
/tool graphing interface
add interface=wifi2
add
add interface=bridge
add interface=ether1
add interface=ether2
add interface=ether3
add interface=ether4
add interface=ether5
add interface=*6
/tool graphing queue
add
/tool graphing resource
add
/tool mac-server
set allowed-interface-list=TRUSTED
/tool mac-server mac-winbox
set allowed-interface-list=TRUSTED
/tool netwatch
add disabled=no down-script=Netwatch host=1.1.1.1 http-codes="" interval=1m \
    name=Netwatch-1.1.1.1-Splunk test-script="" type=simple up-script=\
    Netwatch
/tool romon
set enabled=yes
/tool sniffer
set file-limit=10000KiB filter-interface=Guest5g memory-limit=1000KiB
/user group
add name=HA policy="reboot,read,write,policy,test,api,!local,!telnet,!ssh,!ftp\
    ,!winbox,!password,!web,!sniff,!sensitive,!romon,!rest-api"

Here is a screenshot of last night’s log, in case it is useful.

There is only 1 device using this Guestwifi now – my own iPhone, which works very well with this configuration.

Screenshot 2024-10-06 061750.png

Your complete export has revealed that there is a DHCP client attached to ether1 of the 5009 that is allowed to add a dedault route. So which port of the 5009 is connected to FIOS, ether1 or some other one? What does /ip route print detail show on the 5009?

Isn’t it normal/recommended/needed for the DHCP client on the 5009 to be able to add a default route?

This is the output.

All the 192.168.x.y and 10.10.100.x routes are wireguard-connected sites.

[admin@212RB5009] > ip route print detail without-paging terse

 0  Xs  comment=371 dst-address=192.168.88.0/24 routing-table=main pref-src= gateway=*B distance=1 scope=30 target-scope=10 suppress-hw-offload=no
 1  Xs  comment=355 dst-address=192.168.0.0/24 routing-table=main pref-src= gateway=*B distance=1 scope=30 target-scope=10 suppress-hw-offload=no
 2  Xs  comment=255 dst-address=192.168.1.0/24 routing-table=main pref-src= gateway=*B distance=1 scope=30 target-scope=10 suppress-hw-offload=no
 3  Xs  dst-address=192.168.5.0/24 routing-table=main pref-src= gateway=*B distance=1 scope=30 target-scope=10 suppress-hw-offload=no
 4  Xs  comment=629 dst-address=192.168.20.0/24 routing-table=main pref-src= gateway=*B distance=1 scope=30 target-scope=10 suppress-hw-offload=no
   DAd  dst-address=0.0.0.0/0 routing-table=main pref-src= gateway=100.38.160.1 immediate-gw=100.38.160.1%ether1 distance=1 scope=30 target-scope=10 vrf-interface=ether1 suppress-hw-offload=no
 5  IsH dst-address=0.0.0.0/0 routing-table=main pref-src= gateway=192.168.2.2 immediate-gw= distance=1 scope=30 target-scope=10 suppress-hw-offload=no
 6  As  dst-address=10.0.0.0/24 routing-table=main pref-src= gateway=192.168.2.5 immediate-gw=192.168.2.5%bridge distance=1 scope=30 target-scope=10 suppress-hw-offload=no
   DAc  dst-address=10.10.100.0/24 routing-table=main gateway=212-Wireguard immediate-gw=212-Wireguard distance=0 scope=10 suppress-hw-offload=no local-address=10.10.100.1%212-Wireguard
   DAc  dst-address=100.38.160.0/24 routing-table=main gateway=ether1 immediate-gw=ether1 distance=0 scope=10 suppress-hw-offload=no local-address=100.38.160.98%ether1
 7  As  comment=355 dst-address=192.168.0.0/24 routing-table=main pref-src= gateway=212-Wireguard immediate-gw=212-Wireguard distance=1 scope=30 target-scope=10 suppress-hw-offload=no
 8  As  comment=255 dst-address=192.168.1.0/24 routing-table=main pref-src= gateway=212-Wireguard immediate-gw=212-Wireguard distance=1 scope=30 target-scope=10 suppress-hw-offload=no
   DAc  dst-address=192.168.2.0/24 routing-table=main gateway=bridge immediate-gw=bridge distance=0 scope=10 suppress-hw-offload=no local-address=192.168.2.2%bridge
 9  As  comment=355-Cameras dst-address=192.168.5.0/24 routing-table=main pref-src= gateway=212-Wireguard immediate-gw=212-Wireguard distance=1 scope=30 target-scope=10 suppress-hw-offload=no
10  As  comment=629 dst-address=192.168.20.0/24 routing-table=main pref-src= gateway=212-Wireguard immediate-gw=212-Wireguard distance=1 scope=30 target-scope=10 suppress-hw-offload=no
11  As  comment=76 dst-address=192.168.30.0/24 routing-table=main pref-src= gateway=212-Wireguard immediate-gw=212-Wireguard distance=1 scope=30 target-scope=10 suppress-hw-offload=no
12  As  comment=371 dst-address=192.168.40.0/24 routing-table=main pref-src= gateway=212-Wireguard immediate-gw=212-Wireguard distance=1 scope=30 target-scope=10 suppress-hw-offload=no
13  As  dst-address=192.168.60.0/24 routing-table=main pref-src= gateway=192.168.2.8 immediate-gw=192.168.2.8%bridge distance=1 scope=30 target-scope=10 suppress-hw-offload=no
14  As  comment=125 dst-address=192.168.70.0/24 routing-table=main pref-src= gateway=212-Wireguard immediate-gw=212-Wireguard distance=1 scope=30 target-scope=10 suppress-hw-offload=no

Nothing is 'normal, there are default rules for the very basic setup and the rest are ADMIN decisions.

Okay, so it having the DHCP client configured to set up a route on its own the default setting? And, would you recommend changing it?

More importantly, do you think that this automatically added route is causing a problem?

Thanks anav!

Depends,
If you are assigned a static WANIP, its often easier just to set the IP yourself.
If assigned a dynamic WANIP a dhcp client setting can make sense for route, but it depends on the ISP provider.
Same with ppppoe type connection…

Typically if doing something funky with routes its often better to make manual route vice dhcp client routes, more granular control…
Will probably get many opinions…

Makes perfect sense.

The IP assigned by the ISP is dynamic (Verizon FIOS home).

I don’t think I’m doing anything that rises to the level of funky. Basically, before adding the “guest wifi” to the ax3, there was internet routing through FIOS, wireguard routing, and internal routing. Adding the “guest wifi” on a separate private network (10.0.0.0/24) added a level of complexity, but I thought I configured it properly.

But, I’ve been wrong before…

Is the fact that there are 2 routes with 0.0.0.0/0 destinations a problem?

   DAd  dst-address=0.0.0.0/0 routing-table=main pref-src= gateway=100.38.160.1 immediate-gw=100.38.160.1%ether1 distance=1 scope=30 target-scope=10 vrf-interface=ether1 suppress-hw-offload=no
   IsH dst-address=0.0.0.0/0 routing-table=main pref-src= gateway=192.168.2.2 immediate-gw= distance=1 scope=30 target-scope=10 suppress-hw-offload=no
   DAc  dst-address=100.38.160.0/24 routing-table=main gateway=ether1 immediate-gw=ether1 distance=0 scope=10 suppress-hw-offload=no local-address=100.38.160.98%ether1

The ax3’s routes are:

[admin@212hAP-Ax3] /ip/route> print terse
 
0  As  dst-address=0.0.0.0/0 routing-table=main pref-src= gateway=192.168.2.2 immediate-gw=192.168.2.2%bridge distance=1 scope=30 target-scope=10 suppress-hw-offload=no
  DAc  dst-address=10.0.0.0/24 routing-table=main gateway=Guest5g immediate-gw=Guest5g distance=0 scope=10 target-scope=5 local-address=10.0.0.1%Guest5g
  DIcH dst-address=10.0.0.0/24 routing-table=main gateway=Guest2g distance=0 scope=10 target-scope=5 local-address=10.0.0.1%Guest2g
  DAc  dst-address=192.168.2.0/24 routing-table=main gateway=bridge immediate-gw=bridge distance=0 scope=10 target-scope=5 localaddress=192.168.2.5%bridge

Two routes with the same destination may be both a desired setup or a wrong one - it depends on circumstances.

E.g. if you had two WANs, two default routes could be a desired setup, as the ultimate destination would be the same one (some host in the internet) and reachable via both routes. But neither of your cases fits into that category:

  • the default route added dynamically via DHCP is OK (and the only problem I had with it was that it was missing in your initial “simplified” configuration export), the manually added default route is wrong in terms that its gateway address is an own one of the router. Luckily, although the router did not prevent entering that route into configuration, it marks it as Invalid and does not actually use it.
  • the two routes to 10.0.0.0/24 on the hAP ax³ are a different case, as the router has no way to determine through which of the two interfaces to which 10.0.0.0/24 resolves to send a packet for 10.0.0.x that comes from the 5009 unless you use some advanced techniques (connection marking in firewall mangle based on source interface for the wireless->5009 direction and route marking based on connection mark for 5009->wireless connection). The steps are
  1. find the gateway interface towards the destination IP address using routing
  2. from that interface, send an ARP request asking for the MAC address of the host that has the destination IP address
  3. note down the MAC address from the ARP response and the interface for the destination IP address for a couple of minutes in the “ARP table”
  4. encapsulate the IP packet into an Ethernet interface with the MAC address from the ARP table
    Steps 2 and 3 are only taken if the ARP table for the IP address is empty. But the router does not “fork” the packet to multiple interfaces.