116 lines
4.5 KiB
Markdown
116 lines
4.5 KiB
Markdown
# 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.txt` → `expected 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:
|
|
|
|
```routeros
|
|
/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:
|
|
```bash
|
|
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):**
|
|
```routeros
|
|
/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:
|
|
```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)
|
|
```routeros
|
|
/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)
|
|
```routeros
|
|
/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:
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```routeros
|
|
/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.
|