Files
hermes-skills/skills/devops/infrastructure-automation/references/routeros-file-creation-7-18.md
T

4.5 KiB

RouterOS 7.18 File Creation & SSH Key Deployment

RouterOS v7.18.x has changed/deviated from common forum advice for file creation over SSH. This document captures tested methods.

The Problem

Old forum posts recommend :put "content" file=name.txt or /file/set existing-file contents="data" to write files via CLI. Neither works on RouterOS 7.18.

  • :put "content" file=name.txtexpected end of command (RouterOS doesn't support file= as a :put parameter in v7)
  • /file/set name.txt contents="data"no such item (cannot set a file that was created via /file/add — the reference name doesn't match)

The Fix: /file/add name= contents="

The only reliable method to write text content to a new file on RouterOS 7.18 via SSH:

/file/add name="wisp-key.txt" contents="ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA... wisp-backup"

This creates a 92-byte .txt file with the exact content. Verified on RouterOS 7.18.2 (CCR2004-16G-2S+).

SSH Line Length Limit

Commands sent via ssh user@host 'command' are limited to approximately 170 characters. Commands exceeding this produce expected end of command errors.

What fits (~170 chars):

  • Ed25519 public keys (~92 chars) — fits with /file/add name="x" contents="..."
  • Short variables and simple commands

What doesn't fit:

  • RSA 4096 public keys (~500 chars)
  • Long base64 strings (~124+ chars before the command prefix)
  • Most hex-encoded content (>170 chars)

Workarounds for long content:

  1. Split across SSH calls — Set a global variable first, then use it in a script:

    ssh user@host ':global myvar "longcontent..."'
    ssh user@host '/system script add name=deploy source="... \$myvar ..."'
    ssh user@host '/system script run deploy'
    
  2. Native key add (no file at all):

    /user ssh-keys/add user=wisp-backup key="ssh-ed25519 AAAA... wisp-backup"
    

    Same line-length limitation but avoids the intermediate file step.

  3. Hex-encode the content — RouterOS supports \XX hex escapes in strings. Generate the encoded string in Python:

    key = "ssh-ed25519 AAAA..."
    escaped = ''.join(f'\\\\{b:02X}' for b in key.encode())
    # Result: \73\73\68\2D\65\64...
    

    Then write a RouterOS script with the hex string. Note: hex encoding triples the length of the original content, so this only helps when the original fits in ~55 chars.

SSH Key Import Methods

Method A — File-based (tested, works)

/file/add name="key.txt" contents="ssh-ed25519 AAAA... wisp-backup"
/user ssh-keys import public-key-file="key.txt" user=wisp-backup
/file/remove [find name="key.txt"]

Method B — Native add (v7.18+, no file needed)

/user ssh-keys/add user=wisp-backup key="ssh-ed25519 AAAA... wisp-backup"

Untested on this specific deployment but documented in official MikroTik docs.

FTP and File Transfer

  • FTP service is disabled by default in RouterOS. /ip service print shows X ftp with the X flag.
  • Even with FTP enabled, the write user group has !ftp policy and cannot use /tool/fetch or FTP upload. Only full group includes ftp policy.
  • Enabling FTP temporarily, uploading, then disabling is possible but requires a user with full permissions or enabling FTP service and adjusting user group.
  • SCP is not supported — scp commands produce exec request failed on channel 0.
  • SFTP also fails with Received disconnect — RouterOS SSH subsystem does not include SFTP.

Effective One-Liners Over SSH

These are the only patterns that work reliably from a single ssh user@host 'cmd' invocation:

# Create text file with content
ssh user@host '/file/add name="test.txt" contents="hello world"'

# Add SSH key (if key fits the line limit)
ssh user@host '/user ssh-keys/add user=admin key="ssh-ed25519 AAAA... comment"'

# Check file content
ssh user@host ':put [/file/get [find name="test.txt"] contents]'

# List files containing a pattern
ssh user@host '/file/print where name~"wisp"'

# Delete a file
ssh user@host '/file/remove [find name="test.txt"]'

What to Check When SSH Auth Fails

/ip ssh print
# Look for: always-allow-password-login: no

/user ssh-keys print
# If a key is assigned to the user, password login auto-disables

/user print where name=myuser
# Check the group — groups with !write may restrict management

RouterOS behavior: assigning an SSH key to a user automatically disables password authentication for that user. This is documented, not a bug.