Skip to content

Instantly share code, notes, and snippets.

@lunaroja
Created February 4, 2016 05:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lunaroja/9a3b3ba393b9d66f19e3 to your computer and use it in GitHub Desktop.
Save lunaroja/9a3b3ba393b9d66f19e3 to your computer and use it in GitHub Desktop.
StackScript Bash Library
#!/bin/bash
#
# StackScript Bash Library
# https://www.linode.com/stackscripts/view/1
#
# 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.
###########################################################
# System
###########################################################
function system_update {
apt-get update
apt-get -y install aptitude
aptitude -y full-upgrade
}
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 system_set_hostname {
# $1 - The hostname to define
HOSTNAME="$1"
if [ ! -n "$HOSTNAME" ]; then
echo "Hostname undefined"
return 1;
fi
echo "$HOSTNAME" > /etc/hostname
hostname -F /etc/hostname
}
function system_add_host_entry {
# $1 - The IP address to set a hosts entry for
# $2 - The FQDN to set to the IP
IPADDR="$1"
FQDN="$2"
if [ -z "$IPADDR" -o -z "$FQDN" ]; then
echo "IP address and/or FQDN Undefined"
return 1;
fi
echo $IPADDR $FQDN >> /etc/hosts
}
###########################################################
# Users and Authentication
###########################################################
function user_add_sudo {
# Installs sudo if needed and creates a user in the sudo group.
#
# $1 - Required - username
# $2 - Required - password
USERNAME="$1"
USERPASS="$2"
if [ ! -n "$USERNAME" ] || [ ! -n "$USERPASS" ]; then
echo "No new username and/or password entered"
return 1;
fi
aptitude -y install sudo
adduser $USERNAME --disabled-password --gecos ""
echo "$USERNAME:$USERPASS" | chpasswd
usermod -aG sudo $USERNAME
}
function user_add_pubkey {
# Adds the users public key to authorized_keys for the specified user. Make sure you wrap your input variables in double quotes, or the key may not load properly.
#
#
# $1 - Required - username
# $2 - Required - public key
USERNAME="$1"
USERPUBKEY="$2"
if [ ! -n "$USERNAME" ] || [ ! -n "$USERPUBKEY" ]; then
echo "Must provide a username and the location of a pubkey"
return 1;
fi
if [ "$USERNAME" == "root" ]; then
mkdir /root/.ssh
echo "$USERPUBKEY" >> /root/.ssh/authorized_keys
return 1;
fi
mkdir -p /home/$USERNAME/.ssh
echo "$USERPUBKEY" >> /home/$USERNAME/.ssh/authorized_keys
chown -R "$USERNAME":"$USERNAME" /home/$USERNAME/.ssh
}
function ssh_disable_root {
# Disables root SSH access.
sed -i 's/PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config
touch /tmp/restart-ssh
}
###########################################################
# Postfix
###########################################################
function postfix_install_loopback_only {
# Installs postfix and configure to listen only on the local interface. Also
# allows for local mail delivery
echo "postfix postfix/main_mailer_type select Internet Site" | debconf-set-selections
echo "postfix postfix/mailname string localhost" | debconf-set-selections
echo "postfix postfix/destinations string localhost.localdomain, localhost" | debconf-set-selections
aptitude -y install postfix
/usr/sbin/postconf -e "inet_interfaces = loopback-only"
#/usr/sbin/postconf -e "local_transport = error:local delivery is disabled"
touch /tmp/restart-postfix
}
###########################################################
# Apache
###########################################################
function apache_install {
# installs the system default apache2 MPM
aptitude -y install apache2
a2dissite default # disable the interfering default virtualhost
# clean up, or add the NameVirtualHost line to ports.conf
sed -i -e 's/^NameVirtualHost \*$/NameVirtualHost *:80/' /etc/apache2/ports.conf
if ! grep -q NameVirtualHost /etc/apache2/ports.conf; then
echo 'NameVirtualHost *:80' > /etc/apache2/ports.conf.tmp
cat /etc/apache2/ports.conf >> /etc/apache2/ports.conf.tmp
mv -f /etc/apache2/ports.conf.tmp /etc/apache2/ports.conf
fi
}
function apache_tune {
# Tunes Apache's memory to use the percentage of RAM you specify, defaulting to 40%
# $1 - the percent of system memory to allocate towards Apache
if [ ! -n "$1" ];
then PERCENT=40
else PERCENT="$1"
fi
aptitude -y install apache2-mpm-prefork
PERPROCMEM=10 # the amount of memory in MB each apache process is likely to utilize
MEM=$(grep MemTotal /proc/meminfo | awk '{ print int($2/1024) }') # how much memory in MB this system has
MAXCLIENTS=$((MEM*PERCENT/100/PERPROCMEM)) # calculate MaxClients
MAXCLIENTS=${MAXCLIENTS/.*} # cast to an integer
sed -i -e "s/\(^[ \t]*MaxClients[ \t]*\)[0-9]*/\1$MAXCLIENTS/" /etc/apache2/apache2.conf
touch /tmp/restart-apache2
}
function apache_virtualhost {
# Configures a VirtualHost
# $1 - required - the hostname of the virtualhost to create
if [ ! -n "$1" ]; then
echo "apache_virtualhost() requires the hostname as the first argument"
return 1;
fi
if [ -e "/etc/apache2/sites-available/$1" ]; then
echo /etc/apache2/sites-available/$1 already exists
return;
fi
mkdir -p /srv/www/$1/public_html /srv/www/$1/logs
echo "<VirtualHost *:80>" > /etc/apache2/sites-available/$1
echo " ServerName $1" >> /etc/apache2/sites-available/$1
echo " DocumentRoot /srv/www/$1/public_html/" >> /etc/apache2/sites-available/$1
echo " ErrorLog /srv/www/$1/logs/error.log" >> /etc/apache2/sites-available/$1
echo " CustomLog /srv/www/$1/logs/access.log combined" >> /etc/apache2/sites-available/$1
echo "</VirtualHost>" >> /etc/apache2/sites-available/$1
a2ensite $1
touch /tmp/restart-apache2
}
function apache_virtualhost_from_rdns {
# Configures a VirtualHost using the rdns of the first IP as the ServerName
apache_virtualhost $(get_rdns_primary_ip)
}
function apache_virtualhost_get_docroot {
if [ ! -n "$1" ]; then
echo "apache_virtualhost_get_docroot() requires the hostname as the first argument"
return 1;
fi
if [ -e /etc/apache2/sites-available/$1 ];
then echo $(awk '/DocumentRoot/ {print $2}' /etc/apache2/sites-available/$1 )
fi
}
###########################################################
# mysql-server
###########################################################
function mysql_install {
# $1 - the mysql root password
if [ ! -n "$1" ]; then
echo "mysql_install() requires the root pass as its first argument"
return 1;
fi
echo "mysql-server mysql-server/root_password password $1" | debconf-set-selections
echo "mysql-server mysql-server/root_password_again password $1" | debconf-set-selections
apt-get -y install mysql-server mysql-client
echo "Sleeping while MySQL starts up for the first time..."
sleep 5
}
function mysql_tune {
# Tunes MySQL's memory usage to utilize the percentage of memory you specify, defaulting to 40%
# $1 - the percent of system memory to allocate towards MySQL
if [ ! -n "$1" ];
then PERCENT=40
else PERCENT="$1"
fi
sed -i -e 's/^#skip-innodb/skip-innodb/' /etc/mysql/my.cnf # disable innodb - saves about 100M
MEM=$(awk '/MemTotal/ {print int($2/1024)}' /proc/meminfo) # how much memory in MB this system has
MYMEM=$((MEM*PERCENT/100)) # how much memory we'd like to tune mysql with
MYMEMCHUNKS=$((MYMEM/4)) # how many 4MB chunks we have to play with
# mysql config options we want to set to the percentages in the second list, respectively
OPTLIST=(key_buffer sort_buffer_size read_buffer_size read_rnd_buffer_size myisam_sort_buffer_size query_cache_size)
DISTLIST=(75 1 1 1 5 15)
for opt in ${OPTLIST[@]}; do
sed -i -e "/\[mysqld\]/,/\[.*\]/s/^$opt/#$opt/" /etc/mysql/my.cnf
done
for i in ${!OPTLIST[*]}; do
val=$(echo | awk "{print int((${DISTLIST[$i]} * $MYMEMCHUNKS/100))*4}")
if [ $val -lt 4 ]
then val=4
fi
config="${config}\n${OPTLIST[$i]} = ${val}M"
done
sed -i -e "s/\(\[mysqld\]\)/\1\n$config\n/" /etc/mysql/my.cnf
touch /tmp/restart-mysql
}
function mysql_create_database {
# $1 - the mysql root password
# $2 - the db name to create
if [ ! -n "$1" ]; then
echo "mysql_create_database() requires the root pass as its first argument"
return 1;
fi
if [ ! -n "$2" ]; then
echo "mysql_create_database() requires the name of the database as the second argument"
return 1;
fi
echo "CREATE DATABASE $2;" | mysql -u root -p$1
}
function mysql_create_user {
# $1 - the mysql root password
# $2 - the user to create
# $3 - their password
if [ ! -n "$1" ]; then
echo "mysql_create_user() requires the root pass as its first argument"
return 1;
fi
if [ ! -n "$2" ]; then
echo "mysql_create_user() requires username as the second argument"
return 1;
fi
if [ ! -n "$3" ]; then
echo "mysql_create_user() requires a password as the third argument"
return 1;
fi
echo "CREATE USER '$2'@'localhost' IDENTIFIED BY '$3';" | mysql -u root -p$1
}
function mysql_grant_user {
# $1 - the mysql root password
# $2 - the user to bestow privileges
# $3 - the database
if [ ! -n "$1" ]; then
echo "mysql_create_user() requires the root pass as its first argument"
return 1;
fi
if [ ! -n "$2" ]; then
echo "mysql_create_user() requires username as the second argument"
return 1;
fi
if [ ! -n "$3" ]; then
echo "mysql_create_user() requires a database as the third argument"
return 1;
fi
echo "GRANT ALL PRIVILEGES ON $3.* TO '$2'@'localhost';" | mysql -u root -p$1
echo "FLUSH PRIVILEGES;" | mysql -u root -p$1
}
###########################################################
# PHP functions
###########################################################
function php_install_with_apache {
aptitude -y install php5 php5-mysql libapache2-mod-php5
touch /tmp/restart-apache2
}
function php_tune {
# Tunes PHP to utilize up to 32M per process
sed -i'-orig' 's/memory_limit = [0-9]\+M/memory_limit = 32M/' /etc/php5/apache2/php.ini
touch /tmp/restart-apache2
}
###########################################################
# Wordpress functions
###########################################################
function wordpress_install {
# installs the latest wordpress tarball from wordpress.org
# $1 - required - The existing virtualhost to install into
if [ ! -n "$1" ]; then
echo "wordpress_install() requires the vitualhost as its first argument"
return 1;
fi
if [ ! -e /usr/bin/wget ]; then
aptitude -y install wget
fi
VPATH=$(apache_virtualhost_get_docroot $1)
if [ ! -n "$VPATH" ]; then
echo "Could not determine DocumentRoot for $1"
return 1;
fi
# download, extract, chown, and get our config file started
cd $VPATH
wget http://wordpress.org/latest.tar.gz
tar xfz latest.tar.gz
chown -R www-data: wordpress/
cd $VPATH/wordpress
cp wp-config-sample.php wp-config.php
chown www-data wp-config.php
chmod 640 wp-config.php
# database configuration
WPPASS=$(randomString 20)
mysql_create_database "$DB_PASSWORD" wordpress
mysql_create_user "$DB_PASSWORD" wordpress "$WPPASS"
mysql_grant_user "$DB_PASSWORD" wordpress wordpress
# configuration file updates
for i in {1..4}
do sed -i "0,/put your unique phrase here/s/put your unique phrase here/$(randomString 50)/" wp-config.php
done
sed -i 's/database_name_here/wordpress/' wp-config.php
sed -i 's/username_here/wordpress/' wp-config.php
sed -i "s/password_here/$WPPASS/" wp-config.php
# http://downloads.wordpress.org/plugin/wp-super-cache.0.9.8.zip
}
###########################################################
# Other niceties!
###########################################################
function goodstuff {
# Installs the REAL vim, wget, less, and enables color root prompt and the "ll" list long alias
aptitude -y install wget vim less
sed -i -e 's/^#PS1=/PS1=/' /root/.bashrc # enable the colorful root bash prompt
sed -i -e "s/^#alias ll='ls -l'/alias ll='ls -al'/" /root/.bashrc # enable ll list long alias <3
}
###########################################################
# utility functions
###########################################################
function restartServices {
# restarts services that have a file in /tmp/needs-restart/
for service in $(ls /tmp/restart-* | cut -d- -f2-10); do
/etc/init.d/$service restart
rm -f /tmp/restart-$service
done
}
function randomString {
if [ ! -n "$1" ];
then LEN=20
else LEN="$1"
fi
echo $(</dev/urandom tr -dc A-Za-z0-9 | head -c $LEN) # generate a random string
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment