Skip to content

Instantly share code, notes, and snippets.

@bossjones
Forked from el2ro/setup.sh
Created July 10, 2014 15:37
Show Gist options
  • Save bossjones/34c8ee41b9859cfcbadf to your computer and use it in GitHub Desktop.
Save bossjones/34c8ee41b9859cfcbadf to your computer and use it in GitHub Desktop.
#!/bin/bash
######
#LICENCE#
######
#Released under the BSD license http://www.opensource.org/licenses/bsd-license
#Copyright (c) 2011, Rowan Wookey <admin@rwky.net>
#All rights reserved.
#
#Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
#
#1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
#2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
#3. Neither the name of the <ORGANIZATION> nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
#THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# Modified to be used as standalone for DigitalOcean host, Sami Törölä
#INSTALL_MYSQL #label="Instal MySQL?" oneOf="Yes,No">
#MYSQL_PASSWORD #label="MySQL root password" default="">
#NGINX_VERSION #label="Install nginx from PPA" oneOf="Yes,No" example="See https://launchpad.net/~nginx/+archive/stable">
#SSH_PORT=22 #label="SSH port" default="22">
#USER_NAME #label="Unprivileged User Account" />
#USER_PASSWORD #label="Unprivileged User Password" />
#USER_SSHKEY #label="Public Key for User" default="" />
#SSH_ALLOW_USERS #label="SSH Allow Users directive, leave blank if you don't know what this is" default="" />
#ROOT_EMAIL #label="Email alias for root" />
#HOSTNAME #label="Hostname" default="" />
#INSTALL_PHP #label="Install PHP?" oneOf="Yes,No" />
set -e
read -n1 -p "Instal MySQL? (y/n) "
[[ $REPLY = [yY] ]] && INSTALL_MYSQL="Yes" || INSTALL_MYSQL="No"
echo
read -s -p "MySQL root password:" MYSQL_PASSWORD
[[ $REPLY = "" ]] && { echo "Passwd is needed."; exit 1; }
echo
read -s -p "MySQL root password 2nd time:" MYSQL_PASSWORD2
[[ $MYSQL_PASSWORD != $MYSQL_PASSWORD2 ]] && { echo "Passwd missmatch."; exit 1; }
echo
read -n1 -p "Install nginx from PPA? (y/n) "
[[ $REPLY = [yY] ]] && NGINX_VERSION="Yes" || NGINX_VERSION="No"
echo
read -n1 -p "Install PHP? (y/n)"
[[ $REPLY = [yY] ]] && INSTALL_PHP="Yes" || INSTALL_PHP="No"
echo
read -n1 -p "Install PHP 5.4 from PPA ondrej/php5-oldstable? (y/n) "
[[ $REPLY = [yY] ]] && PHP_VERSION="Yes" || PHP_VERSION="No"
echo
read -n1 -p "Install Webmin to port 10000 behind firewall? (y/n) "
[[ $REPLY = [yY] ]] && WEBMIN="Yes" || WEBMIN="No"
echo
read -n1 -p "Install Munin ? (y/n) "
[[ $REPLY = [yY] ]] && MUNIN="Yes" || MUNIN="No"
echo
if [ $MUNIN == "Yes" ]
then
read -n1 -p "Install Munin 2.0 from PPA ppa:tuxpoldo/munin? (y/n) "
[[ $REPLY = [yY] ]] && MUNIN_VERSION="Yes" || MUNIN_VERSION="No"
echo
read -n1 -p "Install Munin-client only? (y/n) "
[[ $REPLY = [yY] ]] && MUNIN_CLIENT_ONLY="Yes" || MUNIN_CLIENT_ONLY="No"
echo
if [ $MUNIN_CLIENT_ONLY == "Yes" ]
then
read -p "Public SSH Key for Munin server:" MUNIN_SSHKEY
fi
fi
read -p "SSH port (22):"
[[ $REPLY != "" ]] && SSH_PORT=$REPLY || SSH_PORT=22
read -p "Unprivileged User Account:" USER_NAME
[[ $USER_NAME = "" ]] && { echo "Username needed."; exit 1; }
read -s -p "Unprivileged User Password:" USER_PASSWORD
[[ $USER_PASSWORD = "" ]] && { echo "Passwd needed."; exit 1; }
echo
read -s -p "Unprivileged User Password 2nd:" USER_PASSWORD2
[[ $USER_PASSWORD != $USER_PASSWORD2 ]] && { echo "Passwd missmatch."; exit 1; }
echo
read -p "Public SSH Key for User:" USER_SSHKEY
read -p "SSH Allow Users directive leave blank if you don't know what this is:" SSH_ALLOW_USERS
read -p "Email alias for root:" ROOT_EMAIL
read -p "Hostname:" HOSTNAME
echo
echo "INSTALL_MYSQL=$INSTALL_MYSQL"
echo "MYSQL_PASSWORD=$MYSQL_PASSWORD"
echo "NGINX_VERSION=$NGINX_VERSION"
echo "PHP_VERSION=$PHP_VERSION"
echo "MUNIN=$MUNIN"
if [ $MUNIN == "Yes" ]
then
echo "MUNIN_VERSION=$MUNIN_VERSION"
echo "MUNIN_CLIENT_ONLY=$MUNIN_CLIENT_ONLY"
fi
echo "SSH_PORT=$SSH_PORT"
echo "USER_NAME=$USER_NAME"
echo "USER_PASSWORD=$USER_PASSWORD"
echo "USER_SSHKEY=$USER_SSHKEY"
echo "SSH_ALLOW_USERS=$SSH_ALLOW_USERS"
echo "ROOT_EMAIL=$ROOT_EMAIL"
echo "HOSTNAME=$HOSTNAME"
echo "INSTALL_PHP=$INSTALL_PHP"
echo
read -n1 -p "Everything OK? (y/n)"
[[ $REPLY = [yY] ]] && ok="yes" || { echo "Exit."; exit 1; }
echo
source workers.sh
#update system and set hostname
prep_system
echo "prep_system, done"
#setup firewall
install_shorewall
echo "install_shorewall, done"
#setup standard user
configure_user
echo "configure_user, done"
#secure ssh
configure_ssh
echo "configure_ssh, done"
#setup postfix
install_postfix
echo "install_postfix, done"
if [ "$INSTALL_MYSQL" == "Yes" ]
then
#setup mysql
install_mysql
echo "install_mysql, done"
fi
if [ "$INSTALL_PHP" == "Yes" ]
then
#setup php
install_php_fpm
echo "install_php_fpm, done"
fi
#setup nginx
install_nginx
echo "install_nginx, done"
install_phpmyadmin
echo "install phpmyadmin, done"
if [ $WEBMIN == "Yes" ]
then
install_webmin
echo "install_webmin, done"
fi
#install monit/munin/security tools/other tools
install_monit
echo "install_monit, done"
if [ $MUNIN == "Yes" ]
then
install_munin
echo "install_munin, done"
fi
install_security
echo "install_security, done"
install_tools
echo "install_tools, done"
#set root .profile
set_root_profile
echo "set_root_profile, done"
#delete users that aren't needed
deleteusers
echo "Delete users, done"
#cleanup
cleanup
echo "cleanup, done"
#send notification
notification_email
echo "notification_email, done"
#!/bin/bash
######
#LICENCE#
######
#Released under the BSD license http://www.opensource.org/licenses/bsd-license
#Copyright (c) 2011, Rowan Wookey <admin@rwky.net>
#All rights reserved.
#
#Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
#
#1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
#2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
#3. Neither the name of the <ORGANIZATION> nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
#THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#Some functions are taken from http://www.linode.com/stackscripts/view/?StackScriptID=1 the license below applies to those
# Copyright (c) 2010 Linode LLC / Christopher S. Aker <caker@linode.com>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright notice, this
# list of conditions and the following disclaimer in the documentation and/or
# other materials provided with the distribution.
#
# * Neither the name of Linode LLC nor the names of its contributors may be
# used to endorse or promote products derived from this software without specific prior
# written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
# SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
# TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
# BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
# DAMAGE.
# Modified to be used as standalone in DigitalOcean
function system_primary_ip {
# returns the primary IP assigned to eth0
echo $(ifconfig eth0 | awk -F: '/inet addr:/ {print $2}' | awk '{ print $1 }')
}
function get_rdns {
# calls host on an IP address and returns its reverse dns
if [ ! -e /usr/bin/host ]; then
aptitude -y install dnsutils > /dev/null
fi
echo $(host $1 | awk '/pointer/ {print $5}' | sed 's/\.$//')
}
function get_rdns_primary_ip {
# returns the reverse dns of the primary IP assigned to this system
echo $(get_rdns $(system_primary_ip))
}
function prep_system
{
#update system
#setup hostname
if [ -z "$HOSTNAME" ]
then
export HOSTNAME=$(get_rdns_primary_ip)
fi
HOST=$(echo $HOSTNAME | sed 's/\(\[a-z0-9\]\)*\..*/\1/')
echo "$HOST" > /etc/hostname
echo "`system_primary_ip` $HOSTNAME $HOST" >> /etc/hosts
start hostname
echo "/usr/sbin/nologin" >> /etc/shells
#set timezone to UTC
ln -s -f /usr/share/zoneinfo/UTC /etc/localtime
aptitude update
aptitude -y safe-upgrade
aptitude -y install python-software-properties
}
function install_nginx {
#add nginx ppa
if [ $NGINX_VERSION == "Yes" ]
then
add-apt-repository -y ppa:nginx/stable
aptitude update
fi
#Install nginx
aptitude -y install nginx
cat <<EOT > /etc/nginx/fastcgi_config
fastcgi_intercept_errors on;
fastcgi_ignore_client_abort on;
fastcgi_connect_timeout 60;
fastcgi_send_timeout 180;
fastcgi_read_timeout 180;
fastcgi_buffer_size 128k;
fastcgi_buffers 4 256k;
fastcgi_busy_buffers_size 256k;
fastcgi_temp_file_write_size 256k;
fastcgi_max_temp_file_size 0;
fastcgi_index index.php;
EOT
if [ $MUNIN == "Yes" ]
then
cat <<EOT > /etc/nginx/sites-available/nginx_status
server {
listen 127.0.0.1:80;
location /nginx_status {
stub_status on;
access_log off;
}
}
EOT
fi
cat <<EOT >/etc/nginx/conf.d/index
# Default index lookup order, suitable for PHP
index index.php index.html index.htm;
EOT
# Handy nginx configs
mkdir -p /etc/nginx/config
cat <<EOT >/etc/nginx/config/php.conf
fastcgi_split_path_info ^(.+\.php)(.*)$;
fastcgi_pass unix:/var/run/php5-fpm.sock;
include fastcgi_params;
include fastcgi_config;
EOT
cat <<EOT >/etc/nginx/config/drop.conf
location = /robots.txt { access_log off; log_not_found off; }
location = /favicon.ico { access_log off; log_not_found off; }
location ~ /\. { access_log off; log_not_found off; deny all; }
location ~ ~$ { access_log off; log_not_found off; deny all; }
EOT
cat <<EOT >/etc/nginx/config/auth_basic.conf
auth_basic "Access denied";
auth_basic_user_file htpasswd;
EOT
cat <<EOT >/etc/nginx/conf.d/compression.conf
# Compression
# Enable Gzip compressed.
gzip on;
# Enable compression both for HTTP/1.0 and HTTP/1.1 (required for CloudFront).
gzip_http_version 1.0;
# Compression level (1-9).
# 5 is a perfect compromise between size and cpu usage, offering about
# 75% reduction for most ascii files (almost identical to level 9).
gzip_comp_level 5;
# Don't compress anything that's already small and unlikely to shrink much
# if at all (the default is 20 bytes, which is bad as that usually leads to
# larger files after gzipping).
gzip_min_length 256;
# Compress data even for clients that are connecting to us via proxies,
# identified by the "Via" header (required for CloudFront).
gzip_proxied any;
# Tell proxies to cache both the gzipped and regular version of a resource
# whenever the client's Accept-Encoding capabilities header varies;
# Avoids the issue where a non-gzip capable client (which is extremely rare
# today) would display gibberish if their proxy gave them the gzipped version.
gzip_vary on;
# Compress all output labeled with one of the following MIME-types.
gzip_types
application/atom+xml
application/javascript
application/json
application/rss+xml
application/vnd.ms-fontobject
application/x-font-ttf
application/x-web-app-manifest+json
application/xhtml+xml
application/xml
font/opentype
image/svg+xml
image/x-icon
text/css
text/plain
text/x-component;
# text/html is always compressed by HttpGzipModule
# This should be turned on if you are going to have pre-compressed copies (.gz) of
# static files available. If not it should be left off as it will cause extra I/O
# for the check. It is best if you enable this in a location{} block for
# a specific directory, or on an individual server{} level.
# gzip_static on;
EOT
cat <<EOT >/etc/nginx/conf.d/ssl.conf
# Protect against the BEAST attack by preferring RC4-SHA when using SSLv3 and TLS protocols.
# Note that TLSv1.1 and TLSv1.2 are immune to the beast attack but only work with OpenSSL v1.0.1 and higher and has limited client support.
# Ciphers set to best allow protection from Beast, while providing forwarding secrecy, as defined by Mozilla - https://wiki.mozilla.org/Security/Server_Side_TLS#Nginx
ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:ECDHE-RSA-RC4-SHA:ECDHE-ECDSA-RC4-SHA:AES128:AES256:RC4-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!PSK;
ssl_prefer_server_ciphers on;
# Optimize SSL by caching session parameters for 10 minutes. This cuts down on the number of expensive SSL handshakes.
# The handshake is the most CPU-intensive operation, and by default it is re-negotiated on every new/parallel connection.
# By enabling a cache (of type "shared between all Nginx workers"), we tell the client to re-use the already negotiated state.
# Further optimization can be achieved by raising keepalive_timeout, but that shouldn't be done unless you serve primarily HTTPS.
ssl_session_cache shared:SSL:10m; # a 1mb cache can hold about 4000 sessions, so we can hold 40000 sessions
ssl_session_timeout 10m;
EOT
# Generate ssl certs - for internal use
mkdir -p /etc/nginx/ssl-certs
openssl req -x509 -nodes -days 365 -newkey rsa:1024 \
-keyout /etc/nginx/ssl-certs/myssl.key \
-out /etc/nginx/ssl-certs/myssl.crt <<EOF
FI
Finland
My projects
Development
$HOSTNAME
EOF
ln -s /etc/nginx/sites-available/nginx_status /etc/nginx/sites-enabled/nginx_status
mkdir -p /etc/monit/conf.d
cat <<EOT >/etc/monit/conf.d/nginx
check process nginx with pidfile /var/run/nginx.pid
group www-data
start program = "/etc/init.d/nginx start"
stop program = "/etc/init.d/nginx stop"
if failed port 80 protocol HTTP request / within 5 cycles then restart
if 5 restarts within 5 cycles then timeout
EOT
if [ $MUNIN == "Yes" ]
then
mkdir -p /etc/munin/plugins/
ln -s /usr/share/munin/plugins/nginx_request /etc/munin/plugins/nginx_request
ln -s /usr/share/munin/plugins/nginx_status /etc/munin/plugins/nginx_status
mkdir -p /etc/munin/plugin-conf.d/
cat <<EOT >> /etc/munin/plugin-conf.d/nginx
[nginx*]
env.url http://localhost/nginx_status
EOT
fi
# Make directory for web stuff
mkdir -p /var/www/
chown -R www-data:www-data /var/www/
# Nginx conf need some more love
service nginx start
mv /etc/nginx/nginx.conf /etc/nginx/nginx.con_org
cat <<EOT > /etc/nginx/nginx.conf
# nginx Configuration File
# http://wiki.nginx.org/Configuration
# Run as a less privileged user for security reasons.
user www-data;
pid /var/run/nginx.pid;
# How many worker threads to run;
# "auto" sets it to the number of CPU cores available in the system, and
# offers the best performance. Don't set it higher than the number of CPU
# cores if changing this parameter.
# The maximum number of connections for Nginx is calculated by:
# max_clients = worker_processes * worker_connections
worker_processes 2;
# Maximum open file descriptors per process;
# should be > worker_connections.
worker_rlimit_nofile 8192;
events {
# When you need > 8000 * cpu_cores connections, you start optimizing your OS,
# and this is probably the point at which you hire people who are smarter than
# you, as this is *a lot* of requests.
worker_connections 2000;
}
# Default error log file
# (this is only used when you don't override error_log on a server{} level)
error_log /var/log/nginx/error.log warn;
http {
# Hide nginx version information.
server_tokens off;
# How long to allow each connection to stay idle; longer values are better
# for each individual client, particularly for SSL, but means that worker
# connections are tied up longer. (Default: 65)
keepalive_timeout 20;
# Speed up file transfers by using sendfile() to copy directly
# between descriptors rather than using read()/write().
sendfile on;
# Tell Nginx not to send out partial frames; this increases throughput
# since TCP frames are filled up before being sent out. (adds TCP_CORK)
tcp_nopush on;
# Tell Nginx to enable the Nagle buffering algorithm for TCP packets, which
# collates several smaller packets together into one larger packet, thus saving
# bandwidth at the cost of a nearly imperceptible increase to latency. (removes TCP_NODELAY)
tcp_nodelay off;
# Define the MIME types for files.
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Update charset_types due to updated mime.types
charset_types text/xml text/plain text/vnd.wap.wml application/x-javascript application/rss+xml text/css application/javascript application/json;
#increase types has bucket size
types_hash_bucket_size 64;
# Format to use in log files
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
# Default log file
# (this is only used when you don't override access_log on a server{} level)
access_log /var/log/nginx/access.log main;
# rest of the configs
include conf.d/*;
include sites-enabled/*;
}
EOT
#sed -i 's/gzip on/# gzip on/' /etc/nginx/nginx.conf
#sed -i 's/keepalive_timeout/# keepalive_timeout/' /etc/nginx/nginx.conf
#sed -i 's/sendfile/# sendfile/' /etc/nginx/nginx.conf
#sed -i 's/# gzip_types/gzip_types/' /etc/nginx/nginx.conf
#sed -i 's/# gzip_vary/gzip_vary/' /etc/nginx/nginx.conf
}
function notification_email {
#mail root to confirm installation
mail -s "DigitalOcean "`cat /etc/hostname`" setup complete" root <<EOT
Your DigitalOcean setup is complete. Your DigitalOcean will reboot shortly after this email is sent.
Webmin login:
ssh -l <username> -L 10000:localhost:10000 $(get_rdns_primary_ip)
phpMyAdmin login:
ssh -l <username> -L 10001:localhost:10001 $(get_rdns_primary_ip)
Monitored services status:
ssh -l <username> -L 10002:localhost:10002 $(get_rdns_primary_ip)
EOT
$(shutdown -r +1) &
}
function install_php_fpm {
if [ $PHP_VERSION == "Yes" ]
then
add-apt-repository -y ppa:ondrej/php5-oldstable
aptitude update
fi
#Install PHP and common extensions
aptitude -y install php5-fpm php5-cli php5-curl php5-gd php5-mcrypt php5-mysqlnd php5-sqlite php-apc
#configure php to run as fcgi under user www-data on port 8000 edit init script to change this
#NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
sed -i 's/;cgi.fix_pathinfo=1/cgi.fix_pathinfo=0/' /etc/php5/fpm/php.ini
sed -i 's/short_open_tag = On/short_open_tag = Off/' /etc/php5/fpm/php.ini
sed -i 's/disable_functions =/disable_functions = dl/' /etc/php5/fpm/php.ini
sed -i 's/expose_php = On/expose_php = Off/' /etc/php5/fpm/php.ini
sed -i 's/memory_limit = 128M/memory_limit = 32M/' /etc/php5/fpm/php.ini
sed -i 's/;arg_separator.output/arg_separator.output/' /etc/php5/fpm/php.ini
sed -i 's/;date.timezone =/date.timezone = UTC/' /etc/php5/fpm/php.ini
sed -i 's/session.name = PHPSESSID/session.name = SESSID/' /etc/php5/fpm/php.ini
sed -i 's@;error_log = syslog@error_log = /var/log/php/error.log@' /etc/php5/fpm/php.ini
mkdir -p /var/log/php/
chown www-data /var/log/php/
sed -i 's/#/;/' /etc/php5/conf.d/20-mcrypt.ini
#PHP-FPM config tuning
sed -i 's/;events.mechanism = epoll/events.mechanism = epoll/' /etc/php5/fpm/php-fpm.conf
sed -ini 's/pm = dynamic/pm = static/' /etc/php5/fpm/pool.d/www.conf
# Depens on server memory budget, worst case scenario pm.max_children * php_max_mem
sed -ini 's/pm.max_children = 5/pm.max_children = 20/' /etc/php5/fpm/pool.d/www.conf
# Just to take care of memleaks if any
sed -ini 's/;pm.max_requests = 500/pm.max_requests = 500/' /etc/php5/fpm/pool.d/www.conf
# Monit config for PHP
mkdir -p /etc/monit/conf.d
cat <<EOT >/etc/monit/conf.d/php5-fpm
check process php5-fpm with pidfile /var/run/php5-fpm.pid
start program "/etc/init.d/php5-fpm start"
stop program "/etc/init.d/php5-fpm stop"
if failed unixsocket /var/run/php5-fpm.sock then restart
if 5 restarts within 5 cycles then timeout
EOT
}
function install_phpmyadmin
{
pushd .
cd /var/www/
wget https://github.com/phpmyadmin/phpmyadmin/archive/STABLE.zip
aptitude -y install unzip
unzip -x STABLE.zip
mv phpmyadmin-STABLE myadmin
# Create PHP myadmin Config File
configfile="/var/www/myadmin/config.inc.php"
random_chars=$(echo $(date) $(hostname) $(whoami) $(uname -a) | md5sum | cut -c1-10)
cat <<EOF > "$configfile"
<?php
\$cfg['blowfish_secret'] = '$random_chars';
/* Servers configuration */
\$i = 0;
/* Server localhost (cookie) [1] */
\$i++;
\$cfg['Servers'][\$i]['host'] = 'localhost';
\$cfg['Servers'][\$i]['extension'] = 'mysql';
\$cfg['Servers'][\$i]['connect_type'] = 'tcp';
\$cfg['Servers'][\$i]['compress'] = false;
\$cfg['Servers'][\$i]['auth_type'] = 'cookie';
/* End of servers configuration */
?>
EOF
cat <<EOT >/etc/nginx/sites-available/phpmyadmin
server {
# Blocked by firewall
# ssh -l <login> -L 10001:localhost:10001 <server.ip/domain.name>
# http://localhost:10001
listen localhost:10001;
root /var/www/myadmin;
location / {
try_files \$uri \$uri/ index.php;
}
location ~ .php$ {
include config/php.conf;
}
}
EOT
chown -R www-data:www-data myadmin
rm STABLE.zip
cd /etc/nginx/sites-enabled/
ln -s ../sites-available/phpmyadmin
popd
}
function install_webmin
{
#Install webmin
cat <<EOT > /etc/apt/sources.list.d/webmin.list
deb http://download.webmin.com/download/repository sarge contrib
deb http://webmin.mirror.somersettechsolutions.co.uk/repository sarge contrib
EOT
pushd .
cd /tmp
wget http://www.webmin.com/jcameron-key.asc
apt-key add jcameron-key.asc
# install webmin
aptitude update
aptitude -y install webmin
# install nginx module
wget http://www.justindhoffman.com/sites/justindhoffman.com/files/nginx-0.08.wbm__0.gz
gunzip nginx-0.08.wbm__0.gz
/usr/share/webmin/install-module.pl nginx-0.08.wbm__0
popd
}
function install_mysql
{
#Install mysql
echo "mysql-server-5.5 mysql-server/root_password password $MYSQL_PASSWORD" | debconf-set-selections
echo "mysql-server-5.5 mysql-server/root_password_again password $MYSQL_PASSWORD" | debconf-set-selections
aptitude -y install mysql-server mysql-client
echo "Sleeping while MySQL starts up for the first time..."
sleep 5
innodb_memory=$(awk '/MemTotal/ {print int($2/3072)}' /proc/meminfo)
cat <<EOT > /etc/mysql/conf.d/innodb.cnf
[mysqld]
innodb_file_per_table
innodb_buffer_pool_size=${innodb_memory}M
innodb_additional_mem_pool_size=8M
EOT
#set charset to utf8
cat <<EOT > /etc/mysql/conf.d/charset.cnf
[mysqld]
character-set-server=utf8
collation-server=utf8_general_ci
EOT
#enable slow query logging to table compatible with mysql workbench
cat <<EOT > /etc/mysql/conf.d/logging.cnf
[mysqld]
slow_query_log = 1
slow_query_log_file = /var/log/mysql/mysql-slow.log
long_query_time = 1
log-queries-not-using-indexes
log-output=TABLE
EOT
#make pid file static name across installations
cat <<EOT > /etc/mysql/conf.d/pid.cnf
[mysqld]
pid-file = /var/lib/mysql/mysqld.pid
EOT
#limit number of simultanious connections to 20
cat <<EOT > /etc/mysql/conf.d/connections.cnf
[mysqld]
max_connections = 20
EOT
#drop myisam specific settings since I'm assuming you're using innodb
cat <<EOT > /etc/mysql/conf.d/myisam.cnf
[mysqld]
key_buffer_size = 256k
read_buffer_size = 256k
read_rnd_buffer_size = 256k
EOT
#add root password to .my.cnf to prevent prompting
cat <<EOT > /root/.my.cnf
[client]
user=root
password=$MYSQL_PASSWORD
EOT
chmod 0400 /root/.my.cnf
mkdir -p /etc/monit/conf.d/
cat <<EOT > /etc/monit/conf.d/mysql
check process mysqld with pidfile /var/lib/mysql/mysqld.pid
group mysql
start program = "/sbin/start mysql"
stop program = "/sbin/stop mysql"
if failed unixsocket /var/run/mysqld/mysqld.sock protocol mysql then restart
if 5 restarts within 5 cycles then timeout
EOT
}
function install_postfix
{
#Install postfix
echo "postfix postfix/main_mailer_type select Internet Site" | debconf-set-selections
echo "postfix postfix/mailname string $HOSTNAME" | debconf-set-selections
echo "postfix postfix/destinations string localhost.localdomain, localhost, $HOSTNAME" | debconf-set-selections
aptitude -y install postfix mailutils
/usr/sbin/postconf -e "inet_interfaces = loopback-only"
#configure root alias
echo "root: $ROOT_EMAIL" >> /etc/aliases
echo "$USER_NAME: root" >> /etc/aliases
echo $HOSTNAME > /etc/mailname
/usr/bin/newaliases
sed -i "s/mydestination = localhost, localhost.localdomain, , localhost/mydestination = localhost, localhost.localdomain, $HOSTNAME/" /etc/postfix/main.cf
service postfix restart
}
function configure_ssh {
#setup ssh
#add ssh key
sudo -u $USER_NAME mkdir /home/$USER_NAME/.ssh
sudo -u $USER_NAME echo "${USER_SSHKEY}" >> /home/$USER_NAME/.ssh/authorized_keys
mkdir -p /root/.ssh/
echo "${USER_SSHKEY}" >> /root/.ssh/authorized_keys
chmod 0600 /home/$USER_NAME/.ssh/authorized_keys /root/.ssh/authorized_keys
chown $USER_NAME:$USER_NAME /home/$USER_NAME/.ssh/authorized_keys
sed -i "s/Port 22/Port $SSH_PORT/" /etc/ssh/sshd_config #set ssh port
#enable internal sftp for chrooting
sed -i 's@Subsystem sftp /usr/lib/openssh/sftp-server@Subsystem sftp internal-sftp@' /etc/ssh/sshd_config
if [[ "$SSH_ALLOW_USERS" != *root* ]]
then
sed -i 's/PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config
else
sed -i 's/PermitRootLogin yes/PermitRootLogin without-password/' /etc/ssh/sshd_config
fi
#if [ "$USER_SSHKEY" != "" ]
#then
# Digital Ocean will install authorized_keys by default right?
sed -i 's/#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config #disable ssh password auth if $USER_SSHKEY is not empty
#fi
sed -i 's/X11Forwarding yes/X11Forwarding no/' /etc/ssh/sshd_config #disable xforwarding
echo "AllowUsers $USER_NAME $SSH_ALLOW_USERS" >> /etc/ssh/sshd_config #only allow access from $USER
}
function configure_user
{
#configure ssh/sudo
useradd -m -s /bin/bash $USER_NAME #add user account
echo "$USER_NAME:$USER_PASSWORD" | chpasswd #setpassword
#add user to sudoers
echo "$USER_NAME ALL=(ALL) ALL" >> /etc/sudoers
usermod -a -G adm $USER_NAME
#lock out root
passwd -l root
}
function install_shorewall
{
#sets up shorewall firewall
aptitude -y install shorewall shorewall6
cp /usr/share/doc/shorewall/examples/one-interface/* /etc/shorewall/
sed -i 's/BLACKLISTNEWONLY=Yes/BLACKLISTNEWONLY=No/' /etc/shorewall/shorewall.conf
sed -i 's/REJECT/DROP/' /etc/shorewall/policy
if [ "$WEBSERVER" != "None" ]
then
echo "#accept http/s" >> /etc/shorewall/rules
echo "ACCEPT net \$FW:`system_primary_ip` tcp 80" >> /etc/shorewall/rules
echo "ACCEPT net \$FW:`system_primary_ip` tcp 443" >> /etc/shorewall/rules
fi
echo '#accept ssh and ratelimit to 5 connections per miniute per ip' >> /etc/shorewall/rules
echo "ACCEPT net \$FW:`system_primary_ip` tcp $SSH_PORT - - s:ssh:5/min:1" >> /etc/shorewall/rules
sed -i 's/STARTUP_ENABLED=No/STARTUP_ENABLED=Yes/' /etc/shorewall/shorewall.conf
sed -i 's/startup=0/startup=1/' /etc/default/shorewall
#disable ipv6 by default
cp /usr/share/doc/shorewall6/examples/one-interface/* /etc/shorewall6/
sed -i 's/BLACKLISTNEWONLY=Yes/BLACKLISTNEWONLY=No/' /etc/shorewall6/shorewall6.conf
sed -i 's/REJECT/DROP/' /etc/shorewall6/policy
sed -i 's/STARTUP_ENABLED=No/STARTUP_ENABLED=Yes/' /etc/shorewall6/shorewall6.conf
sed -i 's/startup=0/startup=1/' /etc/default/shorewall6
}
function install_monit
{
#install and enable monit
aptitude -y install monit
sed -i 's/startup=0/startup=1/' /etc/default/monit
mkdir -p /etc/monit/conf.d/
sed -i "s/# set daemon 120/set daemon 300/" /etc/monit/monitrc
sed -i "s/# with start delay 240/with start delay 240/" /etc/monit/monitrc
#already in default config
#sed -i "s/# set logfile syslog facility log_daemon/set logfile \/var\/log\/monit.log/" /etc/monit/monitrc
sed -i "s/# set mailserver mail.bar.baz,/set mailserver localhost/" /etc/monit/monitrc
sed -i "s/# set eventqueue/set eventqueue/" /etc/monit/monitrc
sed -i "s/# basedir \/var\/monit/basedir \/var\/monit/" /etc/monit/monitrc
sed -i "s/# slots 100 /slots 100/" /etc/monit/monitrc
sed -i "s/# set alert sysadm@foo.bar/set alert root@localhost reminder 180/" /etc/monit/monitrc
sed -i "s/# set httpd port 2812 and/ set httpd port 10002 and/" /etc/monit/monitrc
sed -i "s/# use address localhost/use address localhost/" /etc/monit/monitrc
sed -i "s/# allow localhost/allow localhost/" /etc/monit/monitrc
sed -i "s/# set mail-format { from: monit@foo.bar }/set mail-format { from: monit@$HOSTNAME }/" /etc/monit/monitrc
cat <<EOT > /etc/monit/conf.d/system
check system `hostname -f`
if loadavg (1min) > 4 then alert
if loadavg (5min) > 4 then alert
if memory usage > 90% then alert
if cpu usage (user) > 70% then alert
if cpu usage (system) > 30% then alert
if cpu usage (wait) > 20% then alert
check filesystem rootfs with path /
if space > 80% then alert
EOT
}
function install_munin
{
#install munin
if [ $MUNIN_VERSION == "Yes" ]
then
add-apt-repository -y ppa:tuxpoldo/munin
aptitude update
fi
if [ $MUNIN_CLIENT_ONLY == "Yes" ]
# http://munin-monitoring.org/wiki/Native_ssh
then
aptitude -y install munin-node
# Allow SSH login to munin user
chsh -s /bin/bash munin
MUNIN_SHELL=`getent passwd munin | cut -d: -f 6`
mkdir -p "$MUNIN_SHELL/.ssh"
echo "${MUNIN_SSHKEY}" >> "$MUNIN_SHELL/.ssh/authorized_keys"
chmod 0600 "$MUNIN_SHELL/.ssh/authorized_keys"
chmod 0700 "$MUNIN_SHELL/.ssh"
chown -R munin:munin "$MUNIN_SHELL"
echo "AllowUsers munin" >> /etc/ssh/sshd_config #only allow access from $USER
else
aptitude -y install munin munin-node libcache-cache-perl libdbd-mysql-perl
sed -i "s/localhost.localdomain/`hostname -f`/" /etc/munin/munin.conf
fi
sed -i 's/host \*/host 127.0.0.1/' /etc/munin/munin-node.conf
sed -i "s#\[mysql\*\]#[mysql*]\nenv.mysqladmin /usr/bin/mysqladmin#" /etc/munin/plugin-conf.d/munin-node
ln -s /usr/share/munin/plugins/postfix_mailstats /etc/munin/plugins/
ln -s /usr/share/munin/plugins/netstat /etc/munin/plugins/
if [ -f /etc/munin/plugins/nfs* ]
then
rm /etc/munin/plugins/nfs*
fi
echo "munin: root" >> /etc/aliases
if [ -x /usr/bin/newaliases ]
then
/usr/bin/newaliases
fi
}
function install_security
{
#install chrootkit rkhunter logwatch
#aptitude -y install chkrootkit rkhunter logwatch logcheck libsys-cpu-perl build-essential logcheck
aptitude -y install chkrootkit rkhunter logwatch libsys-cpu-perl build-essential
echo "yes" | perl -MCPAN -e 'install Sys::MemInfo'
sed -i 's/#ALLOWHIDDENDIR=\/dev\/.initramfs/ALLOWHIDDENDIR=\/dev\/.initramfs/' /etc/rkhunter.conf
sed -i 's/#ALLOWHIDDENDIR=\/dev\/.udev/ALLOWHIDDENDIR=\/dev\/.udev/' /etc/rkhunter.conf
sed -i 's/DISABLE_TESTS="suspscan hidden_procs deleted_files packet_cap_apps apps"/DISABLE_TESTS="suspscan hidden_procs deleted_files packet_cap_apps apps os_specific"/' /etc/rkhunter.conf
rkhunter --propupd
sed -i 's/--output mail/--output mail --detail 10 --service All/' /etc/cron.daily/00logwatch
}
function install_tools
{
#install full vim, nano, less, htop (nice version of top), iotop (top for disk io), logrotate (rotates logs..), lynx (text webbrowser), mytop (top for mysql), screen (terminal emulator), sqlite3 (command line interface for sqlite databases)
#aptitude -y install vim nano less htop iotop logrotate lynx mytop nmap screen sqlite3 cron-apt ntp curl pflogsumm bar apt-show-versions iftop
aptitude -y install vim less htop iotop logrotate mytop nmap cron-apt ntp curl pflogsumm bar apt-show-versions iftop
echo 'SYSLOGON="always"' >> /etc/cron-apt/config
echo 'MAILON="upgrade"' >> /etc/cron-apt/config
}
function set_root_profile
{
#Black 0;30 Dark Gray 1;30
#Blue 0;34 Light Blue 1;34
#Green 0;32 Light Green 1;32
#Cyan 0;36 Light Cyan 1;36
#Red 0;31 Light Red 1;31
#Purple 0;35 Light Purple 1;35
#Brown 0;33 Yellow 1;33
#Light Gray 0;37 White 1;37
cat <<EOT >> /root/.profile
PS1='\[\033[0;33m\]root@'
#add hostname
PS1=\$PS1\$(hostname -f)'\n'
#add ipv4 addresses
PS1=\$PS1\$(ifconfig | grep -v '127.0.0.1' | awk -F: '/inet addr:/ {print \$2}' | awk '{ print \$1 }')
#add ipv6 addresses
PS1=\$PS1'\n'\$(ifconfig | grep 'Global' | awk -F / '/inet6 addr: / {print \$1}' | awk '{ print \$3 }')
#add current working dir and close colours
PS1=\$PS1'\n\$PWD:\$\033[00m\]\n'
export PS1
EOT
}
function cleanup
{
#disable services not required
if [ -f /etc/init/atd.conf ]
then
stop atd
mv /etc/init/atd.conf /etc/init/atd.conf.noexec
fi
#sed -i 's/true/false/' /etc/default/whoopsie
aptitude -y purge whoopsie
update-locale
#tweak min free kbytes to get around page allocation failures on newer kernels
#echo "vm.min_free_kbytes=6144" > /etc/sysctl.d/60-page.conf
}
#deletes users from /etc/passwd that you don't need
function deleteusers
{
deluser irc #delete irc user
deluser games #delete games user
deluser news #delete nntp daemon user
deluser uucp #delete uucp user
deluser proxy #delete proxy user
deluser list #delete mailing list user
deluser gnats #delete gnats bug reporting user
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment