Jump to content

Securing a server with remote SSH access


Recommended Posts

Posted

I've seen some confusion and even some flat out misinformation posted on this generally rather simple subject. It's a basic step in properly securing any server system, but it's a basic step many newbies ignore.

If you manage any server system that has remote SSH access enabled, this is a thread for you.

Why should I care about any of this?
Are you okay with having your entire server compromised, used as a botnet for launching DDoS and other forms of network attacks under your name? I hope you're not. If you are/if you genuinely don't care, I feel sorry for anyone that uses any website you administrate.

Brute force attacks are a common reality. If you run a server, and that server happens to be connected to the internet with remote SSH access enabled, you've likely been the target of many such attacks, though you may not know it. A quick peek at your SSHD servers authentication logfile can generally confirm this.

The common reaction to seeing this for the first time is to freak out a bit.

Before proceeding further, let me give a quick explanation on what brute force attacks are, how they work, and what they mean to you.

Brute force attacks are carried out by bots that scan for open SSH ports and attack servers in mass amounts. When one of these bots finds a server of yours with open SSH access, it generally proceeds to attempt what's called a dictionary attack. This basically means the program goes through a very long list of commonly used passwords and tries to authenticate to your server with them. Most commonly, these bots will first attempt to gain access to the root account, but when that fails, they'll attempt attacks on other commonly used account names. If the attacker fails to gain access to your server, it gives up and moves on to the next target.
For a more detailed analysis, this blog post provides great insight.

Using a weak password on an openly accessible SSH server is a great way to have your entire system compromised. This is a mistake that many people still fall prey to today.

1. Using Secure Passwords


So the first step here, of course, is to ensure you're using secure passwords with all of your SSH accounts. The popular XKCD comic provides a good general guideline for creating strong but easy to remember passwords,
password_strength.png
Using a bit of l33t speak is fine, as long as you can still easily remember the password. Simple Things Like Camel Humping Your Phrases, or EVEN mixing UPPER and LOWERCASE like THIS can also make your passwords considerably more difficult to crack without adding much complication.

Furthermore, here are some things you should never use as passwords:

  • Anything in this list + some numbers added to the end
  • A single dictionary word
  • Your last name
  • Your last time with your SSN at the end
  • Your pets name
  • Your girlfriend/spouses name
  • Anything on this list
  • Anything under 8 characters in length

2. Disable PasswordAuthentication


Now that I've spent all that time lecturing you on using secure passwords, I'm going to tell you to stop using them.

Yep, that's right. The best way to really secure your SSH server is not just by using secure account passwords, but disabling plaintext password authentication entirely.

Using a secure password will make it extremely difficult for anyone to successfully brute force access to your server, but what if someone does manage to obtain your password somehow? Why risk it at all?

One of the most important things you can do to defend your server against brute force attacks is to use SSH keys for authentication. I'm going to explain how to create and implement SSH key authentication on Linux based systems here. If you use Windows/PuTTY as your client machine, you will need to use PuTTYgen for this process.

On your home (client) machine, run these commands under your regular user account:

if [ ! -d ~/.ssh ]; then mkdir ~/.ssh; fi
chmod 0700 ~/.ssh
ssh-keygen -t rsa


Follow the on-screen instructions here. Leave the default paths. The password you provide is used to encrypt your SSH key, so that if the key file itself is ever compromised, it will be useless to the attacker unless they can crack it. (If your key is ever compromised, you should immediately generate a new one). You can also choose not to provide a password, but it's not recommended.

Now you need to copy the public key over to your remote server. There are two ways you can do this, by SCPing the file or by copy and pasting the contents manually. To Secure Copy the file to your server,

scp ~/.ssh/id_rsa.pub USER@REMOTEHOST:~/.ssh/authorized_keys

(Note: Do NOT use "root" as the user here. Use your unprivileged user account.)

The second option is to simply open ~/.ssh/id_rsa.pub and copy and paste the contents into the ~/.ssh/authorized_keys file on your remote server.

Once you do this, try to establish a new SSH connection to your server. You should automatically attempt to connect using your new SSH key, and if all goes well, you should be able to connect without any problems. To ensure you really are connecting using the keyfile, you can pass the "-i ~/.ssh/id_rsa" flag with your SSH command.

Once you have confirmed your key is working, you can disable PasswordAuthentication entirely. To do this, on your remote server, open /etc/ssh/sshd_config and look for the following line,

# Change to no to disable tunnelled clear text passwords
#PasswordAuthentication yes

Uncomment the PasswordAuthentication line (if it is commented) and change the setting to no.

Exit and restart the OpenSSH server,
Debian:

/etc/init.d/ssh restart

CentOS:

service sshd restart

Now attempt to establish a new SSH connection to your server. You should still be able to connect with your SSH key.

