Page 1 of 1

Generating temporary accounts on MikroTik RouterOS

Posted: Tue Oct 05, 2021 4:45 pm
by Tomas
This script can be used to generate a temporary management account on RouterOS devices, which will self destruct in a specific number of days. This can be useful if you need to give temporary access to your device(s) for a pre-defined time period, without needing to worry about forgetting to remove that access later.

The name for the account is pre-configured, and if the account already exists, it is not changed in any way. There are 2 options - generating the account with a pre-defined password, or generating random passwords on each device. Account will be automatically deleted after a specified period.

This script only needs to be deployed once, account deletion is performed by the device itself. If a randomly generated password is used, each device will output the password that was generated, and you will see an Output Group in Unimus Config Push per-device, with it's associated password.

1) pre-configured password

Code: Select all

{
:local username "set-username-here"
:local password "set-password-here"
:local group "read"
:local validForDays "3"

# --- do not change after this point ---

# date manipulation from https://forum.mikrotik.com/viewtopic.php?f=9&t=127294
:local addDate do={
  :local mdays  {31;28;31;30;31;30;31;31;30;31;30;31}
  :local months {"jan"=1;"feb"=2;"mar"=3;"apr"=4;"may"=5;"jun"=6;"jul"=7;"aug"=8;"sep"=9;"oct"=10;"nov"=11;"dec"=12}
  :local monthr  {"jan";"feb";"mar";"apr";"may";"jun";"jul";"aug";"sep";"oct";"nov";"dec"}
  
  :local dd  [:tonum [:pick $date 4 6]]
  :local yy [:tonum [:pick $date 7 11]]
  :local month [:pick $date 0 3]
  
  :local mm ($months->$month)
  :set dd ($dd+$days)
  #:put $dd
  
  :local dm [:pick $mdays ($mm-1)]
  :if ($mm=2 && (($yy&3=0 && $yy/100*100 != $yy) || $yy/400*400=$yy) ) do={ :set dm 29 }
  
  :while ($dd>$dm) do={
    :set dd ($dd-$dm)
    :set mm ($mm+1)
    :if ($mm>12) do={
      :set mm 1
      :set yy ($yy+1)
    }
   :set dm [:pick $mdays ($mm-1)]
   :if ($mm=2 &&  (($yy&3=0 && $yy/100*100 != $yy) || $yy/400*400=$yy) ) do={ :set dm 29 }
  };
  
  :while ($dd<=0) do={
   :set mm ($mm-1)
    :if ($mm=0) do={
      :set mm 12
      :set yy ($yy-1)
    }
   :set dm [:pick $mdays ($mm-1)]
   :if ($mm=2 &&  (($yy&3=0 && $yy/100*100 != $yy) || $yy/400*400=$yy) ) do={ :set dm 29 }
   :set dd ($dd+$dm)
  };
  
  :local res "$[:pick $monthr ($mm-1)]/"
  :if ($dd<10) do={ :set res ($res."0") }
  :set $res "$res$dd/$yy"
  :return $res
}

:if ([:len [/user find name=$username]] = 0) do={
  :local deletionDate [$addDate date=[/system clock get date] days=$validForDays]

  /user
  add name="$username" password="$password" group="$group"

  /system scheduler
  add name="Delete account '$username' on $deletionDate" start-date="$deletionDate" start-time=[/system clock get time] on-event="{ /user remove [find name=\"$username\"]; /system scheduler remove [find name=\"Delete account '$username' on $deletionDate\"] }"
}
}
2) randomly generated password

Code: Select all

{
:local username "set-username-here"
:local group "read"
:local validForDays "3"

# --- do not change after this point ---

# date manipulation from https://forum.mikrotik.com/viewtopic.php?f=9&t=127294
:local addDate do={
  :local mdays  {31;28;31;30;31;30;31;31;30;31;30;31}
  :local months {"jan"=1;"feb"=2;"mar"=3;"apr"=4;"may"=5;"jun"=6;"jul"=7;"aug"=8;"sep"=9;"oct"=10;"nov"=11;"dec"=12}
  :local monthr  {"jan";"feb";"mar";"apr";"may";"jun";"jul";"aug";"sep";"oct";"nov";"dec"}
  
  :local dd  [:tonum [:pick $date 4 6]]
  :local yy [:tonum [:pick $date 7 11]]
  :local month [:pick $date 0 3]
  
  :local mm ($months->$month)
  :set dd ($dd+$days)
  #:put $dd
  
  :local dm [:pick $mdays ($mm-1)]
  :if ($mm=2 && (($yy&3=0 && $yy/100*100 != $yy) || $yy/400*400=$yy) ) do={ :set dm 29 }
  
  :while ($dd>$dm) do={
    :set dd ($dd-$dm)
    :set mm ($mm+1)
    :if ($mm>12) do={
      :set mm 1
      :set yy ($yy+1)
    }
   :set dm [:pick $mdays ($mm-1)]
   :if ($mm=2 &&  (($yy&3=0 && $yy/100*100 != $yy) || $yy/400*400=$yy) ) do={ :set dm 29 }
  };
  
  :while ($dd<=0) do={
   :set mm ($mm-1)
    :if ($mm=0) do={
      :set mm 12
      :set yy ($yy-1)
    }
   :set dm [:pick $mdays ($mm-1)]
   :if ($mm=2 &&  (($yy&3=0 && $yy/100*100 != $yy) || $yy/400*400=$yy) ) do={ :set dm 29 }
   :set dd ($dd+$dm)
  };
  
  :local res "$[:pick $monthr ($mm-1)]/"
  :if ($dd<10) do={ :set res ($res."0") }
  :set $res "$res$dd/$yy"
  :return $res
}

:if ([:len [/user find name=$username]] = 0) do={
  :local deletionDate [$addDate date=[/system clock get date] days=$validForDays]
  # RouterOS will automatically clean up the generated OTP, since it has 0 validity
  :local generatedPassword ([/certificate scep-server otp generate minutes-valid=0 as-value]->"password")

  /user
  add name="$username" password="$generatedPassword" group="$group"
  :put "---"
  :put "Created user '$username' with password '$generatedPassword'"
  :put "---"

  /system scheduler
  add name="Delete account '$username' on $deletionDate" start-date="$deletionDate" start-time=[/system clock get time] on-event="{ /user remove [find name=\"$username\"]; /system scheduler remove [find name=\"Delete account '$username' on $deletionDate\"] }"
}
}