Use iptables to block unwanted traffic on Centos or RH 5 and 6 machines

Ip tables is a powerfull firewall included in many linux distros, we’re here focusing on Centos or Red Hat 5 and 6 distributions, you can check if iptables is installed on your system with the command:
rpm -q iptables
you should get the iptables version if present.

With the command
iptables -L -v
you can check the configuration you’re running, something like this as default configuration:
# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED
ACCEPT icmp -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:ssh
REJECT all -- anywhere anywhere reject-with icmp-host-prohibited

Chain FORWARD (policy ACCEPT)
target prot opt source destination
REJECT all — anywhere anywhere reject-with icmp-host-prohibited

Chain OUTPUT (policy ACCEPT)
target prot opt source destination

The firewall is based on chains, each chain is just a firewall area, looking at the default configuration we have three chains, INPUT, FORWARD, OUTPUT.
in INPUT chain are listed all rules for incoming packets
in FORWARD chain are all forwarding rules, usually for routers.
in OUTPUT chain we have all rules for outgoing packets.
We’ll now set up an easy firewall, frequently used on stand alone internet server, a Stateful Packet Inspection (SPI) firewall allowing all outgoing traffic, but blocking all forwarding and unwanted incoming packets as default, allowing only incoming packet for our hosted services.

Let’s move now into configuration details, starting to edit and add some rules:
iptables -P INPUT ACCEPT
to allow all incoming traffic on chain INPUT, if we’re logging in over an SSH connection and something goes wrong we won’t get ourself locked out from the system, we’ll set DROP as default later, as soon as the configuration process ends.
then digit:
iptables -A INPUT -i lo -j ACCEPT
To allow all local traffic, the -A option adds a rule to the INPUT chain, -i means interface and adds that rule to the specified interface, lo, or local (127.0.0.1), while -j (jump) specify the standard action over packets maching the rule, in this case ACCEPT. This rule is very important.
Another “must add” command is:
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
This rule allows all packets coming or related to an established connection to come in. With -m we load a module (state), the state module can check a packet and see if it’s NEW, ESTABLISHED OR RELATED. NEW are packets from new connections, not initiated by our host, ESTABLISHED and RELATED are packets referring or related to connections established by our host.
Now let’s open ports for our services:
SSH
iptables -I INPUT 4 -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
This command opens a port for SSH service over port 22 tcp. -p adds a rule to a protocol, tcp, while –dport adds the rule to a specific port, 22 is the default for SSH service.

HTTP
iptables -I INPUT 4 -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
Remove the number 4 and leave it blank if you want it to be added on the top.
This rule opens port 80 tcp for http service and add the line in position 4.

If you have other services running you need to issue the above command changing tpc/udp and port number accordingly.
You can find a full list of port numbers and related services here:

As soon as you have all your ports opened, you need to set the default INPUT chain rule to DROP:
iptables -P INPUT DROP
the -P switch sets the default policy for a chain, here is DROP.
If you’re not working on a router system, you also need to block the packet forwarding:
iptables -P FORWARD DROP
while OUTPUT chain should also be set to ACCEPT:
iptables -P OUTPUT ACCEPT
If you trust your users and programs.
Check your rules with
iptables -L -v
and save them so they will be reloaded when booting:
/sbin/service iptables save
the rules are saved in /etc/sysconfig/iptables and reapplied at boot.

If your iptables service do not automatically run on boot check with:
chkconfig --list iptables
If you get something like this everything’s fine
iptables 0:off 1:off 2:on 3:on 4:on 5:on 6:off
else add your iptable command in startup
chkconfig --add iptables
and add the starting run levels:
chkconfig --level 2345 iptables on
so that iptables will automatically start at runlevels 2,3,4,5.

Your all set now, enjoy your brand new firewall.

Reconfiguring SSH making it stronger

SSH is a great and secure way to log into your linux server, but there are some tips to make it stronger and safer. I’m writing some of these tips working on a Centos/RH 5 or 6 distribution, even if different distros can’t be that different.
You better start disabling root logins, but you first need another user for standard logins, just in case you lock yourself out…. we’re calling it newuser, so open your server’s terminal and write:
su -
to login as root
useradd newuser
then give it a password
passwd newuser
and you’ll be promped for a new password, choose a strong password, at least 8 or better 12 digits with caps, numbers and special characters such as !?/%.
Keep yourself logged in as root and edit the file /etc/ssh/sshd_config using nano or vi:
nano /etc/ssh/sshd_config
locate the code and edit to match as follows:
# Prevent root logins:
PermitRootLogin no

restart your sshd service
service sshd restart
Now your root user cannot remotely login by ssh anymore.
Your ssh connection is now safe, anyone trying to break in should break your newuser password first, then gain root password, even using brute force attacks it will take years if you used a strong password as suggested.

You may want to have some computers logging in as root for scripting or other special services, you can do that by using rsa public keys.
You first need to create a public/private key on the client remotely logging into your server:
so move to your client terminal and login as the user running scripts, then digit:
ssh-keygen -t rsa
you’ll be prompted for a file name and password, if you leave it blank pushing return you’ll not be asked for a password when logging in to the server, it’s ok if you’re running scripts, but i strongly suggest you to choose a password if you’re on mobile devices and you’re not running scripts connecting to your remote server. Leave the filename as default (id_rsa.pub)
Now set permissions on your newly created keys:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_rsa

then move to the user ssh directory:
cd ~/.ssh
And copy your public key to the /root/.ssh/authorized_keys on your remote server (remoteserver).
Since you cannot login as root you have to first copy the public key to your newuser home on the remote server
scp ~/.ssh/id_rsa.pub newuser@remoteserver:/home/newuser/
then login to your remote server as newsuser
ssh newuser@remoteserver
become super user (root)
su -
move to newuser home where the public key file is:
cd /home/newuser/
and copy the public key into the server root’s authorized keys file:
cat id_rsa.pub >> /root/.ssh/authorized_keys
Now delete your public key from the server
rm -f /home/newuser/id_rsa.pub
And set permissions on your authorized keys file:
chmod 700 /root/.ssh
chmod 600 /root/.ssh/authorized_keys

And get rid of any possible SElinux problem:
restorecon -Rv /root/.ssh

Now try to login as root to your remote server and you won’t be promped for any password anymore

You may wish to completely disable remote ssh logins, using only public keys logins. Edit the /etc/ssh/sshd_config fileon remote server as root, find and edit the following line as it is:
# Disable password authentication forcing use of keys
PasswordAuthentication no

Be carefull, you can lock yourself out of the system without any ssh logins, so I suggest you to always have a ssh user login available. You can keep it safe changing passwords and using fail2ban (read more later).