Last active
February 19, 2016 16:52
-
-
Save el2ro/5000566 to your computer and use it in GitHub Desktop.
Ubuntu 12.04 DigitalOcean setup script
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 | |
###### | |
#LICENCE# | |
###### | |
#Released under the BSD license http://www.opensource.org/licenses/bsd-license | |
#Copyright (c) 2011, Rowan Wookey <[email protected]> | |
#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" |
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 | |
###### | |
#LICENCE# | |
###### | |
#Released under the BSD license http://www.opensource.org/licenses/bsd-license | |
#Copyright (c) 2011, Rowan Wookey <[email protected]> | |
#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 <[email protected]> | |
# 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 [email protected]/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: [email protected] }/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