Sure, using password authentication is somewhat secure. If you’re like the vast majority of people though, your password sucks. Trust me, it probably sucks. Rather than create a ludicrously long password that you’ll never remember, why not step up into the world of two-factor authentication?

Two-factor authentication simply means that there are 2 items required in order to authenticate the user. You likely use two-factor authentication on a daily basis and don’t know it. If you ever use an ATM, you’re using two-factor authentication. You provide something you have(ATM card) and something you know (ATM pin). We’re going to do the same thing for SSH.

What we’re going to do:

  • Create a public key on your local machine
  • Move this key to your remote server
  • ???
  • Profit!

I’m going to mention this caveat now: This post is primarily intended for SSH connections to shared host, such as GoDaddy shared hosting. Why this caveat? Most shared hosting providers, GoDaddy included, already have sshd configured to support key-authentication. If you’re running your own VPS, you’ll need to make sure you’ve enabled key-authentication in your sshd_config file. Pro tip: Don’t turn off password authentication until AFTER you’ve successfully moved your keys over.

Creating a public key:

I’m going to assume you’re doing this on a Linux box. I’ll come back later and make instructions for Windows users later.

To create a public key you’re simply going to use the command ‘ssh-keygen’.

[jon@localhost ~]$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/jon/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/jon/.ssh/id_rsa.
Your public key has been saved in /home/jon/.ssh/
The key fingerprint is:
6e:24:b9:6d:34:d8:64:da:00:ff:17:ac:ec:56:4b:83 jon@localhost.localdomain

The ‘-t rsa’ specifies that we’re creating an RSA key. Next, it will ask you where to save the private key. You can specify a unique location and file name if you wish, or simply hit enter to use the defaults. It will then prompt you for a passphrase. This is the ‘something I know’ part of using SSH Keys for two-factor authentication. It’s a password that allows you to use your public key, so use strong password practices here. Once you’ve set the passphrase, you’re done! It will tell you where it saves the private key (id_rsa) , the public key ( , and provides you with the public key fingerprint.

Move your public key to the remote sever:

Thanks to a little utility called ‘ssh-copy-id’ moving your public key to the remote server, creating the necessary directories, and correcting permissions is all automated.

To move your newly created public key to your remote server use the following command

[jon@localhost ~]$ ssh-copy-id -i ~/.ssh/ user@remotehost.tld

The authenticity of host ‘remotehost.tld (’ can’t be established.
DSA key fingerprint is 62:5e:b9:fd:3a:70:eb:37:99:e9:12:e3:d9:3f:4e:6c.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added ‘remotehost.tld,’ (DSA) to the list of known hosts.
Now try logging into the machine, with “ssh ‘user@remotehost.tld'”, and check in:


to make sure we haven’t added extra keys that you weren’t expecting.

So what’s happening here? The ‘-i’ flag is simply telling ssh-copy-id where to find your public key. If you used the default settings it should be in ‘~/.ssh/’ . It then makes an SSH connection to the remote host, has you log in via password authentication, then copies your public key to the remote host while creating any necessary directories and correcting permissions.

You can now enjoy two-factor authentication by accessing the remote server using

ssh 'user@remotehost.tld'

You’ll be prompted for your keypass so ‘unlock’ your public key for use in authentication. If you’re using ssh-agent this would actually be automated and you’ll log in automatically. But that’s a post for another day…

Occasionally the need will arise where you have to review the FTP logs for a particular domain. These are located in /var/www/vhosts/$domain/statistics/logs/xferlog_regular

Each log entry will contain what you would expect, the IP accessing, the file being modified, as well as one of the following: a _ i, a _ o, a _ d, b _ i, b _ o, b _ d

But what do those cryptic letters mean? They tell you what type of transfer, a for ascii or b for binary, and whether a file was uploaded (i), downloaded (o), or deleted (d)

Ascii format:

  • a _ i (uploaded)
  • a _ o (downloaded)
  • a _ d (deleted)

  • Binary format:

  • b _ i (uploaded)
  • b _ o (downloaded)
  • b _ d (deleted)
  • lsof -Pni

    Occasionally I’ll run across boxes that have been root-kitted and the netstat binary has been replaced. This new binary gives you the same info every time, and is designed to hide many active connections to the box, even your own SSH session! Luckily, it seems that many rootkits neglect to replace lsof so you can use the above snippet to review all Listening and Established connections to the box.

    Downside: Need to have root access to run the code

    lsof +r 1 -p `ps axww | grep httpd | grep -v grep | awk ' { if(!str) { str=$1 } else { str=str","$1}}END{print str}'` | grep vhosts | grep php

    This one is useful for when Apache is eating up resources and you want to try and find out which site or file is the culprit. It will show you the current working directory for the process as well at what files are currently open. If you’re using FastCGi, just replace the grep httpd with grep php-cgi or whatever the associated process name is. It assumes that you host your web-content in a vhosts directory of some sort (my use for this is on Plesk server’s so /var/www/vhosts/ so don’t forget to update the search for your scenario.

    find / -noleaf -type f -size +51200k -exec ls -lh {} \; | awk '{print $5, substr($0, index($9,$NF))};'

    To find the largest files, recursively from your search path. Works with directories/files that have spaces in the name. Don’t miss the single quote at the very end. Thanks to a co-worker for the awk-foo

    Alter the path immediately after “find” for your search needs. To start from your current location just use . or ./ instead. This particular search will find files over 50MB(51200k). The ‘size’ parameter will also take size in megabytes(M) and you can alter the search for files over the value (+) or under the value(-).

    find is one of my favorite linux commands because it’s just so versatile. The down side though is that there’s a bit of time that needs to be invested in man pages to really get to know the ins and outs of the command.