From e1f134ead584c7b2e9ed406f5520d7f1a23294aa Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Thu, 5 Jul 2018 15:29:26 +0200 Subject: add scripts --- GeneratePSK | 51 +++++++++++++++++++++++++++++++++++ check-certificates | 52 +++++++++++++++++++++++++++++++++++ check-routeros-update | 42 +++++++++++++++++++++++++++++ collect-wireless-mac | 64 +++++++++++++++++++++++++++++++++++++++++++ daily-psk | 41 ++++++++++++++++++++++++++++ dhcp-lease-comment | 22 +++++++++++++++ dhcp-to-dns | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++ email-backup | 51 +++++++++++++++++++++++++++++++++++ email-daily-psk | 47 ++++++++++++++++++++++++++++++++ ethernet-to-default | 17 ++++++++++++ forward-sms | 29 ++++++++++++++++++++ global-config | 42 +++++++++++++++++++++++++++++ ipv6-update | 38 ++++++++++++++++++++++++++ learn-mac-based-vlan | 12 +++++++++ lease-script | 17 ++++++++++++ leds-day-mode | 6 +++++ leds-night-mode | 6 +++++ manage-umts | 26 ++++++++++++++++++ netwatch-syslog | 14 ++++++++++ ppp-on-up | 13 +++++++++ remove-packages | 6 +++++ rotate-ntp | 12 +++++++++ script-updates | 17 ++++++++++++ script2script | 6 +++++ ssh-keys-import | 10 +++++++ super-mario-theme | 66 +++++++++++++++++++++++++++++++++++++++++++++ update-gre-address | 30 +++++++++++++++++++++ update-tunnelbroker | 30 +++++++++++++++++++++ 28 files changed, 842 insertions(+) create mode 100644 GeneratePSK create mode 100644 check-certificates create mode 100644 check-routeros-update create mode 100644 collect-wireless-mac create mode 100644 daily-psk create mode 100644 dhcp-lease-comment create mode 100644 dhcp-to-dns create mode 100644 email-backup create mode 100644 email-daily-psk create mode 100644 ethernet-to-default create mode 100644 forward-sms create mode 100644 global-config create mode 100644 ipv6-update create mode 100644 learn-mac-based-vlan create mode 100644 lease-script create mode 100644 leds-day-mode create mode 100644 leds-night-mode create mode 100644 manage-umts create mode 100644 netwatch-syslog create mode 100644 ppp-on-up create mode 100644 remove-packages create mode 100644 rotate-ntp create mode 100644 script-updates create mode 100644 script2script create mode 100644 ssh-keys-import create mode 100644 super-mario-theme create mode 100644 update-gre-address create mode 100644 update-tunnelbroker diff --git a/GeneratePSK b/GeneratePSK new file mode 100644 index 0000000..c40bb7c --- /dev/null +++ b/GeneratePSK @@ -0,0 +1,51 @@ +# RouterOS script: GeneratePSK +# Copyright (c) 2013-2018 Christian Hesse +# +# return pseudo-random string for PSK + +:local date [ / system clock get date ]; + +# 0-30 for days of month +:local +secret1 { "Abusive"; "Aggressive"; "Bored"; "Chemical"; "Cold"; "Cruel"; + "Curved"; "Delightful"; "Discreet"; "Elite"; "Evasive"; "Faded"; "Flat"; + "Future"; "Grandiose"; "Hanging"; "Humorous"; "Interesting"; "Magenta"; + "Magnificent"; "Numerous"; "Optimal"; "Pathetic"; "Possessive"; + "Remarkable"; "Rightful"; "Ruthless"; "Stale"; "Unusual"; "Useless"; + "Various" }; +# 0-11 for month of year +:local secret2 { "Adhesive"; "Amusing"; "Astonishing"; "Frantic"; + "Kindhearted"; "Limping"; "Roasted"; "Robust"; "Staking"; "Thundering"; + "Ultra"; "Unusual" }; +# 0-6 for days of week +:local secret3 { "Belief"; "Button"; "Curtain"; "Edge"; "Jewel"; "String"; + "Whistle" }; + +:local months { "jan"; "feb"; "mar"; "apr"; "may"; "jun"; "jul"; "aug"; "sep"; + "oct"; "nov"; "dec" }; +:local monthtbl { 0; 3; 3; 6; 1; 4; 6; 2; 5; 0; 3; 5 }; + +:local monthstr [ :pick $date 0 3 ]; +:local month; +:local day [ :pick $date 4 6 ]; +:local century [ :pick $date 7 9 ]; +:local year [ :pick $date 9 11 ]; + +# get numeric value for month +:for mindex from=0 to=[ :len $months ] do={ + :if ([ :pick $months $mindex ] = $monthstr) do={ + :set month $mindex; + }; +}; + +# calculate day of week +:local sum 0; +:set sum ($sum + (2 * (3 - ($century - (($century / 4) * 4))))); +:set sum ($sum + ($year / 4)); +:set sum ($sum + $year + $day); +:set sum ($sum + $month); +:set sum ($sum - (($sum / 7) * 7)); + +:local return ([ :pick $secret1 ($day - 1) ] . [ :pick $secret2 $month ] . [ :pick $secret3 $sum ]); + +:return $return; diff --git a/check-certificates b/check-certificates new file mode 100644 index 0000000..925187d --- /dev/null +++ b/check-certificates @@ -0,0 +1,52 @@ +# RouterOS script: check-certificates +# Copyright (c) 2013-2018 Christian Hesse +# +# check for certificate validity + +:global "identity"; +:global "email-general-to"; +:global "email-general-cc"; + +:local months ("jan","feb","mar","apr","may","jun","jul","aug","sep","oct","nov","dec"); + +:local currentdate [ / system clock get date ]; + +:local currentmonthstr [ :pick $currentdate 0 3 ]; +:local currentday [ :pick $currentdate 4 6 ]; +:local currentyear [ :pick $currentdate 7 11 ]; +:local currentmonth ([ :find $months $currentmonthstr -1 ] + 1); +:local currentstamp ($currentyear * 365 + $currentmonth * 30 + $currentday); + +:foreach cert in=[ / certificate find where !revoked ] do={ + :local certname [ / certificate get $cert name ]; + :local invaliddate [ / certificate get $cert invalid-after ]; + + :if ([ :len $invaliddate ] > 0) do={ + :local invalidmonthstr [ :pick $invaliddate 0 3 ]; + :local invalidday [ :pick $invaliddate 4 6 ]; + :local invalidyear [ :pick $invaliddate 7 11 ]; + :local invalidmonth ([ :find $months $invalidmonthstr -1 ] + 1); + :local invalidstamp ($invalidyear * 365 + invalidmonth * 30 + invalidday); + + :local remaining ($invalidstamp - $currentstamp); + + :if ($remaining < 15) do={ + :local commonname [ / certificate get $cert common-name ]; + :local fingerprint [ / certificate get $cert fingerprint ]; + :local invalidbefore [ / certificate get $cert invalid-before ]; + :local invalidafter [ / certificate get $cert invalid-after ]; + / tool e-mail send to=$"email-general-to" cc=$"email-general-cc" \ + subject=("[" . $identity . "] Certificate warning!") \ + body=("A certificate on " . $identity . " is about to expire.\n\n" . \ + "Certificate Name: " . $certname . "\n" . \ + "Common Name: " . $commonname . "\n" . \ + "Fingerprint: " . $fingerprint . "\n" . \ + "Validity: " . $invalidbefore . " to " . $invalidafter); + :log warning ("A certificate is about to expire within " . $remaining . " days: " . $certname); + } else={ + :log debug ("The certificate " . $certname . " expires in " . $remaining . " days."); + } + } else={ + :log debug ("The certificate " . $certname . " is just a template."); + } +} diff --git a/check-routeros-update b/check-routeros-update new file mode 100644 index 0000000..8cd93fe --- /dev/null +++ b/check-routeros-update @@ -0,0 +1,42 @@ +# RouterOS script: check-routeros-update +# Copyright (c) 2013-2018 Christian Hesse +# +# check for RouterOS update, send notification e-mails + +:global "identity"; +:global "email-general-to"; +:global "email-general-cc"; +:global "sent-routeros-update-notification"; + +:if ([ :len [ / system package find where name="wireless" ] ] > 0) do={ + :if ([ / interface wireless cap get enabled ] = true) do={ + :error "System is managed by CAPsMAN, not checking."; + } +} + +:if ($"sent-routeros-update-notification" = true) do={ + :error "Already sent the RouterOS update notification."; +} + +# get some information +:local model [ / system routerboard get model ]; +:local serialnumber [ / system routerboard get serial-number ]; + +# check for RouterOS +/ system package update check-for-updates without-paging; +:local installedversion [ / system package update get installed-version ]; +:local latestversion [ / system package update get latest-version ]; +:local channel [ / system package update get channel ]; + +:if ($installedversion != $latestversion) do={ + / tool e-mail send to=$"email-general-to" cc=$"email-general-cc" \ + subject=("[" . $identity . "] RouterOS update notification") \ + body=("There is a RouterOS update available\n\n" . \ + "Routerboard: " . $model . "\n" . \ + "Serial number: " . $serialnumber . "\n" . \ + "Hostname: " . $identity . "\n" . \ + "Channel: " . $channel . "\n" . \ + "Installed: " . $installedversion . "\n" . \ + "Available: " . $latestversion); + :set "sent-routeros-update-notification" true; +} diff --git a/collect-wireless-mac b/collect-wireless-mac new file mode 100644 index 0000000..ee93a11 --- /dev/null +++ b/collect-wireless-mac @@ -0,0 +1,64 @@ +# RouterOS script: collect-wireless-mac +# Copyright (c) 2013-2018 Christian Hesse +# +# collect wireless mac adresses in access list +# +# this supports local wireless and caps-man when updating paths: +# $ sed -i '/^$/,$s/caps-man/interface wireless/' collect-wireless-mac +# $ sed -i '/^$/,$s/interface wireless/caps-man/' collect-wireless-mac + +:global "identity"; +:global "email-general-to"; +:global "email-general-cc"; + +:local "place-before" [ / caps-man access-list find where comment="--- collected above ---" disabled ]; +:if ([ :len $"place-before" ] = 0) do={ + :error "Missing disabled access-list entry with comment '--- collected above ---'"; +} + +:foreach regtbl in=[ / caps-man registration-table find ] do={ + :local mac [ / caps-man registration-table get $regtbl mac-address ]; + :local acclst [ :pick [ / caps-man access-list find where mac-address=$mac ] 0 ]; + :if ( [ :len $acclst ] = 0 ) do={ + :local hostname "no dhcp lease"; + :local address "no dhcp lease"; + :local lease [ / ip dhcp-server lease find where mac-address=$mac ]; + :if ( [ :len $lease ] > 0 ) do={ + :set hostname [ / ip dhcp-server lease get $lease host-name ]; + :set address [ / ip dhcp-server lease get $lease address ]; + } + :if ( [ :len $hostname ] = 0 ) do={ + :set hostname "no hostname"; + } + :if ( [ :len $address ] = 0 ) do={ + :set address "no address"; + } + :local regentry [ / caps-man registration-table find where mac-address=$mac ]; + :local interface [ / caps-man registration-table get $regentry interface ]; + :local ssid; + :if ("caps-man" = ("caps" . "-man")) do={ + :set ssid [ / caps-man registration-table get $regentry ssid ]; + } else={ + # keep two spaces here to protect against replace! + :set ssid [ / interface wireless get [ find where name=$interface ] ssid ]; + } + :local datetime ([ / system clock get date ] . " " . [ / system clock get time ]); + :local message ("unknown MAC address " . $mac . " (" . $hostname . ") first seen on " . \ + $datetime . " connected to SSID " . $ssid . ", interface " . $interface); + / log info $message; + / caps-man access-list add place-before=$"place-before" comment=$message mac-address=$mac disabled=yes; + / tool e-mail send to=$"email-general-to" cc=$"email-general-cc" \ + subject=("[" . $identity . "] " . $mac . " connected to " . $ssid) \ + body=("A device with unknown MAC address connected to " . $ssid . " on " . $identity . ".\n\n" . \ + "Controller: " . $identity . "\n" . \ + "Interface: " . $interface . "\n" . \ + "SSID: " . $ssid . "\n" . \ + "MAC: " . $mac . "\n" . \ + "Hostname: " . $hostname . "\n" . \ + "Address: " . $address . "\n" . \ + "Date: " . $datetime); + } else={ + :local comment [ / caps-man access-list get $acclst comment ]; + :log debug ("MAC address " . $mac . " already known: " . $comment); + } +} diff --git a/daily-psk b/daily-psk new file mode 100644 index 0000000..abb1f91 --- /dev/null +++ b/daily-psk @@ -0,0 +1,41 @@ +# RouterOS script: daily-psk +# Copyright (c) 2013-2018 Christian Hesse +# +# update daily PSK (pre shared key) + +:global "daily-psk-match-comment"; + +# check mail server +:if ([ / tool netwatch get [ find where comment=[ / tool e-mail get address ] ] status ] != "up" ) do={ + :error "Mail server is not up."; +} + +# check time +:if ([ / system ntp client get status ] != "synchronized") do={ + :error "Time is not yet synchronized from ntp."; +} + +:local GeneratePSK [ :parse [ / system script get GeneratePSK source ] ]; + +:local newpsk [ $GeneratePSK ]; + +:local sendmail 0; + +:foreach acclist in=[ / interface wireless access-list find where comment~$"daily-psk-match-comment" ] do={ + :local interface [ / interface wireless access-list get $acclist interface ]; + :local ssid [ / interface wireless get $interface ssid ]; + :local oldpsk [ / interface wireless access-list get $acclist private-pre-shared-key ]; + + :if ($newpsk != $oldpsk) do={ + :log info ("Updating daily PSK for " . $interface . " to " . $newpsk . " (was " . $oldpsk . ")"); + / interface wireless access-list set $acclist private-pre-shared-key=$newpsk; + + :set sendmail 1; + } +} + +:if ($sendmail = 1) do={ + / system script run email-daily-psk; +} + +/ system scheduler set disabled=yes [ find where name=daily-psk disabled=no ]; diff --git a/dhcp-lease-comment b/dhcp-lease-comment new file mode 100644 index 0000000..f3a081c --- /dev/null +++ b/dhcp-lease-comment @@ -0,0 +1,22 @@ +# RouterOS script: dhcp-lease-comment +# Copyright (c) 2013-2018 Christian Hesse +# +# update dhcp-server lease comment with infos from access-list +# +# this supports local wireless and caps-man when updating paths: +# $ sed -i '/^$/,$s/caps-man/interface wireless/' dhcp-lease-comment +# $ sed -i '/^$/,$s/interface wireless/caps-man/' dhcp-lease-comment + +:foreach lease in=[ / ip dhcp-server lease find where dynamic=yes ] do={ + :local macaddress [ / ip dhcp-server lease get $lease mac-address ]; + :local oldcomment [ / ip dhcp-server lease get $lease comment ]; + :local newcomment; + :local accesslst [ :pick [ / caps-man access-list find where mac-address=$macaddress ] 0 ]; + :if ( [ :len $accesslst ] > 0 ) do={ + :set newcomment [ / caps-man access-list get $accesslst comment ]; + } + :if ([ :len $newcomment ] != 0 && $oldcomment != $newcomment) do={ + :log info ("Updating comment for DHCP lease " . $macaddress . ": " . $newcomment); + / ip dhcp-server lease set comment=$newcomment $lease; + } +} diff --git a/dhcp-to-dns b/dhcp-to-dns new file mode 100644 index 0000000..40276ef --- /dev/null +++ b/dhcp-to-dns @@ -0,0 +1,75 @@ +# RouterOS script: dhcp-to-dns +# Copyright (c) 2013-2018 Christian Hesse +# +# check DHCP leases and add/remove/update DNS entries + +:global "identity"; +:global "domain"; +:global "hostname-in-zone"; + +:local zone; +:if ($"hostname-in-zone" = true) do={ + :set zone ("dhcp." . $identity . "." . $domain); +} else={ + :set zone ("dhcp." . $domain); +} +:local ttl "00:05:00"; +:local hostname; +:local fqdn; +:local dnsip; +:local dhcpip; +:local dnsnode; +:local dhcpnode; + +:foreach static in=[ / ip dns static find where name ~ (".*\\." . $zone) ] do={ + :set fqdn [ / ip dns static get $static name ]; + :set hostname [ :pick $fqdn 0 ( [ :len $fqdn ] - ( [ :len $zone ] + 1 ) ) ]; + :set dhcpnode [ / ip dhcp-server lease find where host-name=$hostname dynamic=yes ]; + :if ( [ :len $dhcpnode ] > 0) do={ + :log debug ("Lease for " . $hostname . " still exists. Not deleting."); + } else={ + :local found false; + :log info ("Lease expired for " . $hostname . ", deleting DNS entry."); + / ip dns static remove $static; + } +} + +:foreach lease in=[ / ip dhcp-server lease find where dynamic=yes ] do={ + :local mac [ / ip dhcp-server lease get $lease mac-address ]; + :set dhcpip [ / ip dhcp-server lease get $lease address ]; + :local comment ("managed by dhcp-to-dns for " . $mac); + :set hostname [ / ip dhcp-server lease get $lease host-name ]; + + :while ($hostname ~ " ") do={ + :local pos [ :find $hostname " " ]; + :set hostname ( [ :pick $hostname 0 $pos ] . [ :pick $hostname ($pos + 1) 999 ] ); + }; + + :if ( [ :len $hostname ] > 0) do={ + :set fqdn ( $hostname . "." . $zone ); + :set dnsnode [ / ip dns static find where name=$fqdn ]; + :if ( [ :len $dnsnode ] > 0 ) do={ + :set dnsip [ / ip dns static get $dnsnode address ]; + + :local leases [ / ip dhcp-server lease find where host-name=$hostname dynamic=yes ]; + :local hostnamecount [ :len [ / ip dhcp-server lease find where host-name=$hostname dynamic=yes ] ]; + :if ( $hostnamecount > 1) do={ + :foreach j,lease in=$leases do={ + :if ($j + 1 = $hostnamecount) do={ + :set dhcpip [ / ip dhcp-server lease get $lease address ]; + } + } + } + + :if ( $dnsip = $dhcpip ) do={ + :log debug ("DNS entry for " . $fqdn . " does not need updating."); + } else={ + :log info ("Replacing DNS entry for " . $fqdn . ", new address is " . $dhcpip . "."); + / ip dns static set name=$fqdn address=$dhcpip ttl=$ttl comment=$comment $dnsnode; + } + } else={ + :log info ("Adding new DNS entry for " . $fqdn . ", address is " . $dhcpip . "."); + / ip dns static add name=$fqdn address=$dhcpip ttl=$ttl comment=$comment; + } + } +} diff --git a/email-backup b/email-backup new file mode 100644 index 0000000..1c05ff1 --- /dev/null +++ b/email-backup @@ -0,0 +1,51 @@ +# RouterOS script: email-backup +# Copyright (c) 2013-2018 Christian Hesse +# +# create and email backup and config file + +:global "identity"; +:global "domain"; +:global "email-backup-to"; +:global "email-backup-cc"; +:global "backup-send-binary"; +:global "backup-send-export"; +:global "backup-password"; + +# filename based on identity +:local filename ($identity . "." . $domain); + +# get some system information +:local model [ / system routerboard get model ]; +:local serialnumber [ / system routerboard get serial-number ]; +:local channel [ / system package update get channel ]; +:local installedversion [ / system package update get installed-version ]; + +# create and email binary backup +:if ($"backup-send-binary" = true) do={ + / system backup save name=$filename password=$"backup-password"; + / delay delay-time=10; + / tool e-mail send to=$"email-backup-to" cc=$"email-backup-cc" \ + subject=("[" . $identity . "] Backup") \ + body=("Backup file for " . $identity . " is attached.\n\n" . \ + "Routerboard: " . $model . "\n" . \ + "Serial number: " . $serialnumber . "\n" . \ + "Hostname: " . $identity . "\n" . \ + "Channel: " . $channel . "\n" . \ + "RouterOS: " . $installedversion) \ + file=($filename . ".backup"); +} + +# create and email configuration export +:if ($"backup-send-export"= true) do={ + / export file=$filename; + / delay delay-time=10; + / tool e-mail send to=$"email-backup-to" cc=$"email-backup-cc" \ + subject=("[" . $identity . "] Config") \ + body=("Config file for " . $identity . " is attached.\n\n" . \ + "Routerboard: " . $model . "\n" . \ + "Serial number: " . $serialnumber . "\n" . \ + "Hostname: " . $identity . "\n" . \ + "Channel: " . $channel . "\n" . \ + "RouterOS: " . $installedversion) \ + file=($filename . ".rsc"); +} diff --git a/email-daily-psk b/email-daily-psk new file mode 100644 index 0000000..af991ca --- /dev/null +++ b/email-daily-psk @@ -0,0 +1,47 @@ +# RouterOS script: email-daily-psk +# Copyright (c) 2013-2018 Christian Hesse +# +# email daily PSK (pre shared key) + +:global "identity"; +:global "email-general-to"; +:global "email-general-cc"; +:global "daily-psk-match-comment"; + +:local "seen-ssids" { "" }; + +:foreach acclist in=[ / interface wireless access-list find where comment~$"daily-psk-match-comment" ] do={ + :local interface [ / interface wireless access-list get $acclist interface ]; + :local ssid [ / interface wireless get $interface ssid ]; + :local psk [ / interface wireless access-list get $acclist private-pre-shared-key ]; + + :local seen 0; + :foreach "seen-ssid" in=$"seen-ssids" do={ + :if ($"seen-ssid" = $ssid) do={ + :set seen 1; + } + } + + :if ($seen = 0) do={ + :set $"seen-ssids" { $"seen-ssids"; $ssid }; + + :local host "www.eworm.de" + :local srcpath ("/cgi-bin/cqrlogo-wifi.cgi" . \ + "?scale=8" . \ + "&level=1" . \ + "&ssid=" . $ssid . \ + "&pass=" . $psk); + + / tool fetch mode=https check-certificate=yes-without-crl address=$host host=$host \ + src-path=$srcpath dst-path=qrcode-daily.png; + + / tool e-mail send to=$"email-general-to" cc=$"email-general-cc" \ + subject=("[" . $identity . "] daily PSK " . $ssid) \ + body=("This is the daily PSK on " . $identity . ":\n\n" . \ + "SSID: " . $ssid . "\n" . \ + "PSK: " . $psk . "\n" . \ + "Date: " . [ / system clock get date ] . "\n\n" . \ + "https://" . $host . $srcpath) \ + file=qrcode-daily.png; + } +} diff --git a/ethernet-to-default b/ethernet-to-default new file mode 100644 index 0000000..ed86cc7 --- /dev/null +++ b/ethernet-to-default @@ -0,0 +1,17 @@ +# RouterOS script: ethernet-to-default +# Copyright (c) 2013-2018 Christian Hesse +# +# reset ethernet interfaces to default bridge + +:foreach interface in=[ / interface bridge port find where comment~"^default:" ] do={ + :local comment [ / interface bridge port get $interface comment ]; + :local "interface-name" [ / interface bridge port get $interface interface ]; + :local "bridge-default" [ :pick $comment 8 [ :len $comment ] ]; + :local "bridge-current" [ / interface bridge port get $interface bridge ]; + :if ($"bridge-default" != $"bridge-current") do={ + :log info ("Reverting interface " . $"interface-name" . " to default bridge " . $"bridge-default"); + / interface bridge port set bridge=$"bridge-default" $interface; + } else={ + :log debug ("Interface " . $"interface-name" . " already connected to default bridge " $"bridge-default"); + } +} diff --git a/forward-sms b/forward-sms new file mode 100644 index 0000000..f2d03fe --- /dev/null +++ b/forward-sms @@ -0,0 +1,29 @@ +# RouterOS script: forward-sms +# Copyright (c) 2013-2018 Christian Hesse +# +# forward SMS to e-mail + +:global "identity"; +:global "email-general-to"; +:global "email-general-cc"; + +# check mail server +:if ([ / tool netwatch get [ find where comment=[ / tool e-mail get address ] ] status ] != "up" ) do={ + :error "Mail server is not up."; +} + +# forward SMS in a loop +:foreach sms in=[ / tool sms inbox find ] do={ + :local message [ / tool sms inbox get $sms message ]; + :local phone [ / tool sms inbox get $sms phone ]; + :local timestamp [ / tool sms inbox get $sms timestamp ]; + :local type [ / tool sms inbox get $sms type ]; + / tool e-mail send to=$"email-general-to" cc=$"email-general-cc" \ + subject=("[" . $identity . "] SMS Forwarding") \ + body=("A message was received by " . $identity . ":\n\n" . \ + "Phone: " . $phone . "\n" . \ + "Timestamp: " . $timestamp . "\n" . \ + "Type: " . $type . "\n\n" . \ + "Message:\n" . $message); + / tool sms inbox remove $sms; +} diff --git a/global-config b/global-config new file mode 100644 index 0000000..534df40 --- /dev/null +++ b/global-config @@ -0,0 +1,42 @@ +# RouterOS script: global-config +# Copyright (c) 2013-2018 Christian Hesse +# +# global configuration + +# This is used for DNS and backup file. +:global "domain" "example.com"; +:global "hostname-in-zone" true; + +# These addresses are used to send e-mails to. The to-addresses need +# to be filled, cc-addresses can be empty, one address or a comma +# separated list of addresses. +:global "email-general-to" "mail@example.com"; +:global "email-general-cc" "another@example.com"; +:global "email-backup-to" "mail@example.com"; +:global "email-backup-cc" ""; + +# This defines what backups to generate and what password to use. +:global "backup-send-binary" false; +:global "backup-send-export" true; +:global "backup-password" "v3ry-s3cr3t"; + +# This is used to update AAAA records and firewall address-list. +:global "ipv6-interface" "br-local"; +:global "ipv6-pool" "telekom"; + +# These settings are used to update gre interface settings based on +# remote peer configuration. +:global "gre-cert-prefix" "ikev2-"; +:global "gre-int-prefix" "gre-"; + +# Access-list entries matching this comment are updated with daily +# pseudo-random PSK. +:global "daily-psk-match-comment" "Daily PSK"; + +# This address should resolve ntp servers and is used to update +# ntp settings. A pool can rotate servers. +:global "ntp-pool" "pool.ntp.org"; + +# Do *NOT* change these! +:global "sent-routeros-update-notification" false; +:global "identity" [ / system identity get name ]; diff --git a/ipv6-update b/ipv6-update new file mode 100644 index 0000000..b434e05 --- /dev/null +++ b/ipv6-update @@ -0,0 +1,38 @@ +# RouterOS script: ipv6-update +# Copyright (c) 2013-2018 Christian Hesse +# +# update firewall and dns settings on IPv6 prefix change + +:global "ipv6-interface"; +:global "ipv6-pool"; + +:local addrlist [ / ipv6 firewall address-list find where comment=("ipv6-pool-" . $"ipv6-pool") ]; +:local oldprefix [ / ipv6 firewall address-list get $addrlist address ]; + +# give the interfaces a moment to receive their addresses +:delay 2s; + +if ($oldprefix != $"pd-prefix") do={ + :log info ("Updating ipv6 address list with new IPv6 prefix " . $"pd-prefix"); + / ipv6 firewall address-list set address=$"pd-prefix" $addrlist; + + :local oldprefix56 [ :pick $oldprefix 0 [ :find $oldprefix "00::/56" ] ]; + :local oldprefix64 [ :pick $oldprefix 0 [ :find $oldprefix "::/56" ] ]; + + :local newprefix [ / ipv6 address get [ / ipv6 address find where from-pool=$"ipv6-pool" interface=$"ipv6-interface" ] address ]; + :local newprefix64 [ :pick $newprefix 0 [ :find $newprefix "::/64" ] ]; + + :foreach record in=[ / ip dns static find where address~$oldprefix56 ] do={ + :local address [ / ip dns static get $record address ]; + :local name [ / ip dns static get $record name ]; + + :if ( [ :len $name ] = 0) do={ + :set name [ / ip dns static get $record regex ]; + } + + :local suffix [ :pick $address [ :len $oldprefix64 ] [ :len $address ] ]; + + :log info ("Updating dns record for " . $name . ": " . $address . " -> " . $newprefix64 . $suffix); + / ip dns static set address=($newprefix64 . $suffix) $record; + } +} diff --git a/learn-mac-based-vlan b/learn-mac-based-vlan new file mode 100644 index 0000000..34f7e09 --- /dev/null +++ b/learn-mac-based-vlan @@ -0,0 +1,12 @@ +# RouterOS script: learn-mac-based-vlan +# Copyright (c) 2013-2018 Christian Hesse +# +# learn MAC address for MAC-based-VLAN + +:local NewVlanId 33; + +/ log info ("MAC-based-VLAN: learning MAC address " . $leaseActMAC . " for VLAN " . $NewVlanId . "."); + +:if ( [ :len [ / interface ethernet switch mac-based-vlan find where src-mac-address=$leaseActMAC ] ] = 0 ) do={ + / interface ethernet switch mac-based-vlan add src-mac-address=$leaseActMAC new-customer-vid=$NewVlanId; +}; diff --git a/lease-script b/lease-script new file mode 100644 index 0000000..b80b89b --- /dev/null +++ b/lease-script @@ -0,0 +1,17 @@ +# RouterOS script: lease-script +# Copyright (c) 2013-2018 Christian Hesse +# +# run scripts on DHCP lease +# ( / ip dhcp-server set lease-script=lease-script [ find ] ) + +:local scripts { "dhcp-to-dns"; "collect-wireless-mac"; "dhcp-lease-comment" }; + +# delay a second to give time to update the lease table +:delay 1s; + +:foreach script in=$scripts do={ + :if ([ :len [ / system script find where name=$script ] ] > 0) do={ + :log debug ("Running script from lease-script: " . $script); + / system script run $script; + } +} diff --git a/leds-day-mode b/leds-day-mode new file mode 100644 index 0000000..4eba7b1 --- /dev/null +++ b/leds-day-mode @@ -0,0 +1,6 @@ +# RouterOS script: leds-day-mode +# Copyright (c) 2013-2018 Christian Hesse +# +# enable LEDs + +/ system leds settings set all-leds-off=never; diff --git a/leds-night-mode b/leds-night-mode new file mode 100644 index 0000000..5941419 --- /dev/null +++ b/leds-night-mode @@ -0,0 +1,6 @@ +# RouterOS script: leds-night-mode +# Copyright (c) 2013-2018 Christian Hesse +# +# disable LEDs + +/ system leds settings set all-leds-off=immediate; diff --git a/manage-umts b/manage-umts new file mode 100644 index 0000000..d9e5a0b --- /dev/null +++ b/manage-umts @@ -0,0 +1,26 @@ +# RouterOS script: manage-umts +# Copyright (c) 2013-2018 Christian Hesse +# +# manage UMTS interface based on ethernet and wireless status + +:local etherint "en1"; +:local wlanint "wl-station"; +:local umtsint "t-mobile"; + +:local etherstatus [ / interface ethernet get $etherint running ]; +:local wlanstatus [ / interface wireless get $wlanint running ]; + +:if ( $etherstatus = true || wlanstatus = true ) do={ + :if ( [ / interface get $umtsint disabled ] = false ) do={ + :log info ("Ethernet (" . $etherint . " / " . $etherstatus . ") or " . \ + "wireless (" . $wlanint . " / " . $wlanstatus . ") is running, " . \ + "UMTS interface " . $umtsint . " is enabled. Disabling..."); + / interface set disabled=yes $umtsint; + }; +} else={ + :if ( [ / interface get $umtsint disabled ] = true ) do={ + :log info ("Neither ethernet (" . $etherint . ") nor wireless (" . $wlanint . ") interface is running, " . \ + "UMTS interface " . $umtsint . " is disabled. Enabling..."); + / interface set disabled=no $umtsint; + }; +}; diff --git a/netwatch-syslog b/netwatch-syslog new file mode 100644 index 0000000..56e59ea --- /dev/null +++ b/netwatch-syslog @@ -0,0 +1,14 @@ +# RouterOS script: netwatch-syslog +# Copyright (c) 2013-2018 Christian Hesse +# +# manage remote logging facilities + +:local remote [ /system logging action get [ :pick [ find where target=remote ] 0 ] remote ]; + +if ([ / tool netwatch get [ find where host=$remote ] status ] = "up") do={ + / system logging set disabled=no [ find where action=remote disabled=yes ]; +} else={ + / system logging set disabled=yes [ find where action=remote disabled=no ]; +} + +/ system scheduler set disabled=yes [ find where name=netwatch-syslog disabled=no ]; diff --git a/ppp-on-up b/ppp-on-up new file mode 100644 index 0000000..7940f2a --- /dev/null +++ b/ppp-on-up @@ -0,0 +1,13 @@ +# RouterOS script: ppp-on-up +# Copyright (c) 2013-2018 Christian Hesse +# +# run scripts on ppp up + +# variable $interface is available in ppp on-up script +:local dhcpclient [ / ipv6 dhcp-client find where interface=$interface ]; + +:if ( [ :len $dhcpclient ] > 0) do={ + / ipv6 dhcp-client disable $dhcpclient; + :delay 1s; + / ipv6 dhcp-client enable $dhcpclient; +} diff --git a/remove-packages b/remove-packages new file mode 100644 index 0000000..a3bb2a0 --- /dev/null +++ b/remove-packages @@ -0,0 +1,6 @@ +# RouterOS script: remove-packages +# Copyright (c) 2013-2018 Christian Hesse +# +# remove packages (*.npk) from storage + +/ file remove [ / file find type="package" ]; diff --git a/rotate-ntp b/rotate-ntp new file mode 100644 index 0000000..07672fb --- /dev/null +++ b/rotate-ntp @@ -0,0 +1,12 @@ +# RouterOS script: rotate-ntp +# Copyright (c) 2013-2018 Christian Hesse +# +# rotate the ntp servers + +:global "ntp-pool"; + +:local ntp1 [ :resolve ("0." . $"ntp-pool") ]; +:local ntp2 [ :resolve ("1." . $"ntp-pool") ]; + +:log info ("Updating NTP servers to " . $ntp1 . " and " . $ntp2); +/ system ntp client set primary-ntp=$ntp1 secondary-ntp=$ntp2; diff --git a/script-updates b/script-updates new file mode 100644 index 0000000..13480d1 --- /dev/null +++ b/script-updates @@ -0,0 +1,17 @@ +# RouterOS script: script-updates +# Copyright (c) 2013-2018 Christian Hesse +# +# update installed scripts from file + +:foreach script in=[ / system script find ] do={ + :local scriptname [ / system script get $script name ]; + :local scriptfile [ / file find where name=("script-updates/" . $scriptname) ]; + :if ([ :len $scriptfile ] > 0) do={ + :log info ("Updating script: " . $scriptname); + :local scriptcontent [ / file get $scriptfile content ]; + / system script set owner=$scriptname source=$scriptcontent $script; + / file remove $scriptfile; + } else={ + :log debug ("No update for script " . $scriptname); + } +} diff --git a/script2script b/script2script new file mode 100644 index 0000000..dc4c5d8 --- /dev/null +++ b/script2script @@ -0,0 +1,6 @@ +# RouterOS script: script2script +# Copyright (c) 2013-2018 Christian Hesse +# +# change owner to "script" + +/ system script set owner=script [ find where owner!="script" ]; diff --git a/ssh-keys-import b/ssh-keys-import new file mode 100644 index 0000000..56ba6a4 --- /dev/null +++ b/ssh-keys-import @@ -0,0 +1,10 @@ +# RouterOS script: ssh-keys-import +# Copyright (c) 2013-2018 Christian Hesse +# +# import ssh keys from file + +# Split files with several keys from a shell... +# while read type key name; do echo $type $key $name > $name.pub; done < keys.pub +# ... then transfer with scp/sftp. + +:foreach key in=[ / file find where type="ssh key" ] do={ / user ssh-key import user=admin public-key-file=[ / file get $key name ]; } diff --git a/super-mario-theme b/super-mario-theme new file mode 100644 index 0000000..d1eda3f --- /dev/null +++ b/super-mario-theme @@ -0,0 +1,66 @@ +# RouterOS script: super-mario-theme +# Copyright (c) 2013-2018 Christian Hesse +# +# play Super Mario theme + +:local beeps { + { 660; 100 }; 150; { 660; 100 }; 300; { 660; 100 }; 300; + { 510; 100 }; 100; { 660; 100 }; 300; { 770; 100 }; 550; + { 380; 100 }; 575; { 510; 100 }; 450; { 380; 100 }; 400; + { 320; 100 }; 500; { 440; 100 }; 300; { 480; 80 }; 330; + { 450; 100 }; 150; { 430; 100 }; 300; { 380; 100 }; 200; + { 660; 80 }; 200; { 760; 50 }; 150; { 860; 100 }; 300; + { 700; 80 }; 150; { 760; 50 }; 350; { 660; 80 }; 300; + { 520; 80 }; 150; { 580; 80 }; 150; { 480; 80 }; 500; + { 510; 100 }; 450; { 380; 100 }; 400; { 320; 100 }; 500; + { 440; 100 }; 300; { 480; 80 }; 330; { 450; 100 }; 150; + { 430; 100 }; 300; { 380; 100 }; 200; { 660; 80 }; 200; + { 760; 50 }; 150; { 860; 100 }; 300; { 700; 80 }; 150; + { 760; 50 }; 350; { 660; 80 }; 300; { 520; 80 }; 150; + { 580; 80 }; 150; { 480; 80 }; 500; { 500; 100 }; 300; + { 760; 100 }; 100; { 720; 100 }; 150; { 680; 100 }; 150; + { 620; 150 }; 300; { 650; 150 }; 300; { 380; 100 }; 150; + { 430; 100 }; 150; { 500; 100 }; 300; { 430; 100 }; 150; + { 500; 100 }; 100; { 570; 100 }; 220; { 500; 100 }; 300; + { 760; 100 }; 100; { 720; 100 }; 150; { 680; 100 }; 150; + { 620; 150 }; 300; { 650; 200 }; 300; { 1020; 80 }; 300; + { 1020; 80 }; 150; { 1020; 80 }; 300; { 380; 100 }; 300; + { 500; 100 }; 300; { 760; 100 }; 100; { 720; 100 }; 150; + { 680; 100 }; 150; { 620; 150 }; 300; { 650; 150 }; 300; + { 380; 100 }; 150; { 430; 100 }; 150; { 500; 100 }; 300; + { 430; 100 }; 150; { 500; 100 }; 100; { 570; 100 }; 420; + { 585; 100 }; 450; { 550; 100 }; 420; { 500; 100 }; 360; + { 380; 100 }; 300; { 500; 100 }; 300; { 500; 100 }; 150; + { 500; 100 }; 300; { 500; 100 }; 300; { 760; 100 }; 100; + { 720; 100 }; 150; { 680; 100 }; 150; { 620; 150 }; 300; + { 650; 150 }; 300; { 380; 100 }; 150; { 430; 100 }; 150; + { 500; 100 }; 300; { 430; 100 }; 150; { 500; 100 }; 100; + { 570; 100 }; 220; { 500; 100 }; 300; { 760; 100 }; 100; + { 720; 100 }; 150; { 680; 100 }; 150; { 620; 150 }; 300; + { 650; 200 }; 300; { 1020; 80 }; 300; { 1020; 80 }; 150; + { 1020; 80 }; 300; { 380; 100 }; 300; { 500; 100 }; 300; + { 760; 100 }; 100; { 720; 100 }; 150; { 680; 100 }; 150; + { 620; 150 }; 300; { 650; 150 }; 300; { 380; 100 }; 150; + { 430; 100 }; 150; { 500; 100 }; 300; { 430; 100 }; 150; + { 500; 100 }; 100; { 570; 100 }; 420; { 585; 100 }; 450; + { 550; 100 }; 420; { 500; 100 }; 360; { 380; 100 }; 300; + { 500; 100 }; 300; { 500; 100 }; 150; { 500; 100 }; 300; + { 500; 60 }; 150; { 500; 80 }; 300; { 500; 60 }; 350; + { 500; 80 }; 150; { 580; 80 }; 350; { 660; 80 }; 150; + { 500; 80 }; 300; { 430; 80 }; 150; { 380; 80 }; 600; + { 500; 60 }; 150; { 500; 80 }; 300; { 500; 60 }; 350; + { 500; 80 }; 150; { 580; 80 }; 150; { 660; 80 }; 550; + { 870; 80 }; 325; { 760; 80 }; 600; { 500; 60 }; 150; + { 500; 80 }; 300; { 500; 60 }; 350; { 500; 80 }; 150; + { 580; 80 }; 350; { 660; 80 }; 150; { 500; 80 }; 300; + { 430; 80 }; 150; { 380; 80 }; 600; { 660; 100 }; 150; + { 660; 100 }; 300; { 660; 100 }; 300; { 510; 100 }; 100; + { 660; 100 }; 300; { 770; 100 }; 550; { 380; 100 }; 575 }; + +:foreach beep in=$beeps do={ + :if ([ :len $beep ] = 2) do={ + :beep frequency=[ :pick $beep 0 ] length=([ :pick $beep 1 ] . "ms"); + } else={ + :delay ($beep . "ms"); + } +} diff --git a/update-gre-address b/update-gre-address new file mode 100644 index 0000000..ea55a9b --- /dev/null +++ b/update-gre-address @@ -0,0 +1,30 @@ +# RouterOS script: update-gre-address +# Copyright (c) 2013-2018 Christian Hesse +# +# update gre interface remote address with dynamic address from +# ipsec remote peer + +:global "gre-cert-prefix"; +:global "gre-int-prefix"; + +/ interface gre set remote-address=0.0.0.0 disabled=yes [ find where !running !disabled ]; + +:foreach peer in=[ / ip ipsec remote-peers find ] do={ + :local id [ / ip ipsec remote-peers get $peer id ]; + + :if ([ :pick $id 0 [ :len $"gre-cert-prefix" ] ] = $"gre-cert-prefix") do={ + :local name [ :pick $id [ :len $"gre-cert-prefix" ] [ :len $id ] ]; + :local addrnew [ / ip ipsec remote-peers get $peer dynamic-address ]; + :local grename ($"gre-int-prefix" . $name); + :local greint [ / interface gre find where name=$grename ]; + :if ([ :len $greint ] > 0) do={ + :local addrold [ / interface gre get $greint remote-address ]; + :local disabled [ / interface gre get $greint disabled ]; + :if ($addrnew != $addrold || $disabled = true) do={ + :log info ("Update remote address for interface " . $grename . " to " . $addrnew); + / interface gre set remote-address=0.0.0.0 disabled=yes [ find where remote-address=$addrnew name!=$grename ]; + / interface gre set $greint remote-address=$addrnew disabled=no; + } + } + } +} diff --git a/update-tunnelbroker b/update-tunnelbroker new file mode 100644 index 0000000..cce2c0c --- /dev/null +++ b/update-tunnelbroker @@ -0,0 +1,30 @@ +# RouterOS script: update-tunnelbroker +# Copyright (c) 2013-2018 Christian Hesse + +:local tunnelurl "ipv4.tunnelbroker.net"; +:local tunneluser "user"; +:local tunnelpass "v3ry-s3cr3t"; +:local tunnelid "user-XXX.tunnel.tserv6.fra1.ipv6.he.net"; + +# name of the local tunnel interface +:local tunnelint "tunnelbroker"; + +# get the last ip address from tunnel interface +:local tunnellastip [ / interface 6to4 get [ / interface 6to4 find where name=$tunnelint ] local-address ]; + +# Get the current ip address on interface with default route +:local tunnelip [ / ip route get [ / ip route find where gateway=[ / ip route get [ / ip route find where dynamic=yes and dst-address="0.0.0.0/0" dynamic active=yes ] gateway ] dst-address!="0.0.0.0/0" ] pref-src ]; + +# Did we get an IP address to compare? +:if ([ :typeof $tunnelip ] = nil) do={ + :log warning ("No default route? Could not get address, please check."); +} else={ + :if ($tunnelip != $tunnellastip) do={ + :log info ("Local address changed, sending UPDATE to tunnelbroker! New address: " . $tunnelip); + / tool fetch mode=https address=$tunnelurl user=$tunneluser password=$tunnelpass \ + src-path=("/nic/update\?hostname=" . $tunnelid) keep-result=no; + / interface 6to4 set [ / interface 6to4 find where name=$tunnelint ] local-address=$tunnelip; + } else={ + :log debug "All tunnelbroker configuration is up to date."; + } +} -- cgit v1.2.3-54-g00ecf