#!/bin/bash
#
# serverHarden.sh - Server Hardening Script
# Collaborate Effort by Sago SysAdmin Team:
# Max R / Kyle A
#
# Copyright 2007
#
#
# Please store all downloads on apf.sagonet.com and use wgets from that site only.
#


function cpanelcheck {
###
#Is this a Cpanel Server? - KA
echo "Is this a Cpanel Server (0 for no, 1 for yes)? "
read CPANEL
echo "Cpanel: $CPANEL" >> $OUTPUT
echo "Cpanel: $CPANEL" >> $RESULTS
}

function chkrootkit {
###
# chkrootkit - KA
# We need to make a list of false positives for cPanel & non-cPanel - MR
wget -q -nc apf.sagonet.net/chkrootkit.tar.gz  || 
(echo "Error getting chkrootkit ..Exiting" && echo "Error getting chkrootkit ..Exiting" >> $OUTPUT ; exit 1)
tar -xzf chkrootkit.tar.gz
cd chkrootkit-0.47/
make
cd ..
mv chkrootkit-0.47/ /usr/local/chkrootkit
cp /usr/bin/find /bin/echo /bin/awk /bin/cut /bin/egrep /usr/bin/head /usr/bin/id /bin/ls /bin/netstat /bin/ps /usr/bin/strings /bin/sed /bin/uname /usr/local/chkrootkit
echo "Test Run of chkrootkit..." && echo "Test Run of chkrootkit..." >> $OUTPUT
cd /usr/local/chkrootkit/
/usr/local/chkrootkit/chkrootkit -p /usr/local/chkrootkit/ -q >> $RESULTS

if [ $? -eq 0 ]; then
	echo "Chkroot kit ran sucsessfully!" && echo "Chkroot kit ran sucsessfully!" >> $OUTPUT
	return 0
else
	echo "There was a problem running chkrootkit." && echo "There was a problem running chkrootkit." >> $OUTPUT
	return 1
fi
}

function rkhunter {
###
# rkhunter - KA
# We need to make a list of false positives for cPanel & non-cPanel - MR
cd /root
echo "Downloading and installing rkhunter..." && echo "Downloading and installing rkhunter..." >> $OUTPUT
wget -q -nc apf.sagonet.net/rkhunter-1.3.0.tar.gz  || 
(echo "Error getting rkhunter ..Exiting" && echo "Error getting rkhunter ..Exiting" >> $OUTPUT ; exit 1)
tar -xzf rkhunter-1.3.0.tar.gz
cd rkhunter-1.3.0
./installer.sh  --layout default --install
if [ $? -eq 0 ]; then
        echo "rkhunter installed sucsessfully!" && echo "rkhunter installed sucsessfully!" >> $OUTPUT
else
        echo "There was a problem running rkhunter."&& echo "There was a problem running rkhunter." >> $OUTPUT
fi
/usr/local/bin/rkhunter --versioncheck
/usr/local/bin/rkhunter --update
echo -n  "Building initial hash file..." 
/usr/local/bin/rkhunter --propupd && echo "Done." && echo "Building initial hash file...Done." >> $OUTPUT
/usr/local/bin/rkhunter --cronjob --report-warnings-only --pkgmgr RPM >> $RESULTS
return $?
}

function yumupdate {
###
# Removing/Disabling Unused Packages - MR
echo "Removed/Disabled Unused Packages.."
yum remove desktop-file-utils -y
chkconfig gpm off
chkconfig netfs off
yum remove at -y
chkconfig cpuspeed off
}

function sshsecure {
###
# SSH Securing - See: http://www.puschitz.com/SecuringLinux.shtml - MR
sed -e 's|#Port|Port|g' \
 -e 's|#Protocol 2,1|Protocol 2|g' \
 -e 's|#PermitRootLogin no|PermitRootLogin no|g' \
 -e 's|#UsePrivilegeSeparation|UsePrivilegeSeparation|g' \
 -e 's|#AllowTcpForwarding yes|AllowTcpForwarding no|g' \
 -e 's|X11Forwarding yes|X11Forwarding no|g' \
 -e 's|#StrictModes|StrictModes|g' \
 -e 's|#IgnoreRhosts|IgnoreRhosts|g' \
 -e 's|#HostbasedAuthentication|HostbasedAuthentication|g' \
 -e 's|#RhostsRSAAuthentication|RhostsRSAAuthentication|g' \
 -e 's|Subsystem|#Subsystem|g' /etc/ssh/sshd_config > /etc/ssh/new_sshd_config && (echo "sshd secured.." && echo "sshd secured.." >> $OUTPUT) || (echo "sshd securing failed.." && echo "sshd securing failed..") >> $OUTPUT
SSHGOOD=$?

cp /etc/ssh/sshd_config /etc/ssh/sshd_config.original ; mv /etc/ssh/new_sshd_config /etc/ssh/sshd_config
/etc/init.d/sshd restart
return $SSHGOOD
}

