Skip to content

User Management: Password Policy, Service Hardening, and 2FA

User Management: Password Policy, Service Hardening, and 2FA

Section titled “User Management: Password Policy, Service Hardening, and 2FA”

Three complementary controls harden management access on RouterOS:

  • Password policy — enforce minimum length and complexity for local user accounts
  • Service restrictions — disable or restrict management protocols by source address
  • Two-factor authentication — require TOTP alongside password for router logins

These controls layer on top of the user groups and RADIUS AAA configuration covered in User Management: AAA, Groups, and RADIUS.

  • RouterOS v7
  • For TOTP: User Manager package installed and a RADIUS/AAA configuration in place

RouterOS enforces password requirements for local /user accounts via /user settings.

# Require minimum 12-character passwords with mixed character categories
/user settings set minimum-password-length=12 password-complexity=yes minimum-categories=3
PropertyValuesDefaultDescription
minimum-password-length0–10240Minimum required character count
password-complexityno | yes | zxcvbnnoComplexity enforcement mode
minimum-categories1–41Minimum character categories required (with complexity=yes)

Character categories used by complexity=yes:

  • Lowercase letters (a–z)
  • Uppercase letters (A–Z)
  • Digits (0–9)
  • Symbols (!@#$%^&* etc.)

With minimum-categories=3, a password must draw from at least 3 of the 4 categories. Setting minimum-categories=4 requires all four.

password-complexity=zxcvbn uses entropy-based estimation instead of categorical rules — passwords that are long but predictable (e.g. Password1!) are still rejected if the algorithm scores them as weak.

RouterOS exposes management interfaces via /ip service. By default, multiple protocols are enabled — disable any that are not in active use, and restrict the rest by source address.

/ip service print
ServiceDefault PortProtocol
telnet23Telnet (cleartext)
ftp21FTP (cleartext)
www80WebFig (HTTP, cleartext)
ssh22SSH
www-ssl443WebFig (HTTPS)
api8728RouterOS API (cleartext)
winbox8291WinBox
api-ssl8729RouterOS API (TLS)

Disable cleartext management protocols in production:

# Disable cleartext protocols not in use
/ip service disable telnet,ftp,www,api
# Verify remaining enabled services
/ip service print where disabled=no

Confirm SSH or WinBox access is working before disabling services. Disabling all remote management services locks you out of the router.

Limit services to known management networks:

# Restrict SSH and WinBox to the management VLAN
/ip service set ssh address=10.0.10.0/24
/ip service set winbox address=10.0.10.0/24
/ip service set api-ssl address=10.0.10.0/24

The address field accepts a comma-separated list of prefixes:

/ip service set ssh address=10.0.10.0/24,192.168.88.0/24

Leave address empty to allow connections from any source.

Moving services away from standard ports reduces automated scanner noise:

/ip service set ssh port=22222
/ip service set winbox port=18291

For automation, provisioning, and monitoring systems, create accounts scoped to exactly the API permissions required rather than reusing admin credentials.

# Read-only: monitoring and config export
/user/group/add name=api-readonly \
policy=api,rest-api,read,test,!write,!policy,!sensitive,!ftp,!winbox,!web,!ssh,!local,!telnet,!romon,!reboot,!sniff,!password
# Read-write: provisioning and configuration management
/user/group/add name=api-readwrite \
policy=api,rest-api,read,write,reboot,test,!policy,!sensitive,!ftp,!winbox,!web,!ssh,!local,!telnet,!romon,!sniff
# Monitoring system — read-only, locked to one source host
/user add name=zabbix-api group=api-readonly \
password="<GENERATED_PASSWORD>" \
address=10.0.10.50/32 \
comment="Zabbix monitoring exporter"
# Automation system — read-write, locked to CI/CD host
/user add name=ansible group=api-readwrite \
password="<GENERATED_PASSWORD>" \
address=10.0.10.60/32 \
comment="Ansible provisioning"

Key practices for API accounts:

  • Use a unique, generated password per account (not a typed password)
  • Lock each account to the specific source IP with address=
  • Grant only the policy flags actually needed — exclude sensitive unless required
  • Prefer api-ssl (TLS) over plaintext api if the client supports it

RouterOS supports TOTP-based 2FA for router management logins via User Manager, which acts as a RADIUS backend that handles OTP verification before granting access.

Login attempt (SSH / WinBox / WebFig)
RouterOS AAA — username not in local /user
RADIUS query to User Manager
User Manager validates password + TOTP token
├── VALID → Access granted, group applied from Mikrotik-Group RADIUS attribute
└── INVALID → Login denied

TOTP is configured on User Manager users, not on local /user accounts. The User Manager RADIUS integration handles OTP verification before replying to RouterOS.

# Verify User Manager package is installed
/user-manager print
# Verify RADIUS AAA is configured
/user aaa print
/radius print

If User Manager or RADIUS is not configured, see User Management: AAA, Groups, and RADIUS first.

Configuring TOTP on a User Manager Account

Section titled “Configuring TOTP on a User Manager Account”
# Add a user with TOTP enabled
/user-manager user add name=alice password="StrongPass!" otp-secret=JBSWY3DPEHPK3PXP
# View the user entry
/user-manager user print detail where name=alice

The otp-secret is a Base32-encoded shared secret. It must be imported into the user’s authenticator app (Google Authenticator, Authy, 1Password, etc.) to generate codes.

  1. Open the User Manager web interface and view the user entry — a QR code is shown.
  2. Scan the QR code in your TOTP app, or manually enter the Base32 secret.
  3. Verify the app is generating the correct codes before logging out.

At the login prompt, append the 6-digit TOTP code directly to the password with no separator:

Username: alice
Password: StrongPass!123456
─────────────────
password + current TOTP token (no space)

Keep a break-glass local admin account (/user add name=emergency group=full ...) that bypasses RADIUS. RADIUS users cannot log in if the User Manager is unreachable, and a network misconfiguration could lock out all RADIUS-authenticated users simultaneously.

Generate a cryptographically random Base32 secret compatible with RFC 6238:

Terminal window
python3 -c "import base64, os; print(base64.b32encode(os.urandom(20)).decode())"

The TOTP secret is a root credential. Store it in a password manager, never commit it to version control, and do not log it in scripts or automation output.

# Enforce strong passwords
/user settings set minimum-password-length=12 password-complexity=yes minimum-categories=3
# Disable cleartext management protocols
/ip service disable telnet,ftp,www,api
# Restrict remaining services to management subnet
/ip service set ssh address=10.0.10.0/24
/ip service set winbox address=10.0.10.0/24
/ip service set api-ssl address=10.0.10.0/24
/ip service set www-ssl address=10.0.10.0/24
# Minimal read-only group — API and REST access only, no SSH/WinBox/console
/user/group/add name=monitoring-api \
policy=api,rest-api,read,!write,!policy,!sensitive,!ftp,!winbox,!web,!ssh,!local,!telnet,!romon,!reboot,!test,!sniff,!password
# Account locked to a single monitoring host
/user add name=prometheus-api \
group=monitoring-api \
address=10.0.10.100/32 \
comment="Prometheus metrics exporter"

Set the password to a generated value:

/user set prometheus-api password="<output of: openssl rand -base64 32>"

Example 3: RADIUS + TOTP with Local Break-Glass Admin

Section titled “Example 3: RADIUS + TOTP with Local Break-Glass Admin”
# Local emergency account — never queries RADIUS
/user add name=emergency group=full password="EmergencyBreakGlass!" address=192.168.0.0/24
# All other logins go to User Manager via RADIUS
/user aaa set use-radius=yes default-group=read accounting=yes exclude-groups=full
# User Manager RADIUS server
/radius add address=127.0.0.1 secret=LocalSecret service=login
# In User Manager, users have otp-secret set for TOTP enforcement