Thursday, August 11, 2016

Using an SSH Server for Remote Administration

If you manage Linux or Unix servers, then getting remote access to them is often a necessity. An SSH server can be an easy way to provide secure remote access to the servers you manage. It's not hard to set one up and secure it, and once it's ready, you can use an SSH client on your PC, laptop, phone, or tablet to get to your servers any time. You can even create tunnels between your local client and a remote machine through the SSH server, allowing it to act as a proxy between you and your servers on an internal network. All you need in order to set up an SSH server is a Linux box, and it doesn't really matter what distro you choose.

Since the SSH server will have a public IP address, it's important to make sure that the SSH daemon is secure. This means we'll need to do the following:
  • Change the listen port to something other than 22
  • Allow public key authentication only
  • Disable password authentication
  • Disable root logins
  • Set a restrictive authentication timeout
  • Make sure each user's private key has a passphrase (you can't enforce this at the server level, though)

I have created a zip file with an appropriately secured sshd_config, as well as shell scripts for performing various tasks. Before you get started, download and extract the zip file:

Download ssh_server_files.zip

Inside the zip file, there are two subdirectories. The files/ssh/ directory contains the sshd_config file, as well as a generic SSH login banner, which you can customize to your needs. The files/bin/ directory contains shell scripts for performing various tasks on the SSH server, such as adding users and allowing tunnels.

What You Will Need:
  • The ssh_server_files.zip file, which you can download here
  • A PC, server, or virtual machine with a Linux OS installed (it doesn't have to be anything fancy)

How to Do It:
1. Install OpenSSH
  • Debian / Ubuntu / Kali:
    apt-get install ssh

  • CentOS / Fedora / Red Hat:
    yum install openssh


2. Configure the SSH daemon (sshd)
  • Back up the existing /etc/ssh/sshd_config file:
    cp /etc/ssh/sshd_config /etc/ssh/sshd_config.ORIGINAL

  • Copy the new sshd_config and sshd_banner files to the /etc/ssh directory:
    cp files/ssh/sshd_config /etc/ssh
    cp files/ssh/sshd_banner /etc/ssh

  • Edit the sshd_config file and make sure to specify a listen address for the SSH daemon on the ListenAddress line. The IP address must be assigned to an interface on the SSH server.

  • You can also change the listen port by editing the Port line if you want to.


3. Define the tunnels you want to allow through the SSH server
  • Use the add-new-tunnel.sh script to allow tunneling to your servers. For example:

    Allow tunneling to the host mysrv1.example.com on port 443 (HTTPS)
    add-new-tunnel.sh mysrv1.example.com:443


4. Create a user account
  • Use the add-new-user.sh script to add an authorized user account for anyone who will need to use the SSH server. For example:
    add-new-user.sh dave


5. Create and install authentication keys
  • Create an RSA key pair:
    $ ssh-keygen -f mykey -t rsa -b 2048

    You should always specify a passphrase for your private key! Don't leave it empty!

  • Copy the public key into the user's authorized_keys file:
    cat mykey.pub >> /home/dave/.ssh/authorized_keys
    chown dave /home/dave/.ssh/authorized_keys

  • Copy the private key (the file without the .pub extension) to the client machine you'll be using for remote access.


How to Use It:
  • If you simply need console access, you can SSH to the server using your private key. Under Linux or OS X, you would do something like this:
    ssh -p 2222 -i mykey dave@sshsrv.example.com

    In this example:
    • The SSH server is configured to listen on port 2222
    • The username on the SSH server is "dave"
    • There's a private key file called mykey on the local machine
    • The matching public key is contained in the authorized_keys file on the SSH server
    • The server has the hostname sshsrv.example.com

  • If you want to create a tunneled connection between your client machine and a remote machine, you can do so by creating a "local" tunnel (mapping a port on your local machine to a port on the remote machine). Under Linux or OS X, you can use the -L option for the ssh command.

    The syntax for this option is:
    -L <local_port>:<remote_host>:<remote_port>

  • Let's say you have a server on your internal network named mysrv1.example.com, which hosts an HTTPS service but is not accessible from the outside (due to having an internal IP or whatever). You can use an SSH tunnel to map a port on your local machine to port 443 on that server, and then access it using a localhost address:

    ssh -p 2222 -i mykey -L 4443:mysrv1.example.com:443 dave@sshsrv.example.com

    Then, to access the HTTPS service hosted at mysrv1.example.com, you can simply open a browser on your local machine and go to https://localhost:4443.

If you use tunnels, the SSH server makes a great proxy for most TCP-based services, such as HTTP, HTTPS, FTP, SSH, SFTP, LDAP, and MySQL. At my job, our web developers use SSH tunnels to connect their client machines to our web servers and MySQL server. And I often use a tunnel through our SSH server to connect to an LDAP server on our internal network from home.

NOTE:
Virtual hosts on a web server can sometimes prevent HTTP and HTTPS from working correctly through an SSH tunnel. For example, http://localhost:8880 won't work if a virtual host on the server requires a specific host name.


Troubleshooting and Auditing:
  • To diagnose problems with authentication, tunneling, etc., you can check the system logs. With the log level in sshd_config set to DEBUG3, the SSH daemon will generate a lot of log output. You should generally be able to find the underlying error in these logs. A few common issues may arise:
    • In the case of an authentication problem, it's usually due to sshd failing to find a public key in the user's ~/.ssh/authorized_keys file which matches the private key being used for authentication.

    • In the case of a tunneled connection not working, it's usually due to the tunnel not being allowed in sshd_config. Use the add-new-tunnel.sh script to allow tunneling to the desired host and port.

  • If you want to see which servers are being accessed through the SSH server, and by whom, you can use the audit-tunnels.sh script. The script takes a server:port pair as the only argument, and will show you any tunnels which were opened to that host recently.


If you use this solution for remote access, please leave a comment and let me know what you think. Thanks for reading!