#!/usr/bin/env python3 """Read-only inspect of RB4011 via Tailscale jump host.""" from __future__ import annotations import time import paramiko JUMP = ("100.80.255.113", "otantik", "DeararbsFr2@") MK = ("172.30.0.1", "admin", "demopass") def wait(shell, timeout=20) -> str: buf = b"" end = time.time() + timeout while time.time() < end: time.sleep(0.12) if shell.recv_ready(): buf += shell.recv(65535) end = time.time() + 1.3 if b"> " in buf[-300:]: break return buf.decode("utf-8", "replace") def cmd(shell, line: str, timeout=25) -> str: shell.send(line + "\r") out = wait(shell, timeout) print("\n===== " + line + " =====") print(out[-4000:]) return out def main() -> None: jump = paramiko.SSHClient() jump.set_missing_host_key_policy(paramiko.AutoAddPolicy()) jump.connect( JUMP[0], username=JUMP[1], password=JUMP[2], timeout=25, allow_agent=False, look_for_keys=False, ) print("JUMP OK") stdin, stdout, stderr = jump.exec_command( "hostname; ip -4 -o addr show | awk '{print $2,$4}'", timeout=15 ) print(stdout.read().decode("utf-8", "replace")) chan = jump.get_transport().open_channel( "direct-tcpip", (MK[0], 22), ("127.0.0.1", 0) ) mk = paramiko.SSHClient() mk.set_missing_host_key_policy(paramiko.AutoAddPolicy()) mk.connect( MK[0], username=MK[1], password=MK[2], sock=chan, timeout=25, allow_agent=False, look_for_keys=False, ) print("MK SSH OK") shell = mk.invoke_shell(width=220, height=70) first = wait(shell, 12) if b"license" in first.lower().encode() or "license" in first.lower() or "[Y/n]" in first: shell.send("n\r") wait(shell, 8) for c in [ "/system identity print", "/system resource print", "/ip address print without-paging", "/ip hotspot print", "/ip hotspot user print count-only", "/ip hotspot active print count-only", "/ppp secret print count-only", "/ppp active print count-only", "/interface pppoe-server server print", "/interface wireguard print", "/ip service print where name=api", "/ip hotspot profile print", "/ip pool print", "/interface bridge print", ]: cmd(shell, c) mk.close() jump.close() if __name__ == "__main__": main()