October 2018
« Sep    


WordPress Quotes

The future belongs to those who believe in the beauty of their dreams.
Eleanor Roosevelt

Recent Comments

October 2018
« Sep    

Short Cuts

2012 SERVER (64)
2016 windows (9)
AIX (13)
Amazon (34)
Ansibile (18)
Apache (133)
Asterisk (2)
cassandra (2)
Centos (209)
Centos RHEL 7 (258)
chef (3)
cloud (2)
cluster (3)
Coherence (1)
DB2 (5)
DISK (25)
DNS (9)
Docker (28)
Eassy (11)
ELKS (1)
Fedora (6)
ftp (5)
GIT (3)
GOD (2)
Grub (1)
Hacking (10)
Hadoop (6)
horoscope (23)
Hyper-V (10)
IIS (15)
JAVA (7)
JBOSS (32)
jenkins (1)
Kubernetes (2)
Ldap (5)
Linux (189)
Linux Commands (167)
Load balancer (5)
mariadb (14)
Mongodb (4)
MQ Server (22)
MYSQL (84)
Nagios (5)
NaturalOil (13)
Nginx (30)
Ngix (1)
openldap (1)
Openstack (6)
Oracle (34)
Perl (3)
Postfix (19)
Postgresql (1)
PowerShell (2)
Python (3)
qmail (36)
Redis (12)
RHCE (28)
Security on Centos (29)
SFTP (1)
Shell (64)
Solaris (58)
Sql Server 2012 (4)
squid (3)
SSH (10)
SSL (14)
Storage (1)
swap (3)
TIPS on Linux (28)
tomcat (59)
Uncategorized (29)
Veritas (2)
vfabric (1)
VMware (28)
Weblogic (38)
Websphere (71)
Windows (19)
Windows Software (2)
wordpress (1)

WP Cumulus Flash tag cloud by Roy Tanck requires Flash Player 9 or better.

Who's Online

28 visitors online now
5 guests, 23 bots, 0 members

Hit Counter provided by dental implants orange county

E-mail Alert on Root SSH Login

E-mail Alert on Root SSH Login

Want to be notified instantly when someone logs into your server as root? No problem, check out this nice tutorial on email notification for root logins. Keeping track of who logs into your server and when is very important, especially when you’re dealing with the super user account. We recommend that you use an email address not hosted on the server your sending the alert from.


So lets get started!

1. Login to your server and su to root, I know the irony!

2. cd /root

3. pico .bashrc

4. Scroll to the end of the file then add the following:
echo ‘ALERT – Root Shell Access (YourserverName) on:’ `date` `who` | mail -s “Alert: Root Access from `who | cut -d”(” -f2 | cut -d”)” -f1`” you@yourdomain.com

Replace YourServerName with the handle for your actual server
Replace you@yourdomain.com with your actual email address

Log all activity

I log sshd session in a file called /var/log/sshd.log and here’s how I do
1. touch /var/log/sshd.log

2. edit your /etc/syslog.conf and add the lines
*.* /var/log/sshd.log

3. killall -HUP syslogd

The sshd will now log stuff into /var/log/sshd.log. Edit your
/etc/ssh/sshd_config file to determine what gets logged. By default, the following lines are in sshd_config for sylog logging:

SyslogFacility AUTH
LogLevel INFO

Change as necessary, more details are in the sshd manpage.

Hide Apache Info

One of the things which gives a potential attacker some help is them knowing which versions of software you use. This can be very easy to find out, particularly if you have never taken steps to secure this information.

For example: I would like to know what software apache.org are using/have used so I look at netcraft (for example) http://toolbar.netcraft.com/site_report?url=http://www.apache.org Linux Apache/2.2.3 Unix mod_ssl/2.2.3 OpenSSL/0.9.7g 12-Apr-2007

I now know that I should look for exploits relating to linux, apache v2.2.3, mod_ssl 2.2.3 and OpenSSL0.9.7g.

By hiding this information you can either report simply “unknown” or just “apache” and no other info. This doesn’t directly make your box more secure, what it does do is start to make the task more difficult for a would-be attacker and for such a small amount of effort it really does seem silly not to do it. So how?

The first thing is to set the ServerTokens directive. I am using a RH linux box so if you know your OS differs, find the corresponding location of your httpd.conf:

vi or pico /etc/httpd/conf/httpd.conf

Find the line(s) containing ServerTokens and ServerSignature

ServerTokens has the following options (I used Prod):

ProductOnly     Server: Apache
Major     Server: Apache/2
Minor     Server: Apache/2.2
Minimal     Server: Apache/2.2.3
OS     Server: Apache/2.2.3 (RedHat)
Full (or not specified) default     Server: Apache/2.2.34 (RedHat) mod_ssl/2.2.3 OpenSSL/0.9.7g
The syntax is as follows:

ServerTokens ProductOnly
ServerSignature Off

Close the config file and restart apache (service apache restart OR /etc/init.d/httpd restart)

CentOS / Redhat Iptables

How do I configure a host-based firewall called Netfilter (iptables) under CentOS / RHEL / Fedora / Redhat Enterprise Linux?
Netfilter is a host-based firewall for Linux operating systems. It is included as part of the Linux distribution and it is activated by default. This firewall is controlled by the program called iptables. Netfilter filtering take place at the kernel level, before a program can even process the data from the network packet.

Iptables Config File
The default config files for RHEL / CentOS / Fedora Linux are:
/etc/sysconfig/iptables – The system scripts that activate the firewall by reading this file.

Task: Display Default Rules
Type the following command:
iptables –line-numbers -n -L
Sample outputs:
Chain INPUT (policy ACCEPT)
num target prot opt source destination
1 RH-Firewall-1-INPUT all —
Chain FORWARD (policy ACCEPT)
num target prot opt source destination
1 RH-Firewall-1-INPUT all —
Chain OUTPUT (policy ACCEPT)
num target prot opt source destination
Chain RH-Firewall-1-INPUT (2 references)
num target prot opt source destination
1 ACCEPT all —
2 ACCEPT icmp — icmp type 255
3 ACCEPT udp — udp dpt:5353
4 ACCEPT udp — udp dpt:53
6 ACCEPT tcp — state NEW tcp dpt:22
7 ACCEPT tcp — state NEW tcp dpt:53
8 REJECT all — reject-with icmp-host-prohibited

Task: Turn On Firewall
Type the following two commands to turn on firewall:
chkconfig iptables on
service iptables start
# restart the firewall
service iptables restart
# stop the firewall
service iptables stop

