Ansible role for SSH configuration on newly provisioned servers

This is anĀ Ansible role I use when IĀ provision new servers, the role add my SSH key, and disable remote root login, password loginm and GSS login to secure down the SSH server and then restart it.

roles/ssh/tasks/main.yml:

 

---
 
- name: check remote SSH host is in known_hosts
  command: /bin/grep -Fq {{ inventory_hostname }} /home/{{ ansible_ssh_user }}/.ssh/known_hosts
  register: check_known_hosts
  always_run: True
  ignore_errors: True
  changed_when: False
  tags:
  - ssh
 
- name: add remote host fingerprint to known_hosts if not found
  shell: /usr/bin/ssh-keyscan {{ inventory_hostname }} >> /home/{{ ansible_ssh_user }}/.ssh/known_hosts
  #debug: msg="I didn't find the {{ inventory_hostname }} in known_hosts and will add it"
  when: check_known_hosts.rc != 0
  tags:
  - ssh
 
- name: add local public key to remote server
  authorized_key: key="{{ lookup('file', '/home/te/.ssh/id_rsa.pub') }}" user={{ ansible_ssh_user }}
  tags:
  - ssh
 
- name: disallow root SSH access
    lineinfile: dest=/etc/ssh/sshd_config regexp="^PermitRootLogin" line="PermitRootLogin no" state=present
    notify:
      - restart sshd
 
  - name: disallow SSH password authentication
    lineinfile: dest=/etc/ssh/sshd_config regexp="^PasswordAuthentication" line="PasswordAuthentication no" state=present
    notify:
      - restart sshd
 
  - name: disallow SSH GSS API authentication
    lineinfile: dest=/etc/ssh/sshd_config regexp="^GSSAPIAuthentication" line="GSSAPIAuthentication no" state=present
    notify:
      - restart sshd

And in the handler section of the role:

  handlers:
  - name: restart sshd
    service: name=sshd state=restarted

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.