Using OpenBSD as reverse SSH access point using autossh

  • Introduction

Recently, externally accessed SSH server running OpenBSD was firewalled because the infrastructure guys at my employer think SSH is insecure!

On a side not, the reason behind this is a constant brute force attack targeting this server for the past several years, the attack was unsuccessful, password access is disabled in the first place, they refused to give us real IP to disable them at the PF level and they refused to firewall offending IPs, but anyway the attack was unsuccessful because no password authentication was enabled.

I had to secure another method of accessing the server to be able to continue my work along with the team, I installed recent OpenBSD 5.8 snapshot and started to configure it as permanent reverse SSH server.

  • Logical environments

OpenBSD access point

Old method:
– OpenBSD server was given public IP, we used to access it directly from the Internet.

New method:
– Public IP is not necessary
– External SSH server is needed, Linux or UNIX like, that is accessed over SSH, say Amazon AWS instance
– AutoSSH reverse tunnel will be setup between internal OpenBSD and external SSH server
– To access the OpenBSD server from the internet, a connection to the public SSH server will be performed which will tunnel SSH access to the OpenBSD server as usually done

  • How to do it

For the purpose of this exercise, I installed new OpenBSD server inside our internal network, OpenBSD 5.8 13-October snapshot, and performed the following:

1- Installed AutoSSH:

$ cd /usr/ports/sysutils/autossh
$ doas make install

2- Create autossh account on both ends
In local OpenBSD server create user account “autossh”, on external SSH server create “autossh” user account, setup passwordless SSH keys on OpenBSD server and copy the public key to external SSH server “autossh” account’s authorized_keys. At least access it once using “ssh” to make sure it’s working OK.

3- Create OpenBSD service startup script:
/etc/rc.d/autossh:

#!/bin/sh
#
# $OpenBSD$
 
MONITOR_PORT=8000
TUNNEL_SERVER=external.amazon-aws-instance-XXX.com
TUNNEL_USER=autossh
LISTEN_PORT=2015
SERVICE_PORT=22
 
daemon="/usr/local/bin/autossh"
daemon_flags="-f -M $MONITOR_PORT -N -R $LISTEN_PORT:localhost:$SERVICE_PORT $TUNNEL_USER@$TUNNEL_SERVER"
daemon_user="autossh"
 
. /etc/rc.d/rc.subr
 
pexp="autossh:.*"
 
rc_cmd $1

This setup port 2015 on the external SSH server, when connecting to that port it will direct traffic to other end originating the SSH tunnel (OpenBSD server – Local host in this case) and to port 22 (SSH port).

4- Enable the script on machine startup:
/etc/rc.conf.local:

# rc.d(8) packages scripts
# started in the specified order and stopped in reverse order
pkg_scripts="autossh "

5- Start the AutoSSH tunnel:

$ doas /etc/rc.d/autossh start

6- Check the service is running OK

$ ps auxwww
...
autossh 29250 0.0 0.1 492 968 ?? Ss 9:58PM 0:00.00 autossh: parent of 6497 (1) (autossh)
autossh 6497 0.0 0.3 1004 3240 ?? S 9:58PM 0:00.02 /usr/bin/ssh -L 8000:127.0.0.1:8000 -R 8000:127.0.0.1:8001 -N -R 2015:localhost:22 autossh@external.amazon-aws-instance-XXX.com
...

The above processes should show in process list.

7- Check the service is running from command line:

$ doas /etc/rc.d/autossh check
autossh(ok)

8- Now connect to the internal OpenBSD server through the external SSH server:

$ ssh -p 2015 username@external.amazon-aws-instance-XXX.com

And I was able to access the internal OpenBSD server.