Disconnect, and attempt to connect to the server again with the following command,

ssh -o PreferredAuthentications="password" USER@HOSTNAME

You should be denied access and receive this response,

Permission denied (publickey).

You're done! Congratulations, your server is now essentially impossible to brute force. But there are still a couple more things you should do.

3. Disable PermitRootLogin

The next step is to disable root authentication. Technically, this shouldn't be necessary, because with PasswordAuthentication disabled and being that the root account should not have any keys associated with it, there should be no way to properly attempt remote authentication to the root account. Nonetheless, you should not have this enabled, and it's a good practice you need to learn.

To disable root login, open /etc/ssh/sshd_config again and look for the following line,

PermitRootLogin yes

Change this setting to no. Exit and restart the OpenSSH server again.

If you've been connecting to your remote SSH server as root all this time, today you learn to never do that again. There is no reason you should be connecting to your remote server as root, other than laziness.

If someone gains access to your unprivileged user account on your server, the damage the attacker can cause is limited. If they gain access to your servers root account, they gain complete and absolute control over everything on your server. In the worst case scenario that your unencrypted key is stolen, you want to ensure the attackers will NOT have root access to your server.

Furthermore, you should only be running tasks as root when you need to. Connect to your server as an unprivileged user and only use su to root up when necessary.

4. (Optional) Set up an AllowUsers list

The steps I've listed above are all fairly common practice. This is one extra step that you probably won't see as often, but it's a good additional layer of security to have. I'm not going to say you have to use this, because as with root login above, attempts to access any other account without an ~/.authorized_keys file present while PasswordAuthentication is disabled should be pointless.

This directive allows you to explicitly define a list of user accounts that can be accessed remotely via SSH. If anyone attempts to authenticate to a user that's not included in this list, even if the client has a valid SSH key for the account in question, they'll be refused access.

This directive is likely not included in your distributions example configuration, so you'll need to add it to the end of your /etc/ssh/sshd_config file.

# Only allow access to privileged accounts
AllowUsers USER1 USER2

Replace "USER1 USER2" with a space separated list of accounts on the remote server you want to be able to SSH to.

Once you're done, save, exit, restart OpenSSH and attempt to establish a new SSH connection again to ensure all is well.


Did you find this guide helpful and want to help compensate for the hours invested in writing this? Please consider sending a BTC donation to this address,
12rczKcdR42sCVb2BhE211Zn3uhHiVhxse
Or contact me if you'd like to send some rent money my way using other means, such as PayPal.

Thank you, and please feel free to post any questions or concerns you have below!
Posted

Very informative thanks. :thumbsup:

But if that's a post about a simple subject, remind me to put half an hour aside to read when you post about a complex subject. :smile:

Posted

changing ports is good idea too.

while port scanning may find it I notice that they tend to stick to more common ports. so changing them isn't a failsafe its just one more tool

Posted

Changing the SSH port is just security through obscurity though, which is why I don't often bother with it.

Someone who is dedicated enough can still find your SSH port. It's extremely easy if you don't have software set up to thwart port scan attempts, and even then those tools aren't always successful and can sometimes be avoided entirely. (Like you said though, some bots may only attempt common ports and won't bother port scanning your network, but many still probably will.)

Posted

There are many levels of security, some of the above is overkill for a forum community in most cases... however you can never be too safe if you are a target.

Changing your ports up, ensuring you have a proper firewall in place and blocking port scans, is going to be much easier for most if the above makes your head spin.

Posted

Changing your ports up, ensuring you have a proper firewall in place and blocking port scans, is going to be much easier for most if the above makes your head spin.

That's true, but the first item in the list is still absolutely essential if you're going to allow password authentication.

You have to ensure you use a secure password. Neither CSF/fail2ban/etc nor changing your SSH port will protect an account with an insecure password from being compromised.

And regardless if it's a little overkill, I don't think the above is that difficult to set up and learn. The first time you set up a SSH key, it is a bit of a learning experience.

But after you have everything set up, you generally don't have to mess with any of this again. Taking the time to set this up once can make your server exponentially more secure.

If anyone with their ports switched up would like an example, feel free to send me your servers hostname, and I'll see if I can discover your servers open SSH port. I can even run some basic penetration tests with permission.

But nonetheless, most of the stuff I post is targeted at people who want to learn best practices and don't mind investing a little time studying and learning.

Posted

I do agree with your practices, just providing other workable options. :smile:

I thought about including changing ports/using CSF/fail2ban, but I didn't want to cram too much information in here, and I haven't actually used either csf or fail2ban in a while, so I'd have to download those again to refresh my memory before posting anything on that.

I could try and write up some (simpler/less wordy) instructions on that at a later date in a new topic though, if it'd help some people.

Posted

Nice writeup. That's about all I do to secure my systems, as well. I recently started running denyhosts and it seems to work well.