Understanding Firewall
There are total 4 chains:
INPUT – The default chain is used for packets addressed to the system. Use this to open or close incoming ports (such as 80,25, and 110 etc) and ip addresses / subnet (such as
OUTPUT – The default chain is used when packets are generating from the system. Use this open or close outgoing ports and ip addresses / subnets.
FORWARD – The default chains is used when packets send through another interface. Usually used when you setup Linux as router. For example, eth0 connected to ADSL/Cable modem and eth1 is connected to local LAN. Use FORWARD chain to send and receive traffic from LAN to the Internet.
RH-Firewall-1-INPUT – This is a user-defined custom chain. It is used by the INPUT, OUTPUT and FORWARD chains.
Packet Matching Rules
Each packet starts at the first rule in the chain .
A packet proceeds until it matches a rule.
If a match found, then control will jump to the specified target (such as REJECT, ACCEPT, DROP).
Target Meanings
The target ACCEPT means allow packet.
The target REJECT means to drop the packet and send an error message to remote host.
The target DROP means drop the packet and do not send an error message to remote host or sending host.
Edit /etc/sysconfig/iptables, enter:
# vi /etc/sysconfig/iptables
You will see default rules as follows:
:RH-Firewall-1-INPUT – [0:0]
-A INPUT -j RH-Firewall-1-INPUT
-A FORWARD -j RH-Firewall-1-INPUT
-A RH-Firewall-1-INPUT -i lo -j ACCEPT
-A RH-Firewall-1-INPUT -p icmp –icmp-type any -j ACCEPT
-A RH-Firewall-1-INPUT -p udp –dport 5353 -d -j ACCEPT
-A RH-Firewall-1-INPUT -p udp -m udp –dport 53 -j ACCEPT
-A RH-Firewall-1-INPUT -m state –state ESTABLISHED,RELATED -j ACCEPT
-A RH-Firewall-1-INPUT -m state –state NEW -m tcp -p tcp –dport 22 -j ACCEPT
-A RH-Firewall-1-INPUT -m state –state NEW -m tcp -p tcp –dport 53 -j ACCEPT
-A RH-Firewall-1-INPUT -j REJECT –reject-with icmp-host-prohibited
Drop All Traffic
Find lines:
Update as follows to change the default policy to DROP from ACCEPT for the INPUT and FORWARD built-in chains:
Log and Drop Spoofing Source Addresses
Append the following lines before final COMMIT line:
-A INPUT -i eth0 -s -j LOG –log-prefix “IP DROP SPOOF ”
-A INPUT -i eth0 -s -j LOG –log-prefix “IP DROP SPOOF ”
-A INPUT -i eth0 -s -j LOG –log-prefix “IP DROP SPOOF ”
-A INPUT -i eth0 -s -j LOG –log-prefix “IP DROP MULTICAST ”
-A INPUT -i eth0 -s -j LOG –log-prefix “IP DROP SPOOF ”
-A INPUT -i eth0 -d -j LOG –log-prefix “IP DROP LOOPBACK ”
-A INPUT -i eth0 -s -j LOG –log-prefix “IP DROP MULTICAST ”
-A INPUT -i eth0 -s -j LOG –log-prefix “IP DROP ”
-A INPUT -i eth0 -s -j LOG –log-prefix “IP DROP ”
-A INPUT -i eth0 -s -j LOG –log-prefix “IP DROP ”
-A INPUT -i eth0 -s -j LOG –log-prefix “IP DROP ”
-A INPUT -i eth0 -s -j LOG –log-prefix “IP DROP ”

Log And Drop All Traffic
Find the lines:
-A RH-Firewall-1-INPUT -j REJECT –reject-with icmp-host-prohibited
Update it as follows:
-A RH-Firewall-1-INPUT -j LOG
-A RH-Firewall-1-INPUT -j DROP

Open Port
To open port 80 (Http server) add the following before COMMIT line:
-A RH-Firewall-1-INPUT -m tcp -p tcp –dport 80 -j ACCEPT
To open port 53 (DNS Server) add the following before COMMIT line:
-A RH-Firewall-1-INPUT -m tcp -p tcp –dport 53 -j ACCEPT
-A RH-Firewall-1-INPUT -m udp -p tcp –dport 53 -j ACCEPT
To open port 443 (Https server) add the following before COMMIT line:
-A RH-Firewall-1-INPUT -m tcp -p tcp –dport 443 -j ACCEPT
To open port 25 (smtp server) add the following before COMMIT line:
-A RH-Firewall-1-INPUT -m tcp -p tcp –dport 25 -j ACCEPT
Only allow SSH traffic From
-A RH-Firewall-1-INPUT -s -m state –state NEW -p tcp –dport 22 -j ACCEPT
Enable Printing Access For
-A RH-Firewall-1-INPUT -s -p udp -m udp –dport 631 -j ACCEPT
-A RH-Firewall-1-INPUT -s -p tcp -m tcp –dport 631 -j ACCEPT
Allow Legitimate NTP Clients to Access the Server
-A RH-Firewall-1-INPUT -s -m state –state NEW -p udp –dport 123 -j ACCEPT
Open FTP Port 21 (FTP)
-A RH-Firewall-1-INPUT -m state –state NEW -p tcp –dport 21 -j ACCEPT
Save and close the file. Edit /etc/sysconfig/iptables-config, enter:
# vi /etc/sysconfig/iptables-config
Make sure ftp module is loaded with the space-separated list of modules:
To restart firewall, type the following commands:
# service iptables restart
# iptables -vnL –line-numbers
Edit /etc/sysctl.conf For DoS and Syn Protection
Edit /etc/sysctl.conf to defend against certain types of attacks and append / update as follows:
net.ipv4.conf.all.log_martians = 1
net.ipv4.conf.default.accept_source_route = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.default.secure_redirects = 0
net.ipv4.icmp_echo_ignore_broadcasts = 1
#net.ipv4.icmp_ignore_bogus_error_messages = 1
net.ipv4.tcp_syncookies = 1
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
See previous FAQ, “Linux Kernel /etc/sysctl.conf Security Hardening” for more details.

Alternate Configuration Option
You can skip /etc/sysconfig/iptables file and create a shell script from scratch as follows:
# A sample firewall shell script
# Stop certain attacks
echo “Setting sysctl IPv4 settings…”
$SYSCTL net.ipv4.ip_forward=0
$SYSCTL net.ipv4.conf.all.send_redirects=0
$SYSCTL net.ipv4.conf.default.send_redirects=0
$SYSCTL net.ipv4.conf.all.accept_source_route=0
$SYSCTL net.ipv4.conf.all.accept_redirects=0
$SYSCTL net.ipv4.conf.all.secure_redirects=0
$SYSCTL net.ipv4.conf.all.log_martians=1
$SYSCTL net.ipv4.conf.default.accept_source_route=0
$SYSCTL net.ipv4.conf.default.accept_redirects=0
$SYSCTL net.ipv4.conf.default.secure_redirects=0
$SYSCTL net.ipv4.icmp_echo_ignore_broadcasts=1
#$SYSCTL net.ipv4.icmp_ignore_bogus_error_messages=1
$SYSCTL net.ipv4.tcp_syncookies=1
$SYSCTL net.ipv4.conf.all.rp_filter=1
$SYSCTL net.ipv4.conf.default.rp_filter=1
$SYSCTL kernel.exec-shield=1
$SYSCTL kernel.randomize_va_space=1
echo “Starting IPv4 Firewall…”
$IPT -t nat -F
$IPT -t nat -X
$IPT -t mangle -F
$IPT -t mangle -X
# load modules
modprobe ip_conntrack
[ -f “$BLOCKEDIPS” ] && BADIPS=$(egrep -v -E “^#|^$” “${BLOCKEDIPS}”)
# interface connected to the Internet
#Unlimited traffic for loopback
# DROP all incomming traffic
if [ -f “${BLOCKEDIPS}” ];
# create a new iptables list
for ipblock in $BADIPS
$IPT -A $SPAMLIST -s $ipblock -j LOG –log-prefix “$SPAMDROPMSG ”
$IPT -A $SPAMLIST -s $ipblock -j DROP
# Block sync
$IPT -A INPUT -i ${PUB_IF} -p tcp ! –syn -m state –state NEW -m limit –limit 5/m –limit-burst 7 -j LOG –log-level 4 –log-prefix “Drop Sync”
$IPT -A INPUT -i ${PUB_IF} -p tcp ! –syn -m state –state NEW -j DROP
# Block Fragments
$IPT -A INPUT -i ${PUB_IF} -f -m limit –limit 5/m –limit-burst 7 -j LOG –log-level 4 –log-prefix “Fragments Packets”
$IPT -A INPUT -i ${PUB_IF} -f -j DROP
# Block bad stuff
$IPT -A INPUT -i ${PUB_IF} -p tcp –tcp-flags ALL FIN,URG,PSH -j DROP
$IPT -A INPUT -i ${PUB_IF} -p tcp –tcp-flags ALL ALL -j DROP
$IPT -A INPUT -i ${PUB_IF} -p tcp –tcp-flags ALL NONE -m limit –limit 5/m –limit-burst 7 -j LOG –log-level 4 –log-prefix “NULL Packets”
$IPT -A INPUT -i ${PUB_IF} -p tcp –tcp-flags ALL NONE -j DROP # NULL packets
$IPT -A INPUT -i ${PUB_IF} -p tcp –tcp-flags SYN,RST SYN,RST -j DROP
$IPT -A INPUT -i ${PUB_IF} -p tcp –tcp-flags SYN,FIN SYN,FIN -m limit –limit 5/m –limit-burst 7 -j LOG –log-level 4 –log-prefix “XMAS Packets”
$IPT -A INPUT -i ${PUB_IF} -p tcp –tcp-flags SYN,FIN SYN,FIN -j DROP #XMAS
$IPT -A INPUT -i ${PUB_IF} -p tcp –tcp-flags FIN,ACK FIN -m limit –limit 5/m –limit-burst 7 -j LOG –log-level 4 –log-prefix “Fin Packets Scan”
$IPT -A INPUT -i ${PUB_IF} -p tcp –tcp-flags FIN,ACK FIN -j DROP # FIN packet scans
$IPT -A INPUT -i ${PUB_IF} -p tcp –tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP
# Allow full outgoing connection but no incomming stuff
# Allow ssh
$IPT -A INPUT -i ${PUB_IF} -p tcp –destination-port 22 -j ACCEPT
# Allow http / https (open port 80 / 443)
$IPT -A INPUT -i ${PUB_IF} -p tcp –destination-port 80 -j ACCEPT
#$IPT -A INPUT -o ${PUB_IF} -p tcp –destination-port 443 -j ACCEPT
# allow incomming ICMP ping pong stuff
$IPT -A INPUT -i ${PUB_IF} -p icmp –icmp-type 8 -m state –state NEW,ESTABLISHED,RELATED -j ACCEPT
#$IPT -A OUTPUT -o ${PUB_IF} -p icmp –icmp-type 0 -m state –state ESTABLISHED,RELATED -j ACCEPT
# Allow port 53 tcp/udp (DNS Server)
$IPT -A INPUT -i ${PUB_IF} -p udp –dport 53 -m state –state NEW,ESTABLISHED,RELATED -j ACCEPT
#$IPT -A OUTPUT -o ${PUB_IF} -p udp –sport 53 -m state –state ESTABLISHED,RELATED -j ACCEPT
$IPT -A INPUT -i ${PUB_IF} -p tcp –destination-port 53 -m state –state NEW,ESTABLISHED,RELATED -j ACCEPT
#$IPT -A OUTPUT -o ${PUB_IF} -p tcp –sport 53 -m state –state ESTABLISHED,RELATED -j ACCEPT
# Open port 110 (pop3) / 143
$IPT -A INPUT -i ${PUB_IF} -p tcp –destination-port 110 -j ACCEPT
$IPT -A INPUT -i ${PUB_IF} -p tcp –destination-port 143 -j ACCEPT
##### Add your rules below ######
##### END your rules ############
# Do not log smb/windows sharing packets – too much logging
$IPT -A INPUT -p tcp -i ${PUB_IF} –dport 137:139 -j REJECT
$IPT -A INPUT -p udp -i ${PUB_IF} –dport 137:139 -j REJECT
# log everything else and drop
exit 0

CentOS 6 as a production LAMP server

LAMP (Linux, Apache, MySQL, PHP) server from the scratch in an virtualized environment. There are many articles, but neither of them cover all the required steps. So far after each I had to troubleshoot many issues that weren’t even mentioned in the articles and that involves lot of searching and playing around. One of many issues came from SElinux security contexts. That supports my personal believe that many people just turn SElinux off when run into troubles and don’t care much about security, since those how-tos were aimed for development / sandbox servers for just playing and not real production usage. Otherwise there would be a troubleshooting info included, or not?

My motivation to write down this article is because I think I reinvented the wheel many times and sometimes running into same issues again. So I decided to compile all the information all-together into this one bulletproof how-to, so i can return to it and improve it over time and to prevent repeating mistakes in future. I see the clear benefits from sharing my know-how here, because you will definitely come up with some comments and bright ideas which could help me to improve it over time and maybe introduce new features inside installation. Also writing it down forces me to think about the correct order of the commands and include every change as it will come.

I want to have a production, enterprise grade, free, fast and secure linux. In other words I want to keep SElinux enabled and I would like to have it as minimal as possible and install only what is necessary. In my case webserver is virtualized in VMware vSphere Hypervisor (ESXi) environment – at the time of writing of this article HP’s customized ver4.1 hosted on an HP ProLiant DL380 G7 rack server HW with 16GB RAM, 6x146GB SAS/6G 15000rpm drives in RAID10 array. I’m preparing for an upgrade to version 5.0 and will share an how-to do it after that.

The designation of this system is to run custom developed PHP/MySQL CRM server and accounting software. Therefore there is some specific optimization for my environment included and I will especially mention those steps trough this how-to.

The requirements for the target system state are these:

  • Free but enterprise-grade linux (done)
  • httpd (Apache) including configuration:
    • SSL support (done)
    • targeting to /home/webroot directory (needs improvement)
    • ServerName FDQN (needs insertion)
    • http auto redirecting to https (needs improvement)
  • PHP (done)
  • MySQL (done)
    • MySQL security hardening (needs improvement according to the script)
  • vsftpd (FTP sever) including SFTP support and passive mode transfers, MySQL login/password authentication (needs improvement, currently missing SFTP and passive mode support)
  • phpMyAdmin accessible trough HTTPS (needs improvement, allow access only trough https)
  • midnight commander accessible trough SSH (done)
  • SElinux enabled and security hardening performed, possibility to put the system into DMZ or directly on internet (done, needs testing)
  • firewall enabled and configured (done)
  • SSH enabled for remote administration via putty (done)
  • Optimized performance (needs improvement)
  • Scalable solution (done)
  • Easy to maintain, support, backup trough cron and restore (needs improvement – I will provide backup scripts and cron part)
  • Tested (needs more testing to claim it stable and secure)

Now let’s get to the thing:

I assume that you have up and running HW or virtual machine for this. I recommend you to allocate at least these specs. And remember – more is better!

  • Production server:
    • 4GB of RAM (8GB recommended)
    • Dual-Core CPU (Quad-Core recommended especially if server is running in virtual environment)
    • 40GB of storage (100GB recommended)
    • stable and fast internet connectivity with low latency and no lags
  • Development/testing server
    • 2GB RAM should be enough
    • 20GB of storage or more
    • internet connectivity
  • Sandbox with minimal configuration
    • 512MB RAM
    • 20GB of storage
    • internet connectivity

First we have to do a netinstall CentOS v6.0 x86_64. I’m always performing this with a netinstall and choose minimal installation during setup wizard. This allow me to always quickly download the actual version of CentOS in minutes and perform basic installation very fast. It usually takes around 15-45 minutes depending on HW and internet connection speed. My choice of 64-bit architecture comes from that system will operate above 4GB RAM and probably more over the time. I also believe that x64 is slightly improving performance but it depends on the application. My favorite Linux distros are RHEL, CentOS, Fedora and Debian, but last year I always ended up with CentOS since it’s free and equal to RHEL. I use RHEL for middle and large enterprise deployments with high-availability and standardization demands, where 3rd level vendor support is crucial. But for many and many deployments the CentOS is a perfect free solution that will get the job done.

  1. Download an iso image with netinstall version of CentOS 6.0 according to the server architecture (can be found at mirror.centos.org). I’ve used this one.
  2. Burn the iso onto CD/DVD, write it to USB drive, or mount it trough remote management of the server (iLO for HP or DRAC for Dell). If you use VMware you can mount it via VMware vSphere client.
  3. Setup your computer system’s BIOS to boot from media where you stored the image or use the boot menu feature. In VMware vCenter client, you can press Escape key during BIOS POST boot-up sequence – and you have to be very fast 😉 otherwise it will take more than one try…
  4. Boot into installation
  5. Select “Install or upgrade an existing system” (first choice) by just pressing enter.
  6. You can test you iso downloaded media if it is not corrupted. I prefer to test.
  7. Choose URL as Installation Method
  8. Configure TCP/IP (DHCP or manual)
  9. During URL setup you will have to enter the path to server, where installation files resides. This can be any from CentOS mirrors. I use this path, because it’s easy to remember: http://mirror.centos.org/centos/6.0/os/x86_64. Be sure to check the processor architecture, this one is for Intel/AMD 64 bit.
  10. The setup will download necessary files and proceed onto welcome screen
  11. Then you can proceed trough installation steps according to this article, starting up with step 5 and ending up with step 22 from that article and returning back here. No need to reinvent the wheel ;).
  12. That’s it, we have minimal CentOS 6 installation up and running
  13. Now we can proceed into LAMP installation and configuration:
  14. Be sure you’ve issued update command as a root user before continuing, it will update whole system and load patches since the iso initial release:
    yum -y update
  15. Install required packages (be sure to copy the whole line):
    yum -y install mc httpd mysql-server php php-mysql mysql php-mbstring php-pear php-pecl-apc php-xml php-imap yum-priorities php-pecl-zip php-gd php-ldap mod_ssl openssl vsftpd pam_mysql
  16. Install the support for EPEL repository:
    rpm -hUv http://download.fedora.redhat.com/pub/epel/6/x86_64/epel-release-6-5.noarch.rpm
  17. Generate private key for Apache:
    openssl genrsa -out ca.key 1024
  18. Generate CSR for Apache:
    openssl req -new -key ca.key -out ca.csr
  19. Generate Self Signed Key:
    openssl x509 -req -days 365 -in ca.csr -signkey ca.key -out ca.crt
  20. Copy the files to the correct locations:
    cp ca.crt /etc/pki/tls/certs
    cp ca.key /etc/pki/tls/private/ca.key
    cp ca.csr /etc/pki/tls/private/ca.csr
  21. Then we need to update the Apache SSL configuration file:
    vi /etc/httpd/conf.d/ssl.conf
    # Change the paths to match where the Key file is stored. If you've
    # used the method above it will be: 
    SSLCertificateFile /etc/pki/tls/certs/ca.crt 
    # Then set the correct path for the Certificate Key File a few lines 
    # below. If you've followed the instructions above it is:
    SSLCertificateKeyFile /etc/pki/tls/private/ca.key
    # Quit and save
  22. Enable MySQL daemon auto start-up with system:
    chkconfig mysqld on
  23. Start MySQL daemon:
    service mysqld start
  24. Connect locally to MySQL CLI:
    mysql -h -u root
  25. List all users in MySQL. You should perform the root password setting for each line as described below:
    select user,host,password from mysql.user;
  26. Set the MySQL root password for localhost connections. Remember to use only sensible SAFE passwords! Most of people will use the same password for all three steps:
    set password for root@localhost=password('desiredmysqlrootpassword');
  27. Set the MySQL root password for loopback connections:
    set password for root@''=password('desiredmysqlrootpassword');
  28. Set the MySQL root password for your hostname loopback connections. Remeber to replace hostname for the one you have entered during CentOS installation. In the future, you should perform this security step for each internet realm/domain name you will need to be accessed from:
    set password for root@'hostname'=password('desiredmysqlrootpassword');
  29. Delete anonymous users:
    delete from mysql.user where user='';
  30. Print the final MySQL user table:
    select user,host,password from mysql.user;
  31. Exit the MySQL CLI:
  32. Start the MySQL CLI (be sure to use -h, because MySQL from CentOS rpm repository doesnt support IPv6, although localhost is mapped to an IPv6 address:
    mysql -h -u root –p
    # Perform these commands onto MySQL CLI:
    CREATE DATABASE vsftpd; 
    USE vsftpd; 
    GRANT SELECT ON vsftpd.* TO 'vsftpd'@'' IDENTIFIED BY 'vsftpdpassword'; 
    CREATE TABLE `accounts` ( `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY , `username` VARCHAR( 30 ) NOT NULL , `pass` VARCHAR( 50 ) NOT NULL , UNIQUE (`username`) ) ENGINE = MYISAM ;
    INSERT INTO accounts (username, pass) VALUES('ftpdesiredusername', md5('ftpdesiredpassword'));
  33. Add vsftpd system account:
    useradd -G users -s /bin/false -d /home/vsftpd vsftpd
  34. Backup the vsftpd backup file content:
    cp -v /etc/vsftpd/vsftpd.conf /etc/vsftpd/vsftpd.conf-orig
  35. Empty the config file:
    > /etc/vsftpd/vsftpd.conf
  36. Edit the vsftpd config file:
    vi /etc/vsftpd/vsftpd.conf
    # Enter this into vsftpd.conf file:
    # No ANONYMOUS users allowed
    # Allow 'local' users with WRITE permissions (0755)
    # if you want to LOG vsftpd activity then uncomment this  log_ftp_protocol
    # log_ftp_protocol=YES
    # uncomment xferlog_file and xferlog_std_format if you  DIDN'T use the line above
    # with log_ftp_protocol - it must be excluding each other
    # The name of log file when xferlog_enable=YES and  xferlog_std_format=YES
    # WARNING - changing this filename affects /etc/logrotate.d/vsftpd.log
    # xferlog_std_format Switches between logging into  vsftpd_log_file and xferlog_file files.
    # NO writes to vsftpd_log_file, YES to xferlog_file
    # xferlog_std_format=YES
    # You may change the default value for timing out an idle session (in  seconds).
    # You may change the default value for timing out a data connection (in  seconds).
    # define a unique user on your system which the
    # ftp server can use as a totally isolated and unprivileged user.
    # here we use the authentication module for vsftpd to check users name  and passw
    # here the vsftpd will allow the 'vsftpd' user to login into the 
    # '/home/vsftpd/$USER'  directory
  37. Create directory with user configuration files:
    mkdir /etc/vsftpd/vsftpd_user_conf
  38. Edit ftp user configuration:
    vi /etc/vsftpd/vsftpd_user_conf/ftpusername
    # full path to the directory where 'ftpusername' will have access, change  to your needs
  39. Create webroot directory:
    mkdir /home/webroot
  40. Allow full permissions for owner:
    chmod 700 /home/webroot
  41. Change owner:
    chown vsftpd:users /home/webroot
  42. Backup pam.d vsftpd authentication profile file:
    cp /etc/pam.d/vsftpd /etc/pam.d/vsftpd-orig
  43. Erase vsftpd pam.d auth config file:
    cat /dev/null > /etc/pam.d/vsftpd
  44. Edit file /etc/pam.d/vsftpd:
    vi /etc/pam.d/vsftpd
    # Insert the lines below into the file:
     session       optional        pam_keyinit.so       force revoke
     auth required pam_mysql.so user=vsftpd passwd=vsftpdpassword  host= db=vsftpd table=accounts usercolumn=username   passwdcolumn=pass crypt=3
     account required pam_mysql.so user=vsftpd passwd=vsftpdpassword  host= db=vsftpd table=accounts usercolumn=username  passwdcolumn=pass crypt=3
  45. SElinux: Allow ftp daemon to connect to database to obtain user logins and passwords:
    setsebool -P ftpd_connect_db 1
  46. SElinux: Change security context to webroot directory:
    chcon -R -t public_content_rw_t /home/webroot
  47. SElinux: Change security context to webroot to be accessible for Apache
    setsebool -P allow_httpd_anon_write 1
  48. SElinux: Allow ftp daemon to access webroot
    setsebool -P ftp_home_dir 1
    setsebool -P allow_ftpd_anon_write 1
  49. Edit the firewall settings so you can get onto desired ports:
    vi /etc/sysconfig/iptables
    # You should end up with iptables file something like this. You will have to add lines if you wanna enable more ports, or on the contrary remove the ports not needed:
    :INPUT ACCEPT [0:0]
    :OUTPUT ACCEPT [2:516]
    -A INPUT -p icmp -j ACCEPT
    -A INPUT -i lo -j ACCEPT
    -A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT        # SSH
    -A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT       # HTTP
    -A INPUT -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT # HTTPS
    -A INPUT -p tcp -m state --state NEW -m tcp --dport 21 -j ACCEPT # FTP
    -A INPUT -p tcp -m state --state NEW -m tcp --dport 20 -j ACCEPT # SFTP
    -A INPUT -j REJECT --reject-with icmp-host-prohibited # reject all other traffic (its important to have this line at the end of the port opening rules, otherwise firewall will drop the packets before they even got to the rule
    -A FORWARD -j REJECT --reject-with icmp-host-prohibited
  50. Start Apache daemon:
    service httpd start
  51. Restart affected services:
    service iptables restart 
    service vsftpd restart
  52. Reboot the system
  53. Test the apache/php

Resources used to develop this article:


PCI Audits often reveal TRACE & TRACK : Apache Hardening

PCI Audits often reveal TRACE & TRACK as issues that must be handled before the website can be considered PCI compliant.

If you are running apache 2.x, the following directives will disable TRACE & TRACK functionality.

This change needs to be made in /etc/httpd/conf/httpd.conf:
ServerTokens OS
TraceEnable OFF

The Mod_rewrite directives below need to be added to all paragraphs in both of the following locations:

nsert this code right before for each Virtual Host

RewriteEngine on
RewriteRule .* – [F]

Hardening Linux Web Servers

Security is a process, not a result. It is a process which is difficult to adopt under normal conditions; the problem is compounded when it spans several job descriptions. All the system level security in the world is rendered useless by insecure web-applications. The converse is also true—programming best practices, such as always verifying user input, are useless when the code is running on a server which hasn’t been properly hardened. Securing forward facing GNU/Linux web servers can seem like a daunting task, but it can be made much easier by breaking the process into manageable portions.

This article will cover installing, configuring and hardening free software web servers and associated software including Apache 2.2.0, MySQL 5.0.18, PHP 5.1.2, Apache-Tomcat 5.5.16 and common Apache modules such as mod_security, mod_ssl, mod_rewrite, mod_proxy and mod_jk. Common security mistakes in web-applications and how to fix them will also be discussed, focusing on PHP and Java environments.

The most common and apt analogy for security is the onion. That is to say it is a layered approach—any one layer is inadequate, the onion is the sum of its layers. With that in mind, this article attempts to bridge the knowledge gap between system administrators and web developers, allowing individuals tasked with security to achieve a layered security solution.

Only a basic understanding of GNU/Linux and common command line tools is assumed.

Note: due to formatting constraints, long lines of code are often broken into several smaller lines using the \ character. This is not a return and when typing in the line you should not hit the enter key, it is just to prevent line wrapping. Output from commands will also be limited to relevant fields, so the output will look slightly different when you run the commands on your system.

Security is a process, not a result

Security at the system level

System level security is one of the most crucial layers in any defense. Hardening at the system level is roughly categorized into network security and file system security.

Network level security can be increased by securing common services such as xinetd (otherwise known as the super server) and OpenSSH, by correctly configuring or disabling them and enabling a firewall (in our case, iptables.

File-System security can be increased by: preventing common avenues of attack, such as root kits; enabling intrusion detections systems (IDS) to verify the integrity of key configuration files; by using tools to detect and remove root kits; and by configuring your logging system so that it will log to a remote host, thereby protecting the integrity of your system logs.

Network security

The first thing you need to do to secure a system from network attacks is find out which processes are listening for connections and on which ports. There are several time tested tools available for this: nmap and netstat.


The following command will show you which ports are being listened on, the IP address of the listening socket, and which program or PID is associated with the socket (note: running as the super-user or root is necessary for the program field to work properly).

$ netstat -l -n -p -t -u -w

(-l is for listening, -n is for IP information and -p is for program/PID information, -t, -u, -w are for tcp, udp and raw socket connections. By setting these flags, I disable displaying information about unix sockets which are not relevant to network security, as they are only used for interprocess communication on the current host.)

The output will look something like this:

Note: Certain columns have been omitted for space

  proto Local Address      State    PID/Program name
  tcp    LISTEN   4079/java
  tcp      LISTEN   4079/java
  tcp      LISTEN   18542/mysqld
  tcp        LISTEN   23736/httpd
  tcp      LISTEN   4079/java
  tcp        LISTEN   11045/sshd
  tcp      LISTEN   23283/(squid)
  tcp      LISTEN   24453/master
  udp               23283/(squid)
  udp              23283/(squid)

Understanding the output from netstat is pretty simple. The first field is the protocol, and you will notice that when the protocol is udp, there is no state (as obviously udp is stateless unlike tcp). The next interesting field is the Address field. means that the server will respond to any IPs on port 80, while means that the server is only listening to the loop back device.


Another tool in our arsenal is nmap, the network mapper. nmap is good for determining what ports and services are available on a server from other machines on the network.

(Note: The default option is -sS. However, when the system being scanned is running a firewall, such as iptables, it won’t work, as firewalls that block icmp traffic will also block the subsequent scan and the results will be meaningless. The -P0 option disables pinging the host before scanning it, The -O (as in “oh” rather than zero) is to enable nmap’s operating system detection via the network stack fingerprint.)

$nmap -P0 -O

The output will look something like this:

 The 1661 ports scanned but not shown below are in 
                                    state: filtered)
  22/tcp  open   ssh
  443/tcp closed https

  Device type: general purpose
  Running: Linux 2.6.X
  OS details: Linux 2.6.7 - 2.6.8
  Uptime 40.462 days since Mon Dec 26 10:05:57 2005

Now that I know what services are listening on which ports, I can go about securing them. In some cases, the solution will be disabling the unwanted service via inetd; in others, I will use iptables rules to block external access to that port.

In the context of a web server, I would recommended disabling all services managed by inetd (if they aren’t already).

/etc/xinetd.conf (Red Hat): this file usually has some minimalistic configuration of the logging software and then an include statement for all the files under /etc/xinetd.d, which are configuration files for each service run through the super server.

/etc/inetd.conf (Debian): Debian has a much simpler configuration layout—one simple file /etc/inetd.conf containing one line for each service managed by inetd.


The venerable iptables has been the standard Linux firewall since the 2.4 kernel. The kernels that come with Red Hat and Debian have the proper modules enabled; however, on Debian systems you may need to install the iptables user land tools. Configuring iptables is fairly simple: iptables has chains, rules and targets. iptables has three built in chains: FORWARD, INPUT, and OUTPUT. To create an effective firewall I will append rules to chains that will be matched by connection type, source or destination address or state. In more advanced configurations, it is favorable to create custom chains and then reference them in the default chains; but, to demonstrate the basic principles, I am just going to append rules to the three default chains. When a connection is being matched against the configured rules, each rule is checked. If it matches, it is executed, if not, the next rule is tested. As such, the rules allowing traffic should be appended first, and the very last line in any chain should be a deny rule. This is the most secure firewall configuration, where everything is dropped except the explicitly allowed connections.

If you use Debian, run:

  $apt-get install iptables ( to install iptables )
  $apt-cache search iptables ( to search for packages related to iptables)

To get started with iptables I will list the current rule set using the following command:

  $iptables --list

(Note: Output has been modified due to formatting constraints.)

   Chain INPUT (policy ACCEPT)
   target     prot   opt     source   destination
   ACCEPT     all       anywhere  anywhere \ 
            state RELATED,ESTABLISHED

   Chain FORWARD (policy ACCEPT)
   target     prot   opt     source   destination
   ACCEPT     all       anywhere anywhere   \
                        state RELATED,ESTABLISHED

   Chain OUTPUT (policy ACCEPT)
   target     prot   opt     source   destination
   DROP       tcp       anywhere anywhere  \
                                       tcp dpt:ssh

The partial listing above shows rules that allow incoming traffic that isn’t new; that is to say: the connection has been established from inside the network. IP forwarding follows the same rule, and using ssh to connect out to other hosts is blocked.

The flush command with no options will flush all rules; if a chain is passed, all rules in that chain will be flushed. I’ll flush all rules and begin configuring the firewall.

  $iptables -F 
  $iptables -F INPUT 
  $iptables -F FORWARD
  $iptables -F OUTPUT

Next, I am going to append the rules to the appropriate chain. A high level overview of the firewall will be the following:

  1. Allow outgoing connections initiated from the host
  2. Allow inbound ssh connections on port 2
  3. Allow inbound http connections on port 80
  4. Allow inbound https connections on port 443
  5. Block outbound ssh connections
  6. Block everything else
  # Enable stateful filtering allowing connections 
  # initiated on host be allowed.
  $iptables -A INPUT -m state --state \ 

  $iptables -A OUTPUT -m state --state \ 

  # Allow Incoming SSH, HTTP, HTTPS
  $iptables -A INPUT -p tcp -m tcp \
            --dport 22 -j ACCEPT
  $iptables -A INPUT -p tcp -m tcp \
            --dport 80 -j ACCEPT
  $iptables -A INPUT -p tcp -m tcp \
            --dport 443 -j ACCEPT

  # Allow Everything from the local host
  $iptables -A INPUT -s -j ACCEPT

  # Block Outgoing SSH connections
  $iptables -A OUTPUT -p tcp -m tcp \
            --dport 22 -j DROP

  # Block Everything else
  $iptables -A INPUT -j DROP
  $iptables -A FORWARD -j DROP

To save the changes I have made to the firewall rules I use the iptables-save command:

  $iptables-save > /root/firewall

Later if I wanted to restore my saved rules I would run the iptables-restore command:

  $iptables-restore -c /root/firewall

It’s a very good idea to have these rules applied at boot time; check your distribution’s documentation for this. In general, on Debian systems the network configuration scripts can be used for this, and on Red-Hat systems a startup script in /etc/init.d is appropriate.

Changing the default port that `OpenSSH` listens on is a good way to avoid brute force attacks

Hardening SSH

The OpenSSH package comes installed by default on most distributions. The default configuration on most distributions is pretty lax and favors functionality over security. Allowing root logins, listening on all IPs on port 22, and allowing all system accounts to ssh-in are all potential security holes.

Edit /etc/ssh/sshd_config in your favorite editor and change the following lines.

  # ListenAddress defines the IP address ssh will 
  # listen on

  #ListenAddress -> ListenAddress 

  #Only accept SSH protocol 2 connections
  #Protocol 2,1 -> Protocol 2     

  #Disable root login
  PermitRootLogin yes -> PermitRootLogin no

  #Disable allowing all system accounts to ssh in, 
  # only allow certain users (space delimited)
  AllowUsers userName1 userName2 userName3

  # Change Default port
  Port 22 -> Port 2200

After making the changes, restart the SSH server for the changes to take affect:

$ /etc/init.d/ssh restart

Partition for security

File system security

The UNIX file system has several standard directories: /, /tmp, /var, /usr and /home. The two that present the weakest links for a variety of attacks are /tmp and /var. The two most common attacks are: “Denial of Service”, by causing the root partition to fill up with logs or other junk (assuming all these directories are mounted on one partition); and running rootkits from the /tmp directory.

One solution to file system Denial of Service attacks is to have these directories mounted on their own partitions, this will prevent the / file system from filling up and stop that avenue of attack.

Rootkits typically write to the /tmp directory and then attempt to run from /tmp. A crafty way to prevent this is to mount the /tmp directory on a separate partition with the noexec, nodev, and nosuid options enabled. This prevents binaries from being executed under /tmp, disables any binary to be suid root, and disables any block or character devices from being created under /tmp.

Edit /etc/fstab with your favorite editor, find the line corresponding to /tmp and change it to look like this one.


  /dev/hda2  /tmp  ext3  nodev,nosuid, noexec  0  0

Wikipedia [6] defines rootkits as a set of software tools frequently used by a third party (usually an intruder) after gaining access to a computer system. This translates to custom versions of ps that won’t list the irc server the attacker installed, or a custom version of ls that doesn’t show certain files. Tools like chkrootkit must be run in combination with IDS systems like fcheck to prevent the successful deployment of rootkits.

chkrootkit is very simple to run, and doesn’t require any installation or configuration.

It’s a good idea to run chkrootkit at regular intervals, see the script below used by fcheck for inspiration.

 # Use the wget utility to download the latest
 # version of chkrootkit

 wget ftp://ftp.pangeia.com.br/pub/seg/pac/chkrootkit.tar.gz
 tar -xzvf chkrootkit.tar.gz
 cd chkrootkit-version (whatever version is)

The next layer of file system security is maintaining and verifying the integrity of configuration files that are typically located under /etc. Intrusion Detection Systems (IDS) allow us to create cryptographic identifiers of important configuration files and store them in a database. They are then periodically re-created and verified against those stored in the database. If there is a mis-match, the file has been changed, you know your system integrity has been violated and which aspects of it are affected. Two well known IDS packages are tripwire and fcheck, which work equally well. However, fcheck has a much simpler configuration and installation process, which is why I favored it for this article.


Download fcheck (see resources) and unpack it. fcheck is a cross-platform Perl script which runs on UNIX and Windows systems (as long as they have Perl installed).

  $mkdir /usr/local/fcheck
  $cp fcheck /usr/local/fcheck
  $cp fcheck.cfg /usr/local/fcheck

Edit /usr/local/fcheck/fcheck.cfg with your favorite editor and change the following values: Directory, FileTyper, Database, Logger, TimeZone, and Signature.

  # Directories that will be monitored
  # if there is a trailing / it will be recursive 

  Directory       = /etc/
  Directory       = /bin/
  Directory       = /sbin/
  Directory       = /lib/
  Directory       = /usr/bin/
  Directory       = /usr/sbin/
  Directory       = /usr/lib/
  TimeZone        = PST8PDT # For Pacific Standard

  # Database of file signatures

  DataBase        = /usr/local/fcheck/sol.dbf
  Logger          = /usr/bin/logger -t fcheck

  # Utility to determin file type
  FileTyper       = /bin/file 

  # What to use to create signatures Database of 
  # file signatures

  $Signature      = /usr/bin/md5sum#
  DataBase        = /usr/local/fcheck/sol.dbf
  Logger          = /usr/bin/logger -tfcheck

  # Utility to determin file type

  FileTyper       = /bin/file

Also edit the fcheck script and change the path of the configuration file to /usr/local/fcheck/fcheck.cfg

Then run fcheck for the first time to create the baseline database.

# Options explained:
# c create the database
# a is for all
# d is to monitor directory creation 
# s is to create signatures for all files
# x is for extended permissions monitoring

$ ./fcheck -cadsx

To test that everything has been setup correctly run the following commands and fcheck should alert you to the difference.

$ touch /etc/FOO 
$ ./fcheck -adsx

fcheck should display some information about /etc/FOO. $rm /etc/FOO will prevent future messages.

Next, create a short shell script that will be run periodically by cron and check for changes. Open your favorite editor and create /usr/local/bin/fcheck_script.

When using the `cron` utility lookout for _symlink attacks_


  # Use mktemp instead of $$ to prevent sym-link attacks

  # Grep for any changes  
  /usr/local/fcheck/fcheck -adsx  \ 
  | grep -Ev ^PROGRESS: |^STATUS:^$ > $FCHECK_LOG

  # If there were any changes email the sys-admin
  if [-s $FCHECK_LOG ] then
      /usr/bin/mail -s fcheck \
      `hostname` youremail@yourprovider.com  < \
      /bin/rm $FCHECK_LOG

The cron utility will be used to run periodic checks of the file-system and will compare it to the baseline database. The following command will edit root’s crontab:

$ crontab -e

# Add this line to run the script every 15 minutes 
# using nice lower priority when the system load 
# is high.
*/15 * * * * nice /usr/local/bin/fcheck_script > \

Symlink Attacks

Side Note: Symlink Attacks running an IDS package usually involve running a script at a pre-configured time using the cron utility. This opens up systems to symlink attacks. Symlink Attacks rely on the attacker knowing that a certain file is going to be created at a certain time with a certain name. A common shell scripting technique that generates some randomness is the use of $$, which is the PID of the running script. However, this is vulnerable to Symlink Attacks because most PIDs are below 35K and most file systems can have 35K files. The correct technique is the use of mktemp, which is a truly random file name.

Install and configure common services

At this stage, you should have a solid base to build upon. The next step is to compile and install the software servers you will use to serve up your web applications. Installing software from source can be tedious; and there is a great temptation to use the packaged binaries that come with your distribution of choice. I would recommend against this. In a world of zero day exploits, the time it takes the package maintainer to compile and distribute the binaries may be unacceptable. By compiling from the source, you will be in full control of your security situation.

Apache 2.2.0

Now to start compiling and install the services you will be using. Apache is a good place to start, since other packages have compile time dependencies on it.

Always verify the `checksums` of packages you download, if there is a mismatch start over and download it again

    md5sum httpd-2.2.0.tar.gz  
    tar -xzvf httpd-2.2.0.tar.gz 
    ./configure --prefix=/usr/local/apache \
           --enable-ssl --enable-speling \ 
           --enable-rewrite --enable-proxy  
    make install

MySQL 5.0.18

Download the MySQL binaries from the mysql site (see resources). This is an exception to my mantra of compiling from source—since the binaries come directly from MySQL, as soon as there is an update you can download the latest version.

Note: due to space constraints {.} is shorthand for the version of the tarball.

  md5sum mysql-{.}-linux-i686-glibc23.tar.gz
  cp mysql-{.}-linux-i686-glibc23.tar.gz /usr/local
  tar -xzvf mysql-{.}-linux-i686-glibc23.tar.gz
  ln -s /usr/local/mysql-{.}-linux-i686-glibc23 \

  groupadd mysql
  useradd -g mysql mysql
  cd mysql
  scripts/mysql_install_db --user=mysql
  chown -R root  .
  chown -R mysql data
  chgrp -R mysql .
  bin/mysqld_safe --user=mysql &
  cp  support-files/mysql.server /etc/init.d/mysql

  # Make sure that mysql is started if 
  # there is a reboot

  cd /etc/rc3.d/
  ln -s /etc/init.d/mysql S90mysql
  ln -s /etc/init.d/mysql K90mysql

  # Copy the configuration file
  cp support-files/my-medium.cnf /etc/my.cnf

PHP 5.1.2

Now download the php package from the php.net site (see resources).

  md5sum php-5.1.2.tar.gz
  tar -xzvf php-5.1.2.tar.gz
  ./configure --with-prefix=/usr/local/php \ 
      --with-apxs2=/usr/local/apache/bin/apxs \
  make install
  cp php.ini-dist /usr/local/php/php.ini

Tomcat 5.5.16

Apache-Tomcat is also an exception to my always compile rule.

  md5sum apache-tomcat-5.5.16.tar.gz
  tar -xzvf apache-tomcat-5.5.16.tar.gz


Download mod_jk from the the tomcat project page (see resources).

  tar -xzvf jakarta-tomcat-connectors.tar.gz
  cd jakarta/jk/native
  ./configure --with-apxs=/usr/local/apache/bin/apxs
  make install


mod_security is the most excellent Apache module written by Ivan Ristic.

  md5sum modsecurity-apache-1.9.2.tar.gz
  tar -xzvf modsecurity-apache-1.9.2.tar.gz
  cd modsecurity-apache-1.9.2/apache2
  /usr/local/apache/bin/apxs -cia mod_security.c

Configuring Apache 2.2.0

By this point, you should have installed all of the services and apache modules needed to host and secure PHP and Java environments. Now it’s time to take a look at properly configuring everything for security.

_Apache 2.2.0_ has the ability to list both statically compiled and shared modules with the `-M` option to `apachectl`

Apache 2.2.0 introduces a new configuration layout and new default options in the httpd.conf file. In previous versions of Apache, there was only one configuration file by default, which was conf/httpd.conf; in the current version, the Apache project has taken another step towards its goal of making configuration more managable and modular. The conf/httpd.conf is the main configuration file with include statements for the various configuration files under conf/extra such as httpd-ssl.conf and httpd-vhosts.conf.

Another new and exciting security feature in Apache 2.2.0 is that the root httpd.conf access is denied to all directories. This can be confusing to users coming from previous versions such as 2.0.55 but it is a great step forward in terms of security.

Here is the configuration directive mentioned above; I would suggest leaving it the way it is. We will allow access for specific virtual-hosts and directories later on.

  # Default access control  \
  # Highly restrictive and applies \
  # to everything below it.

  <Directory />
    Options FollowSymLinks
    AllowOverride None
    Order deny,allow
    Deny from all

Every host, which Apache will be responsible for, will be a virtual host or “vhost”. So, start by uncommenting the Include directives at the bottom of conf/httpd.conf. This is done so that the httpd-vhosts.conf, httpd-ssl.conf and httpd-dedfault.conf are included in the main httpd.conf configuration file.

Yet another cool new feature in Apache 2.2.0 is the ability to see all modules both statically compiled and shared with the -M option to apachectl.

  # Edit /usr/local/apache/conf/httpd.conf

  # Move the LoadModule Statement for mod_security 
  # to the top of all module
  # statements. This is needed to use SecChrootDir

  # Add the following line to load mod_jk
   LoadModule jk_module   modules/mod_jk.so

  # The default User and Group is set to daemon, 
  # create and apache user and group and then 
  # configure apache to run as such.
  User apache
  Group apache

  # List all modules to verify that mod_jk, 
  # mod_security, mod_php, and mod_ssl 
  # are correctly installed and loaded.
   /usr/local/apache/bin/apachectl -M 

  # Virtual hosts 

  Include conf/extra/httpd-vhosts.conf \
  -> Include conf/extra/httpd-vhosts.conf 

  # Various default settings
  Include conf/extra/httpd-default.conf \
  -> Include conf/extra/httpd-default.conf 

  # Secure (SSL/TLS) connections
   Include conf/extra/httpd-ssl.conf \
  -> Include conf/extra/httpd-ssl.conf

Now it’s time to descend into the extra directory to configure virtual hosts. Open httpd-vhosts.conf in your favorite editor. Next, configure the document root to be /srv/www/vhost1. Also, add the AddType directive for php. PHP files don’t have to have the .php file extension. In fact, it’s probably a good idea if they are .html files. By using the .php file extention you are advertizing more information about your setup than you need to.

`mod_security` makes `chrooting` Apache easy!

Here is the full vhost configuration stanza. It is annotated with inline comments: please take the time to read through it.

  # Enable mod_security engine
  SecFilterEngine On

  # Chroot Apache the easy way just make sure 
  # your web content is under the chrooted directory

  # Note: The log directives must also be valid 
  # directories releative to the chroot dir.

  # as it applies to the entire apache configuration
  SecChrootDir /chroot/apache

  # Delete the 2nd Vhost stanza as you will only be 
  # using one for now
  <VirtualHost *:80>
    ServerAdmin webmaster@mydomain.com
    DocumentRoot /srv/www/vhost1
    ServerName vhost.mydomain.com
    ServerAlias www.mydomain.com
    ErrorLog logs/vhost.mydomain.com-error_log
    CustomLog logs/vhost.mydomain.com-access_log \ 

    # The PHP engine will interpret all 
    # .php and .html files for php code
    AddType application/x-httpd-php .php .phtml \ 

    AddType application/x-httpd-php-source .phps

    # Add a local Directory directive to override 
    # the global Deny From all in conf/httpd.conf
    <Directory />
      Options FollowSymLinks
      AllowOverride None
      Order deny,allow
      Allow from all

    # Restrict Access to sensitive files
    <FilesMatch "\.(inc|txt|tar|gz|zip)$">
      Deny from all

    # Configure MOD_JK
    JkWorkersFile \
    JkLogFile \
    JkLogLevel info
    JkLogStampFormat "[%a %b %d %H:%M:%S %Y] "
    JkOptions +ForwardKeySize +ForwardURICompat \ 
    JkRequestLogFormat "%w %V %T"

    # Any URL that begins with /java/ will be 
    # forwarded to the java webapp in tomcat
    JkMount /java/* ajp13

    # Enable and configure MOD_SECURITY

    # See the mod_security documentation 
    # link in resources [3]

    # POST Scanning is disabled by default
    SecFilterScanPOST On

    # Make sure only content with standard 
    # encoding types is accepted
    SecFilterSelective HTTP_Content-Type \


    # Default Action is to reject request, log, and
    # then return HTTP Response 404 which is 
    # File Not Found. 
    # Another option would be 403 which is access
    # denied.
    SecFilterDefaultAction "deny,log,status:404"

    # Enable URLEncoding validation. This can 
    # prevent Cross-Site Scripting attacks 
    SecFilterCheckURLEncoding On

    # Catch and Prevent PHP Fatal Errors from 
    # being displayed to the USER
    SecFilterSelective OUTPUT "Fatal error:" \

    # Obviously you have to code up this custom 
    # Error Page
    ErrorDocument 500 /php-fatal-error.html 

    # This can be useful to avoid stack overflow 
    # attacks default is 0 255 ie All bytes allowed
    SecFilterForceByteRange 32 126


Here is the mod_jk configuration file apache/conf/workers.properties (referenced above):

  workers.tomcat_home= \


Apache can be used to configure other web consoles such as the Tomcat Manager application

The configuration stanza below is a variation on an article:

<VirtualHost *:80>
  ServerAdmin webmaster@zero-analog.com
  DocumentRoot /srv/www/hercules.zero-analog.com
  ServerName hercules.zero-analog.com
  ErrorLog logs/hercules.zero-analog-error_log
  CustomLog logs/hercules.zero-analog-access_log \

  <Directory />
      Options FollowSymLinks
      AllowOverride None
      Order deny,allow

  <FilesMatch "\.(inc|txt|tar|gz|zip)$">
      Deny from all

  # This whole stanza is really to forward http 
  # requests to https:// tomcat manager
  # so appended /html to the rewrite target. 
  # since the full path is manager/html 

  <IfModule mod_rewrite.c>
   <IfModule mod_ssl.c>
       <Location /manager>
         RewriteEngine on
         RewriteCond %{HTTPS} !^on$ [NC]
         RewriteRule . \
          https://%{HTTP_HOST}%{REQUEST_URI}/html \


# This is the ssl-vhost under extra/httpd-ssl.conf 

<VirtualHost _default_:443>
  # General setup for the virtual host
  DocumentRoot "/srv/www/outpost.zero-analog.com"
  ServerName hercules.zero-analog.com:443
  ServerAdmin webmaster@zero-analog.com

  ErrorLog /usr/local/apache2/logs/error_log
  TransferLog /usr/local/apache2/logs/access_log

  <Directory />
    Options FollowSymLinks
    AllowOverride None
    Order deny,allow

  RewriteEngine on
  RewriteRule "^/manager$" \
    "https://outpost.zero-analog.com/manager/html" \

   JkWorkersFile \
   JkLogFile \
   JkLogLevel info
   JkLogStampFormat "[%a %b %d %H:%M:%S %Y] "
   JkOptions +ForwardKeySize +ForwardURICompat \
   JkRequestLogFormat "%w %V %T"
   JkMount /manager/* ajp13

   #   Enable/Disable SSL for this virtual host.
   SSLEngine on

   # List the ciphers that the client is permitted 
   # to negotiate. See the mod_ssl documentation
   # for a complete list.
   SSLCipherSuite  ALL:!ADH:!EXPORT56:RC4+RSA: \ 

   # Server Certificate: Point SSLCertificateFile
   # at a PEM encoded certificate.

   SSLCertificateFile \ 

   # Server Private Key:
   SSLCertificateKeyFile \ 

   SSLOptions +FakeBasicAuth \
              +ExportCertData \

   <FilesMatch "\.(cgi|shtml|phtml|php)$">
           SSLOptions +StdEnvVars

   <Directory "/usr/local/apache2/cgi-bin">
           SSLOptions +StdEnvVars

   BrowserMatch ".*MSIE.*" \
           nokeepalive ssl-unclean-shutdown \
            downgrade-1.0 force-response-1.0

   # Per-Server Logging:
   # The home of a custom SSL log file. 
   # Use this when you want a compact non-error 
   # SSL logfile on a virtual host basis.

   # *** Note there are \ characters in this 
   # string. These are not my artificial line-
   # breaks, please include them ***

   CustomLog /usr/local/apache2/logs/ssl_request_log 
             %t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"


Configuring PHP

I have already copied the php.ini to /usr/local/php/php.ini so that it will be read by the PHP engine at startup. By default it’s fairly secure, but there are one or two things you can do to improve security.

Disable PHP display_errors for security

  # Edit /usr/local/php/php.ini with your 
  # favorite editor

  # Since you're are going through the trouble of 
  # hiding PHP files you might as well disable 
  # this as well
   expose_php = On -> expose_php = Off 

  # You really don't want users, or worse yet 
  # an attacker to see error messages
   display_errors = On -> \
      display_erros = Off 

  # But you do want them logged \
   log_errors = Off -> log_errors = On 

  # Log to a file
  ;error_log = filename -> \
       error_log = /var/log/php-err

Another option to consider is the Hardened-PHP project (see resources section). This is the brain child of three German developers, who continously perform code audits of popular PHP applications. They also release a patch for the standard PHP code, which fixes bugs and security holes in fringe configuration cases, where the main project developers have not had the time or the desire to find a fix.

Configuring Tomcat

The main configuration files from Tomcat are under $CATALINA_HOME/conf. The following files are of interest:

  • tomcat-users.xml
  • server.xml
  • web.xml

As you might have guessed, the tomcat-users.xml file contains user access information. It is important to create a custom user with a hard-to-guess password for the manager application.

  # Edit tomcat-users.xml with your favorite 
  # editor and append the following line.

  <user username="bob" password="subGen1us" \

Another important tenet of security is preventing information leakage. That’s why you enable PHP pages to masquerade as html files. It’s also why you want to disable directory listings in Tomcat. This is achieved by editing the tomcat/conf/web.xml file.

  # Open web.xml in your favorite editor and 
  # look for the following lines:


  # The default value is true, which enables 
  # directory listings, simply change this to false
  # to prevent tomcat directory listings.

You can also hide JSP files by using a servlet-mapping directive in the webapps web.xml configuration file. The following lines will map all html files to the JSP servlet, which is internal to Tomcat.

Note: The listing above goes in the main tomcat/conf/web.xml, while this listing should go in the web.xml of each application. You can put it in the main web.xml. However, there may be cases where this is undesirable.


I want to restrict access to apache-tomcat to control the flow through Apache. iptables is already blocking port 8080 by default, but following the onion principle I’m going to bound Tomcat to loop-back device. This will prevent direct traffic to Tomcat in case of any unforeseen circumstances such as the iptables rules being flushed.

 # Open sever.xml in your favorite editor 
 # and look for the following lines:

 <Connector port="8080" maxHttpHeaderSize="8192"
   maxThreads="150" minSpareThreads="25" 
   maxSpareThreads="75" enableLookups="false" 
   redirectPort="8443" acceptCount="100"
   disableUploadTimeout="true" />

 # And change to this:

  <Connector port="8080" maxHttpHeaderSize="8192" 
     address="" maxThreads="150" 
     minSpareThreads="25" maxSpareThreads="75"
     enableLookups="false" redirectPort="8443" 
     acceptCount="100"  connectionTimeout="20000" 
     disableUploadTimeout="true" />

Configuring MySQL

The default MySQL installation is not very secure. This is the case when it is installed manually and also when you use your distribution’s precompiled binaries. The default root password is blank, which means anyone can login is as the DBA. This is understandable, as, obviously, a DBA has to login to set the password. However, it’s too easy to forget that anyone can login as the MySQL root user and anonymous users are also enabled by default.

# Set the root password
mysqladmin -u root -h localhost password subGen1us 

# Once this is done, log in as the root user and 
# disable anonymous accounts
mysql -u root -p

# Drop the test database which comes installed 
# by default
mysql> drop database test;

# Disable anonymous accounts
mysql> use mysql;

mysql> delete from db where User=’’;
mysql> delete from user where User=’’;

# Change DBA NAME
mysql> update user set user="mydbadmin" \ 
          where user="root";

mysql> flush privileges;

# Make sure to login again to make sure 
# all the changes work

mysql -u mydbadmin -p
password: subGen1us

# Configure /etc/my.cnf for security Uncomment 
# the following line to disable TCP connections 
# to mysql.  As with tomcat this prevents remote 
# connections event in the even of the firewall
# even in the even of the firewall rules being 
# flushed.


Security mistakes in web applications

Now that you are done with configuration, it’s time to put your web developer hat on. You now have a very solid base upon which to build your web applications. This brings me to the Achilles heal: the web applications themselves.

What is Cross Site Scripting (XSS)?

Wikipedia [4] defines the term Cross Site Scripting as inaccurate as it really refers to an entire class of vulnerabilities. In general XSS vulnerabilities come down to an age old security problem: not verifying user input. The most common vector of attack is when data is passed to a processing program such as a PHP or JSP script, and then printed back out to the page without being URLEncoded.

The following (highly contrived) PHP code is vulnerable to XSS. If the database to this PHP script contains javascript, it will be executed.

Never trust user input, it is the root of all evil

        # Vulnerable Code
                $userInput = $_GET['input'];
                print $userInput;

        # Secure Code
            $userInput = urlencode($_GET['input']);
            print $userInput;

JSP’s or Java Servlets are no less vulnerable. First of all, it is important to understand that all JSP’s are compiled to servlets the first time a JSP is called. So, the two are basically the same thing, with different source code representations.

Here is the same vulnerability in the Java world. Note: JSP’s have access to the same HttpServletRequest object as the servlets they are compiled to. So, in a JSP page, this would manifest itself as request.getParameter().

  # Vulnerable Code
  public class myServlet extends HttpServlet {
    public static void doGet 
              (HttpServletRequest req, 
               HttpServletResponse res) {

     // Get User Input       
     String userInput = req.getParameter("input");

     // Print User Input to page
     PrintWriter out = response.getWriter();


  # Secure Code
  import java.net.URLEncoder;
  public class myServlet extends HttpServlet {
    public static void doGet 
              (HttpServletRequest req, 
               HttpServletResponse res) {

       // Get User Input       
       String userInput = req.getParameter("input");
       // URLEncode Input
       userInput = 
            URLEncoder.encode(userInput, "UTF-8"); 

       // Print User Input to page
       PrintWriter out = response.getWriter();


What is SQL Injection?

SQL Injection is the ability to insert and execute arbitrary SQL code through a web-application. Like XSS attacks, it involves mishandling user input. In this case, properly escaping the input that is to become part of the SQL query. The PHP solution is to use the mysql_real_escape_string statement, and the java solution is to use PreparedStatements, with the user input as bind variables.

The following code snippets are from Wikipedia [5]:

  # Partial PHP
  $query_result = mysql_query
   ( "select * from users where name = \""
      "\"" );

  # Partial Java, ? is the bind variable
  Connection con = (acquire Connection)

  PreparedStatement pstmt = 
       ("SELECT * FROM users WHERE name = ?");

  pstmt.setString(1, userInput);
  ResultSet rset = pstmt.executeQuery()


There is no magic bullet. “Conclusion” is a misleading heading: there is no conclusion when it comes to security. Security holes are constantly found and patched. Attackers change their methods, and security professionals respond; it is a process, rather than a result. When it’s implemented correctly, this process can mitigate or prevent the damage done by attacks.

There is a silver lining: there is an entire community of security professionals sharing their experience, tips and tricks on the web. Sites like Securityfocus.com provide heaps of useful information, and the latest trends in security. It’s also the home of bugtraq, a mailing list of security holes that I highly recommend you subscribe to. Sites like freshmeat.net are the yellow pages of free software projects, listing new releases and updates. All of these sites have RSS feeds, a resource I would also recommend you take advantage of to stay abreast of the latest news.


SSH Hardening


Top 20 OpenSSH Server Best Security Practices

Don't tell anyone that I'm free
OpenSSH is the implementation of the SSH protocol. OpenSSH is recommended for remote login, making backups, remote file transfer via scp or sftp, and much more. SSH is perfect to keep confidentiality and integrity for data exchanged between two networks and systems. However, the main advantage is server authentication, through the use of public key cryptography. From time to time there are rumors about OpenSSH zero dayexploit. Here are a few things you need to tweak in order to improve OpenSSH server security.

Default Config Files and SSH Port

  • /etc/ssh/sshd_config – OpenSSH server configuration file.
  • /etc/ssh/ssh_config – OpenSSH client configuration file.
  • ~/.ssh/ – Users ssh configuration directory.
  • ~/.ssh/authorized_keys or ~/.ssh/authorized_keys – Lists the public keys (RSA or DSA) that can be used to log into the user’s account
  • /etc/nologin – If this file exists, sshd refuses to let anyone except root log in.
  • /etc/hosts.allow and /etc/hosts.deny : Access controls lists that should be enforced by tcp-wrappers are defined here.
  • SSH default port : TCP 22

SSH Session in Action

SSH Session in Action

#1: Disable OpenSSH Server

Workstations and laptop can work without OpenSSH server. If you need not to provide the remote login and file transfer capabilities of SSH, disable and remove the SSHD server. CentOS / RHEL / Fedora Linux user can disable and remove openssh-server with yum command:


# chkconfig sshd off
# yum erase openssh-server
Debian / Ubuntu Linux user can disable and remove the same with apt-get command:

# apt-get remove openssh-server

You may need to update your iptables script to remove ssh exception rule. Under CentOS / RHEL / Fedora edit the files /etc/sysconfig/iptables and /etc/sysconfig/ip6tables. Once donerestart iptables service:


# service iptables restart
# service ip6tables restart

#2: Only Use SSH Protocol 2

SSH protocol version 1 (SSH-1) has man-in-the-middle attacks problems and security vulnerabilities. SSH-1 is obsolete and should be avoided at all cost. Open sshd_config file and make sure the following line exists:
Protocol 2

#3: Limit Users’ SSH Access

By default all systems user can login via SSH using their password or public key. Sometime you create UNIX / Linux user account for ftp or email purpose. However, those user can login to system using ssh. They will have full access to system tools including compilers and scripting languages such as Perl, Python which can open network ports and do many other fancy things. One of my client has really outdated php script and an attacker was able to create a new account on the system via a php script. However, attacker failed to get into box via ssh because it wasn’t in AllowUsers.
Only allow root, vivek and jerry user to use the system via SSH, add the following to sshd_config:
AllowUsers root vivek jerry
Alternatively, you can allow all users to login via SSH but deny only a few users, with the following line:
DenyUsers saroj anjali foo
You can also configure Linux PAM allows or deny login via the sshd server. You can allow list of group name to access or deny access to the ssh.

#4: Configure Idle Log Out Timeout Interval

User can login to server via ssh and you can set an idel timeout interval to avoid unattended ssh session. Open sshd_config and make sure following values are configured:
ClientAliveInterval 300
ClientAliveCountMax 0
You are setting an idle timeout interval in seconds (300 secs = 5 minutes). After this interval has passed, the idle user will be automatically kicked out (read as logged out). See how to automatically log BASH / TCSH / SSH users out after a period of inactivity for more details.

#5: Disable .rhosts Files

Don’t read the user’s ~/.rhosts and ~/.shosts files. Update sshd_config with the following settings:
IgnoreRhosts yes
SSH can emulate the behavior of the obsolete rsh command, just disable insecure access via RSH.

#6: Disable Host-Based Authentication

To disable host-based authentication, update sshd_config with the following option:
HostbasedAuthentication no

#7: Disable root Login via SSH

There is no need to login as root via ssh over a network. Normal users can use su or sudo (recommended) to gain root level access. This also make sure you get full auditing information about who ran privileged commands on the system via sudo. To disable root login via SSH, update sshd_config with the following line:
PermitRootLogin no
However, bob made excellent point:
Saying “don’t login as root” is h******t. It stems from the days when people sniffed the first packets of sessions so logging in as yourself and su-ing decreased the chance an attacker would see the root pw, and decreast the chance you got spoofed as to your telnet host target, You’d get your password spoofed but not root’s pw. Gimme a break. this is 2005 – We have ssh, used properly it’s secure. used improperly none of this 1989 will make a damn bit of difference. -Bob

#8: Enable a Warning Banner

Set a warning banner by updating sshd_config with the following line:
Banner /etc/issue
Sample /etc/issue file:
You are accessing a XYZ Government (XYZG) Information System (IS) that is provided for authorized use only.
By using this IS (which includes any device attached to this IS), you consent to the following conditions:
ed to, penetration testing, COMSEC monitoring, network operations and defense, personnel misconduct (PM), law enfo
+ The XYZG routinely intercepts and monitors communications on this IS for purposes including, but not limi
trcement (LE), and counterintelligence (CI) investigations. 

+ At any time, the XYZG may inspect and seize data stored on this IS.
may be disclosed or used for any XYZG authorized purpose. + This IS includes security measures (e.g.,
+ Communications using, or data stored on, this IS are not private, are subject to routine monitoring,
interception, and search, and
  authentication and access controls) to protect XYZG interests--not
for your personal benefit or privacy.

+ Notwithstanding the above, using this IS does not constitute consent to PM, LE or CI investigative searching
oduct are private and confidential. See User Agreement for details. ——————————————
or monitoring of the content of privileged communications, or work product, related to personal representation
or services by attorneys, psychotherapists, or clergy, and their assistants. Such communications and work
Above is standard sample, consult your legal team for exact user agreement and legal notice details.

#8: Firewall SSH Port # 22

You need to firewall ssh port # 22 by updating iptables or pf firewall configurations. Usually, OpenSSH server must only accept connections from your LAN or other remote WAN sites only.

Netfilter (Iptables) Configuration

Update /etc/sysconfig/iptables (Redhat and friends specific file) to accept connection only from and, enter:
-A RH-Firewall-1-INPUT -s -m state –state NEW -p tcp –dport 22 -j ACCEPT
-A RH-Firewall-1-INPUT -s -m state –state NEW -p tcp –dport 22 -j ACCEPT
If you’ve dual stacked sshd with IPv6, edit /etc/sysconfig/ip6tables (Redhat and friends specific file), enter:
-A RH-Firewall-1-INPUT -s ipv6network::/ipv6mask -m tcp -p tcp --dport 22 -j ACCEPT
Replace ipv6network::/ipv6mask with actual IPv6 ranges.

*BSD PF Firewall Configuration

If you are using PF firewall update /etc/pf.conf as follows:
pass in on $ext_if inet proto tcp from {,} to $ssh_server_ip port ssh flags S/SA synproxy state

#9: Change SSH Port and Limit IP Binding

By default SSH listen to all available interfaces and IP address on the system. Limit ssh port binding and change ssh port (by default brute forcing scripts only try to connects to port # 22). To bind to and IPs and to port 300, add or correct the following line:
Port 300
A better approach to use proactive approaches scripts such as fail2ban or denyhosts (see below).

#10: Use Strong SSH Passwords and Passphrase

It cannot be stressed enough how important it is to use strong user passwords and passphrase for your keys. Brute force attack works because you use dictionary based passwords. You can force users to avoid passwords against a dictionary attack and use john the ripper tool to find out existing weak passwords. Here is a sample random password generator (put in your ~/.bashrc):
genpasswd() {
local l=$1
[ “$l” == “” ] && l=20
tr -dc A-Za-z0-9_ < /dev/urandom | head -c ${l} | xargs
Run it:

genpasswd 16


#11: Use Public Key Based Authentication

Use public/private key pair with password protection for the private key. See how to use RSAand DSA key based authentication. Never ever use passphrase free key (passphrase key less) login.

#12: Use Keychain Based Authentication

keychain is a special bash script designed to make key-based authentication incredibly convenient and flexible. It offers various security benefits over passphrase-free keys. See how to setup and use keychain software.

#13: Chroot SSHD (Lock Down Users To Their Home Directories)

By default users are allowed to browse the server directories such as /etc/, /bin and so on. You can protect ssh, using os based chroot or use special tools such as rssh. With the release of OpenSSH 4.8p1 or 4.9p1, you no longer have to rely on third-party hacks such as rssh or complicated chroot(1) setups to lock users to their home directories. See this blog post about new ChrootDirectory directive to lock down users to their home directories.

#14: Use TCP Wrappers

TCP Wrapper is a host-based Networking ACL system, used to filter network access to Internet. OpenSSH does supports TCP wrappers. Just update your /etc/hosts.allow file as follows to allow SSH only from :
sshd :
See this FAQ about setting and using TCP wrappers under Linux / Mac OS X and UNIX like operating systems.

#15: Disable Empty Passwords

You need to explicitly disallow remote login from accounts with empty passwords, update sshd_config with the following line:
PermitEmptyPasswords no

#16: Thwart SSH Crackers (Brute Force Attack)

Brute force is a method of defeating a cryptographic scheme by trying a large number of possibilities using a single or distributed computer network. To prevents brute force attacks against SSH, use the following softwares:
  • DenyHosts is a Python based security tool for SSH servers. It is intended to prevent brute force attacks on SSH servers by monitoring invalid login attempts in the authentication log and blocking the originating IP addresses.
  • Explains how to setup DenyHosts under RHEL / Fedora and CentOS Linux.
  • Fail2ban is a similar program that prevents brute force attacks against SSH.
  • security/sshguard-pf protect hosts from brute force attacks against ssh and other services using pf.
  • security/sshguard-ipfw protect hosts from brute force attacks against ssh and other services using ipfw.
  • security/sshguard-ipfilter protect hosts from brute force attacks against ssh and other services using ipfilter.
  • security/sshblock block abusive SSH login attempts.
  • security/sshit checks for SSH/FTP bruteforce and blocks given IPs.
  • BlockHosts Automatic blocking of abusive IP hosts.
  • Blacklist Get rid of those bruteforce attempts.
  • Brute Force Detection A modular shell script for parsing application logs and checking for authentication failures. It does this using a rules system where application specific options are stored including regular expressions for each unique auth format.
  • IPQ BDB filter May be considered as a fail2ban lite.

#17: Rate-limit Incoming Port # 22 Connections

Both netfilter and pf provides rate-limit option to perform simple throttling on incoming connections on port # 22.

Iptables Example

The following example will drop incoming connections which make more than 5 connection attempts upon port 22 within 60 seconds:
$IPT -I INPUT -p tcp –dport ${ssh_port} -i ${inet_if} -m state –state NEW -m recent –set
$IPT -I INPUT -p tcp –dport ${ssh_port} -i ${inet_if} -m state –state NEW -m recent –update –seconds 60 –hitcount 5 -j DROP
Call above script from your iptables scripts. Another config option:
$IPT -A INPUT -i ${inet_if} -p tcp –dport ${ssh_port} -m state –state NEW -m limit –limit 3/min –limit-burst 3 -j ACCEPT
$IPT -A INPUT -i ${inet_if} -p tcp –dport ${ssh_port} -m state –state ESTABLISHED -j ACCEPT
$IPT -A OUTPUT -o ${inet_if} -p tcp –sport ${ssh_port} -m state –state ESTABLISHED -j ACCEPT
# another one line example
# $IPT -A INPUT -i ${inet_if} -m state –state NEW,ESTABLISHED,RELATED -p tcp –dport 22 -m limit –limit 5/minute –limit-burst 5-j ACCEPT
See iptables man page for more details.

*BSD PF Example

The following will limits the maximum number of connections per source to 20 and rate limit the number of connections to 15 in a 5 second span. If anyone breaks our rules add them to our abusive_ips table and block them for making any further connections. Finally, flush keyword kills all states created by the matching rule which originate from the host which exceeds these limits.
table persist
block in quick from
pass in on $ext_if proto tcp to $sshd_server_ip port ssh flags S/SA keep state (max-src-conn 20, max-src-conn-rate 15/5, overload flush)

#18: Use Port Knocking

Port knocking is a method of externally opening ports on a firewall by generating a connection attempt on a set of prespecified closed ports. Once a correct sequence of connection attempts is received, the firewall rules are dynamically modified to allow the host which sent the connection attempts to connect over specific port(s). A sample port Knocking example for ssh using iptables:
$IPT -N stage1
$IPT -A stage1 -m recent –remove –name knock
$IPT -A stage1 -p tcp –dport 3456 -m recent –set –name knock2

$IPT -N stage2
$IPT -A stage2 -m recent –remove –name knock2
$IPT -A stage2 -p tcp –dport 2345 -m recent –set –name heaven

$IPT -N door
$IPT -A door -m recent –rcheck –seconds 5 –name knock2 -j stage2
$IPT -A door -m recent –rcheck –seconds 5 –name knock -j stage1
$IPT -A door -p tcp –dport 1234 -m recent –set –name knock

$IPT -A INPUT -p tcp –dport 22 -m recent –rcheck –seconds 5 –name heaven -j ACCEPT
$IPT -A INPUT -p tcp –syn -j doo
  • fwknop is an implementation that combines port knocking and passive OS fingerprinting.
  • Multiple-port knocking Netfilter/IPtables only implementation.

#19: Use Log Analyzer

Read your logs using logwatch or logcheck. These tools make your log reading life easier. It will go through your logs for a given period of time and make a report in the areas that you wish with the detail that you wish. Make sure LogLevel is set to INFO or DEBUG in sshd_config:
LogLevel INFO

#20: Patch OpenSSH and Operating Systems

It is recommended that you use tools such as yumapt-getfreebsd-update and others to keep systems up to date with the latest security patches.

Other Options

To hide openssh version, you need to update source code and compile openssh again. Make sure following options are enabled in sshd_config:
# Turn on privilege separation
UsePrivilegeSeparation yes
re home directory and key file permissions StrictModes yes # Turn on
# Prevent the use of insec
u reverse name checking
VerifyReverseMapping yes
# Do you need port forwarding?
ion is allowed. The
AllowTcpForwarding no
X11Forwarding no
#  Specifies whether password authentica
tdefault is yes
PasswordAuthentication no
Verify your sshd_config file before restarting / reloading changes:

# /usr/sbin/sshd -t

Tighter SSH security with two-factor or three-factor (or more) authentication.


  1. The official OpenSSH project.
  2. Forum thread: Failed SSH login attempts and how to avoid brute ssh attacks
  3. man pages sshd_config, ssh_config, tcpd, yum, and apt-get.
If you have a technique or handy software not mentioned here, please share in the comments below to help your fellow readers keep their openssh based server secure.

Linux Server Hardening TIPS

Securing your Linux server is important to protect your data, intellectual property, and time, from the hands of crackers (hackers). The system administrator is responsible for security Linux box. In this first part of a Linux server security series, I will provide 20 hardening tips for default installation of Linux system.

#1: Encrypt Data Communication

All data transmitted over a network is open to monitoring. Encrypt transmitted data whenever possible with password or using keys / certificates.

  1. Use scp, ssh, rsync, or sftp for file transfer. You can also mount remote server file system or your own home directory using special sshfs and fuse tools.
  2. GnuPG allows to encrypt and sign your data and communication, features a versatile key managment system as well as access modules for all kind of public key directories.
  3. Fugu is a graphical frontend to the commandline Secure File Transfer application (SFTP). SFTP is similar to FTP, but unlike FTP, the entire session is encrypted, meaning no passwords are sent in cleartext form, and is thus much less vulnerable to third-party interception. Another option is FileZilla – a cross-platform client that supports FTP, FTP over SSL/TLS (FTPS), and SSH File Transfer Protocol (SFTP).
  4. OpenVPN is a cost-effective, lightweight SSL VPN.
  5. Lighttpd SSL (Secure Server Layer) Https Configuration And Installation
  6. Apache SSL (Secure Server Layer) Https (mod_ssl) Configuration And Installation

#1.1: Avoid Using FTP, Telnet, And Rlogin / Rsh

Under most network configurations, user names, passwords, FTP / telnet / rsh commands and transferred files can be captured by anyone on the same network using a packet sniffer. The common solution to this problem is to use either OpenSSH , SFTP, or FTPS (FTP over SSL), which adds SSL or TLS encryption to FTP. Type the following command to delete NIS, rsh and other outdated service:
# yum erase inetd xinetd ypserv tftp-server telnet-server rsh-serve

#2: Minimize Software to Minimize Vulnerability

Do you really need all sort of web services installed? Avoid installing unnecessary software to avoid vulnerabilities in software. Use the RPM package manager such as yum or apt-get and/or dpkg to review all installed set of software packages on a system. Delete all unwanted packages.
# yum list installed
# yum list packageName
# yum remove packageName

# dpkg --list
# dpkg --info packageName
# apt-get remove packageName

#3: One Network Service Per System or VM Instance

Run different network services on separate servers or VM instance. This limits the number of other services that can be compromised. For example, if an attacker able to successfully exploit a software such as Apache flow, he / she will get an access to entire server including other services such as MySQL, e-mail server and so on. See how to install Virtualization software:

  • Install and Setup XEN Virtualization Software on CentOS Linux 5
  • How To Setup OpenVZ under RHEL / CentOS Linux

#4: Keep Linux Kernel and Software Up to Date

Applying security patches is an important part of maintaining Linux server. Linux provides all necessary tools to keep your system updated, and also allows for easy upgrades between versions. All security update should be reviewed and applied as soon as possible. Again, use the RPM package manager such as yum and/or apt-get and/or dpkg to apply all security updates.
# yum update
# apt-get update && apt-get upgrade
You can configure Red hat / CentOS / Fedora Linux to send yum package update notification via email. Another option is to apply all security updates via a cron job. Under Debian / Ubuntu Linux you can use apticron to send security notifications.

#5: Use Linux Security Extensions

Linux comes with various security patches which can be used to guard against misconfigured or compromised programs. If possible use SELinux and other Linux security extensions to enforce limitations on network and other programs. For example, SELinux provides a variety of security policies for Linux kernel.

#5.1: SELinux

I strongly recommend using SELinux which provides a flexible Mandatory Access Control (MAC). Under standard Linux Discretionary Access Control (DAC), an application or process running as a user (UID or SUID) has the user’s permissions to objects such as files, sockets, and other processes. Running a MAC kernel protects the system from malicious or flawed applications that can damage or destroy the system. See the official Redhat documentation which explains SELinux configuration.

#6: User Accounts and Strong Password Policy

Use the useradd / usermod commands to create and maintain user accounts. Make sure you have a good and strong password policy. For example, a good password includes at least 8 characters long and mixture of alphabets, number, special character, upper & lower alphabets etc. Most important pick a password you can remember. Use tools such as “John the ripper” to find out weak users passwords on your server. Configure pam_cracklib.so to enforce the password policy.

#6.1: Password Aging

The chage command changes the number of days between password changes and the date of the last password change. This information is used by the system to determine when a user must change his/her password. The /etc/login.defs file defines the site-specific configuration for the shadow password suite including password aging configuration. To disable password aging, enter:
chage -M 99999 userName
To get password expiration information, enter:
chage -l userName
Finally, you can also edit the /etc/shadow file in the following fields:



  1. Minimum_days: The minimum number of days required between password changes i.e. the number of days left before the user is allowed to change his/her password.
  2. Maximum_days: The maximum number of days the password is valid (after that user is forced to change his/her password).
  3. Warn : The number of days before password is to expire that user is warned that his/her password must be changed.
  4. Expire : Days since Jan 1, 1970 that account is disabled i.e. an absolute date specifying when the login may no longer be used.

I recommend chage command instead of editing the /etc/shadow by hand:
# chage -M 60 -m 7 -W 7 userName
Recommend readings:

  • Linux: Force Users To Change Their Passwords Upon First Login
  • Linux turn On / Off password expiration / aging
  • Lock the user password
  • Search for all account without password and lock them
  • Use Linux groups to enhance security

#6.2: Restricting Use of Previous Passwords

You can prevent all users from using or reuse same old passwords under Linux. The pam_unix module parameter remember can be used to configure the number of previous passwords that cannot be reused.

#6.3: Locking User Accounts After Login Failures

Under Linux you can use the faillog command to display faillog records or to set login failure limits. faillog formats the contents of the failure log from /var/log/faillog database / log file. It also can be used for maintains failure counters and limits.To see failed login attempts, enter:
To unlock an account after login failures, run:
faillog -r -u userName
Note you can use passwd command to lock and unlock accounts:
# lock account
passwd -l userName
# unlocak account
passwd -u userName

#6.4: How Do I Verify No Accounts Have Empty Passwords?

Type the following command
# awk -F: '($2 == "") {print}' /etc/shadow
Lock all empty password accounts:
# passwd -l accountName

#6.5: Make Sure No Non-Root Accounts Have UID Set To 0

Only root account have UID 0 with full permissions to access the system. Type the following command to display all accounts with UID set to 0:
# awk -F: '($3 == "0") {print}' /etc/passwd
You should only see one line as follows:


If you see other lines, delete them or make sure other accounts are authorized by you to use UID 0.

#7: Disable root Login

Never ever login as root user. You should use sudo to execute root level commands as and when required. sudo does greatly enhances the security of the system without sharing root password with other users and admins. sudo provides simple auditing and tracking features too.

#8: Physical Server Security

You must protect Linux servers physical console access. Configure the BIOS and disable the booting from external devices such as DVDs / CDs / USB pen. Set BIOS and grub boot loader password to protect these settings. All production boxes must be locked in IDCs (Internet Data Center) and all persons must pass some sort of security checks before accessing your server. See also:

  • 9 Tips To Protect Linux Servers Physical Console Access.

#9: Disable Unwanted Services

Disable all unnecessary services and daemons (services that runs in the background). You need to remove all unwanted services from the system start-up. Type the following command to list all services which are started at boot time in run level # 3:
# chkconfig --list | grep '3:on'
To disable service, enter:
# service serviceName stop
# chkconfig serviceName off

#9.1: Find Listening Network Ports

Use the following command to list all open ports and associated programs:
netstat -tulpn
nmap -sT -O localhost
nmap -sT -O server.example.com

Use iptables to close open ports or stop all unwanted network services using above service and chkconfig commands.

#9.2: See Also

  • update-rc.d like command on Redhat Enterprise / CentOS Linux.
  • Ubuntu / Debian Linux: Services Configuration Tool to Start / Stop System Services.
  • Get Detailed Information About Particular IP address Connections Using netstat Command.

#10: Delete X Windows

X Windows on server is not required. There is no reason to run X Windows on your dedicated mail and Apache web server. You can disable and remove X Windows to improve server security and performance. Edit /etc/inittab and set run level to 3. Finally, remove X Windows system, enter:
# yum groupremove "X Window System"

#11: Configure Iptables and TCPWrappers

Iptables is a user space application program that allows you to configure the firewall (Netfilter) provided by the Linux kernel. Use firewall to filter out traffic and allow only necessary traffic. Also use the TCPWrappers a host-based networking ACL system to filter network access to Internet. You can prevent many denial of service attacks with the help of Iptables:

  • Lighttpd Traffic Shaping: Throttle Connections Per Single IP (Rate Limit).
  • How to: Linux Iptables block common attack.
  • psad: Linux Detect And Block Port Scan Attacks In Real Time.

#12: Linux Kernel /etc/sysctl.conf Hardening

/etc/sysctl.conf file is used to configure kernel parameters at runtime. Linux reads and applies settings from /etc/sysctl.conf at boot time. Sample /etc/sysctl.conf:

# Turn on execshield
# Enable IP spoofing protection
# Disable IP source routing
# Ignoring broadcasts request
# Make sure spoofed packets get logged
net.ipv4.conf.all.log_martians = 1

#13: Separate Disk Partitions

Separation of the operating system files from user files may result into a better and secure system. Make sure the following filesystems are mounted on separate partitions:

  • /usr
  • /home
  • /var and /var/tmp
  • /tmp

Create septate partitions for Apache and FTP server roots. Edit /etc/fstab file and make sure you add the following configuration options:

  1. noexec – Do not set execution of any binaries on this partition (prevents execution of binaries but allows scripts).
  2. nodev – Do not allow character or special devices on this partition (prevents use of device files such as zero, sda etc).
  3. nosuid – Do not set SUID/SGID access on this partition (prevent the setuid bit).

Sample /etc/fstab entry to to limit user access on /dev/sda5 (ftp server root directory):

/dev/sda5  /ftpdata          ext3    defaults,nosuid,nodev,noexec 1 2

#13.1: Disk Quotas

Make sure disk quota is enabled for all users. To implement disk quotas, use the following steps:

  1. Enable quotas per file system by modifying the /etc/fstab file.
  2. Remount the file system(s).
  3. Create the quota database files and generate the disk usage table.
  4. Assign quota policies.
  5. See implementing disk quotas tutorial for further details.

#14: Turn Off IPv6

Internet Protocol version 6 (IPv6) provides a new Internet layer of the TCP/IP protocol suite that replaces Internet Protocol version 4 (IPv4) and provides many benefits. Currently there are no good tools out which are able to check a system over network for IPv6 security issues. Most Linux distro began enabling IPv6 protocol by default. Crackers can send bad traffic via IPv6 as most admins are not monitoring it. Unless network configuration requires it, disable IPv6 or configure Linux IPv6 firewall:

  • RedHat / Centos Disable IPv6 Networking.
  • Debian / Ubuntu And Other Linux Distros Disable IPv6 Networking.
  • Linux IPv6 Howto – Chapter 19. Security.
  • Linux IPv6 Firewall configuration and scripts are available here.

#15: Disable Unwanted SUID and SGID Binaries

All SUID/SGID bits enabled file can be misused when the SUID/SGID executable has a security problem or bug. All local or remote user can use such file. It is a good idea to find all such files. Use the find command as follows:
#See all set user id files:
find / -perm +4000
# See all group id files
find / -perm +2000
# Or combine both in a single command
find / ( -perm -4000 -o -perm -2000 ) -print
find / -path -prune -o -type f -perm +6000 -ls

You need to investigate each reported file. See reported file man page for further details.

#15.1: World-Writable Files

Anyone can modify world-writable file resulting into a security issue. Use the following command to find all world writable and sticky bits set files:
find /dir -xdev -type d ( -perm -0002 -a ! -perm -1000 ) -print
You need to investigate each reported file and either set correct user and group permission or remove it.

#15.2: Noowner Files

Files not owned by any user or group can pose a security problem. Just find them with the following command which do not belong to a valid user and a valid group
find /dir -xdev ( -nouser -o -nogroup ) -print
You need to investigate each reported file and either assign it to an appropriate user and group or remove it.

#16: Use A Centralized Authentication Service

Without a centralized authentication system, user auth data becomes inconsistent, which may lead into out-of-date credentials and forgotten accounts which should have been deleted in first place. A centralized authentication service allows you maintaining central control over Linux / UNIX account and authentication data. You can keep auth data synchronized between servers. Do not use the NIS service for centralized authentication. Use OpenLDAP for clients and servers.

#16.1: Kerberos

Kerberos performs authentication as a trusted third party authentication service by using cryptographic shared secret under the assumption that packets traveling along the insecure network can be read, modified, and inserted. Kerberos builds on symmetric-key cryptography and requires a key distribution center. You can make remote login, remote copy, secure inter-system file copying and other high-risk tasks safer and more controllable using Kerberos. So, when users authenticate to network services using Kerberos, unauthorized users attempting to gather passwords by monitoring network traffic are effectively thwarted. See how to setup and use Kerberos.

#17: Logging and Auditing

You need to configure logging and auditing to collect all hacking and cracking attempts. By default syslog stores data in /var/log/ directory. This is also useful to find out software misconfiguration which may open your system to various attacks. See the following logging related articles:

  1. Linux log file locations.
  2. How to send logs to a remote loghost.
  3. How do I rotate log files?.
  4. man pages syslogd, syslog.conf and logrotate.

#17.1: Monitor Suspicious Log Messages With Logwatch / Logcheck

Read your logs using logwatch or logcheck. These tools make your log reading life easier. You get detailed reporting on unusual items in syslog via email. A sample syslog report:

 ################### Logwatch 7.3 (03/24/06) ####################
        Processing Initiated: Fri Oct 30 04:02:03 2009
        Date Range Processed: yesterday
                              ( 2009-Oct-29 )
                              Period is day.
      Detail Level of Output: 0
              Type of Output: unformatted
           Logfiles for Host: www-52.nixcraft.net.in
 --------------------- Named Begin ------------------------
 **Unmatched Entries**
    general: info: zone XXXXXX.com/IN: Transfer started.: 3 Time(s)
    general: info: zone XXXXXX.com/IN: refresh: retry limit for master ttttttttttttttttttt#53 exceeded (source ::#0): 3 Time(s)
    general: info: zone XXXXXX.com/IN: Transfer started.: 4 Time(s)
    general: info: zone XXXXXX.com/IN: refresh: retry limit for master ttttttttttttttttttt#53 exceeded (source ::#0): 4 Time(s)
 ---------------------- Named End -------------------------
  --------------------- iptables firewall Begin ------------------------
 Logged 87 packets on interface eth0
   From 58.y.xxx.ww - 1 packet to tcp(8080)
   From 59.www.zzz.yyy - 1 packet to tcp(22)
   From 60.32.nnn.yyy - 2 packets to tcp(45633)
   From 222.xxx.ttt.zz - 5 packets to tcp(8000,8080,8800)
 ---------------------- iptables firewall End -------------------------
 --------------------- SSHD Begin ------------------------
 Users logging in through sshd:
       123.xxx.ttt.zzz: 6 times
 ---------------------- SSHD End -------------------------
 --------------------- Disk Space Begin ------------------------
 Filesystem            Size  Used Avail Use% Mounted on
 /dev/sda3             450G  185G  241G  44% /
 /dev/sda1              99M   35M   60M  37% /boot
 ---------------------- Disk Space End -------------------------
 ###################### Logwatch End #########################

(Note output is truncated)

#17.2: System Accounting with auditd

The auditd is provided for system auditing. It is responsible for writing audit records to the disk. During startup, the rules in /etc/audit.rules are read by this daemon. You can open /etc/audit.rules file and make changes such as setup audit file log location and other option. With auditd you can answers the following questions:

  1. System startup and shutdown events (reboot / halt).
  2. Date and time of the event.
  3. User respoisble for the event (such as trying to access /path/to/topsecret.dat file).
  4. Type of event (edit, access, delete, write, update file & commands).
  5. Success or failure of the event.
  6. Records events that Modify date and time.
  7. Find out who made changes to modify the system’s network settings.
  8. Record events that modify user/group information.
  9. See who made changes to a file etc.

See our quick tutorial which explains enabling and using the auditd service.

#18: Secure OpenSSH Server

The SSH protocol is recommended for remote login and remote file transfer. However, ssh is open to many attacks. See how to secure OpenSSH server:

#19: Install And Use Intrusion Detection System

A network intrusion detection system (NIDS) is an intrusion detection system that tries to detect malicious activity such as denial of service attacks, port scans or even attempts to crack into computers by monitoring network traffic.

It is a good practice to deploy any integrity checking software before system goes online in a production environment. If possible install AIDE software before the system is connected to any network. AIDE is a host-based intrusion detection system (HIDS) it can monitor and analyses the internals of a computing system.

Snort is a software for intrusion detection which is capable of performing packet logging and real-time traffic analysis on IP networks.

#20: Protecting Files, Directories and Email

Linux offers excellent protections against unauthorized data access. File permissions and MAC prevent unauthorized access from accessing data. However, permissions set by the Linux are irrelevant if an attacker has physical access to a computer and can simply move the computer’s hard drive to another system to copy and analyze the sensitive data. You can easily protect files, and partitons under Linux using the following tools:

  • To encrypt and decrypt files with a password, use gpg command.
  • Linux or UNIX password protect files with openssl and other tools.
  • See how to encrypting directories with ecryptfs.
  • TrueCrypt is free open-source disk encryption software for Windows 7/Vista/XP, Mac OS X and Linux.
  • Howto: Disk and partition encryption in Linux for mobile devices.
  • How to setup encrypted Swap on Linux.

#20.1: Securing Email Servers

You can use SSL certificates and gpg keys to secure email communication on both server and client computers:

  • Linux Securing Dovecot IMAPS / POP3S Server with SSL Configuration.
  • Linux Postfix SMTP (Mail Server) SSL Certificate Installations and Configuration.
  • Courier IMAP SSL Server Certificate Installtion and Configuration.
  • Configure Sendmail SSL encryption for sending and receiving email.
  • Enigmail: Encrypted mail with Mozilla thunderbird.



NU/Linux CentOS server hardening that meets security guidelines.

The document will cover Physical Protection, User Rights, Network Security, Kernel Security and Tamper Resistance

File System Partitioning
File System LVM (So partitions can be shrunk or grown if needs be)

Partitions: (must be journaled FS)
/boot        primary
/        primary


-Install from clean formatted drive (check md5 sum)
-Use CentOS-ver-arch-minimal (roughly 260MB)
-Custom installations (installation must be done with minimal packages as possible)

Package installs
-The list of apps should be determined by the use of the machine.
-As a base no more than SSH installed, this to allow remote access.
-If we don’t need i386/i686 packages for compatibility purposes, we may want to remove them as well, by using yum remove *.i?86, and then keep them gone by adding exclude = *.i?86 to your /etc/yum.conf

Physical Protection
-Set up BIOS password.
-Place servers in a controlled area.
-Prevent servers from being booted through other medium.
-Servers are to be placed in racks with locking mechanisms.
-Conceal cabling and power outlets.
-Activate password for grub.
-Do not install any auto mount package for mount of external devices  such as USB, PCMCI, etc.
-Once installation of server is complete make sure that you’ve logged out from tty (virtual terminal).
-Allow only 2 tty and disable others (there are 6 by default), so make sure that we have only 2 runlevel.

CentOS Hardening
After installing and configuring, further steps have to be taken to ensure operating system hardening.
The minimum procedure that must be followed:
•Accounts (check if passwd files is shadowed)
•Check service and ports (services are background programs that serve as a utility function without being called by a user. This utility may range from maintenance utility or to provide an interface upon request. Most of these services are not useful depending on the UNIX/Linux usage purposes.
•Securing root applications (ensure /sbin and /etc folders are owned by root. By default, normal users can reboot the system by issuing ‘reboot’ command or by pressing Ctrl-Alt-Del combo keys.
•Detecting SUID/SGID apps (a regular user will be able to run a program as root if it is set to SUID root. We should minimize the use of these SUID/GUID apps and disable the programs which are not needed.
•Setup a specific server for repository that can be the only one with access to global internet.
•Install and check patches (verify integrity of patch by md5sum)
•Make sure that the server has no access to global internet.
•The list of apps should be determined by the use of the machine.
•The only service running by default should be SSH

Alert to show when user log on

-SSH banner alert message

NOTICE TO USERS WARNING! The use of this system is restricted to authorized users, unauthorized access is forbidden and will be prosecuted by law. All information and communications on this system are subject to review, monitoring and recording at any time, without notice or permission. Users should have no expectation of privacy.

Lock down GRUB 2
•Grub 2 has the ability to set password protection on individual menu entries and/or for specific users.
•The username and password will also be required to gain access to the Grub 2 command line and menu editing modes.
•The username and/or password do not have to be the same as the system logon name/password.
•This is basic password security. The name/password are unencrypted; anyone having physical access to the machine and more than an elementary knowledge of how Linux works will be able to access the configuration files and bypass this feature.
•Grub 2 password protection is still evolving. Currently (Grub 1.97beta4) password protection must be assigned to each menu entry. There is a chance the password feature will be revised so that all entries are protected by default. If and when this feature is incorporated in Grub 2, password protection can be eliminated for a specific menu entry by adding “(–unlock)” on the menu entry line.

Setting up password protection:
There are three steps to enabling Grub 2 password protection. The user must set up the authorized users, designate the password(s), and identify the password-protected menu entries in the/etc/grub.d/ scripts.

1. Superuser & password designation (required):
A superuser must be designated. This superuser can access any menu entry, edit the menu entries in the Grub 2 menu by pressing “e”, or invoke the Grub 2 command line mode. Add the following the bottom of /etc/grub.d/00_header
cat << EOF
set superusers=”user1?
password user1 password1

2. Other users (optional)
Other users can be identified and given a password. A designated user can access unprotected and their own menuentries. Add the following the bottom of /etc/grub.d/00_header

cat << EOF
set superusers=”sysadmin”
password sysadmin 1234
password user 5678

3. Designating menu entries for password protection
Once the superuser/other users and their password(s) are established, the entries to be protected must be identified. Currently Grub 2 adds no password protection to any entries upon establishment of a superuser and password in /etc/grub.d/00_header. Each entry must be identified and modified. Scripts can be used to tailor entries for specific menu entries.

Turn on SELinux protection (basic)

-Edit /etc/selinux/config file using “vi” or other text tool
-Update the configuration as follows:

Remove unnecessary modules

-A simple loop can be used to disable them via a blacklist file in /etc/modprobe.d:
-For example to remove wireless modules perform:
for i in $(find /lib/modules/`uname -r`/kernel/drivers/net/wireless -name “*.ko” -type f) ; do echo blacklist $i >> /etc/modprobe.d/blacklist-wireless ; done

Linux Kernel /etc/sysctl.conf Security Hardening

-Use “vi” to edit /etc/sysctl.conf and setup basic configuration as follows:
oLimit network-transmitted configuration for IPv4
oLimit network-transmitted configuration for IPv6
oTurn on exec shield protection
oPrevent against the common ‘syn flood attack’
oTurn on source IP address verification
oPrevents a cracker from using a spoofing attack against the IP address of the server.
oLogs several types of suspicious packets, such as spoofed packets, source-routed packets, and redirects.

-For example:
net.ipv4.ip_forward = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.tcp_max_syn_backlog = 1280
net.ipv4.icmp_echo_ignore_broadcasts = 1
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.secure_redirects = 0
net.ipv4.conf.all.log_martians = 1
net.ipv4.conf.default.accept_source_route = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.default.secure_redirects = 0
net.ipv4.icmp_echo_ignore_broadcasts = 1
net.ipv4.icmp_ignore_bogus_error_responses = 1
net.ipv4.tcp_syncookies = 1
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
net.ipv4.tcp_timestamps = 0

Harden password policies
-vi /etc/login.defs then edit PASS_MIN_LEN    5 ==> 8
-Strong passwords should be used. A strong password should have mixed case, special characters, numbers, and be at least 8 characters.
-Password complexity requirements should be in place to enforce strong password usage.
-Passwords should be changed reasonably regularly.
•echo “Passwords expire every 90 days”
•perl -npe ‘s/PASS_MAX_DAYS\s+99999/PASS_MAX_DAYS 90/’ -i /etc/login.defs

-The command below will update your system to use sha512 instead of md5 for password protection.

•authconfig –passalgo=sha512 –update
Time out after 15 minutes of idle time
-echo “Idle users will be removed after 15 minutes”
-echo “readonly TMOUT=900” >> /etc/profile.d/os-security.sh
-echo “readonly HISTFILE” >> /etc/profile.d/os-security.sh
-chmod +x /etc/profile.d/os-security.sh

Remove unwanted base applications
-rpm -ev iptables-ipv6 system-config-securitylevel-tui system-config-network-tui firstboot-tui wireless-tools
-rpm -ev xorg-x11-filesystem cups redhat-lsb rhpl gpm vim-enhanced pcsc-lite ifd-egate ccid coolkey

Ensure that root cannot log on through ssh
-sed “# PermitRootLogin yes/PermitRootLogin no/g” /etc/sshd.conf > /tmp/swap; cp /tmp/swap /etc/sshd.conf

Ensure that root can only log on locally

-Once a server is up and running, root shouldn’t be logging in directly except in emergency situations. These usually require hands at the console, so that’s the only place root should be allowed to log in. To do this, we need to modify /etc/securetty. Additionally, no one other than root should be allowed in root’s home directory. The default settings are close to this, but not quite paranoid enough.

echo “tty1” > /etc/securetty
chmod 700 /root

-Since we have effectively removed root’s ability to log in from anywhere but the local console, it becomes necessary to use su and sudo. This offers a few secondary benefits in a multi-admin environment.

•sudo allows for granular control over privileged actions. This way a website administrator can start, stop and otherwise manage the web server without being able to affect other services.

•You get a much clearer picture of who did what in your logs, since who became root at what time is no longer a mystery.
Blocking “su” to root user

The su (Substitute User) command allows a user to become other existing users on the system. To prevent users from su to root or restrict su command to certain users then add the following two lines to the top of su configuration in the /etc/pam.d directory.

Edit the su file (vi /etc/pam.d/su) and add the following two lines to the top of the file:
-auth sufficient /lib/security/pam_rootok.so debug
-auth required /lib/security/Pam_wheel.so group=wheel

This example provides that only members of the ‘wheel’ group can su to root, which also includes logging.
Securing root apps

Ensure /sbin and /etc folders are owned by root. By default, normal users can reboot the system by issuing ‘reboot’ command or by pressing Ctrl-Alt-Del combo keys.

To disable the reboot command to users, ensure /sbin/halt is owned by root:
# chmod 700 /sbin/halt

To disable Ctrl-Alt-Del, edit /etc/inittab :
# vi /etc/inittab

Add a comment to the line stating, ca::ctrlaltdel:/sbin/shutdown -t3 -r now, so it reads
# ca::ctrlaltdel:/sbin/shutdown -t3 -r now

After making changes issue the command to take effect :
# /sbin/init q

By commenting out the line, restarting using Ctrl-Alt-Del is useless even to root. To shutdown, login as root and use the proper shutdown command :
# /sbin/shutdown –r now

Replace ‘r’ with ‘h’ for powering off the system.

Securing /etc/services file

Securing the “/etc/services” file prevents unauthorized deletion or addition of services. This involves in adding an immutable bit to the file. To secure the “/etc/services” file, use the command:
# chattr +i /etc/services

Hardening the IPTables

IPTables provide customization of rules depending on the user needs. Here are some
recommended IPTables configurations. First general rule is to block everything, and from there rules are added accordingly. An allowed rule, ACCEPT, will bypass a blocking rule, e.g DROP, REJECT.

IPTables consists of chains that control the packet flow. These chains are INPUT,  OUTPUT and FORWARD.

Here are some basic configurations:
Rules should be cleared from the beginning.
# iptables -F; iptables -t nat -F; iptables -t mangle –F

To deny everything:
# iptables –A INPUT –j DROP
# iptables –A OUTPUT –j DROP
# iptables –A FORWARD –j DROP

These sample rules make a secure connection by enabling inspection against flowing packets. Only packets with established sessions are allowed through. ‘eth0’ is the interface number of a network card, changes should be applied accordingly:
# iptables -A INPUT -m state –state ESTABLISHED,RELATED -j ACCEPT
# iptables -A INPUT -m state –state NEW -i ! eth0 -j ACCEPT
# iptables -P INPUT DROP
# iptables –A FORWARD –I eth0 –o eth0 –j REJECT
TCP Wrappers

TCP wrapper is used to provide additional security against intrusion by controlling connections to defined services. TCP wrappers are controlled from two files.
– /etc/hosts.allow

The best policy is to deny all hosts by putting “ALL: ALL@ALL, PARANOID” in the “/etc/hosts.deny” file and then explicitly list trusted hosts who are allowed to connect to the machine in the “/etc/hosts.allow” file.

However, advance filtering can be achieved using a built-in utility IPTables.
Hiding the system information

echo ” ” >/etc/issue
echo ” ” >/etc/issue.net

chattr +i /etc/issue
chattr +i /etc/issue.net
Hardening network

-Remove ipv6
cp /etc/sysconfig/network /root/aspf_files/network.aspf

cat > /etc/sysconfig/network <<DELIM

-Enabled bonding on the network cards, will need to discuss the best algorithm
Enable NTP and sync

-Sort NTP — Should be the router once it works for NTP
cp /etc/ntp.conf /root/aspf_files/ntp.conf.aspf

sed “/[0-1].centos.pool.ntp.org/d” /etc/ntp.conf > /tmp/swap;
sed “s/2.centos.pool.ntp.org/hostname/g” /tmp/swap > /etc/ntp.conf;

ntpdate -d hostname

-Sync everything to the NTP clock before installing any applications — Add to root cron for consistent time stamps
yum install ntp

hwclock; date; ntpdate
/usr/sbin/hwclock –systohc

** Add it cron
cat > /tmp/crontab.txt <<DELIM
*/10 * * * * /usr/sbin/hwclock –systohc
crontab /tmp/crontab.txt; rm -f /tmp/crontab.txt

Install sudosh

-Setup sudosh
Assume root PWD is with security, enusre all user shells including roots are recorded when used, the sudosh-replay logs need to be shipped out via syslog. For the moment they are local “TPOC”
-echo “/usr/bin/sudosh” >>/etc/shells
Synchronise all group accounts

-Synchronise all group accounts across all systems to use specific GID’s using higher numbers so we have no chance of application group overlap i.e.

groupadd ops -g 1000
groupadd ops_support -g 1001

-Then ( only use -g 10 if they need sudo for root )
useradd spannerh -n -m -c “Spanner Admin” -G 1000 -s /usr/bin/sudosh
-use -p and crypt if you do not want to use #passwd spannerh to set the password

Disable YUM after updates run
-Disable yum automatic updates and do it manually if needed
-List all packages installed on the sytem:
yum list installed  >>  ~/installed.txt

-Add it to cron
cat > /tmp/yumtab.txt <<DELIM
/usr/bin/yum -R 120 -e 0 -d 0 -y update yum
/usr/bin/yum -R 10 -e 0 -d 0 -y update

cp /tmp/yumtab.txt /etc/cron.daily/yum_update.cron
chmod 500 /etc/cron.daily/yum_update.cron

-manual until we script it | kill off suid
find / \( -perm -4000 -o -perm -2000 \) –print

Ensure that the system cannot be messed with

-You should have a central logging system, on a remote server (LDAP with Kerberos/PAM auth and Samba for other OS cooperation)
-On critical machines can be installed/configured Host Based IDS and Network Based IDS at software level such as (Snort, AIDE, Tripwire, LogCheck, etc.)



Twenty-Five Linux Server Hardening Tips

When it comes to having a Linux server hosted in a data center or it is not behind any kind of Firewall or NAT device there are a number of security requirements that need to be addressed. Linux servers generally come with no protection configured by default and depending on the hosting company or distro can come preconfigured with many services installed that are not required, including Web Servers, FTP Servers, Mail Servers and SSH Remote Access.

The following is a compilation of various settings and techniques you can employ to harden the security of your vulnerable Linux systems. While I have tried to put them in order of the most important features first I would recommend all of these options be used on your critical production servers.

TIP #1 – Strong Passwords
Always create long passwords that contain upper and lower case letters, numbers and non alpha-numeric characters. Enforce password ageing so users need to change their passwords regularly. Lock user accounts after a certain number of failed login attempts.

TIP #2 – Use Public/Private Keys
Make use of Public/Private SSH keys for login of remote users instead of passwords, this provides the benefit of turning off password authentication in SSH so that your server can’t be Brute-Force cracked. However this does introduce a new problem whereby a malicious person could compromise a user’s computer or steal their laptop and then have access to the server. This can be overcome by using a password on the client certificate which must be entered before connecting, a kind of two factor authentication.

TIP #3 – Disable Root Login
Disable the Root user from being able to login either via the console or remote SSH connections. Instead have users use Sudo to run programs that require root privileges, or use sudo su to change to the Root user once logged in. This provides an audit path to show which user installed a piece of software or ran a program.

TIP #4 – Use Encrypted Traffic
Always use the encrypted equivalent protocol when transferring critical and sensitive data such as passwords and confidential material. Remove RSH and always use SSH for remote access. Instead of using FTP for file transfer, consider using SFTP or FTP/S (FTP over SSL) or RSYNC. Instead of having remote access open to the internet i.e. SSH or VNC setup an OpenVPN SSL VPN Server to connect to first.

TIP #6 – Use Centralized Password Server
Consider implementing either a LDAP or Kerebos server to perform password authentication. This allows for a central database to maintain user’s passwords between multiple servers for easy management. This prevents user account and password data from becoming inconsistent and out of date, and prevents user accounts that should have been deleted on all servers being left behind on one server.

TIP #7 – Use IPTABLES Firewall/TCP Wrapper
Implementing a secure IPTABLES firewall will limit your exposure to network threats such as DOS and Port Scanning attacks. You can lock down any ports that don’t require access from external networks. For instance you can use the following command to only allow SSH access to the server from the local network.

# iptables –A INPUT –s –p tcp –dport 22 –j ACCEPT

You can install a TCP Wrapper named libwrap which will give information like who connected, when and from where and even which services they connected to. It can also be used for locking down access to ports and services for certain hosts or IP’s.

TIP #8 – Use Intrusion Detection Systems
Consider installing both a Network IDS (NIDS) and a Host Based IDS (HIDS). NIDS’s are used to protect against malicious threats such as DOS and Port Scan Attacks. HIDS’s such as AIDE are used to monitor file system changes such as an intruder replacing core system files like ls or ps with malicious ones that hide their Trojan from file or process lists. It will produce a report that tells you what files have been modified so you can repair or replace them.

TIP #9 – Users Assigned Least Privileges
Disable Shell access to users that don’t need it (ftp, mail users etc) by changing to /bin/noshell in the /etc/passwd file. Setup a group for standard users and remove permissions to tools that can be used to download malicious software like wget, lynx, ftp etc. Consider chrooting users to their home directories to stop them from modifying critical system files.

TIP #10 – Minimize Software
Only install software that is actually needed, some systems come preconfigured with many software packages that you may never need or use. When installing always choose the Minimal Installation or Manual Installation option if they exist. Then simply install the software that you actually need.

TIP #11 – Keep Software Updated
Always try to keep your software packages up to date, such as ensuring the latest version of Apache, MySQL and PHP on a standard LAMP setup will protect you against any vulnerabilities that have been discovered in previous versions.

TIP #12 – Disable Unwanted Services
Your servers will most likely have many background services (Daemons) running which are not required and some may be configured to run on start-up. The following command (Red Hat, Cent OS only) can be used to show all services that will start on boot.

# chkconfig --list | grep : on

Or just use the following command to view services which are turned on only for Run Level 3.

# chkconfig --list | grep 3:on

You would then use a command like this to remove the service from start-up.

# chkconfig --del ‘service-name’

TIP #13 – Remove X Windows
Consider completely removing X Windows from the system and just using the command line for management. There isn’t anything that you can do in the GUI that you can’t do using the command line and removing it will not only enhance security but also performance because no system resources are wasted displaying the GUI.

TIP #14 – Secure Linux Kernel
You can secure your Linux Kernel by modifying the /etc/sysctl.conf file, this file is read by the Kernel at boot time and can be edited with the following settings to add extra security.

# Turn on execshield
kernel.exec-shield = 1
kernel.randomize_va_space = 1
# Don't reply to broadcasts. Prevents joining a smurf attack
net.ipv4.icmp_echo_ignore_broadcasts = 1
# Enable protection for bad icmp error messages
net.ipv4.icmp_ignore_bogus_error_responses = 1
# Enable syncookies for SYN flood attack protection
net.ipv4.tcp_syncookies = 1
# Enable IP spoofing protection
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
# Log spoofed, source routed, and redirect packets
net.ipv4.conf.all.log_martians = 1
net.ipv4.conf.default.log_martians = 1
# Don't allow source routed packets
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0
# Don't allow outsiders to alter the routing tables
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.all.secure_redirects = 0
net.ipv4.conf.default.secure_redirects = 0
# Don't pass traffic between networks or act as a router
net.ipv4.ip_forward = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0

TIP #15 – Install Linux Kernel Patches
You should have a written security policy for handling Linux Kernel Patches, which should include which Linux security notices have been received, which updates have been tested to ensure problems don’t arise and which patches have been installed on the system. Always ensure Production servers are updated regularly to avoid any potential known vulnerability from being exploited on your system.

TIP #16 – Separate Partitions
You should create separate partitions for user modifiable directories and block write and execute access to unneeded partitions. You should consider placing the following file systems on different partitions.
/var and /var/tmp

Then you can edit the /etc/fstab file to prevent execution of binary files, disable block devices on the partition and prevent the SUID/SGID from being set on files. Here is a common fstab file entry to limit user access to the ftpdata directory.

/dev/sda5  /ftpdata  ext3    defaults,noexec,nodev,nosuid 1 2

TIP #17 – Use Linux Security Extensions
Make use of software like SELinux, AppArmor or GRSecurity to provide additional hardening to your Linux Kernel. These products provide additional policies to restrict processes and services based on Access Control Lists.

TIP #18 – Separate Servers for Services
Consider setting up different physical or virtual servers for different roles, i.e. separate your Mail server and your Webserver, or your Database server and your Application server. This ensures that if one particular service is compromised it is contained to just one server.

TIP #19 – Physical Server Security
You can secure your server as much as possible from remote attacks, but if you don’t do anything to protect the physical hardware it is pointless. If someone has access to your physical server they can remove your hard drive and read your confidential data or boot from a CD and access your data. Consider creating a BIOS password and disabling booting from CD or USB. Also you should password protect your boot loader (GRUB, LILO, etc) to prevent users from accessing Single User Mode or Recovery Environments where passwords are not required.

TIP #20 – Setup NTP
Having an accurate system clock is important for reviewing log files and determining when an event occurred. Often system clocks can become out of sync or be reset to an older date and this can cause havoc with tracking of errors. Consider creating a Cron job rather than running ntpd (See Tip #12) to update the time daily or hourly with a common source for all servers.

TIP #21 – Monitor All Logs
Setup logging and auditing software to track errors and changes to your servers, such as Auditd and Logwatch/Logcheck. Consider configuring a remote logging server that is updated regularly to protect against an intruder compromising your log files without your knowledge.

TIP #22 – Disable IPv6
IPv6 is very rarely needed at this stage as most traffic only utilizes IPv4 and having IPV6 enabled is just another network you need to monitor and protect. Disabling IPv6 is the easiest option but if for some reason you do require it then you should configure an IPv6 Firewall.

TIP #23 – Remove SUID and SGID from Files
After you have setup and configured your system and software you should run the following commands to search for all file and folders with either the SUID, SGID bit set or world writeable folders.
To find all SUID files:

# find / -xdev -type f -perm +u=s –print

To find all SGID files:

# find / -xdev -type f -perm +g=s -print

To find all World Writeable Dirs:

# find / -xdev -perm +o=w ! \( -type d -perm +o=t \) ! -type l -print

You should then inspect each file and folder to determine if they have the correct settings and if not use the chmod command to make changes to them.

TIP #24 – Encrypt Confidential Data
Your data is usually stored on a hard drive in an unencrypted format so any user that has access to the server can remove the hard drive and install it in another system and read all your data. You should consider configuring Linux disk or folder encryption on either your home directories or your sensitive folders (i.e. Database Files, Emails, etc). While you could encrypt your entire drive this is a lot of work and may not be worth the hassle.

TIP #25 – Harden Your Software
It is great to have a highly secure Linux server but your system is only secure as the software you run on it. You should always install the latest versions of software and ensure they stay up to date. Also most programs have ways to make them more secure by editing their configuration files and disabling unnecessary parts of the software. The following is an example for hardening your OpenSSH Server settings, simply add the following  to your OpenSSH config file.

# Use only SSH Protocol Ver 2
Protocol 2
# Only allow the following users SSH Access
AllowUsers User1 User2 etc
# Deny access to the following users
DenyUsers admin etc
# Set the timeout period for idle sessions (in seconds)
ClientAliveInterval 300
ClientAliveCountMax 0
# Disable .rhosts files
IgnoreRhosts yes
# Disable Host-Based Authentication
HostbasedAuthentication no
# Remove ability to login as Root
PermitRootLogin no
# Change the default SSH Port (Not essential but can help uncomment if you want)
#Port 22
# Consider CHRooting users to their own directories.
# Subsystem sftp internal-sftp
#Match group sftponly
#         ChrootDirectory /home/%u
#         X11Forwarding no
#         AllowTcpForwarding no
#         ForceCommand internal-sftp
# Disable empty passwords from login
PermitEmptyPasswords no
# Set your required Log Level (Either INFO or DEBUG)
LogLevel INFO
#  Turn on privilege separation
UsePrivilegeSeparation yes
# Prevent the use of insecure home directory and key file permissions
StrictModes yes
# Turn on  reverse name checking
VerifyReverseMapping yes
# Do you need port forwarding?
AllowTcpForwarding no
X11Forwarding no
#  Specifies whether password authentication is allowed.  The default is yes.
PasswordAuthentication no



Linux Commands – Not Usual

Check Validity of a Certificate File (PEM File)

# openssl x509 -in Certificates.pem -inform PEM -text -noout -enddate



Version: 3 (0x2)

Serial Number:


Signature Algorithm: sha1WithRSAEncryption

Issuer: C=US, O=Sabe Inc., OU=Sabe Relations, CN=Sabe Certification Authority


Not Before: Oct  1 11:56:10 2011 GMT
Not After : Sep 30 11:56:10 2012 GMT

Sometime Apache process, keeps on execution (Seems like Hangs), so generally trying to get the exact PHP file that is running by Apache Process, So here is my Try.

I used Strace to get the opened files by the apache process. (Get PID of 
Apache process that is taking time, though you can also get it From top  command)

# pstree -p -n | grep http
(This will show each files that is being processed by that Apache Proc)

# strace -p <PID of Apache>
The list of files could also be get using lsof, but that could not be of full use, as you need the files continuusly  using by Apache Process

Create many Files Sequentially

# seq -w 1 30 | xargs -i -t zcat in_Feb2011/in_Files-{}May2011.gz | grep -E ‘name.html?secsid=3304847|name.html?secsid=30780899’

Delete Empty Directories

# find folder/ -type d -empty | xargs -i -t rm -rf {}
# find folder/ -type d -empty -delete 

Tail, Vmstat and Date  in Loop, Output every 10 Sec

# vmstat 1 1;for ((;;));do date; vmstat 10 2 | tail -n1;done

Real Time Monitoring on Linux
# watch -n1 –difference “echo “Uptime”; uptime; echo \n ; ps -eo pcpu,pid,args | sort -k 1 -r |grep -v watch | head -10; echo “\n” ; tail /var/log/cron | grep “check_load”

Find files based and sorted on Size
# find / -type f -size +20000k -exec ls -lh {} \; 2> /dev/null | awk ‘{ print $NF “: ” $5 }’  | sort -nrk 2,2

Check Memory Fault
# dd if=/dev/urandom bs=768304 of=/tmp/memtest count=1050
# md5sum /tmp/memtest; md5sum /tmp/memtest; md5sum /tmp/memtest

Repair Mysql MYISAM File
# myisamchk –force –sort_buffer_size=64M –key_buffer_size=16M –read_buffer_size=8M –write_buffer_size=8M ../data/phplists/phplist_linktrack.MYI

DELETE mail Que from Qmail
# qmail stop
# find /var/qmail/queue/mess -type f -exec rm {} \;
# find /var/qmail/queue/info -type f -exec rm {} \;
# find /var/qmail/queue/local -type f -exec rm {} \;
# find /var/qmail/queue/intd -type f -exec rm {} \;
# find /var/qmail/queue/todo -type f -exec rm {} \;
# find /var/qmail/queue/remote -type f -exec rm {} \;
# qmail start

Display sorted process taking most CPU in descending order
# ps -eo pcpu,pid,user,args | sort -k 1 -r | head -10

Download FTP files Recursivly using ncftpget
ncftpget -R -v -u “<username>” -p “<password>” <servername not IP>   <local Path to store /temp><destination FTP Server file Path /www.domain.com/2009_Feb/*>
# ncftpget -R -v -u “ibnlive” -p “ibn123” ftpserver /temp/ /www.domain.com/2009_Feb/*

Command to make Services off in Defined Level on Linux
# chkconfig –list | awk ‘{print $1}’ | cut -d: -f1 | grep -vE ‘^crond|^network|^sshd|^syslog|^iptables’ | awk ‘{print $1}’ | while read line; do chkconfig  –level 3 $line off; count=`expr $count + 1`; echo $count $line;done
or Use this… One lineer
# chkconfig –list | awk ‘{print $1}’| grep -vE ‘^crond|^network|^sshd|^syslog|^iptables’ | xargs -i chkconfig –level 3 {} off

Counting Hits from Web Server Access log
# awk ‘{print $1}’ /opt/indian.com/access_log | grep -vE ‘^:|^common|^-‘ | sort | uniq -c | sort -nr > /var/www/reports/ips/indian.txt
or  # awk ‘$1>10000 {print $1}’ /opt/indian.com/access_log | uniq -c | sort -nr  > /var/www/reports/ips/indian.txt

PERL Search and Replace Text Pattern using Perl On linux Platform
# find . -type f -name “*.html” | xargs perl -pi~ -e ‘s/\/js\/active18\//\/read\/js\/active18\//’Killing processes in one Line
# kill -9 `ps -ef | grep rsync| grep -v grep| awk ‘{print $2}’`

Check CPU Temperature
# echo `date +%b-%d-%H:%M:%S` | tr -d ‘\ 012’ ; echo -n ‘ ‘; sensors | awk ‘/CPU Temp:/{ print $3 }’
Check those commands which have been used most
# history|awk ‘{print $2}’ |awk ‘{print $1}’ | sort | uniq -c | sort -rn | head -10
Mount / partition in “Repair Mode” Repair filesystem
# mount -w -o remount /

Free Memory  on Linux at Runtime
# sync

# echo 3 > /proc/sys/vm/drop_caches