From e069ad76127acc2c0783e0a4b0e1240ea9a8d54d Mon Sep 17 00:00:00 2001 From: Ville Rantanen Date: Thu, 29 Aug 2019 19:14:12 +0300 Subject: [PATCH] move to autossh --- src/ssh-backdoor | 75 ++++++++++++++++++++++++++----------------- src/ssh-backdoor-open | 42 +++++++++++++----------- 2 files changed, 68 insertions(+), 49 deletions(-) diff --git a/src/ssh-backdoor b/src/ssh-backdoor index 06c180e..0dba091 100755 --- a/src/ssh-backdoor +++ b/src/ssh-backdoor @@ -152,7 +152,8 @@ class DataBase: self.db.execute('CREATE TABLE ports (\ id TEXT PRIMARY KEY,\ host TEXT, \ - port INTEGER,\ + reverseport INTEGER,\ + monitorport INTEGER,\ pid INTEGER,\ die INTEGER,\ date INTEGER)') @@ -160,10 +161,10 @@ class DataBase: def clean_db(self): self.db = self.conn.cursor() - self.db.execute("SELECT id,port,date,pid,host FROM ports") + self.db.execute("SELECT id,date,pid,host FROM ports") for row in self.db.fetchall(): - age = int(time.time() - row[2]) - running = self.is_running(row[3]) + age = int(time.time() - row[1]) + running = self.is_running(row[2]) if running: continue if age < self.alive: @@ -214,18 +215,23 @@ class DataBase: self.conn_end() - def update(self, id, port = None): + def update(self, id, reverseport = None, monitorport = None): self.id = id - if port == None: - port = self.get_port(id) - if port == None: - port = self.new_port() + if reverseport == None: + reverseport = self.get_port('reverseport',id) + if reverseport == None: + reverseport = self.new_port() + if monitorport == None: + monitorport = self.get_port('monitorport',id) + if monitorport == None: + monitorport = self.new_port() parent = self.get_pid() self.db = self.conn.cursor() - self.db.execute("INSERT OR REPLACE INTO ports(id,port,date,pid,host,die) \ - VALUES(?,?,?,?,?,?)",( + self.db.execute("INSERT OR REPLACE INTO ports(id,monitorport,reverseport,date,pid,host,die) \ + VALUES(?,?,?,?,?,?,?)",( id, - port, + monitorport, + reverseport, int(time.time()), parent, os.getenv("SSH_CLIENT","-").split(" ")[0], @@ -233,16 +239,16 @@ class DataBase: ) ) self.conn_end() - return port + return "%d %d"%( reverseport, monitorport ) def list(self): self.db = self.conn.cursor() - self.db.execute("SELECT id,port,host,date,pid,die FROM ports ORDER BY id") + self.db.execute("SELECT id,reverseport,monitorport,host,date,pid,die FROM ports ORDER BY id") rows = [] for row in self.db: row = list(row) - row[3] = self.human_age(row[3]) - row.append(self.is_running(row[4])) + row[4] = self.human_age(row[4]) + row.append(self.is_running(row[5])) # ~ row.append("ssh-nosave -p %d localhost"%( row[1], ) ) rows.append(row) return rows @@ -265,32 +271,38 @@ class DataBase: def get_pid(self): return os.getppid() - def get_port(self, id): + def get_port(self, type, id): self.db = self.conn.cursor() - self.db.execute("SELECT port FROM ports WHERE id = ?", (id,)) + if type == 'reverseport': + self.db.execute("SELECT reverseport FROM ports WHERE id = ?", (id,)) + if type == 'monitorport': + self.db.execute("SELECT monitorport FROM ports WHERE id = ?", (id,)) result = self.db.fetchall() if len(result) == 0: return None - return result[0][0] + return int(result[0][0]) def new_port(self): self.db = self.conn.cursor() while True: - port = random.randint(22200, 22400) - self.db.execute("SELECT port FROM ports WHERE port = ?", (port,)) - result = self.db.fetchall() - if len(result) == 0: + # ports alweays even (because monitor requires + 1 + port = int(random.randint(22200, 22999) / 2) * 2 + self.db.execute("SELECT reverseport FROM ports WHERE reverseport = ?", (port,)) + result_reverse = self.db.fetchall() + self.db.execute("SELECT monitorport FROM ports WHERE monitorport = ?", (port,)) + result_monitor = self.db.fetchall() + if len(result_reverse) + len(result_monitor) == 0: return port def connect_backdoor(self, id): self.db = self.conn.cursor() - self.db.execute("SELECT port,pid FROM ports WHERE id = ?", (id,)) + self.db.execute("SELECT reverseport,monitorport,pid FROM ports WHERE id = ?", (id,)) result = self.db.fetchall() if len(result) == 0: eprint("No such ID") return port = result[0][0] - pid = result[0][1] + pid = result[0][2] if not self.is_running(pid): eprint("Backdoor not open") return @@ -324,14 +336,17 @@ if __name__ == "__main__": if opts.command == "list": print(tabulate( db.list(), - headers = ['Id','Port','Host','Age','PID','Die','Alive'] + headers = ['Id','RevPort','MonPort','Host','Age','PID','Die','Alive'] )) if opts.command == "query": - port = db.get_port(opts.id) - if port == None: + reverseport = db.get_port('reverseport',opts.id) + monitorport = db.get_port('monitorport',opts.id) + if reverseport == None: sys.exit(1) - print(port) + if monitorport == None: + sys.exit(1) + print("%d %d"%(reverseport, monitorport)) sys.exit(0) if opts.command == "kill": @@ -342,7 +357,7 @@ if __name__ == "__main__": db.connect_backdoor(opts.id) if opts.command == "open": - print(db.update(opts.id, opts.port)) + print(db.update(opts.id, reverseport = opts.port)) if opts.command == "keep": print(db.update(opts.id)) diff --git a/src/ssh-backdoor-open b/src/ssh-backdoor-open index 10db6d1..ac2d045 100755 --- a/src/ssh-backdoor-open +++ b/src/ssh-backdoor-open @@ -12,8 +12,19 @@ if [[ "$1" = update ]]; then } fi +_autossh() { + autossh \ + -M ${MONITORPORT} \ + -o UserKnownHostsFile=/dev/null \ + -o StrictHostKeyChecking=no \ + -o ConnectTimeout=10 \ + -o ServerAliveInterval=15 \ + -o ServerAliveCountMax=3 \ + -p ${BACKDOORPORT} \ + ${BACKDOORHOST} \ + "$@" +} _ssh() { - trap 'kill -INT -$SSHPID; exit;' INT ssh \ -o UserKnownHostsFile=/dev/null \ -o StrictHostKeyChecking=no \ @@ -22,9 +33,7 @@ _ssh() { -o ServerAliveCountMax=3 \ -p ${BACKDOORPORT} \ ${BACKDOORHOST} \ - "$@" & - SSHPID=$! - wait $SSHPID + "$@" } BACKDOORHOST={{BACKDOORHOST}} @@ -32,24 +41,19 @@ BACKDOORPORT={{BACKDOORPORT}} USER=$( id -u -n ) BGPID=0 echo "Must use ssh agent (ssh-add)" +which autossh &>/dev/null || { + echo Must have autossh + exit 1 +} while true; do date - port=$( _ssh bin/ssh-backdoor open $USER@$HOSTNAME ) - [[ -z "$port" ]] && { sleep 2; continue; } - echo "$port port assigned" + read -r reverseport MONITORPORT <<<$( _ssh bin/ssh-backdoor open $USER@$HOSTNAME ) + [[ -z "$reverseport" ]] && { sleep 2; continue; } + echo "$reverseport $MONITORPORT ports assigned" #~ _ssh pkill -a -f $USER@$HOSTNAME - _ssh \ - -L $port:localhost:$port \ - -R $port:localhost:22 \ - bin/ssh-backdoor keep $USER@$HOSTNAME & - BGPID=$! - while true; do - sleep 60 - timeout 20 ssh-keyscan -p "$port" localhost 2>/dev/null | grep -q "$port" || { - kill $BGPID - break - } - done + _autossh \ + -R $reverseport:localhost:22 \ + bin/ssh-backdoor keep $USER@$HOSTNAME for i in {1..10}; do sleep 1