LEMP stack + basic security + user security

by webandblog
444 deployments · 86 still active · last rev. 1 year ago

Installs LEMP + basic security + user security. No root acct. Use sudo -s to get root permissions. For PHP-FPM setup change nginx setting to access PHP via socket not port:

location ~ \.php$ {
if (!-f $request_filename) {
return 404;
fastcgi_pass unix:/var/run/php-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_intercept_errors on;
include /etc/nginx/fastcgi_params;

Compatible with: No distros currently supported
#yu di efs
# <UDF name="DB_PASSWORD"		Label="MySQL root Password" />
# <UDF name="LOGRO_FREQ"		Label="nginx: log rotation frequency" default="monthly" />
# <UDF name="LOGRO_ROTA"		Label="nginx: number of log rotations to keep" default="12" />
# Basic Security StackScript
# By Jed Smith <jed@linode.com>
# <UDF name="allow" label="Allowed services" example="Punch holes in the firewall for these services. SSH is already open (see Restrict SSH)." default="" manyOf="FTP Server: TCP 21,Telnet: TCP 23,SMTP: TCP 25,DNS Server: TCP/UDP 53,Web Server: TCP 80,POP3 Mail Service: TCP 110,NTP Service: UDP 123,IMAP Mail Service: TCP 143,SSL Web Server: TCP 443,Mail Submission: TCP 587,SSL IMAP Server: TCP 993,OpenVPN Server: UDP 1194,IRC Server: TCP 6667">
# <UDF name="extraT" label="Extra TCP holes" example="Extra holes in the firewall for TCP. Understands service names ('kerberos') and port numbers ('31337'), separate by spaces." default="">
# <UDF name="extraU" label="Extra UDP holes" example="Extra holes in the firewall for UDP. Understands service names ('daytime') and port numbers ('1094'), separate by spaces." default="">
# <UDF name="sshrange" label="Restrict SSH" example="Will restrict SSH access to the given CIDR range. Leave empty for no restrictions." default="0/0">
# <UDF name="icmplevel" label="ICMP paranoia level" example="Rules for ICMP. You should leave this at the default to be a good net citizen." oneOf="Well-behaved,Only allow pings,Ignore all ICMP" default="None">
# <UDF name="loglevel" label="Logging level" example="How much to log. This can generate a lot of output." oneOf="Nothing,Some stuff,Everything" default="Nothing">

# Security StackScript
# By Donald von Stufft <donald.stufft@gmail.com>
# <udf name="user_name" label="Unprivileged User Account" />
# <udf name="user_password" label="Unprivileged User Password" />
# <udf name="user_sshkey" label="Public Key for User" default="" />
# <udf name="sshd_port" label="SSH Port" default="22" />
# <udf name="sshd_protocol" label="SSH Protocol" oneOf="1,2,1 and 2" default="2" />
# <udf name="sshd_permitroot" label="SSH Permit Root Login" oneof="No,Yes" default="No" />
# <udf name="sshd_passwordauth" label="SSH Password Authentication" oneOf="No,Yes" default="Yes" />
# <udf name="sshd_group" label="SSH Allowed Groups" default="sshusers" example="List of groups seperated by spaces" />
# <udf name="sudo_usergroup" label="Usergroup to use for Admin Accounts" default="wheel" />
# <udf name="sudo_passwordless" label="Passwordless Sudo" oneof="Require Password,Do Not Require Password", default="Require Password" />

#using postfix and restartServices stuff from Linode's StackScript Bash Library

#scripts used
source <ssinclude StackScriptID="1">		#StackScript Bash Library
source <ssinclude StackScriptID="41">		#LEMP_lib
lemp_system_update_aptitude			#StackScriptID="41"
lemp_mysql_install		 		#StackScriptID="41"
postfix_install_loopback_only			#StackScriptID="1"
lemp_php-fpm					#StackScriptID="41"
lemp_nginx					#StackScriptID="41"
restartServices					#StackScriptID="1"

    echo iptables $@ >&1 2>&1
    iptables $@

# Make sure we have iptables, and do this business while we're at it
echo Updating system and installing iptables.
aptitude -y install iptables

echo ===========================================================================
echo Configuring iptables firewall.

# Set up scripts to load/unload the rules at ifup/ifdown
echo Generating store/restore scripts.
for i in $IFUP $IFDOWN; do
    echo $i
    touch $i && chmod 744 $i
    echo >$i "#!/bin/bash"
    echo >>$i "# Generated by iptables StackScript"
    echo >>$i
echo >>$IFUP "iptables-restore < /etc/firewall.conf"
echo >>$IFDOWN "iptables-save > /etc/firewall.conf"

# Fix sysctl so this will not log to console
# The distro-default kernel printk is commented out, so we cheat and add
echo Changing kernel.printk in the kernel.
echo "3 1 1 1" > /proc/sys/kernel/printk
echo Modifying /etc/sysctl.conf.
echo >>/etc/sysctl.conf
echo "# Added by iptables StackScript, to not log iptables information to console" >>/etc/sysctl.conf
echo 'kernel.printk = "3 1 1 1"' >>/etc/sysctl.conf

# Build iptables
echo Building iptables rules.
for i in INPUT OUTPUT; do IPTABLES -P $i ACCEPT && IPTABLES -F $i; done
for i in DROP1 DROP2 TCP UDP; do
    IPTABLES -F $i >/dev/null 2>/dev/null
    IPTABLES -X $i >/dev/null 2>/dev/null
    IPTABLES -N $i

# Dropper rules based on selected loglevel
# Drop1 is logged if loglevel >= Some Stuff, Drop2 if loglevel = Everything
test "${LOGLEVEL}" == "Everything" && (for i in DROP1 DROP2; do IPTABLES -A $i -j LOG --log-level notice --log-prefix "iptables: "; done)
test "${LOGLEVEL}" == "Some stuff" && (IPTABLES -A DROP1 -j LOG --log-level notice --log-prefix "iptables: ")
for i in DROP1 DROP2; do IPTABLES -A $i -j DROP; done

# Preamble
IPTABLES -A INPUT -m state --state INVALID -j DROP1

echo Configuring ICMP behavior.
test "${ICMPLEVEL}" == "Well-behaved" && (IPTABLES -A INPUT -p icmp -j ACCEPT)
test "${ICMPLEVEL}" == "Only allow pings" && (IPTABLES -A INPUT -p icmp --icmp-type echo-request -j ACCEPT)

# Bottom of the input chain -- log?
test "${LOGLEVEL}" == "Everything" && (IPTABLES -A INPUT -j LOG --log-level notice --log-prefix "iptables: ")

# SSH is open by default
if [ -z "$SSHRANGE" ]; then SSHRANGE="0/0"; fi
echo Allowing: SSH from $SSHRANGE
IPTABLES -A TCP -p tcp --dport ssh -s $SSHRANGE -j ACCEPT

# Allowed services
for service in $ALLOW; do
    echo Allowing: $service
    interested=${service#*: }
    IFS=$' '
    set -- $interested
    for i in TCP UDP; do
        if [[ "$1" == *$i* ]]; then IPTABLES -A $i -p $i --dport $2 -j ACCEPT; fi
unset IFS

# Extras
for i in $EXTRAU; do
    echo Allowing: UDP $i
    IPTABLES -A UDP -p UDP --dport $i -j ACCEPT
for i in $EXTRAT; do
    echo Allowing: TCP $i
    IPTABLES -A TCP -p TCP --dport $i -j ACCEPT

# Lock 'n save
echo Completing.
iptables-save > /etc/firewall.conf

echo Done.
source <ssinclude StackScriptID="1">

# Update the System

# Install and Configure Sudo
aptitude -y install sudo

cp /etc/sudoers /etc/sudoers.tmp
chmod 0640 /etc/sudoers.tmp
test "${SUDO_PASSWORDLESS}" == "Do Not Require Password" && (echo "%`echo ${SUDO_USERGROUP} | tr '[:upper:]' '[:lower:]'` ALL = NOPASSWD: ALL" >> /etc/sudoers.tmp)
test "${SUDO_PASSWORDLESS}" == "Require Password" && (echo "%`echo ${SUDO_USERGROUP} | tr '[:upper:]' '[:lower:]'` ALL = (ALL) ALL" >> /etc/sudoers.tmp)
chmod 0440 /etc/sudoers.tmp
mv /etc/sudoers.tmp /etc/sudoers

# Configure SSHD
echo "Port ${SSHD_PORT}" > /etc/ssh/sshd_config.tmp
echo "Protocol ${SSHD_PROTOCOL}" >> /etc/ssh/sshd_config.tmp

sed -n 's/\(HostKey .*\)/\1/p' < /etc/ssh/sshd_config >> /etc/ssh/sshd_config.tmp

sed -n 's/\(UsePrivilegeSeparation .*\)/\1/p' < /etc/ssh/sshd_config >> /etc/ssh/sshd_config.tmp

sed -n 's/\(KeyRegenerationInterval .*\)/\1/p' < /etc/ssh/sshd_config >> /etc/ssh/sshd_config.tmp
sed -n 's/\(ServerKeyBits .*\)/\1/p' < /etc/ssh/sshd_config >> /etc/ssh/sshd_config.tmp

sed -n 's/\(SyslogFacility .*\)/\1/p' < /etc/ssh/sshd_config >> /etc/ssh/sshd_config.tmp
sed -n 's/\(LogLevel .*\)/\1/p' < /etc/ssh/sshd_config >> /etc/ssh/sshd_config.tmp

sed -n 's/\(LoginGraceTime .*\)/\1/p' < /etc/ssh/sshd_config >> /etc/ssh/sshd_config.tmp
echo "PermitRootLogin `echo ${SSHD_PERMITROOT} | tr '[:upper:]' '[:lower:]'`" >> /etc/ssh/sshd_config.tmp
sed -n 's/\(StrictModes .*\)/\1/p' < /etc/ssh/sshd_config >> /etc/ssh/sshd_config.tmp

sed -n 's/\(RSAAuthentication .*\)/\1/p' < /etc/ssh/sshd_config >> /etc/ssh/sshd_config.tmp
sed -n 's/\(PubkeyAuthentication .*\)/\1/p' < /etc/ssh/sshd_config >> /etc/ssh/sshd_config.tmp

sed -n 's/\(IgnoreRhosts .*\)/\1/p' < /etc/ssh/sshd_config >> /etc/ssh/sshd_config.tmp
sed -n 's/\(RhostsRSAAuthentication .*\)/\1/p' < /etc/ssh/sshd_config >> /etc/ssh/sshd_config.tmp
sed -n 's/\(HostbasedAuthentication .*\)/\1/p' < /etc/ssh/sshd_config >> /etc/ssh/sshd_config.tmp

sed -n 's/\(PermitEmptyPasswords .*\)/\1/p' < /etc/ssh/sshd_config >> /etc/ssh/sshd_config.tmp

sed -n 's/\(ChallengeResponseAuthentication .*\)/\1/p' < /etc/ssh/sshd_config >> /etc/ssh/sshd_config.tmp

echo "PasswordAuthentication `echo ${SSHD_PASSWORDAUTH} | tr '[:upper:]' '[:lower:]'`" >> /etc/ssh/sshd_config.tmp

sed -n 's/\(X11Forwarding .*\)/\1/p' < /etc/ssh/sshd_config >> /etc/ssh/sshd_config.tmp
sed -n 's/\(X11DisplayOffset .*\)/\1/p' < /etc/ssh/sshd_config >> /etc/ssh/sshd_config.tmp
sed -n 's/\(PrintMotd .*\)/\1/p' < /etc/ssh/sshd_config >> /etc/ssh/sshd_config.tmp
sed -n 's/\(PrintLastLog .*\)/\1/p' < /etc/ssh/sshd_config >> /etc/ssh/sshd_config.tmp
sed -n 's/\(TCPKeepAlive .*\)/\1/p' < /etc/ssh/sshd_config >> /etc/ssh/sshd_config.tmp

sed -n 's/\(MaxStartups .*\)/\1/p' < /etc/ssh/sshd_config >> /etc/ssh/sshd_config.tmp

sed -n 's/\(AcceptEnv .*\)/\1/p' < /etc/ssh/sshd_config >> /etc/ssh/sshd_config.tmp

sed -n 's/\(Subsystem .*\)/\1/p' < /etc/ssh/sshd_config >> /etc/ssh/sshd_config.tmp

sed -n 's/\(UsePAM .*\)/\1/p' < /etc/ssh/sshd_config >> /etc/ssh/sshd_config.tmp

echo "AllowGroups `echo ${SSHD_GROUP} | tr '[:upper:]' '[:lower:]'`" >> /etc/ssh/sshd_config.tmp

chmod 0600 /etc/ssh/sshd_config.tmp
mv /etc/ssh/sshd_config.tmp /etc/ssh/sshd_config
touch /tmp/restart-ssh

# Create Groups
groupadd ${SSHD_GROUP}
groupadd ${SUDO_USERGROUP}

# Create User & Add SSH Key
USER_NAME_LOWER=`echo ${USER_NAME} | tr '[:upper:]' '[:lower:]'`

useradd -m -s /bin/bash -G ${SSHD_GROUP},${SUDO_USERGROUP} ${USER_NAME_LOWER}
echo "${USER_NAME_LOWER}:${USER_PASSWORD}" | chpasswd

USER_HOME=`sed -n "s/${USER_NAME_LOWER}:x:[0-9]*:[0-9]*:[^:]*:\(.*\):.*/\1/p" < /etc/passwd`

sudo -u ${USER_NAME_LOWER} mkdir ${USER_HOME}/.ssh
echo "${USER_SSHKEY}" >> $USER_HOME/.ssh/authorized_keys
chmod 0600 $USER_HOME/.ssh/authorized_keys
chown ${USER_NAME_LOWER}:${USER_NAME_LOWER} $USER_HOME/.ssh/authorized_keys

# Setup Hostname
get_rdns_primary_ip > /etc/hostname
/etc/init.d/hostname.sh start

echo y|apt-get install fail2ban
echo y|apt-get install php5-gd
echo y|apt-get install htop
echo y|apt-get install zip	
# add eAccelerator to make php fly 
echo y| apt-get install php5-dev
aptitude -y install build-essential
cd /usr/src
wget http://downloads.sourceforge.net/project/eaccelerator/eaccelerator/eAccelerator%
unzip eaccelerator-
cd eaccelerator-
make install
mkdir /tmp/eaccelerator
chown -R ${USER_NAME_LOWER}:${USER_NAME_LOWER} /tmp/eaccelerator/
echo 'extension="eaccelerator.so"' >> /etc/php5/fpm/php.ini
echo 'eaccelerator.shm_size="16"' >> /etc/php5/fpm/php.ini
echo 'eaccelerator.cache_dir="/tmp/eaccelerator"' >> /etc/php5/fpm/php.ini
echo 'eaccelerator.enable="1"' >> /etc/php5/fpm/php.ini
echo 'eaccelerator.optimizer="1"' >> /etc/php5/fpm/php.ini
echo 'eaccelerator.check_mtime="1"' >> /etc/php5/fpm/php.ini
echo 'eaccelerator.debug="0"' >> /etc/php5/fpm/php.ini
echo 'eaccelerator.filter=""' >> /etc/php5/fpm/php.ini
echo 'eaccelerator.shm_max="0"' >> /etc/php5/fpm/php.ini
echo 'eaccelerator.shm_ttl="0"' >> /etc/php5/fpm/php.ini
echo 'eaccelerator.shm_prune_period="0"' >> /etc/php5/fpm/php.ini
echo 'eaccelerator.shm_only="0"' >> /etc/php5/fpm/php.ini
echo 'eaccelerator.compress="1"' >> /etc/php5/fpm/php.ini
echo 'eaccelerator.compress_level="9"' >> /etc/php5/fpm/php.ini

# Restart Services