CentOS setup - page 1

These CentOS articles will take you from a 'barebones' CentOS 5.1 Slice to a secured and up to date Slice ready for your server software (or whatever you use the Slice for).

Not only that, you will have a better understanding of what is going on and, more importantly, why it's going on.


Log in

On your LOCAL computer, edit the SSH known_hosts file and remove any entries that point to your Slice IP address. If this is a brand new Slice then you will not need to do this, but a reinstall will result in a different signature.

nano ~/.ssh/known_hosts

If you are not using Linux or a Mac on your LOCAL computer, the location of the known_hosts file will differ. Please refer to your own OS for details of where this file is kept.

As soon as you have your IP address and password for your VPS login via SSH:

ssh root@123.45.67.890

User administration

Now we're logged in to the VPS, immediately change your root password

passwd

Add an admin user (I've used the name demo here but any name will do).

adduser demo

You will need to specifically set the password for your new user:

passwd demo

As you know we never log in as the root user (this initial setup is the only time you would need to log in as root). As such, the main administration user (demo) needs to have sudo (Super User) privileges so he can, with a password, complete administrative tasks.

To do this, we're going to add the main user to the 'wheel' group. Once that is done, we need to edit the 'sudoers' file, using visudo, and ensure the 'wheel' group has the correct privileges.

So firstly, add the user to the wheel group:

usermod -a -G wheel demo

Next, give the 'visudo' command:

visudo

Near the bottom of the file you will see this line:

## Allows people in group wheel to run all commands
# %wheel  ALL=(ALL)       ALL

Simply uncomment (remove the '#') so it looks like this:

## Allows people in group wheel to run all commands
%wheel  ALL=(ALL)       ALL

Now members of the 'wheel' group have full sudo privileges.

SSH keygen

One effective way of securing SSH access to your slice is to use a public/private key. This means that a 'public' key is placed on the server and the 'private' key is on our local workstation. This makes it impossible for someone to log in using just a password - they must have the private key.

The first step is to create a folder to hold your keys. On your LOCAL workstation:

mkdir ~/.ssh

That's assuming you use Linux or a Mac and the folder does not exist. For Windows users we have a separate article for key generation using Puttygen.

To create the ssh keys, on your LOCAL workstation enter:

ssh-keygen -t rsa

If you do not want a passphrase then just press enter when prompted.

That created two files in the .ssh directory: id_rsa and id_rsa.pub. The pub file holds the public key. This is the file that is placed on the Slice.

The other file is your private key. Never show, give away or keep this file on a public computer.

SSH copy

Now we need to get the public key file onto the Slice.

We'll use the 'scp' command for this as it is an easy and secure means of transferring files.

Still on your LOCAL workstation enter this command:

scp ~/.ssh/id_rsa.pub demo@123.45.67.890:/home/demo/

When prompted, enter the demo user password.

Change the IP address to your slice and the location to your admin user's home directory (remember the admin user in this example is called demo).

SSH Permissions

OK, so now we've created the public/private keys and we've copied the public key onto the Slice.

Now we need to sort out a few permissions for the ssh key.

On your Slice, create a directory called .ssh in your home folder and move the pub key into it.

mkdir /home/demo/.ssh
mv /home/demo/id_rsa.pub /home/demo/.ssh/authorized_keys

Now we can set the correct permissions on the key:

chown -R demo:demo /home/demo/.ssh
chmod 700 /home/demo/.ssh
chmod 600 /home/demo/.ssh/authorized_keys

Again, change the 'demo' user and group to your admin user and group.

Done. It may seem a long set of steps but once you have done it once you can see the order of things: create the key on your local workstation, copy the public key to the Slice and set the correct permissions for the key.

SSH config

Next we'll change the default SSH configuration to make it more secure:

nano /etc/ssh/sshd_config

Use can use this ssh configuration as an example.

The main things to change (or check) are:

Port 30000                           <--- change to a port of your choosing
Protocol 2
PermitRootLogin no
PasswordAuthentication no
X11Forwarding no
UsePAM no
UseDNS no
AllowUsers demo

I think the setting are fairly self explanatory but the main thing is to move it from the default port of 22 to one of your choosing, turn off root logins and define which users can log in.

PasswordAuthentication has been turned off as we setup the public/private key earlier. Do note that if you intend to access your slice from different computers you may want leave PasswordAuthentication set to yes. Only use the private key if the local computer is secure

iptables

Right, now we have the basics of logging in and securing SSH done.

Next thing is to set up our iptables so we have a more secure installation. To start with, we're going to have three ports open: ssh, http and https.

Let's have a look at the default rules:

iptables -L

This will output something similar to this:

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
RH-Firewall-1-INPUT  all  --  anywhere             anywhere            

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         
RH-Firewall-1-INPUT  all  --  anywhere             anywhere            

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         

Chain RH-Firewall-1-INPUT (2 references)
target     prot opt source               destination         
ACCEPT     all  --  anywhere             anywhere            
ACCEPT     icmp --  anywhere             anywhere            icmp any 
ACCEPT     esp  --  anywhere             anywhere            
ACCEPT     ah   --  anywhere             anywhere            
ACCEPT     udp  --  anywhere             224.0.0.251         udp dpt:mdns 
ACCEPT     udp  --  anywhere             anywhere            udp dpt:ipp 
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:ipp 
ACCEPT     all  --  anywhere             anywhere            state RELATED,ESTABLISHED 
ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:ssh 
REJECT     all  --  anywhere             anywhere            reject-with icmp-host-prohibited

While I won't go into detail about each rule shown here, we like to use our own default iptable rules for the sake of consistency between the articles.

Let's go ahead and remove the current ruleset:

iptables -F

We can then input several commands that allow local connections and keep established connections (which is how the root SSH connection on port 22 will still work when we apply the SSH port changes and apply the new iptables rules).

We'll also open port 80 and port 443 (the normal HTTP and HTTPS ports) and, of course, allow connections to our custom SSH port (30000).

Then we'll allow pings to the Slice and, effectively, reject all other attempts to connect to a port.

So, on the command line, enter these:

iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -i ! lo -d 127.0.0.0/8 -j REJECT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -j ACCEPT
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
iptables -A INPUT -p tcp -m state --state NEW --dport 30000 -j ACCEPT
iptables -A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT
iptables -A INPUT -j REJECT
iptables -A FORWARD -j REJECT

If you are new to iptables then that may seem a little intimidating but, as I recommend with most things, take it one step at a time.

Have a look at each line and see what it does. I actually think they are all pretty self explanatory but don't be afraid to do some research if you are not sure.

Anyway, let's have a look at what rules are in place now:

iptables -L

See the difference between the first time we entered that command and now? Again, have a look at each line of the output and see where is marries up with the rules we entered earlier.

As previously mentioned, If you are unhappy or have made a mistake you can flush the rules and start again with a:

iptables -F

Good.

Although the rules are up and running, they are only active for the current session. If the Slice was rebooted they would be lost.

As such, let's ensure they are restarted on a Slice reboot:

service iptables save

The output confirms the rules were added to the correct file:

Saving firewall rules to /etc/sysconfig/iptables:          [  OK  ]

Feel free to have a look at that file and familiarize yourself with the syntax.

Logging in with the new user

Now we have our basic firewall humming along and we've set the ssh configuration. Now we need to test it. Reload ssh so it uses the new ports and configurations:

/etc/init.d/sshd reload

Don't logout as root yet...

On your LOCAL computer, open a new terminal and log in using the administration user (in this case, demo) to the port number you configured in the sshd_config file:

ssh -p 30000 demo@123.45.67.890

The reason we use a new terminal is that if you can't login you will still have the working connection to try and fix any errors.

Slicehost also has the excellent ajax console so if it all goes horribly wrong, you can log into your slice from the Slicehost management area.

You will be greeted with a plain terminal prompt like this:

[demo@yourvpsname ~]$

Success!

We now know that the firewall and ssh_config works and we can log in.

Let's move on to page 2 which includes updating the install and installing some base programmes.

PickledOnion.

Article Comments:

Brad commented Sat Apr 19 14:32:23 UTC 2008:

In this article we read:

"The first step is to create a folder to hold your keys... That's assuming you use Linux or a Mac and the folder does not exist. I will do a separate article for key generation using Putty for Windows users"

Has this article been completed? I don't see it.

Robert commented Sun Apr 27 01:43:05 UTC 2008:

This is just what I was looking for. I started by reading the Debian Etch guide (I just found that first for some reason).

Is there any reason why in Centos you open root access to a group and add the admin user to the group, whereas in the Debian you give the privilege directly to the user?

Just interested ..

Joah commented Sun Apr 27 03:32:41 UTC 2008:

Ditto.

Chris commented Wed May 28 02:42:04 UTC 2008:

Hi guys, I had a problem stemming from too much cockiness. Coming from Ubuntu I decided to skip from the user creation to the iptables install/config.

This caused a problem that gave me: "-bash: iptables: command not found" ...when I tried running iptables form my new user. This is because in CentOS, as far as I can tell $PATH is relative to the original user regardless of whatever "sudoing" is happening, by default. So, su root and then iptables -L failed. Apparently "su -" gives you the right $PATH.

Email me (chris at christopherhart dot ca) if you have questions.

Mike commented Tue Jul 01 15:51:44 UTC 2008:

@chris: totally, i just worked that one out. if you add /sbin to your PATH list in your user's ~/.bash_profile all is good, no matter what sudoing you're up to. (this is only if you really don't wanna put a /sbin/ infront of iptables

keep it locked

dani commented Sat Jul 12 09:37:08 UTC 2008:

I am trying to use knock to access to the ssh. It would be useful if you could provide with the config of the iptables to allow knocking.

Justin commented Fri Aug 01 07:39:23 UTC 2008:

As Mike said, you have to add the sbin folder to your PATH directive to get iptables to work on the new user your created.

Simple do:

--> nano ~/.bash_profile

Modify the PATH directive to look like this:

PATH=$PATH:$HOME/bin:/sbin/

Hit Crtl+X and Save.

Then

--> source ~/.bash_profile

Should be all set.

Robert commented Wed Aug 13 21:44:37 UTC 2008:

Two comments:

  1. Once you create your ssh key do $ ssh-copy-id -i .ssh/id_rsa.pub root@my.slice.ip This is the built in ssh tool to copy the public key over

  2. the su command doesn't reimport the users path as was hinted earlier by Chris, but to make it more clear this is perfectly legal...
    $ sudo su - root or $ sudo su - demo

The '-' will reload all of the system configuration for that user.

Martin commented Fri Nov 21 10:08:29 UTC 2008:

I too am looking for information on setting up key generation using Putty please advise.

rmd commented Sun Dec 21 13:52:36 UTC 2008:

martin: the two putty programs "puttygen" and "pageant" are what you want here. http://the.earth.li/~sgtatham/putty/0.60/htmldoc/Chapter8.html#pubkey-puttygen for puttygen info. http://the.earth.li/~sgtatham/putty/0.60/htmldoc/Chapter9.html#pageant for pageant

puttygen lets you generate keys and pageant is an agent to hand out the keys when you connect.

Joey commented Fri Jan 23 20:29:36 UTC 2009:

I would like to add some suggestions as far as server security. Perhaps I'm going a bit overboard with paranoia here, but I go with the following:

yum install rkhunter chkrootkit denyhosts
prelink -a
rkhunter --update
rkhunter --propupd
rkhunter -c -sk
chkconfig denyhosts on
service denyhosts start

Then for my firewall, I go with a far more explicit and, again, perhaps overly paranoid setup. The following is from my /etc/sysconfig/iptables file (Created with iptables-save > /etc/sysconfig/iptables)

*filter
:INPUT ACCEPT [61591:24865164]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [53722:15976364]
-A INPUT -s 10.0.0.0/8 -j DROP
-A INPUT -s 169.254.0.0/16 -j DROP
-A INPUT -s 192.168.0.0/16 -j DROP
-A INPUT -s 224.0.0.0/4 -j DROP
-A INPUT -d 224.0.0.0/4 -j DROP
-A INPUT -d 240.0.0.0/5 -j DROP
-A INPUT -s 240.0.0.0/5 -j DROP
-A INPUT -s 0.0.0.0/8 -j DROP
-A INPUT -d 0.0.0.0/8 -j DROP
-A INPUT -d 239.255.255.0/24 -j DROP
-A INPUT -d 255.255.255.255/32 -j DROP
-A INPUT -m state --state INVALID -j DROP
-A INPUT -p icmp -m icmp --icmp-type 17 -j DROP
-A INPUT -p icmp -m icmp --icmp-type 13 -j DROP
-A INPUT -p icmp -m icmp --icmp-type any -m limit --limit 1/sec --limit-burst 5 -j ACCEPT
-A INPUT -p tcp -m tcp --tcp-flags FIN,SYN FIN,SYN -j DROP
-A INPUT -p tcp -m tcp --tcp-flags SYN,RST SYN,RST -j DROP
-A INPUT -p tcp -m tcp --tcp-flags RST RST -m limit --limit 2/sec --limit-burst 2 -j ACCEPT
-A FORWARD -m state --state INVALID -j DROP
-A OUTPUT -m state --state INVALID -j DROP
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 443 -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -d 127.0.0.0/255.0.0.0 -i ! lo -j REJECT --reject-with icmp-port-unreachable
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT
COMMIT

Hope that's useful to somebody. :)

Cory commented Tue Mar 24 02:10:49 UTC 2009:

For anyone looking for the windows SSH keys article, you can find it here:

http://articles.slicehost.com/2009/2/4/ssh-puttygen

Justin commented Sat Mar 28 21:13:03 UTC 2009:

You may need to restart sshd to get the changes to sshd_config to take effect:

/etc/init.d/sshd restart

Mick Knutson commented Tue Apr 21 13:25:57 UTC 2009:

Joey, can you please explain what edits you did to you iptables to get the output you posted here?

I am assuming you jut installed these packages (i.e rkhunter etc), then has to modify your iptables?

Jeff Schuler commented Thu May 07 14:48:18 UTC 2009:

Thanks for these articles! Great stuff. You are a brilliant sysadmin info distillery.

Minor typo in iptables section:

allow connections to our custom SSH port (3000).

...should be 30000

0xc0000005 commented Wed Jun 24 11:10:25 UTC 2009:

"yum install rkhunter chkrootkit denyhosts"

...

Parsing package install arguments No package rkhunter available. No package chkrootkit available. No package denyhosts available.

Wrong suggestions? :)

Mike commented Wed Jun 24 12:58:26 UTC 2009:

Every time when i type this string

iptables -A INPUT -j REJECT

the ssh connection breaks and i need to reboot with old firewall rules and start again

:(

What's wrong?

ferdegje commented Fri Aug 21 06:43:47 UTC 2009:

If you are using Windows as your local machine and these steps do not work, you might want to follow http://andremolnar.com/howto_setupsshkeyswithputtyandnotgetserverrefusedour_key tutorial.

That worked for me

navjeet Singh commented Thu Oct 29 23:48:40 UTC 2009:

Awesome post. This made my initial migration to centos a breeze! (given my limited sys admin skills)

SSH Access commented Tue May 04 17:14:27 UTC 2010:

Hey, That's a great explanation, really helpful for those who have just started configuring servers. For precaution don't forget to test the ssh login with different window, just to avoid locking your self.

Ben Forrest commented Sun Jun 17 09:44:32 UTC 2012:

I solved the package not available problem for rkhunter etc. install rpm here http://j.mp/KcoNGA

Want to comment?


(not made public)

(optional)

(use plain text or Markdown syntax)