I’ve recently started using Rimuhosting’s VPS services. The server is running CentOS 5 and bundled with a bunch of goodies. A VPS offers more control, but is also more susceptible to hacking attempts, and requires a bit of preventative medicine. This is just a log of my experiences setting up a more secure environment.

Update RMPs with APT

APT (Advanced Package Tool) is a dependency tool originally developed for Debian, but packaged to work with RPMs (Package Manager) and is similar to YUM (Yellowdog Updater Modified). APT commands connect to a repositoristory to not only install, or update requested packages, but also any required dependent packages. You can also keyword search the repository to find packages based on functionality.

First things first,

# update the db of available rpms.
# Do this before running the other commands.
apt-get update

# upgrade currently installed rpms to the most stable version
apt-get upgrade

I got a

Resolving: The following packages have been kept back

message, meaning that one of the updated packages has a dependency which does not currently exist on my system. and so ran

apt-get dist-upgrade

to install these new dependencies as well as update the package.

Secure remote login

1. Run SSH daemon on a non-standard port

Run SSHd on a non-standard port. Since most automated attacks only attempt to connect on (the standard) port 22, this can be an effective way to hide from many attackers. To configure this, just change the Port line in /etc/ssh/sshd_config. I was digging around trying to find pico, the text editor I’m used to. It wasn’t installed and wasn’t in the APT repository. I don’t like emacs or vi so much, but a bit of google revealed that nano is exactly the same as pico.

Now, to connect via ssh I need to use the p switch, replacing 22 below the with the non-standard port number and user and password as required.

ssh -p 22 user@servername

I’ve set up the login as an alias in my .bash_profile (on my local machines). This new port has to be specified in the scp command too. Here is the format (note that the P switch needs to be uppercase here, and that 22 should be replaced with the non-standard port number):

#copy a file
scp -P 22 local/path/filename.ext  user@remoteserver:/remote/path/

#copy a file and rename
scp -P 22 local/path/filename.ext \

#copies a directory
scp -Pr 22 localdirectory  user@server.com:/remote/path/directory/

2. Use ‘hashlimit’ in ‘iptables’

Limits one connection to the SSH port from one IP address per minute with this rule via the command line.

#change the port number to match SSH port
iptables -I INPUT -m hashlimit -m tcp -p tcp --dport 22 \
    --hashlimit 1/min --hashlimit-mode srcip \
    --hashlimit-name ssh -m state --state NEW -j ACCEPT

Then, I set iptables to start at boot via the Webmin control panel (have to say I like Webmin way more than Plesk so far).

3. Use a public-private key and disable password authentiification

Even if you don’t disable password authentification in the end, you’ll be able to log into your server via SSH without typing your password every time with a public-private key pair. If you haven’t already generated an RSA private key, do so now.

ssh-keygen -t rsa

Next, you MUST copy your public key to the server before you can authorize it.

scp -P 22 ~/.ssh/id_rsa.pub user@server.com:~/

ssh to the server, replacing 22 with your non-standard port

ssh -p 22 user@example.com

Now append the public key to your authorized keys file and delete the file you uploaded. Only create the .ssh directory if it doesn’t already exist in your home folder:

cd ~
mkdir .ssh
cat id_rsa.pub >> .ssh/authorized_keys
rm id_rsa.pub

Now make sure permissions are set properly for all necessary files and directories. The go shortcut stands for group and others. In this case, we’re removing write priveliges on the home folder. The +, and – operators add or remove, = assigns. You can also use chmod a, where a stands for all users:

chmod go-w ~
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys

If everything is configured properly, you should be able to access your server account through SSH without a password now.

For ultimate protection against brute-force attacks, you can now set PasswordAuthentication to ‘no’ by editing the sshd_config file

nano /etc/ssh/sshd_config

To disable password authentication just for root, use ‘PermitRootLogin without-password’.

4. Restart SSH

with this command (requires the absolute path).

/etc/init.d/sshd restart

Install Denyhosts

Denyhosts provides SSH attack (also known as dictionary based attacks and brute force attacks) prevention and is used by thousands of users worldwide and now has over 27,000 users contributing synchronization data. There is no RPM in the standard repo, neither YUM or APT worked at first.

Solution: use and external repository. The RPMForge guys provide stable, common packages which are missing from the main repos. I added their repositories to my sources by installing their latest RPM. Info here: http://dag.wieers.com/rpm/FAQ.php#B2. I used this command:

rpm -Uhv http://apt.sw.be/packages/rpmforge-release/rpmforge-release-0.3.6-1.el5.rf.i386.rpm

then, ran

yum update

as I hadn’t before, and then

yum install denyhosts

though apt-get install would have worked equally well. I checked the instructions here http://denyhosts.sourceforge.net/ssh_config.html and confirmed that my shd server was compiled w/ tcp_wrappers support. That’s not all, though. The installer doesn’t actually do the whole job for you.

#this is where the script looks for config details
mkdir /usr/share/denyhosts

#go there
cd /usr/share/denyhosts/

#Copy the sample configuration file to the real configuration file
cp /usr/share/doc/denyhosts-2.6/denyhosts.cfg-dist \

#edit the config file
nano denyhosts.cfg

Uncomment line 379, RESET_ON_SUCCESS = yes and set on line 129, to accommodate my sticky fingers: DENY_THRESHOLD_ROOT = 3. We’ll get back to this file to enable synchronization mode.

#make it possible for DenyHosts to run as a daemon
cp /usr/share/doc/denyhosts-2.6/daemon-control-dist \

#edit the daemon config
nano daemon-control

#make sure that the daemon control script is executable (by root)
chown root:root daemon-control
chmod 700 daemon-control

#manually start denyhosts to make sure it's working
service denyhosts start

#Check the daemon log to ensure that
#DenyHosts is running successfully
nano /var/log/denyhosts

#Create a symbolic link from /etc/init.d
cd /etc/init.d
ln -s /usr/share/denyhosts/daemon-control denyhosts

#use chkconfig to ensure that DenyHosts runs at boot time
chkconfig --add denyhosts

GREAT! Now let’s set up synchronization mode

service denyhosts stop

#Now, configure the last section of the
#denyhosts.cfg file, then restart denyhosts
service denyhosts start

#Check the daemon log to ensure that
#DenyHosts is running successfully
nano /var/log/denyhosts

Dance for joy! Take a break. That was a lot of work.

Set up a Linux Firewall Using IPTables and Webmin

I basically followed the instructions here: http://rimuhosting.com/howto/firewall.jsp. Worth noting: the “hashlimit in IPTables” rule previously mentioned needs to be committed and, upon doing so, makes you skip the default rule configuration as described on the Rimuhosting site. So, I went ahead and reset the firewall, implemented the defaults, clicked “Apply Configuration” then entered the my hashlimit rule via the command line again.

Add to Yahoo Add to Google Save to Del.icio.us Digg IT! Live Bookmarks!

5 Responses to “securing SSH under CentOS 5”  

  1. 1 jamon

    To make scp/sftp connections to a server with ssh not running on port 22 easier, create a ~/.ssh/config file. Typically host, user, and port are sufficient. Here’s an example:

    Host foo
    Hostname foo.bar.com
    User baz
    Port 2022
    Compression yes

    You can use an IP in place of the hostname. Then you can run something like “scp file.tar.gz baz@foo:” instead of “scp -P 2022 file.tar.gz baz@foo.bar.com:” Note that compression is optional and sometimes makes things slower depending on the client and server.

  2. 2 BlueNile

    You can write specific firewall rules to filter ssh scanner. Also you van limit ssh access from selected IP addresses.

  3. 3 Dougal

    Lovely tutorial.

    Obviously I’m a latecomer, but I can confirm that now on CentOS 5 installing denyhosts from http://apt.sw.be/redhat/el5/en/x86_64/rpmforge/RPMS//rpmforge-release-0.3.6-1.el5.rf.x86_64.rpm DOES do the whole job for you and there’s no need to move and rename the config files.

    It leaves the config file at /etc/denyhosts/denyhosts.cfg and the service control script at /etc/init.d/denyhosts

    The default “working directory” is, however, in /usr/share/denyhosts – but this will be created automatically.

    Thank you.

  4. 4 freelance coder

    Excellent. I haven’t had the same experience here in Newfoundland, but I suppose that isn’t very suprising.

  5. 5 Quinn Harbison

    I’d enjoy seeing an article of the top 10 VPS suppliers to get actual peoples thoughts of their products and services.


This is the blog of Andrew Mallis, a Toronto-born, San Francisco-based polymedia artist. I work in new(er) media with code, photography and electronics, and in traditional media by writing, drawing & painting.