One other comment: there's no reason to make the username obvious, either. I use KeePass' password generator to generate my login names when I really, really care. Pretty much nobody is going to be trying to log in as "gT1JKouF", for example.

robert

Posted

using csf with an odd port, ips blocked after scanning sensed. brute force monitors also block after being sensed.

I also change the port every few weeks. only takes a moment to do, on the rare occasion I need to allow root access to an entity I change immediately when done as well as alter passwords. remembering to do it is actually harder then doing it

by no means a fail safe, just another tool to use.

Posted

Overkill = write a server side script to change your SSH port according to a preset formula depending on the time of day + day of week :lol:

  • 3 months later...
  • 2 weeks later...
Posted

Changing the SSH port is just security through obscurity though, which is why I don't often bother with it.

Someone who is dedicated enough can still find your SSH port. It's extremely easy if you don't have software set up to thwart port scan attempts, and even then those tools aren't always successful and can sometimes be avoided entirely. (Like you said though, some bots may only attempt common ports and won't bother port scanning your network, but many still probably will.)

I disagree. In theory you're correct but here's the real world choice:

(1) Run on port 22, get potentially hundreds of script kiddies hammering you 24x7. I've admined servers where I received 200-300 "this IP has been temp blocked for ssh failures" alerts per day.

(2) Run on a different port and avoid 99.9% of skiddies. Yes, absolutely if one of them wants to, he can still scan your box and find your SSH. But 99.9% will not do this in my experience (well, actually 100% in my experience).

Posted

script kiddies ... skiddies


That last nickname made me think of soiled underwear. :lol:

Surprisingly, thats another pretty good description. LMAO.
Posted

I disagree. In theory you're correct but here's the real world choice:

You're right that it will probably thwart a large majority of attempts, but the real world impact these "script kiddies" have on you is almost always extremely negligible with a proper setup anyways. But I'm certainly not saying doing this is a bad idea, just that if you care about security, you need to do more than just change your SSH port.

The point was that you shouldn't actually do this and think it gives you any significant security itself. It is still security through obscurity, that's just the simple reality of what it is. That doesn't mean it's bad, but it means it doesn't actually really enhance your servers security, it just works as a deterrent to discourage people from even trying to test it. If someone or some specific organization decided to specifically target you, STO methods wouldn't save you.

Following basic security practices in addition to changing your SSH port is fine and good.

Posted

for ssh attempts, it's really as simple as using a non standard port, and blocking port scan attempts. I have been doing this for the last 10 years or so and have yet to have anyone hit the proper port, they are blocked long before they even come close.

Posted

for ssh attempts, it's really as simple as using a non standard port, and blocking port scan attempts. I have been doing this for the last 10 years or so and have yet to have anyone hit the proper port, they are blocked long before they even come close.

While at the same time, I'm using the obvious, standard port 22. Everyone knows where my front door is, but no one has a chance in hell of breaking it down.

In the instance that someone decides to put me in their crosshairs, this is what's truly important.

Your door is hidden well, and for the common attacker that's just running an automated script to find open networks, it's not worth their time to try and hunt your specific port down. But if someone really wants to, if you have OpenSSH publicly broadcasted on any port, anyone can find it, and there's nothing that will realistically stop that.

Changing your SSH port is just a deterrent. I'll admit that it's probably good practice, but it's still pseudosceurity.

Posted

How are they going to find it if you block on port scans? :tongue: You can go challenge yourself though, half of you likes to bicker, I'm sure your other half is up for it! :)

Posted

How are they going to find it if you block on port scans?

There's a very finite number of ports you can broadcast on, 65,535 specifically.

There are also various ways to avoid detection.

Creative use of nmap, having access to a wide variety of proxies and/or botnets, and time is all that's needed.

99% of attacks come from automated scripts anyways, they are not direct attacks. Which is why changing your port and blocking general port scans works fine for thwarting these pests.

Posted

My #1 reason for changing ssh port:

So I can stop getting spammed with the emails from csf/lfd about failed login attempts from bots.

Changing your SSH port is just a deterrent. I'll admit that it's probably good practice, but it's still pseudosceurity.


As I see it, every security in the world (not just servers) is only a matter of degree of deterrence. Greater the deterrence, greater the dissuasion to stop the offense.

Why do you get a bike lock? So, you deter someone from stealing it. If they had a bolt cutter, your cheap bike locks wouldn't do crap. Why get an expensive lock? So it requires a more expensive bolt cutter...

I'm sure if someone really had the means and desire, they could just barge into the data center flaring with guns and forcefully take your server. If someone really wanted to ddos you, they could nuke the datacenter. Then you'll be down for good. Deter the offenders by reducing the means to, making it more hard to and reducing the motive to. That's really all I see security as.

Archived

This topic is now archived and is closed to further replies.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...