Forked from cballou/linode-stackscript-centos-lemp-advanced
Created
September 27, 2016 22:08
-
-
Save Alambador/db5fbd3905b1e8f59f09083e0fdaa412 to your computer and use it in GitHub Desktop.
An advanced Linode StackScript for deploying a CentOs 64bit LEMP Stack with a ton of extras and configuration: MySQL, Suhosin, Memcached, Monit, Supervisord, Gearman, Beanstalk, Fail2Ban, IPTables Firewall, SSH
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# | |
# MYSQL CONFIG | |
# ============ | |
# <UDF name="db_password" Label="Choose a MySQL Root Password" /> | |
# <UDF name="db_name" Label="MySQL - Database Name" default="" example="Optionally create this database." /> | |
# <UDF name="db_user" Label="MySQL - Username" default="" example="Optionally create this user." /> | |
# <UDF name="db_user_password" Label="MySQL - Password" default="" example="The user password." /> | |
# | |
# OPTIONAL LIBRARIES TO INSTALL | |
# ============================= | |
# <UDF name="suhosin_enabled" label="Would you like to install Suhosin?" oneOf="yes,no" default="yes" example="Suhosin is an advanced protection system for PHP installations." /> | |
# <UDF name="memcached_enabled" label="Would you like to install memcached (pecl-memcache)?" oneOf="yes,no" default="no" example="APC is already enabled so the choice is yours. You can use memcached with gearman for persistent queues as opposed to libdrizzle." /> | |
# <UDF name="monit_enabled" label="Would you like to install monit?" oneOf="yes,no" default="yes" example="Monit can start a process if it does not run, restart a process if it does not respond and stop a process if it uses too much resources." /> | |
# <UDF name="supervisord_enabled" label="Would you like to install supervisord?" oneOf="yes,no" default="yes" example="is a client/server system that allows its users to monitor and control a number of processes (daemons) on UNIX-like operating systems." /> | |
# <UDF name="gearman_enabled" label="Would you like to install gearman?" oneOf="yes,no" default="yes" example="Gearman provides a generic application framework to farm out work to other machines or processes that are better suited to do the work." /> | |
# <UDF name="beanstalk_enabled" label="Would you like to install beanstalk?" oneOf="yes,no" default="yes" example="Beanstalk is a simple, fast work queue originally designed for reducing the latency of page views in high-volume web applications by running time-consuming tasks asynchronously." /> | |
# <UDF name="fail2ban_enabled" label="Would you like to install fail2ban?" oneOf="yes,no" default="yes" example="Fail2ban scans log files like /var/log/pwdfail or /var/log/apache/error_log and bans IP that makes too many password failures." /> | |
# | |
# LIBDRIZZLE MYSQL CONFIG | |
# ======================= | |
# <UDF name="drizzle_enabled" label="Would you like to install libdrizzle as gearman's persistent queue store?" oneOf="yes,no" default="yes" example="Skip this section if you aren't using gearman." /> | |
# <UDF name="drizzle_db_name" label="Name of your database (we suggest gearman)" default="gearman" /> | |
# <UDF name="drizzle_db_table" label="Name of your database table (we suggest gearman_queue)" default="gearman_queue" /> | |
# <UDF name="drizzle_db_user" label="Name of your database user (we suggest gearman)" default="gearman" /> | |
# <UDF name="drizzle_db_user_password" label="Password of your database user" default="" /> | |
# | |
# IPTABLES FIREWALL CONFIG | |
# ======================== | |
# <UDF name="allow" label="Allowed services" example="Punch holes in the firewall for these services. SSH is already open on port 22 (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 (SSH is already handled for you)" 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="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" /> | |
# | |
# SSH SECURITY CONFIG (via Donald von Stufft <[email protected]>) | |
# =================== | |
# <udf name="user_name" label="SSH User Name" /> | |
# <udf name="user_password" label="SSH User Password" /> | |
# <udf name="user_sshkey" label="Public Key for User" 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="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="No" /> | |
# <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 Sudo Accounts" default="wheel" /> | |
# <udf name="sudo_passwordless" label="Passwordless Sudo" oneof="Require Password,Do Not Require Password", default="Require Password" /> | |
########################################################### | |
# include the StackScript Bash Library for RH Derivatives # | |
########################################################### | |
source <ssinclude StackScriptID="154"> | |
#################### | |
# useful functions # | |
#################### | |
function mysql_create_table { | |
# $1 - the mysql root password | |
# $2 - the table create statement | |
if [ ! -n "$1" ]; then | |
echo "mysql_grant_user_table() requires the root pass as its first argument" | |
return 1; | |
fi | |
if [ ! -n "$2" ]; then | |
echo "mysql_grant_user_table() requires a creation statement as the argument" | |
fi | |
echo "$2" | mysql -u root -p"$1" | |
} | |
function mysql_grant_user_table { | |
# $1 - the mysql root password | |
# $2 - the username to grant table access | |
# $3 - the database | |
# $4 - the table | |
if [ ! -n "$1" ]; then | |
echo "mysql_grant_user_table() requires the root pass as its first argument" | |
return 1; | |
fi | |
if [ ! -n "$2" ]; then | |
echo "mysql_grant_user_table() requires username as the second argument" | |
return 1; | |
fi | |
if [ ! -n "$3" ]; then | |
echo "mysql_grant_user_table() requires a database as the third argument" | |
return 1; | |
fi | |
if [ ! -n "$4" ]; then | |
echo "mysql_grant_user_table() requires a table as the fourth argument" | |
fi | |
echo "GRANT ALL PRIVILEGES ON $3.$4 TO '$2'@'localhost';" | mysql -u root -p"$1" | |
echo "FLUSH PRIVILEGES;" | mysql -u root -p"$1" | |
} | |
function overwrite_sysctl_config { | |
cat <<- _EOF_ | |
# Controls IP packet forwarding | |
net.ipv4.ip_forward = 0 | |
# Do not accept source routing | |
net.ipv4.conf.default.accept_source_route = 0 | |
# Controls the System Request debugging functionality of the kernel | |
kernel.sysrq = 0 | |
# Controls whether core dumps will append the PID to the core filename | |
# Useful for debugging multi-threaded applications | |
kernel.core_uses_pid = 1 | |
# Controls the use of TCP syncookies | |
net.ipv4.tcp_syncookies = 1 | |
# Controls the maximum size of a message, in bytes | |
kernel.msgmnb = 65536 | |
# Controls the default maxmimum size of a message queue | |
kernel.msgmax = 65536 | |
# Controls the maximum shared segment size, in bytes | |
kernel.shmmax = 68719476736 | |
# Controls the maximum number of shared memory segments, in pages | |
kernel.shmall = 4294967296 | |
#################################### | |
# CUSTOM OPTIMIZATIONS STACKSCRIPT # | |
#################################### | |
# Disables IP source routing | |
net.ipv4.conf.all.accept_source_route = 0 | |
net.ipv4.conf.lo.accept_source_route = 0 | |
net.ipv4.conf.eth0.accept_source_route = 0 | |
# Enable IP spoofing protection, turn on source route verification | |
net.ipv4.conf.default.rp_filter = 1 | |
net.ipv4.conf.all.rp_filter = 1 | |
net.ipv4.conf.lo.rp_filter = 1 | |
net.ipv4.conf.eth0.rp_filter = 1 | |
# Disable ICMP Redirect Acceptance | |
net.ipv4.conf.all.accept_redirects = 0 | |
net.ipv4.conf.lo.accept_redirects = 0 | |
net.ipv4.conf.eth0.accept_redirects = 0 | |
net.ipv4.conf.default.accept_redirects = 0 | |
# Enable Log Spoofed Packets, Source Routed Packets, Redirect Packets | |
net.ipv4.conf.default.log_martians = 0 | |
net.ipv4.conf.all.log_martians = 0 | |
net.ipv4.conf.lo.log_martians = 0 | |
net.ipv4.conf.eth0.log_martians = 0 | |
# Decrease the time default value for tcp_fin_timeout connection | |
net.ipv4.tcp_fin_timeout = 15 | |
# Decrease the time default value for tcp_keepalive_time connection | |
net.ipv4.tcp_keepalive_time = 1800 | |
# Turn off the tcp_window_scaling | |
net.ipv4.tcp_window_scaling = 0 | |
# Turn off the tcp_sack | |
net.ipv4.tcp_sack = 0 | |
# Turn off the tcp_timestamps | |
net.ipv4.tcp_timestamps = 0 | |
# Enable ignoring broadcasts request | |
net.ipv4.icmp_echo_ignore_broadcasts = 1 | |
# Enable bad error message Protection | |
net.ipv4.icmp_ignore_bogus_error_responses = 1 | |
# Increases the size of the socket queue (effectively, q0). | |
net.ipv4.tcp_max_syn_backlog = 1024 | |
# Increase the tcp-time-wait buckets pool size | |
net.ipv4.tcp_max_tw_buckets = 1440000 | |
# Allowed local port range | |
net.ipv4.ip_local_port_range = 1024 65000 | |
# bump up the memory | |
net.core.rmem_default = 256960 | |
net.core.rmem_max = 256960 | |
net.core.wmem_default = 256960 | |
net.core.wmem_max = 256960 | |
# Linode Xen Virtualization specific | |
vm.swappiness = 25 | |
_EOF_ | |
} | |
function overwrite_gearman_sysconfig { | |
cat <<- _EOF_ | |
#OPTIONS="-q libdrizzle --libdrizzle-host=127.0.0.1 --libdrizzle-user=${DRIZZLE_DB_USER} --libdrizzle-password=${DRIZZLE_DB_PASSWORD} --libdrizzle-db=${DRIZZLE_DB_NAME} --libdrizzle-table=gearman_queue --libdrizzle-mysql" | |
_EOF_ | |
} | |
function lemp_install_drizzle_repo { | |
cat <<- _EOF_ | |
[drizzle] | |
name=drizzle | |
baseurl=http://5dollarwhitebox.org/repos/drizzle/dev/Redhat/5/$basearch/ | |
enabled=1 | |
gpgcheck=0 | |
[drizzle-src] | |
name=drizzle-src | |
baseurl=http://5dollarwhitebox.org/repos/drizzle/dev/Redhat/5/SRPMS | |
enabled=1 | |
gpgcheck=0 | |
_EOF_ | |
} | |
################################# | |
# system update # | |
################################# | |
function lemp_system_update { | |
echo "" >> /var/log/stackscript.log | |
echo "Ensuring YUM priorities are in check..." >> /var/log/stackscript.log | |
# enable yum priorities to avoid rpm conflicts | |
yum -y install yum-priorities | |
echo "Adding EPEL and IUS repos to yum..." >> /var/log/stackscript.log | |
# install latest EPEL and IUS repos | |
# http://rob.olmos.name/2010/08/centos-5-5-php-5-3-3-php-fpm-nginx-rpms/ | |
rpm -Uvh http://dl.iuscommunity.org/pub/ius/stable/Redhat/5/x86_64/epel-release-1-1.ius.el5.noarch.rpm | |
rpm -Uvh http://dl.iuscommunity.org/pub/ius/stable/Redhat/5/x86_64/ius-release-1.0-6.ius.el5.noarch.rpm | |
echo "Altering /etc/yum.repos.d/ius.repo params..." >> /var/log/stackscript.log | |
# need to force IUS repo to use CentOS 5.5 | |
# comment out the following mirrorlist | |
# mirrorlist=http://dmirr.iuscommunity.org/mirrorlist?repo=ius-el5&arch=$basearch | |
sed -i 's/mirrorlist=http:\/\/dmirr.iuscommunity.org\/mirrorlist?repo=ius-el5\&arch=\$basearch/#mirrorlist=http:\/\/dmirr.iuscommunity.org\/mirrorlist?repo=ius-el5\&arch=\$basearch/g' /etc/yum.repos.d/ius.repo | |
# add the following to the bottom of the file | |
# comment out the baseurl in favor of 5.5 | |
# baseurl=http://dl.iuscommunity.org/pub/ius/stable/Redhat/5.5/$basearch | |
sed -i 's/#baseurl=http:\/\/dl.iuscommunity.org\/pub\/ius\/stable\/Redhat\/5\/\$basearch/baseurl=http:\/\/dl.iuscommunity.org\/pub\/ius\/stable\/Redhat\/5.5\/\$basearch/g' /etc/yum.repos.d/ius.repo | |
# update the system | |
echo "Performing a system update..." >> /var/log/stackscript.log | |
yum -yq upgrade | |
} | |
################################# | |
# optimize a few basics # | |
################################# | |
function lemp_system_optimize { | |
echo "" >> /var/log/stackscript.log | |
echo "Optimizing max file descriptors and sysctl.conf..." >> /var/log/stackscript.log | |
# increase the max number of file descriptors | |
echo 512000 > /proc/sys/fs/file-max | |
# backup limits.conf for safety | |
cp /etc/security/limits.conf /etc/security/limits.conf.bak | |
# increase file descriptors per user_name (requires re-login or reboot to take effect) | |
echo -e "*\t\t-\tnofile\t\t8192" >> /etc/security/limits.conf | |
# backup sysctl.conf for safety | |
cp /etc/sysctl.conf /etc/sysctl.conf.bak | |
# tweak variables in sysctl.conf | |
overwrite_sysctl_config > /etc/sysctl.conf | |
# save the changes to sysctl.conf | |
sysctl -p | |
} | |
################################# | |
# install some useful packages # | |
################################# | |
function lemp_install_basics { | |
echo "" >> /var/log/stackscript.log | |
echo "Installing the following basic applications:" >> /var/log/stackscript.log | |
echo "yum-priorities wget jwhois rsync openssh-clients sudo subversion git gcc libjpeg-devel libpng-devel libmcrypt libmcrypt-devel pcre pcre-devel curl curl-devel" >> /var/log/stackscript.log | |
# install some popular shit, maybe not so much for you | |
yum install -y wget jwhois rsync openssh-clients sudo subversion git gcc libjpeg-devel libpng-devel libmcrypt libmcrypt-devel pcre pcre-devel curl curl-devel | |
# install optional shit | |
test "${MONIT_ENABLED}" == "yes" && (yum install -y monit) | |
test "${FAIL2BAN_ENABLED}" == "yes" && (yum install -y fail2ban) | |
test "${BEANSTALK_ENABLED}" == "yes" && (yum install -y beanstalkd) | |
test "${SUPERVISORD_ENABLED}" == "yes" && (yum install -y supervisord) | |
# make sure we set optional shit to restart later | |
test "${MONIT_ENABLED}" == "yes" && (touch /tmp/restart-monit) | |
test "${FAIL2BAN_ENABLED}" == "yes" && (touch /tmp/restart-fail2ban) | |
test "${BEANSTALK_ENABLED}" == "yes" && (touch /tmp/restart-beanstalkd) | |
test "${SUPERVISORD_ENABLED}" == "yes" && (touch /tmp/restart-supervisord) | |
} | |
############################################# | |
# optionally install gearman and libdrizzle # | |
############################################# | |
function lemp_install_gearman { | |
echo "" >> /var/log/stackscript.log | |
#echo "Adding webtatic repo for gearman..." >> /var/log/stackscript.log | |
#rpm -ivh http://repo.webtatic.com/yum/centos/5/`uname -i`/webtatic-release-5-1.noarch.rpm | |
rpm -ivh http://www.alunduil.com/svn/RHELL/trunk/libgearman-0.14-3.x86_64.rpm http://www.alunduil.com/svn/RHELL/trunk/libgearman-devel-0.14-3.x86_64.rpm http://www.alunduil.com/svn/RHELL/trunk/gearmand-0.14-3.x86_64.rpm | |
# install optional libdrizzle | |
test "${DRIZZLE_ENABLED}" == "yes" && (echo "Installing libdrizzle dependencies..." >> /var/log/stackscript.log) | |
test "${DRIZZLE_ENABLED}" == "yes" && (yum -y install autoconf automake bison-devel bison bzr cpp curl-devel e2fsprogs-devel.i386 e2fsprogs-devel.x86_64 gcc gcc-c++.x86_64 gcc.x86_64 glib2-devel glibc-devel.x86_64 glibc.x86_64 gperf intltool libevent-devel.x86_64 libstdc++.i386 libtool ncurses-devel.i386 make ncurses-devel.x86_64 ncurses.x86_64 pam-devel pcre-devel.x86_64 pcre.i386 pcre.x86_64 readline-devel.x86_64 readline.x86_64 zlib-devel.x86_64 boost-devel) | |
# handle drizzle server install | |
test "${DRIZZLE_ENABLED}" == "yes" && (echo "Installing libdrizzle for persistent queues with gearman..." >> /var/log/stackscript.log) | |
test "${DRIZZLE_ENABLED}" == "yes" && (echo "Installing drizzle server..." >> /var/log/stackscript.log) | |
test "${DRIZZLE_ENABLED}" == "yes" && (echo "Adding unofficial drizzle repo for gearman..." >> /var/log/stackscript.log) | |
test "${DRIZZLE_ENABLED}" == "yes" && (echo "More info at: http://wiki.drizzle.org/RPMInstallation#Official_Fedora.2FEPEL_Packages" >> /var/log/stackscript.log) | |
test "${DRIZZLE_ENABLED}" == "yes" && (lemp_install_drizzle_repo > /etc/yum.repos.d/drizzle.repo | |
test "${DRIZZLE_ENABLED}" == "yes" && (yum -y install drizzle7 drizzle7-client drizzle7-lib drizzle7-mysql-protocol) | |
# handle libdrizzle database | |
test "${DRIZZLE_ENABLED}" == "yes" && (echo "Setting up gearman libdrizzle database queue..." >> /var/log/stackscript.log) | |
test "${DRIZZLE_ENABLED}" == "yes" && (mysql_create_database "$DRIZZLE_DB_PASSWORD" "$DRIZZLE_DB_NAME") | |
test "${DRIZZLE_ENABLED}" == "yes" && (mysql_create_user "$DRIZZLE_DB_PASSWORD" "$DRIZZLE_DB_USER" "$DRIZZLE_DB_USER_PASSWORD") | |
test "${DRIZZLE_ENABLED}" == "yes" && (mysql_create_table "$DRIZZLE_DB_PASSWORD" "CREATE TABLE $DRIZZLE_DB_NAME.$DRIZZLE_DB_TABLE (unique_key VARCHAR(64) PRIMARY KEY, function_name VARCHAR(255), priority INT, data LONGBLOB);") | |
test "${DRIZZLE_ENABLED}" == "yes" && (mysql_grant_user_table "$DRIZZLE_DB_PASSWORD" "$DRIZZLE_DB_USER" "$DRIZZLE_DB_NAME" "$DRIZZLE_DB_TABLE") | |
echo "Installing gearman..." >> /var/log/stackscript.log | |
yum -y install gearmand libgearman libgearman-devel php-pecl-gearman --enablerepo=webtatic | |
touch /tmp/restart-gearmand | |
# fix the gearman config | |
test "${DRIZZLE_ENABLED}" == "yes" && (echo "Modifying the gearmand sysconfig to use libdrizzle..." >> /var/log/stackscript.log) | |
test "${DRIZZLE_ENABLED}" == "yes" && (overwrite_gearman_sysconfig > /etc/sysconfig/gearmand) | |
# ensure it restarts | |
test "${DRIZZLE_ENABLED}" == "yes" && (touch /tmp/restart-drizzled) | |
} | |
############################# | |
# install mysql and php 5.3 # | |
############################# | |
function lemp_install_lemp { | |
# first install latest mysql version | |
echo "Installing mysql 5.0.77..." >> /var/log/stackscript.log | |
yum install -y mysql mysql-server | |
touch /tmp/restart-mysqld | |
# install php with some added bonuses | |
echo "Installing php-fpm 5.3 (including APC, CLI, GD, mbstring, mcrypt, mysql, suhosin)" >> /var/log/stackscript.log | |
yum install -y php53-fpm php53-pecl-apc php53-cli php53-devel php53-xml php53-gd php53-mbstring php53-mcrypt php53-mysql | |
touch /tmp/restart-php-fpm | |
# optionally install suhosin | |
test "${SUHOSIN_ENABLED}" == "yes" && (echo Installing php53-suhosin) | |
test "${SUHOSIN_ENABLED}" == "yes" && (yum install -y php53-suhosin) | |
# optionally install memcached | |
test "${MEMCACHED_ENABLED}" == "yes" && (echo Installing the REMI repository specifically for libmemcached...) | |
test "${MEMCACHED_ENABLED}" == "yes" && (rpm -ivh http://rpms.famillecollet.com/enterprise/remi-release-5.rpm) | |
test "${MEMCACHED_ENABLED}" == "yes" && (echo Installing libmemcached libmemcached-devel memcached php53-pecl-memcache) | |
test "${MEMCACHED_ENABLED}" == "yes" && (yum install -y libmemcached libmemcached-devel memcached php53-pecl-memcache --enablerepo=remi) | |
# install nginx | |
echo "Installing nginx 0.8.53..." >> /var/log/stackscript.log | |
yum install -y nginx | |
touch /tmp/restart-nginx | |
} | |
########################################## | |
# setup chkconfig to auto-start services # | |
########################################## | |
function lemp_setup_chkconfig { | |
echo "" >> /var/log/stackscript.log | |
echo "Ensuring all processes are set to auto-start on boot in chkconfig..." >> /var/log/stackscript.log | |
# ensure nginx starts up | |
chkconfig --level=345 nginx on | |
# ensure php-fpm starts up | |
chkconfig --level=345 php-fpm on | |
# ensure mysqld starts up | |
chkconfig --level=345 mysqld on | |
# ensure iptables starts up | |
chkconfig --level=345 iptables on | |
# ensure postfix starts up | |
chkconfig --level=345 postfix on | |
# ensure fail2ban is initialized | |
test "${FAIL2BAN_ENABLED}" == "yes" && (chkconfig --level=345 fail2ban on) | |
# ensure monit starts up | |
test "${MONIT_ENABLED}" == "yes" && (chkconfig --level=345 monit on) | |
# ensure supervisord starts up | |
test "${SUPERVISORD_ENABLED}" == "yes" && (chkconfig --level=345 supervisord on) | |
# ensure gearman starts up | |
test "${GEARMAN_ENABLED}" == "yes" && (chkconfig --level=345 gearmand on) | |
# ensure drizzle starts up | |
test "${GEARMAN_ENABLED}" == "yes" && test "${DRIZZLE_ENABLED}" == "yes" && (chkconfig --level=345 drizzled on) | |
# ensure beanstalk starts up | |
test "${BEANSTALK_ENABLED}" == "yes" && (chkconfig --level=345 beanstalkd on) | |
} | |
################################### | |
# IPTables security configuration # | |
################################### | |
function lemp_setup_firewall { | |
echo "" >> /var/log/stackscript.log | |
echo "Configuring iptables firewall..." >> /var/log/stackscript.log | |
IFUP=/etc/sysconfig/network-scripts/ifup-iptables.sh | |
IFDOWN=/etc/sysconfig/network-scripts/ifdown-iptables.sh | |
IPTABLES() { | |
echo iptables $@ >&1 2>&1 | |
iptables $@ | |
} | |
# Set up scripts to load/unload the rules at ifup/ifdown | |
echo "Generating iptables store/restore scripts..." >> /var/log/stackscript.log | |
for i in $IFUP $IFDOWN; do | |
echo $i | |
touch $i && chmod 744 $i | |
echo >$i "#!/bin/bash" | |
echo >>$i "# Generated by RHEL IPTables" | |
echo >>$i | |
done | |
echo >>$IFUP "iptables-restore < /etc/sysconfig/firewall.conf" | |
echo >>$IFDOWN "iptables-save > /etc/sysconfig/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." >> /var/log/stackscript.log | |
for i in INPUT OUTPUT; do IPTABLES -P $i ACCEPT && IPTABLES -F $i; done | |
IPTABLES -P FORWARD DROP && IPTABLES -F FORWARD | |
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 | |
done | |
# 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 RELATED,ESTABLISHED -j ACCEPT | |
IPTABLES -A INPUT -m state --state INVALID -j DROP1 | |
IPTABLES -A INPUT -i lo -j ACCEPT | |
IPTABLES -A INPUT -p tcp -j TCP | |
IPTABLES -A INPUT -p udp -j UDP | |
# ICMP | |
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: ") | |
# start a TCP chain if necessary | |
iptables -N TCP | |
# start a UDP chain if necessary | |
iptables -N UDP | |
# SSH is open by default | |
if [ -z "$SSHD_PORT" ]; then SSHD_PORT="22";fi | |
if [ -z "$SSHRANGE" ]; then SSHRANGE="0/0"; fi | |
echo Allowing: SSH from $SSHRANGE | |
IPTABLES -A TCP -p tcp --dport $SSHD_PORT -s $SSHRANGE -j ACCEPT | |
# optionally open up gearman | |
test "${GEARMAN_ENABLED}" == "yes" && (echo "Allowing: Gearman on port 4730 from 127.0.0.1") | |
test "${GEARMAN_ENABLED}" == "yes" && (IPTABLES -A TCP -p tcp --dport 4730 -s 127.0.0.1 -j ACCEPT) | |
# optionally open up libdrizzle | |
test "${GEARMAN_ENABLED}" == "yes" && test "${DRIZZLE_ENABLED}" == "yes" && (echo "Allowing: Drizzle on port 4427 from 127.0.0.1") | |
test "${GEARMAN_ENABLED}" == "yes" && test "${DRIZZLE_ENABLED}" == "yes" && (IPTABLES -A TCP -p tcp --dport 4427 -s 127.0.0.1 -j ACCEPT) | |
# optionally open up memcached | |
test "${MEMCACHED_ENABLED}" == "yes" && (echo "Allowing: Memcached on port 11211 from 127.0.0.1") | |
test "${MEMCACHED_ENABLED}" == "yes" && (IPTABLES -A TCP -p tcp --dport 11211 -s 127.0.0.1 -j ACCEPT) | |
# optionally open up beanstalk | |
test "${BEANSTALK_ENABLED}" == "yes" && (echo "Allowing: Beanstalk on port 11300 from 127.0.0.1") | |
test "${BEANSTALK_ENABLED}" == "yes" && (IPTABLES -A TCP -p tcp --dport 11300 -s 127.0.0.1 -j ACCEPT) | |
# Allowed services | |
IFS=$',' | |
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 | |
done | |
done | |
unset IFS | |
# Extras | |
for i in $EXTRAU; do | |
echo Allowing: UDP $i | |
IPTABLES -A UDP -p UDP --dport $i -j ACCEPT | |
done | |
for i in $EXTRAT; do | |
echo Allowing: TCP $i | |
IPTABLES -A TCP -p TCP --dport $i -j ACCEPT | |
done | |
# Lock 'n save | |
IPTABLES -P INPUT DROP | |
iptables-save > /etc/firewall.conf | |
echo "Completed firewall config..." >> /var/log/stackscript.log | |
} | |
################ | |
# SSH SECURITY # | |
################ | |
function lemp_setup_ssh { | |
echo "" >> /var/log/stackscript.log | |
echo "Beginning SSH security setup..." >> /var/log/stackscript.log | |
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 | |
} | |
###################################################### | |
# IMPORTANT - BELOW SECTION RUNS INSTALL IN SEQUENCE # | |
###################################################### | |
# starting of stackscript | |
touch /var/log/stackscript.log | |
echo "Starting StackScript processing..." >> /var/log/stackscript.log | |
# update the system | |
lemp_system_update | |
# optimize a few things | |
lemp_system_optimize | |
# install basic packages | |
lemp_install_basics | |
# install postfix | |
postfix_install_loopback_only | |
# set up the firewall | |
lemp_setup_firewall | |
# set up ssh | |
lemp_setup_ssh | |
# install php and nginx | |
lemp_install_lemp | |
# setup and install mysql | |
mysql_install "$DB_PASSWORD" && mysql_tune 40 | |
mysql_create_database "$DB_PASSWORD" "$DB_NAME" | |
mysql_create_user "$DB_PASSWORD" "$DB_USER" "$DB_USER_PASSWORD" | |
mysql_grant_user "$DB_PASSWORD" "$DB_USER" "$DB_NAME" | |
touch /tmp/restart-mysqld | |
# install gearmand | |
test "${GEARMAN_ENABLED}" == "yes" && lemp_install_gearman | |
# setup auto-start services | |
lemp_setup_chkconfig | |
# restart new services | |
restartServices |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Source: https://gist.github.com/cballou/1092473