function sysctl {
# Auto-Reboot on Kernel Panic - MR
# Commenting out until we can make it email the customer or us too - KA
#echo "Setting OS to reboot after 60 seconds on Kernel Panic" && echo "Setting OS to reboot after 60 seconds on Kernel Panic" >> $OUTPUT
#echo "kernel.panic = 60" >> /etc/sysctl.conf

#Enable Sysrq key - KA
echo "Turning on magic sysrq key" && echo "Turning on magic sysrq key" >> $OUTPUT
echo "kernel.sysrq = 1" >> /etc/sysctl.conf
}

function fixtime {
# Configure NTP server - MR
yum install ntp -y
echo "Setting up Hourly Time Fix" && echo "Setting up Hourly Time Fix" >> $OUTPUT
echo "/usr/sbin/ntpdate ntp.sagonet.net" > /etc/cron.hourly/fixTime
chmod +x /etc/cron.hourly/fixTime
/etc/cron.hourly/fixTime
return $?
}


##**************************************************************************************************
##**************************************************************************************************
##**************************************************************************************************
##**************************************************************************************************

##################################################
## I'm doubtful the following can be scripted - MR
# Apache & mySQL Hardening/Optimization
# Edit /etc/hosts.deny to include this entry as the first uncommented line in the file: ALL:ALL
# Ensure /etc/hosts.allow is edited appropriately to allow the administrator(s) to connect.
# LFD cPanel Firewall
# Tripwire installation
# mod_evasive installation
# Tmp Hardening
# Integrity checks of groups and permissions(remove unused groups/accounts)
##################################################


###
# mod_security installation
# This is IMPORTANT as to whether it is Apache2 or Apache 2..these steps are for Apache2!!!!
#rm -rdf mod_limitipconn-0.22
#wget http://www.modsecurity.org/download/modsecurity-apache_1.9.4.tar.gz
#tar zxvf modsecurity-apache*.gz
#rm -rdf modsecurity-apache*.gz
#cd modsecurity-apache_1.9.4/apache2
#apxs -cia mod_security.c
#mkdir /etc/modsecurity
#cd /etc/modsecurity
#cp /aux/buildWebServer/*.conf /etc/modsecurity
#rm -rdf /etc/modsecurity/httpd.conf

function phphardening {
###
# PHP Hardening - MR
if [ $CENTOSVERSION -eq 5 ]; then
cd /etc/yum.repos.d
wget http://dev.centos.org/centos/5/CentOS-Testing.repo
yum --enablerepo=c5-testing install php-suhosin
echo "suhosin.session.encrypt = Off" >> /etc/php.d/suhosin.ini
fi
if [ $CENTOSVERSION -eq 4 ]; then
cd /etc/yum.repos.d
wget http://dev.centos.org/centos/4/CentOS-Testing.repo
yum --enablerepo=c4-testing install php-suhosin
echo "suhosin.session.encrypt = Off" >> /etc/php.d/suhosin.ini
fi
}

function limitipconn {
###
# mod_limitipconn installation - MR
cd /root
wget http://dominia.org/djao/limit/mod_limitipconn-0.22.tar.gz
tar zxvf mod_limitipconn*.gz
rm -rdf mod_limitipconn*.gz
cd mod_limitipconn-0.22
make install
return $?
}

