#!/bin/bash # Clear Screen tput clear # Hide Cursor tput civis trap 'tput cnorm' EXIT # Set some styles bold=$(tput bold) alert=$(tput setaf 1) info=$(tput setaf 3) normal=$(tput sgr0) red=$(tput setaf 1; tput bold) green=$(tput setaf 2; tput bold) script_dir="$( cd "$( dirname "$0" )" && pwd )" # Ensure this script is run as root if [ "$(id -u)" != "0" ]; then echo "#\tThis script must be run as root." 1>&2 exit 1 fi # Progress spinner function function _spinner() { # $1 start/stop # on start: $2 display message # on stop : $2 process exit status # $3 spinner function pid (supplied from stop_spinner) local on_success="SUCCESS" local on_fail="FAIL" case $1 in start) # Calculate the column where spinner and status msg will be displayed let column=$(tput cols)-${#2} # Display message and position the cursor in $column column printf "${2}" printf "%${column}s" # Start spinner i=1 sp='\|/-' delay=0.15 while : do printf "\b${sp:i++%${#sp}:1}" sleep $delay done ;; stop) if [[ -z ${3} ]]; then # Spinner isn't running exit 1 fi kill $3 > /dev/null 2>&1 # inform the user uppon success or failure if [[ $2 -eq 0 ]]; then printf "\b[${green}${on_success}${normal}]\n" sleep 1 else printf "\b[${red}${on_fail}${normal}]\n\n" eval printf %.0s- '{1..'"${COLUMNS:-$(tput cols)}"\}; echo error_title="${bold}Check Error Log${normal}" printf "%*s\n" $(((${#error_title}+$(tput cols))/2)) "$error_title" eval printf %.0s- '{1..'"${COLUMNS:-$(tput cols)}"\}; echo tail -2 install.log printf "\n" exit 1 fi ;; *) # Invalid argument exit 1 ;; esac } function start_spinner { # $1 : Msg to display _spinner "start" "${1}" & # Set global spinner pid _sp_pid=$! disown } function stop_spinner { # $1 : Command exit status _spinner "stop" $1 $_sp_pid unset _sp_pid } # Remove previous install log if [[ -f "install.log" ]]; then rm -f install.log fi start_spinner "${bold}Installing Dependencies${normal}" { # Install the CSF dependencies if [ -f /etc/redhat-release ]; then yum -y update && yum -y install sed openssl perl-Time-HiRes perl-libwww-perl perl-GDGraph perl-IO-Socket-SSL.noarch perl-Net-SSLeay perl-Net-LibIDN perl-IO-Socket-INET6 perl-Socket6 net-tools rsyslog else apt-get -y update && apt-get -y install apache2 sed openssl libio-socket-ssl-perl libcrypt-ssleay-perl libnet-libidn-perl libio-socket-inet6-perl libsocket6-perl fi } &> install.log stop_spinner $? start_spinner "${bold}Installing Latest Version of CSF${normal}" { # Make a temp dir to toss install files in mkdir -p /tmp/csf_install # Grab the latest version of CSF for FREE!!! ...let's decompress and install it too wget -q -O /tmp/csf_install/csf.tgz https://download.configserver.com/csf.tgz tar -xf /tmp/csf_install/csf.tgz -C /tmp/csf_install cd /tmp/csf_install/csf && sh install.sh } &> install.log stop_spinner $? start_spinner "${bold}Configuring CSF${normal}" { # Extra security stuffs because we don't like warning messages, view readme @ http://configserver.com/free/csf/readme.txt sed -i -e 's|RESTRICT_SYSLOG = "0"|RESTRICT_SYSLOG = "3"|g' /etc/csf/csf.conf # We'll just flip this switch off, we don't wanna test give us security now! sed -i -e 's|TESTING = "1"|TESTING = "0"|g' /etc/csf/csf.conf # Turn that UI on sed -i -e 's|UI = "0"|UI = "1"|g' /etc/csf/csf.conf } &> install.log stop_spinner $? # Do we want to harden access to the CSF UI based on IP? # printf "\n${alert}${bold}Attention:${normal} Highly recommended that you restrict IP access to the UI"; # printf "\n${info}${bold}Note:${normal} This restricts access based on client IP not server IP"; # printf "\n${info}${bold}Note:${normal} If you're behind a dynamic IP then you may want to decline\n"; tput sc; tput cnorm read -e -p "Do you wish to enable UI IP access restrictions? (y/n)" yn tput civis case $yn in [Yy]* ) # Just in case you want to switch the option from the installer sed -i -e 's|UI_ALLOW = "0"|UI_ALLOW = "1"|g' /etc/csf/csf.conf tput rc; tput el printf "UI IP Restriction: [ ${green}ON${normal} ]\n" # Giz me your IP address!... the one you're on now because it's the only one that will have access to the CSF UI # printf "\n${alert}${bold}Attention:${normal} This is the only IP allowed access to the CSF UI" # printf "\n${info}${bold}Note:${normal} You can add/remove IP's @ /etc/csf/ui/ui.allow\n" tput cnorm read -e -p "CSF UI Allowed Access IP: " -i "${SSH_CLIENT%% *}" csfIP tput civis echo ${csfIP} >> /etc/csf/ui/ui.allow ;; [Nn]* ) tput rc; tput el printf "UI IP Restriction: [ ${red}OFF${normal} ]\n" sed -i -e 's|UI_ALLOW = "1"|UI_ALLOW = "0"|g' /etc/csf/csf.conf ;; esac # Giz me your UI username! # Also this cannot be "username" or CSF will complain # printf "\n${info}${bold}Note:${normal} You can edit this username @ /etc/csf/csf.conf\n" tput cnorm read -e -p "CSF UI Login Username: " csfUser tput civis sed -i -e '/UI_USER/s/"\([^"]*\)"/"'${csfUser}'"/' /etc/csf/csf.conf # Giz me your UI password! # You'll want this one strong although CSF has built in brute force detection (4 attempts) # Also this cannot be "password" or CSF will complain # printf "\n${info}${bold}Note:${normal} You can edit this password @ /etc/csf/csf.conf\n" while true do tput sc; tput cnorm read -es -p "Password: " password tput rc; tput el read -es -p "Password (again): " csfPass tput rc; tput el; tput civis [ "$password" = "$csfPass" ] && break printf "Passwords do not match, try again" sleep 1 tput rc; tput el done # read -e -p "CSF UI Login Password: " csfPass sed -i -e '/UI_PASS/s/"\([^"]*\)"/"'${csfPass}'"/' /etc/csf/csf.conf tput rc; tput el printf "CSF UI Password: [ ${green}OK${normal} ]\n" # Wanna get some emails from CSF? # printf "\n${info}${bold}Note:${normal} Leave this blank to disable firewall activity alerts" # printf "\n${info}${bold}Note:${normal} You can edit this email @ /etc/csf/csf.conf\n" tput cnorm read -e -p "CSF Alert Email: " csfEmail tput civis sed -i -e '/LF_ALERT_TO/s/"\([^"]*\)"/"'${csfEmail}'"/' /etc/csf/csf.conf # Let's setup a port to push the UI through # printf "\n${info}${bold}Note:${normal} Should be >1023 and an unused port" # printf "\n${info}${bold}Note:${normal} You can edit this port @ /etc/csf/csf.conf\n" tput cnorm read -e -p "CSF UI Port: " csfPort tput civis sed -i -e '/UI_PORT/s/"\([^"]*\)"/"'${csfPort}'"/' /etc/csf/csf.conf sed -i -e 's|TCP_IN = "20,21,22,25,53,80,110,143,443,465,587,993,995"|TCP_IN = "20,21,22,25,53,80,110,143,443,465,587,993,995,'${csfPort}'"|g' /etc/csf/csf.conf start_spinner "${bold}Removing Installation Files & APF+BFD${normal}" { # Just in case you were using APF+BFD we'll try to remove it if it exists sh /etc/csf/remove_apf_bfd.sh # Remove the temp install dir rm -rf /tmp/csf_install } &> install.log stop_spinner $? # Install SSL if you say we need to (we need it for UI access) # printf "\n${alert}${bold}Attention:${normal} SSL is ${bold}required${normal} for connecting to the CSF UI\n"; tput sc; tput cnorm read -e -p "Do you need SSL installed and configured (required for UI)? (y/n)" yn case $yn in [Yy]* ) tput rc; tput el read -e -p "FQDN: " domain tput rc; tput el read -e -p "Email: " email tput rc; tput el read -e -p "SSL 2-Digit Country Code: " country tput rc; tput el read -e -p "SSL State: " state tput rc; tput el read -e -p "SSL City: " city tput rc; tput el read -e -p "SSL Organization: " organization tput rc; tput el; tput civis start_spinner "${bold}Installing OpenSSL & Configuring${normal}" { # echo "Installing and configuring SSL for CSF UI access..." if [ -f /etc/redhat-release ]; then yum -y install mod_ssl cd /etc/csf/ui openssl req -new -newkey rsa:4096 -days 3650 -nodes -x509 -subj "/C=${country}/ST=${state}/L=${city}/O=${organization}/CN=${domain}" -keyout server.key -out server.crt chmod 400 server.* cp server.key /etc/pki/tls/certs/server.key cp server.crt /etc/pki/tls/certs/server.crt sed -i -e 's|SSLCertificateFile /etc/pki/tls/certs/localhost.crt|SSLCertificateFile /etc/pki/tls/certs/server.crt|g' /etc/httpd/conf.d/ssl.conf sed -i -e 's|SSLCertificateKeyFile /etc/pki/tls/private/localhost.key|SSLCertificateKeyFile /etc/pki/tls/certs/server.key|g' /etc/httpd/conf.d/ssl.conf else cd /etc/csf/ui openssl req -new -newkey rsa:4096 -days 3650 -nodes -x509 -subj "/C=${country}/ST=${state}/L=${city}/O=${organization}/CN=${domain}" -keyout server.key -out server.crt chmod 400 server.* mkdir /etc/apache2/ssl/ a2enmod ssl cp server.key /etc/apache2/ssl/server.key cp server.crt /etc/apache2/ssl/server.crt ln -s /etc/apache2/mods-available/ssl.load /etc/apache2/mods-enabled/ssl.load ln -s /etc/apache2/mods-available/ssl.conf /etc/apache2/mods-enabled/ssl.conf # printf "\n${info}${bold}Note:${normal} You can edit this file @ /etc/apache2/sites-available/domain.com.conf\n" # read -e -p "Your FQDN: " -i "your-domain.com" domain # read -e -p "Your Email: " -i "you@your-domain.com" email echo " ServerName ${domain} ServerAlias *.${domain} ServerAdmin ${email} DocumentRoot "/var/www/html" ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined SSLEngine on SSLProtocol SSLv3 SSLCertificateFile /etc/apache2/ssl/server.crt SSLCertificateKeyFile /etc/apache2/ssl/server.key " >> /etc/apache2/sites-available/${domain}.conf cd fi } &> install.log stop_spinner $? ;; [Nn]* ) # printf "\n${alert}${bold}Attention:${normal} Make sure you copy your key and cert files to /etc/csf/ui\n"; tput rc; tput el; tput civis printf "SSL Installation: [ ${red}NO ]\n" ;; esac start_spinner "${bold}Starting CSF+LFD${normal}" { # Restart firewall and Apache if [ -f /etc/redhat-release ]; then service httpd stop && service httpd start && csf -r && lfd -r else service apache2 stop && service apache2 start && csf -r && lfd -r fi } &> install.log stop_spinner $? printf "\n" # Let's run a quick test make sure we don't have any fatal errors perl /usr/local/csf/bin/csftest.pl # Restor cursor tput cnorm