function apfinstall {
#APF
# Removes existing apf and installs a one. I do not have egress on because I think it will cause too 
# many trouble tickets in the future. KA
cd /root
rm -rf /etc/apf*
wget -q -nc apf.sagonet.net/apf-current.tar.gz || 
(echo "Error getting apf ..Exiting" && echo "Error getting apf .. Exiting" >> $OUTPUT ; exit 1)
tar xzf apf-current.tar.gz
cd apf-0.9.6-2/
./install.sh
if [ $CPANEL -eq 1 ]; then
	wget -q apf.sagonet.net/conf.apf.cpanel -O /etc/apf/conf.apf || 
	(echo "Error downloading apf conf" && echo "Error downloading apf conf" >> $OUTPUT ; exit 1)
	echo "Starting apf..." && echo "Starting apf..." >> $OUTPUT
	apf -s || (echo "Error starting apf ..Exiting" && echo "Error starting apf ..Exiting" >> $OUTPUT ; exit 1)
else
	echo "You will need to manually edit your conf.apf" && echo "You will need to manually edit your conf.apf" >> $OUTPUT
	echo "-Press Any Key to Continue-"
	read PRESSANYKEY
fi
}

function bfdinstall {
###
# Brute Force Detection
#Stock install except I turned alerts on - KA
cd /root
wget -q -nc apf.sagonet.net/bfd-current.tar.gz || 
(echo "Error getting bfd ..Exiting" && echo "Error getting bfd ..Exiting" >> $OUTPUT ; exit 1)
tar xzf bfd-current.tar.gz
cd bfd-0.9
./install.sh
(sed 's/ALERT_USR="0"/ALERT_USR="1"/' /usr/local/bfd/conf.bfd > /usr/local/bfd/conf.bfd.new && 
mv -f /usr/local/bfd/conf.bfd.new /usr/local/bfd/conf.bfd)
return $?
}


function siminstall {
###
# System Integrity Monitor
cd /root
wget -q -nc apf.sagonet.net/sim-current.tar.gz
tar -xzf sim-current.tar.gz
cd sim-2.5-4/
./setup -i
return $?
}


function rootloginemailer {
###
# Root Login Emailer - MR
echo "Enter Administrator's Email for Root Login Notification: "
read SYSADMINROOTLOGIN
echo "Administrator's Email for Root Login Notification: $SYSADMINROOTLOGIN" >> $OUTPUT

TEXT="echo 'WARNING - Root Login on:' \`date\` \`who\` | mail -s \"WARNING - Root Login: \`who | awk '{print \$6}'\`\" $SYSADMINROOTLOGIN" ; echo $TEXT > /root/.bash_profile && echo "Email on Root Login Notification Activated" || echo "Error Activating Root Login Notifications...does /root/.bash_profile exist?"
}

function psacctinstall {
###
# Install sysstat & psacct - MR
yum -y install sysstat psacct
echo "*/10 * * * * root /usr/lib/sa/sa1 -d 1 1" >> /etc/crontab
echo "53 23 * * * root /usr/lib/sa/sa2 -A" >> /etc/crontab
/etc/init.d/crond restart
sar -A 1 1 >> $RESULTS && sar -A 1 1
chkconfig psacct on
/etc/init.d/psacct start
echo "Displaying Logged in User Minutes" && echo "Displaying Logged in User Minutes" >> $RESULTS
(ac -p && ac -p >> $RESULTS) && (sa -m && sa -m >> $RESULTS)
echo "Sysstat & Psacct Installed" && echo "Sysstat & Psacct Installed" >> $OUTPUT
}

function motdinstall {
###
# Set up MOTD - MR
echo "#############################################################" > /etc/banner
echo "#            Sago Networks - Hardened Server                #" >> /etc/banner
echo "#                     -------------                         #" >> /etc/banner
echo "#                  4465 W. Gandy Blvd.                      #" >> /etc/banner
echo "#                      Suite 800                            #" >> /etc/banner
echo "#                   Tampa, Fl. 33611                        #" >> /etc/banner
echo "#                                                           #" >> /etc/banner
echo "#        Network Operations Center: 1-866-510-4000          #" >> /etc/banner
echo "#                   support@sagonet.com                     #" >> /etc/banner
echo "#                                                           #" >> /etc/banner
echo "# This system is being monitored and logged. Unauthorized   #" >> /etc/banner
echo "# access is strictly prohibited and will be prosecuted to   #" >> /etc/banner
echo "# the fullest extent of the law. If there are any questions #" >> /etc/banner
echo "# regarding this system, please call the Network Operations #" >> /etc/banner
echo "# Center at the number above.                               #" >> /etc/banner
echo "#                                                           #" >> /etc/banner
echo "#############################################################" >> /etc/banner
echo "Banner /etc/banner" >> /etc/ssh/sshd_config
}


function johntheripper {
###
# Check users' password strength with a tool such as John the Ripper - MR
cd /root
wget http://www.openwall.com/john/f/john-1.7.0.2.tar.gz
tar zxvf john-*.gz
cd john-*
echo "`uname -s`-`uname -i`-any" > NAME
sed 's|L|l|g' NAME > NAME.new || sed 's|F|f|g' NAME > NAME.new
echo -n "Name: " ; 
cd src ; make clean generic
return $?
}


function clamavinstall {
###
# Install clamAV and set up server-wide scanning - MR
# clamAV 0.91.1
cd /root
wget http://freshmeat.net/redir/clamav/29355/url_tgz/clamav-0.91.1.tar.gz
tar zxvf clamav-*.gz
cd clamav-*
adduser -s /sbin/nologin clamav
groupadd clamav
./configure  --disable-zlib-vcheck
make && make install
sed -e 's/Example/#Example/g' \
-e 's|#LogFile /tmp/clamd.log|LogFile /var/log/clamd.log|g' \
-e 's|#LogFileMaxSize|LogFileMaxSize|g' \
-e 's|#LogTime|LogTime|g' \
-e 's|#LogSyslog|LogSyslog|g' \
-e 's|#PidFile|PidFile|g' \
-e 's|#User|User|g' \
-e 's|#Foreground|Foreground|g' \
-e 's|#ScanPDF|ScanPDF|g' \
-e 's|#DatabaseDirectory|DatabaseDirectory|g' \
/usr/local/etc/clamd.conf > new
mv -f new /usr/local/etc/clamd.conf

sed -e 's|Example|#Example|g' \
-e 's|#DatabaseDirectory|DatabaseDirectory|g' \
-e 's|#LogSyslog|LogSyslog|g' /usr/local/etc/freshclam.conf > new

mv -f new /usr/local/etc/freshclam.conf
mkdir /var/lib/clamav ; chown clamav:clamav /var/lib/clamav
/usr/local/bin/freshclam >> $RESULTS
/usr/local/bin/clamscan -i -r / >> $RESULTS
return $?
}

function securephp {
perl -pi -e 's/fopen = On/fopen = Off/' /usr/lib/php.ini
}

function securetmp {
if [ "CPANEL" = "1" ]; then
/scripts/securetmp
fi
}

function binarylockdown {
#
# Lock down all download and compiling programs - MR
chmod 700 /usr/bin/wget
chmod 700 /usr/bin/telnet
chmod 700 /usr/local/bin/lynx
chmod 700 /usr/bin/links
chmod 700 /usr/bin/bcc
chmod 700 /usr/bin/byacc
chmod 700 /usr/bin/cc
chmod 700 /usr/bin/gcc
chmod 700 /usr/bin/i386-redhat-linux-gcc
chmod 700 /usr/bin/perlcc
chmod 700 /usr/bin/yacc
chmod 700 /usr/bin/curl
chmod 700 /usr/bin/lwp-*
chmod 700 /usr/bin/*ncftp*
}
 

# The Output file will be the output of all echo commands sent to the screen
OUTPUT=/root/hardenServer.output
# The results file will be the output of any command checks..this is the first stage of the report to be sent to the customer
RESULTS=/root/hardenServer.results

# What Version of CentOS is this? "4" or "5" ??
CENTOSVERSION=`cat /etc/redhat-release | cut -c16`

# Start by verifying I am root! - MR
WHO=`id | cut -f1 -d" "`
if [ ! "$WHO" = "uid=0(root)" ]
then
echo "You must be super-user to run this script..Exiting"
exit 1
fi
echo "Super-User access verified.."
echo "Super-User access verified.." > $OUTPUT

echo "" > /tmp/hardened.results
for EACH in cpanelcheck chkrootkit rkhunter yumupdate sshsecure sysctl fixtime limitipconn apfinstall bfdinstall siminstall rootloginemailer psacctinstall motdinstall clamavinstall binarylockdown securephp securetmp
do
$EACH 
if [ $? -eq 0 ]; then
echo -e "For Module $EACH: \t Success" >> /tmp/hardened.results
else
echo -e "For Module $EACH: \t Failed" >> /tmp/hardened.results
fi
done
cat /tmp/hardened.results >> /root/hardenServer.results

