From df39050f1ac1224df501c7a2b0360a4b91af3101 Mon Sep 17 00:00:00 2001 From: Filip Wasilewski Date: Sat, 14 Apr 2012 11:51:03 +0200 Subject: [PATCH 01/35] Python script for parsing and concatenating StackSctipts --- prepare.py | 135 +++++++++++++++++++++++++++++++++++++++++++++++++++ settings.txt | 21 ++++++++ 2 files changed, 156 insertions(+) create mode 100644 prepare.py create mode 100644 settings.txt diff --git a/prepare.py b/prepare.py new file mode 100644 index 0000000..594b4fe --- /dev/null +++ b/prepare.py @@ -0,0 +1,135 @@ +#!/usr/bin/env python +#-*- coding: utf-8 -*- + +""" +Script for parsing and concatenating StackScripts + +Usage example: + +prepare.py "131 - Stack - Security, PostgreSQL, MySQL, MongoDB, Apache, Django.sh" @settings.txt +""" + +import argparse +import glob +import os +import re +import sys +from xml.etree.ElementTree import fromstring + + +class ArgParser(argparse.ArgumentParser): + + def convert_arg_line_to_args(self, arg_line): + parts = arg_line.split(None, 1) + if len(parts) == 2: + return [p.strip() for p in parts] + return [] + + +def get_udfs(content): + udf_re = re.compile("^\s*#\s*()", re.IGNORECASE | re.MULTILINE) + return udf_re.findall(content) + + +def parse_param(udf): + element = fromstring(udf) + choices = element.get("oneof") + if choices: + choices = choices.split(",") + return { + 'name': element.get("name"), + 'label': element.get("label"), + 'choices': choices, + 'default': element.get("default"), + 'example': element.get("example") + } + + +def build_argparser(content): + parser = ArgParser( + description='Process StackScript file params.', + fromfile_prefix_chars='@', + formatter_class=argparse.ArgumentDefaultsHelpFormatter, + epilog="Use @settings.txt as param to read configuration from settings file." + ) + parser.add_argument('script', metavar='SCRIPT', nargs=1, help='main script') + + for udf in get_udfs(content): + param = parse_param(udf) + help = param["example"] or "" + default = param["default"] + required = param["default"] is None + parser.add_argument( + '--%s' % param["name"], dest=param["name"].upper(), + action='store', default=default, choices=param["choices"] or None, + required=required, help=help + ) + return parser + + +def lookup_script(script_id): + try: + return glob.glob("%s - *.sh" % script_id)[0] + except IndexError: + raise ValueError("Script for given id does not exist: %s." % script_id) + + +def get_content(script_id): + with open(lookup_script(script_id)) as fp: + return fp.read() + + +def expand_script(content, mode="source"): + assert mode in ["source", "include"] + re_source = re.compile("""""") + re_include = re.compile("""^(\s*source\s+.*)$""", re.MULTILINE) + if mode == "source": + content = re_source.sub( + lambda x: '"%s"' % lookup_script(x.group(1)), + content + ) + else: + content = re_include.sub( + lambda x: '\n#==> Content of %s ==>>\n%s\n#<<== end of %s <=\n' % + (x.group(2), get_content(x.group(2)), x.group(2)), + content + ) + return content + + +def add_variables(content, args): + # Add script variables + variables = "\n".join( + '%s="%s"' % (k,v) for k,v in sorted(args.__dict__.items()) if k.isupper() + ) + lines = iter(content.splitlines()) + content = [] + for line in lines: + if line.startswith("#") or not line.strip(): + content.append(line) + else: + content.append(variables) + content.extend(list(lines)) + break + return "\n".join(content) + + +def main(stack_script): + + if stack_script: + with open(stack_script) as fp: + content = fp.read() + + parser = build_argparser(content) + args = parser.parse_args() + + content = expand_script(content, mode="include") + content = add_variables(content, args) + + print content + + +if __name__ == "__main__": + if len(sys.argv) < 2 or os.path.exists(sys.argv[1]): + print "First argument must be a valid script name" + main(sys.argv[1]) diff --git a/settings.txt b/settings.txt new file mode 100644 index 0000000..d7616ae --- /dev/null +++ b/settings.txt @@ -0,0 +1,21 @@ +--user_name ubuntu +--user_password pass +--user_sshkey +--sshd_permitrootlogin No +--sshd_passwordauth Yes +--sys_hostname myvps +--base_data_directory /srv +--setup_postgresql Yes +--postgresql_database django +--postgresql_user django +--postgresql_password django +--setup_mysql No +--mysql_database_password +--mysql_database +--mysql_user +--mysql_password +--setup_mongodb Yes +--setup_django_project Yes +--django_domain +--django_project_name my_project +--django_user django From b1aba670fb939c43735d949c5c84a5b8431e6068 Mon Sep 17 00:00:00 2001 From: Filip Wasilewski Date: Tue, 15 May 2012 19:01:53 +0200 Subject: [PATCH 02/35] Use pip to install virtualenv. --- 126 - lib-python.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/126 - lib-python.sh b/126 - lib-python.sh index ac2d45a..b5c1141 100644 --- a/126 - lib-python.sh +++ b/126 - lib-python.sh @@ -8,5 +8,6 @@ function python_install { aptitude -y install python python-dev python-setuptools - easy_install virtualenv virtualenvwrapper pip + easy_install pip + pip install virtualenv virtualenvwrapper } From 3ce586d2098939515dc2b82342561bcd1d332b01 Mon Sep 17 00:00:00 2001 From: Filip Wasilewski Date: Tue, 15 May 2012 19:06:06 +0200 Subject: [PATCH 03/35] Added python-software-properties to system utils. Removed references to existing packages. --- 124 - lib-system.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/124 - lib-system.sh b/124 - lib-system.sh index 0fbafb4..3cf9be9 100644 --- a/124 - lib-system.sh +++ b/124 - lib-system.sh @@ -7,7 +7,7 @@ # My ref: http://www.linode.com/?r=aadfce9845055011e00f0c6c9a5c01158c452deb function system_install_utils { - aptitude -y install wget less vim sudo screen htop bsd-mailx + aptitude -y install htop bsd-mailx python-software-properties } function system_install_build { From c6db011a7a7e4b388661f6a8209981d218437291 Mon Sep 17 00:00:00 2001 From: Filip Wasilewski Date: Tue, 15 May 2012 19:24:13 +0200 Subject: [PATCH 04/35] Simplified MongoDB install. --- 128 - lib-mongodb.sh | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/128 - lib-mongodb.sh b/128 - lib-mongodb.sh index a4b1ea0..ce01355 100644 --- a/128 - lib-mongodb.sh +++ b/128 - lib-mongodb.sh @@ -1,26 +1,12 @@ #!/bin/bash # -# Installs MongoDB from 10gen.com repository. +# Installs MongoDB. # # Copyright (c) 2010 Filip Wasilewski . # # My ref: http://www.linode.com/?r=aadfce9845055011e00f0c6c9a5c01158c452deb -function system_configure_mongodb_repository { - RELEASE=`lsb_release -sr | sed 's/\.0/\./'` - echo -e "\n##MongoDB repository by 10gen\ndeb http://downloads.mongodb.org/distros/ubuntu $RELEASE 10gen\n" >> /etc/apt/sources.list - apt-key adv --keyserver pgp.mit.edu --recv 7F0CEB10 || apt-key adv --keyserver keyserver.ubuntu.com --recv 7F0CEB10 - aptitude update -} function mongodb_install { - BASE_DIRECTORY=$1 # /var/lib or /srv - aptitude -y install mongodb-stable - if [ -n "$BASE_DIRECTORY" ]; then - DATA_DIRECTORY="$BASE_DIRECTORY/mongodb" - mkdir -p "$DATA_DIRECTORY" - chown mongodb:mongodb "$DATA_DIRECTORY" - sed -i "s:dbpath=.*:dbpath=$DATA_DIRECTORY:" /etc/mongodb.conf - fi; - touch /tmp/restart-mongodb + aptitude -y install mongodb } From f4a1593a63f6b23dcab58d34c3c0543f00adaa41 Mon Sep 17 00:00:00 2001 From: Filip Wasilewski Date: Tue, 15 May 2012 19:40:58 +0200 Subject: [PATCH 05/35] Function postgresql_recreate_cluster is not needed anymore. Minor style and sudo invocation tweaks. --- 125 - lib-postgresql.sh | 39 +++++++++------------------------------ 1 file changed, 9 insertions(+), 30 deletions(-) diff --git a/125 - lib-postgresql.sh b/125 - lib-postgresql.sh index bdd6c2d..6bcc17e 100644 --- a/125 - lib-postgresql.sh +++ b/125 - lib-postgresql.sh @@ -7,54 +7,33 @@ # My ref: http://www.linode.com/?r=aadfce9845055011e00f0c6c9a5c01158c452deb function postgresql_install { - aptitude -y install postgresql postgresql-contrib postgresql-dev postgresql-client libpq-dev -} - - -function postgresql_recreate_cluster { - # WARNING: this procedure removes all data in the main cluster - # drop default cluster and recreate it with UTF-8 encoding - # $1 - root data dicrecotry, i.e. /var/lib or /srv - BASE_DIRECTORY=$1 - pg_dropcluster -stop 8.4 main - if [ -z "$BASE_DIRECTORY" ]; then - pg_createcluster -start -e UTF-8 8.4 main - else - DATA_DIRECTORY="$BASE_DIRECTORY/postgresql" - mkdir -p "$DATA_DIRECTORY/8.4/main" - chown -R postgres:postgres "$DATA_DIRECTORY" - pg_createcluster -start -e UTF-8 -d "$DATA_DIRECTORY/8.4/main" 8.4 main - fi; + aptitude -y install postgresql postgresql-contrib postgresql-dev libpq-dev } function postgresql_create_user { - # $1 - the user to create - # $2 - their password - - if [ ! -n "$1" ]; then + # postgresql_create_user(username, password) + if [ -z "$1" ]; then echo "postgresql_create_user() requires username as the first argument" return 1; fi - if [ ! -n "$2" ]; then + if [ -z "$2" ]; then echo "postgresql_create_user() requires a password as the second argument" return 1; fi - echo "CREATE ROLE $1 WITH LOGIN ENCRYPTED PASSWORD '$2';" | sudo -u postgres psql + echo "CREATE ROLE $1 WITH LOGIN ENCRYPTED PASSWORD '$2';" | sudo -i -u postgres psql } function postgresql_create_database { - # $1 - the db name to create - # $2 - the db owner user - - if [ ! -n "$1" ]; then + # postgresql_create_database(dbname, owner) + if [ -z "$1" ]; then echo "postgresql_create_database() requires database name as the first argument" return 1; fi - if [ ! -n "$2" ]; then + if [ -z "$2" ]; then echo "postgresql_create_database() requires an owner username as the second argument" return 1; fi - sudo -u postgres createdb --owner=$2 $1 + sudo -i -u postgres createdb --owner=$2 $1 } From 398bd949549f5f9b75fa723d10392462096546eb Mon Sep 17 00:00:00 2001 From: Filip Wasilewski Date: Tue, 15 May 2012 19:54:11 +0200 Subject: [PATCH 06/35] Updated bash library to latest version. --- 1 - StackScript Bash Library.sh | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/1 - StackScript Bash Library.sh b/1 - StackScript Bash Library.sh index cec2773..9466e20 100644 --- a/1 - StackScript Bash Library.sh +++ b/1 - StackScript Bash Library.sh @@ -35,7 +35,8 @@ ########################################################### function system_update { - aptitude update + apt-get update + apt-get -y install aptitude aptitude -y full-upgrade } @@ -342,9 +343,9 @@ function wordpress_install { do sed -i "0,/put your unique phrase here/s/put your unique phrase here/$(randomString 50)/" wp-config.php done - sed -i 's/putyourdbnamehere/wordpress/' wp-config.php - sed -i 's/usernamehere/wordpress/' wp-config.php - sed -i "s/yourpasswordhere/$WPPASS/" wp-config.php + 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 } @@ -369,7 +370,7 @@ function goodstuff { function restartServices { # restarts services that have a file in /tmp/needs-restart/ - for service in $(ls /tmp/restart-* | cut -d- -f2); do + for service in $(ls /tmp/restart-* | cut -d- -f2-10); do /etc/init.d/$service restart rm -f /tmp/restart-$service done @@ -382,4 +383,4 @@ function randomString { fi echo $( Date: Tue, 15 May 2012 21:33:29 +0200 Subject: [PATCH 07/35] Added zsh shell to installed utils. --- 124 - lib-system.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/124 - lib-system.sh b/124 - lib-system.sh index 3cf9be9..5df702c 100644 --- a/124 - lib-system.sh +++ b/124 - lib-system.sh @@ -7,7 +7,7 @@ # My ref: http://www.linode.com/?r=aadfce9845055011e00f0c6c9a5c01158c452deb function system_install_utils { - aptitude -y install htop bsd-mailx python-software-properties + aptitude -y install htop bsd-mailx python-software-properties zsh } function system_install_build { From 8f7e62ce29de523380c6ed2283f0aecfe40bfca7 Mon Sep 17 00:00:00 2001 From: Filip Wasilewski Date: Tue, 15 May 2012 21:37:03 +0200 Subject: [PATCH 08/35] Removed unnecessary functions. --- 123 - lib-system-ubuntu.sh | 29 +---------------------------- 1 file changed, 1 insertion(+), 28 deletions(-) diff --git a/123 - lib-system-ubuntu.sh b/123 - lib-system-ubuntu.sh index 8d228a3..278d2a7 100644 --- a/123 - lib-system-ubuntu.sh +++ b/123 - lib-system-ubuntu.sh @@ -11,14 +11,6 @@ function lower { echo $1 | tr '[:upper:]' '[:lower:]' } -function system_get_codename { - echo `lsb_release -sc` -} - -function system_get_release { - echo `lsb_release -sr` -} - function system_add_user { # $1 - username # $2 - password @@ -76,25 +68,6 @@ function system_sshd_passwordauthentication { system_sshd_edit_bool "PasswordAuthentication" "$1" } -function system_sshd_pubkeyauthentication { - system_sshd_edit_bool "PubkeyAuthentication" "$1" -} - -function system_sshd_passwordauthentication { - system_sshd_edit_bool "PasswordAuthentication" "$1" -} - -function system_enable_universe { - sed -i 's/^#\(.*deb.*\) universe/\1 universe/' /etc/apt/sources.list - aptitude update -} - -function system_update_locale_en_US_UTF_8 { - # locale-gen en_US.UTF-8 - dpkg-reconfigure locales - update-locale LANG=en_US.UTF-8 -} - function system_update_hostname { # $1 - system hostname if [ ! -n "$1" ]; then @@ -116,7 +89,7 @@ function system_security_ufw_install { function system_security_ufw_configure_basic { # see https://help.ubuntu.com/community/UFW - ufw logging on + ufw logging on ufw default deny From b5d172509fa8f786d076830a331f7240b4caf826 Mon Sep 17 00:00:00 2001 From: Filip Wasilewski Date: Tue, 15 May 2012 21:39:38 +0200 Subject: [PATCH 09/35] Code formatting. --- 123 - lib-system-ubuntu.sh | 34 +++++++++++++++------------------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/123 - lib-system-ubuntu.sh b/123 - lib-system-ubuntu.sh index 278d2a7..9fb888a 100644 --- a/123 - lib-system-ubuntu.sh +++ b/123 - lib-system-ubuntu.sh @@ -12,13 +12,14 @@ function lower { } function system_add_user { - # $1 - username - # $2 - password - # $3 - groups + # system_add_user(username, password, groups, shell=/bin/bash) USERNAME=`lower $1` PASSWORD=$2 SUDO_GROUP=$3 - SHELL="/bin/bash" + SHELL=$4 + if [ -z "$1" ]; then + SHELL="/bin/bash" + fi useradd --create-home --shell "$SHELL" --user-group --groups "$SUDO_GROUP" "$USERNAME" echo "$USERNAME:$PASSWORD" | chpasswd } @@ -36,13 +37,12 @@ function system_add_system_user { } function system_get_user_home { - # $1 - username + # system_get_user_home(username) cat /etc/passwd | grep "^$1:" | cut --delimiter=":" -f6 } function system_user_add_ssh_key { - # $1 - username - # $2 - ssh key + # system_user_add_ssh_key(username, ssh_key) USERNAME=`lower $1` USER_HOME=`system_get_user_home "$USERNAME"` sudo -u "$USERNAME" mkdir "$USER_HOME/.ssh" @@ -52,8 +52,7 @@ function system_user_add_ssh_key { } function system_sshd_edit_bool { - # $1 - param name - # $2 - Yes/No + # system_sshd_edit_bool (param_name, "Yes"|"No") VALUE=`lower $2` if [ "$VALUE" == "yes" ] || [ "$VALUE" == "no" ]; then sed -i "s/^#*\($1\).*/\1 $VALUE/" /etc/ssh/sshd_config @@ -69,22 +68,22 @@ function system_sshd_passwordauthentication { } function system_update_hostname { - # $1 - system hostname - if [ ! -n "$1" ]; then + # system_update_hostname(system hostname) + if [ -z "$1" ]; then echo "system_update_hostname() requires the system hostname as its first argument" return 1; fi echo $1 > /etc/hostname hostname -F /etc/hostname - echo -e "\n127.0.0.1 $1.local $1\n" >> /etc/hosts + echo -e "\n127.0.0.1 $1 $1.local\n" >> /etc/hosts } -function system_security_fail2ban { - aptitude -y install fail2ban +function system_security_logcheck { + aptitude -y install logcheck logcheck-database } -function system_security_ufw_install { - aptitude -y install ufw +function system_security_fail2ban { + aptitude -y install fail2ban } function system_security_ufw_configure_basic { @@ -100,6 +99,3 @@ function system_security_ufw_configure_basic { ufw enable } -function system_security_logcheck { - aptitude -y install logcheck logcheck-database -} From 08b6db208ae2001b06e1bf668b95d5a1a40efe82 Mon Sep 17 00:00:00 2001 From: Filip Wasilewski Date: Tue, 15 May 2012 21:48:47 +0200 Subject: [PATCH 10/35] Create home dir for system user. Make zsh default shell. --- 123 - lib-system-ubuntu.sh | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/123 - lib-system-ubuntu.sh b/123 - lib-system-ubuntu.sh index 9fb888a..9830649 100644 --- a/123 - lib-system-ubuntu.sh +++ b/123 - lib-system-ubuntu.sh @@ -12,28 +12,27 @@ function lower { } function system_add_user { - # system_add_user(username, password, groups, shell=/bin/bash) + # system_add_user(username, password, groups, shell=/bin/zsh) USERNAME=`lower $1` PASSWORD=$2 SUDO_GROUP=$3 SHELL=$4 - if [ -z "$1" ]; then - SHELL="/bin/bash" + if [ -z "$4" ]; then + SHELL="/bin/zsh" fi useradd --create-home --shell "$SHELL" --user-group --groups "$SUDO_GROUP" "$USERNAME" echo "$USERNAME:$PASSWORD" | chpasswd } function system_add_system_user { - # $1 - username - # $2 - home + # system_add_system_user(username, home, shell=/bin/zsh) USERNAME=`lower $1` HOME_DIR=$2 - if [ -z "$HOME_DIR" ]; then - useradd --system --no-create-home --user-group $USERNAME - else - useradd --system --no-create-home --home-dir "$HOME_DIR" --user-group $USERNAME - fi; + SHELL=$3 + if [ -z "$3" ]; then + SHELL="/bin/zsh" + fi + useradd --system --create-home --home-dir "$HOME_DIR" --shell "$SHELL" --user-group $USERNAME } function system_get_user_home { From f412cffa4c02c48381739aa3eb3384a569bbc344 Mon Sep 17 00:00:00 2001 From: Filip Wasilewski Date: Tue, 15 May 2012 21:50:08 +0200 Subject: [PATCH 11/35] Limit ssh connections rate using UFW. --- 123 - lib-system-ubuntu.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/123 - lib-system-ubuntu.sh b/123 - lib-system-ubuntu.sh index 9830649..bc083d3 100644 --- a/123 - lib-system-ubuntu.sh +++ b/123 - lib-system-ubuntu.sh @@ -92,6 +92,8 @@ function system_security_ufw_configure_basic { ufw default deny ufw allow ssh + ufw limit ssh/tcp + ufw allow http ufw allow https From eb52b926800c942bc91be5de2c6ae1a47f9a47fd Mon Sep 17 00:00:00 2001 From: Filip Wasilewski Date: Tue, 15 May 2012 21:50:42 +0200 Subject: [PATCH 12/35] Added restart_services function. --- 123 - lib-system-ubuntu.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/123 - lib-system-ubuntu.sh b/123 - lib-system-ubuntu.sh index bc083d3..cf42dec 100644 --- a/123 - lib-system-ubuntu.sh +++ b/123 - lib-system-ubuntu.sh @@ -100,3 +100,10 @@ function system_security_ufw_configure_basic { ufw enable } +function restart_services { + # restarts upstart services that have a file in /tmp/needs-restart/ + for service_name in $(ls /tmp/restart-* | cut -d- -f2-10); do + service service_name restart + rm -f /tmp/restart-$service_name + done +} From 32f0cb9ac0fc406609f00bdca3c408169bc78fce Mon Sep 17 00:00:00 2001 From: Filip Wasilewski Date: Tue, 15 May 2012 21:56:02 +0200 Subject: [PATCH 13/35] No need to install mod-wsgi from source anymore. --- 122 - lib-apache.sh | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/122 - lib-apache.sh b/122 - lib-apache.sh index d40e770..3b7b76a 100644 --- a/122 - lib-apache.sh +++ b/122 - lib-apache.sh @@ -14,26 +14,6 @@ function apache_mod_wsgi_install { aptitude -y install libapache2-mod-wsgi } -function apache_mod_wsgi_install_from_source { - #$1 - version - - VERSION=$1 - pushd /tmp - wget http://modwsgi.googlecode.com/files/mod_wsgi-$VERSION.tar.gz - tar xvfz mod_wsgi-$VERSION.tar.gz - cd mod_wsgi-$VERSION - ./configure - make - make install - cd .. - rm -rf mod_wsgi-$VERSION - popd - - echo "LoadModule wsgi_module /usr/lib/apache2/modules/mod_wsgi.so" > /etc/apache2/mods-available/wsgi.load - - a2enmod wsgi -} - function apache_cleanup { a2dissite default # disable default vhost } From 8c82ca8dd6358feddd202f7ae5a277047861fee5 Mon Sep 17 00:00:00 2001 From: Filip Wasilewski Date: Wed, 16 May 2012 01:43:17 +0200 Subject: [PATCH 14/35] Corrected variable. --- 123 - lib-system-ubuntu.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/123 - lib-system-ubuntu.sh b/123 - lib-system-ubuntu.sh index cf42dec..558cfec 100644 --- a/123 - lib-system-ubuntu.sh +++ b/123 - lib-system-ubuntu.sh @@ -103,7 +103,7 @@ function system_security_ufw_configure_basic { function restart_services { # restarts upstart services that have a file in /tmp/needs-restart/ for service_name in $(ls /tmp/restart-* | cut -d- -f2-10); do - service service_name restart + service $service_name restart rm -f /tmp/restart-$service_name done } From cfe615da5d02c58aca1343aa69676122a399bbea Mon Sep 17 00:00:00 2001 From: Filip Wasilewski Date: Wed, 16 May 2012 01:47:16 +0200 Subject: [PATCH 15/35] Catch and ignore return code related to hg "nothing changed". --- 124 - lib-system.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/124 - lib-system.sh b/124 - lib-system.sh index 5df702c..496cc3d 100644 --- a/124 - lib-system.sh +++ b/124 - lib-system.sh @@ -39,5 +39,5 @@ function system_record_etc_dir_changes { else MESSAGE="$1" fi hg addremove /etc - hg commit -u root -m "$MESSAGE" /etc + hg commit -u root -m "$MESSAGE" /etc || echo > /dev/null # catch "nothing changed" return code } From 404e587cf9948815e419a30ec95f78518f7a7251 Mon Sep 17 00:00:00 2001 From: Filip Wasilewski Date: Wed, 16 May 2012 01:50:48 +0200 Subject: [PATCH 16/35] Updated setup and configuration for Python 2.7 and Django 1.4. --- 127 - lib-django.sh | 105 +++++++++++++++++--------------------------- 1 file changed, 40 insertions(+), 65 deletions(-) diff --git a/127 - lib-django.sh b/127 - lib-django.sh index f2cd71e..1737f72 100644 --- a/127 - lib-django.sh +++ b/127 - lib-django.sh @@ -6,27 +6,32 @@ # # My ref: http://www.linode.com/?r=aadfce9845055011e00f0c6c9a5c01158c452deb + +function django_get_user_or_default { + # django_get_user_or_default([user]) + if [ -z "$1" ]; + then USER="www-data" + else USER="$1" + fi + echo "$USER" +} + function django_get_project_path { + # django_get_project_path(project_name) PROJECT_NAME="$1" echo "/srv/$PROJECT_NAME" } function django_change_project_owner { + # django_change_project_owner(project_path, user) PROJECT_PATH="$1" USER="$2" - GROUP="$3" - if [ -z "$USER" ]; then - USER="www-data" - fi - if [ -z "$GROUP" ]; then - GROUP="$USER" - fi + GROUP="$USER" chown -R "$USER:$GROUP" "$PROJECT_PATH" } - function django_create_project { - # $1 - name of the project to create create + # django_create_project(project_name) PROJECT_NAME="$1" if [ -z "$PROJECT_NAME" ]; then @@ -35,49 +40,25 @@ function django_create_project { fi PROJECT_PATH=`django_get_project_path "$PROJECT_NAME"` - mkdir -p "$PROJECT_PATH/app" "$PROJECT_PATH/app/conf/apache" + mkdir -p "$PROJECT_PATH/app/conf/apache" mkdir -p "$PROJECT_PATH/logs" "$PROJECT_PATH/run/eggs" - virtualenv --no-site-packages "$PROJECT_PATH/venv" - pip -E "$PROJECT_PATH/venv" install django + virtualenv "$PROJECT_PATH/venv" + $PROJECT_PATH/venv/bin/pip install django pushd "$PROJECT_PATH/app" - "$PROJECT_PATH/venv/bin/python" "$PROJECT_PATH/venv/bin/django-admin.py" startproject webapp + "$PROJECT_PATH/venv/bin/python" "$PROJECT_PATH/venv/bin/django-admin.py" startproject webapp . popd - mkdir -p "$PROJECT_PATH/app/webapp/site_media" - - cat > "$PROJECT_PATH/app/conf/apache/django.wsgi" << EOF -import os -import sys - -root_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', '..')) -sys.path.insert(0, os.path.abspath(os.path.join(root_path, 'venv/lib/python2.6/site-packages/'))) -sys.path.insert(0, os.path.abspath(os.path.join(root_path, 'app'))) -sys.path.insert(0, os.path.abspath(os.path.join(root_path, 'app', 'webapp'))) - -os.environ['DJANGO_SETTINGS_MODULE'] = 'settings' - -import django.core.handlers.wsgi -application = django.core.handlers.wsgi.WSGIHandler() -EOF + mkdir -p "$PROJECT_PATH/app/webapp/static" } - function django_install_db_driver { - # $1 - project root - # $2 - driver package - pip -E "$1/venv" install "$2" + # django_install_db_driver(project_path, driver_package) + $1/venv/bin/pip install django "$2" } - function django_configure_db_settings { - # $1 - project root - # $2 - engine - # $3 - name - # $4 - user - # $5 - password - # $6 - host (optional) - # $7 - port (optional) + # django_configure_db_settings(project_path, engine, name, user, password, [host, [port]]) SETTINGS="$1/app/webapp/settings.py" sed -i -e "s/'ENGINE': 'django.db.backends.'/'ENGINE': 'django.db.backends.$2'/" "$SETTINGS" @@ -92,18 +73,13 @@ function django_configure_db_settings { fi } - function django_configure_apache_virtualhost { - - # $1 - required - the hostname of the apache virtualhost to create - # $2 - required - path to the django project - # $3 - wsgi process user - # $4 - wsgi process group + # django_configure_apache_virtualhost(hostname, project_path, wsgi_user) VHOST_HOSTNAME="$1" PROJECT_PATH="$2" USER="$3" - GROUP="$4" + GROUP="$USER" if [ -z "$VHOST_HOSTNAME" ]; then echo "django_configure_apache_virtualhost() requires the hostname as the first argument" @@ -115,32 +91,30 @@ function django_configure_apache_virtualhost { return 1; fi - if [ -z "$USER" ]; then - USER="www-data" - fi - if [ -z "$GROUP" ]; then - GROUP="$USER" - fi + APACHE_CONF="200-$VHOST_HOSTNAME" + APACHE_CONF_PATH="$PROJECT_PATH/app/conf/apache/$APACHE_CONF" - cat > "/etc/apache2/sites-available/$VHOST_HOSTNAME" << EOF + cat > "$APACHE_CONF_PATH" << EOF ServerAdmin root@$VHOST_HOSTNAME ServerName $VHOST_HOSTNAME + ServerSignature Off - Alias /site_media/ $PROJECT_PATH/app/webapp/site_media/ - Alias /media/ $PROJECT_PATH/venv/lib/python2.6/site-packages/django/contrib/admin/media/ - Alias /robots.txt $PROJECT_PATH/app/webapp/site_media/robots.txt - Alias /favicon.ico $PROJECT_PATH/app/webapp/site_media/favicon.ico + Alias /static/ $PROJECT_PATH/app/webapp/static/ + Alias /robots.txt $PROJECT_PATH/app/webapp/static/robots.txt + Alias /favicon.ico $PROJECT_PATH/app/webapp/static/favicon.ico - CustomLog "|/usr/sbin/rotatelogs $PROJECT_PATH/logs/access.log.%Y%m%d-%H%M%S 5M" combined - ErrorLog "|/usr/sbin/rotatelogs $PROJECT_PATH/logs/error.log.%Y%m%d-%H%M%S 5M" + CustomLog "|/usr/sbin/rotatelogs $PROJECT_PATH/logs/access.log.%Y%m%d-%H%M 5M" combined + ErrorLog "|/usr/sbin/rotatelogs $PROJECT_PATH/logs/error.log.%Y%m%d-%H%M 5M" LogLevel warn - WSGIDaemonProcess $VHOST_HOSTNAME user=$USER group=$GROUP processes=1 threads=15 maximum-requests=10000 python-path=$PROJECT_PATH/venv/lib/python2.6/site-packages python-eggs=$PROJECT_PATH/run/eggs + WSGIScriptAlias / $PROJECT_PATH/app/webapp/wsgi.py + + WSGIDaemonProcess $VHOST_HOSTNAME user=$USER group=$GROUP processes=2 threads=10 maximum-requests=10000 display-name=%{GROUP} python-path=$PROJECT_PATH/app:$PROJECT_PATH/venv/lib/python2.7/site-packages python-eggs=$PROJECT_PATH/run/eggs WSGIProcessGroup $VHOST_HOSTNAME - WSGIScriptAlias / $PROJECT_PATH/app/conf/apache/django.wsgi + WSGIScriptAlias / $PROJECT_PATH/app/webapp/wsgi.py - + Order deny,allow Allow from all Options -Indexes FollowSymLinks @@ -154,5 +128,6 @@ function django_configure_apache_virtualhost { EOF - a2ensite "$VHOST_HOSTNAME" + ln -t /etc/apache2/sites-available/ "$APACHE_CONF_PATH" + a2ensite "$APACHE_CONF" } From 1197358373a9dc930b58b7ad158004bce30a715e Mon Sep 17 00:00:00 2001 From: Filip Wasilewski Date: Wed, 16 May 2012 14:18:17 +0200 Subject: [PATCH 17/35] Keep bash as the default shell. --- 123 - lib-system-ubuntu.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/123 - lib-system-ubuntu.sh b/123 - lib-system-ubuntu.sh index 558cfec..a69baea 100644 --- a/123 - lib-system-ubuntu.sh +++ b/123 - lib-system-ubuntu.sh @@ -12,25 +12,25 @@ function lower { } function system_add_user { - # system_add_user(username, password, groups, shell=/bin/zsh) + # system_add_user(username, password, groups, shell=/bin/bash) USERNAME=`lower $1` PASSWORD=$2 SUDO_GROUP=$3 SHELL=$4 if [ -z "$4" ]; then - SHELL="/bin/zsh" + SHELL="/bin/bash" fi useradd --create-home --shell "$SHELL" --user-group --groups "$SUDO_GROUP" "$USERNAME" echo "$USERNAME:$PASSWORD" | chpasswd } function system_add_system_user { - # system_add_system_user(username, home, shell=/bin/zsh) + # system_add_system_user(username, home, shell=/bin/bash) USERNAME=`lower $1` HOME_DIR=$2 SHELL=$3 if [ -z "$3" ]; then - SHELL="/bin/zsh" + SHELL="/bin/bash" fi useradd --system --create-home --home-dir "$HOME_DIR" --shell "$SHELL" --user-group $USERNAME } From db8c562965370ac043dd38c9c5663c7bb6fe117f Mon Sep 17 00:00:00 2001 From: Filip Wasilewski Date: Wed, 16 May 2012 14:19:18 +0200 Subject: [PATCH 18/35] Added system_lock_user function. --- 123 - lib-system-ubuntu.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/123 - lib-system-ubuntu.sh b/123 - lib-system-ubuntu.sh index a69baea..ac314bb 100644 --- a/123 - lib-system-ubuntu.sh +++ b/123 - lib-system-ubuntu.sh @@ -35,6 +35,11 @@ function system_add_system_user { useradd --system --create-home --home-dir "$HOME_DIR" --shell "$SHELL" --user-group $USERNAME } +function system_lock_user { + # system_lock_user(username) + passwd -l "$1" +} + function system_get_user_home { # system_get_user_home(username) cat /etc/passwd | grep "^$1:" | cut --delimiter=":" -f6 From 0bbe5802976b5dcf90a0314d7061a64caff51a3b Mon Sep 17 00:00:00 2001 From: Filip Wasilewski Date: Wed, 16 May 2012 14:20:16 +0200 Subject: [PATCH 19/35] Specified ufw rules. --- 123 - lib-system-ubuntu.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/123 - lib-system-ubuntu.sh b/123 - lib-system-ubuntu.sh index ac314bb..a9dbbbf 100644 --- a/123 - lib-system-ubuntu.sh +++ b/123 - lib-system-ubuntu.sh @@ -96,11 +96,11 @@ function system_security_ufw_configure_basic { ufw default deny - ufw allow ssh + ufw allow ssh/tcp ufw limit ssh/tcp - ufw allow http - ufw allow https + ufw allow http/tcp + ufw allow https/tcp ufw enable } From d9574f8989c3c02d517ca59615a519b9507a60d9 Mon Sep 17 00:00:00 2001 From: Filip Wasilewski Date: Wed, 16 May 2012 14:22:31 +0200 Subject: [PATCH 20/35] Added compatibility functions for scripts depending on this library. --- 123 - lib-system-ubuntu.sh | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/123 - lib-system-ubuntu.sh b/123 - lib-system-ubuntu.sh index a9dbbbf..54717a3 100644 --- a/123 - lib-system-ubuntu.sh +++ b/123 - lib-system-ubuntu.sh @@ -112,3 +112,32 @@ function restart_services { rm -f /tmp/restart-$service_name done } + +# Maintain for compatibility with scripts using this library for Ubuntu 10.04 + +function system_get_codename { + echo `lsb_release -sc` +} + +function system_get_release { + echo `lsb_release -sr` +} + +function system_sshd_pubkeyauthentication { + system_sshd_edit_bool "PubkeyAuthentication" "$1" +} + +function system_update_locale_en_US_UTF_8 { + # locale-gen en_US.UTF-8 + dpkg-reconfigure locales + update-locale LANG=en_US.UTF-8 +} + +function system_enable_universe { + sed -i 's/^#\(.*deb.*\) universe/\1 universe/' /etc/apt/sources.list + aptitude update +} + +function system_security_ufw_install { + aptitude -y install ufw +} From 9e21cca736ce66b41be3c418e3b44f080314945f Mon Sep 17 00:00:00 2001 From: Filip Wasilewski Date: Wed, 16 May 2012 14:30:13 +0200 Subject: [PATCH 21/35] Added iotop to installed utils. --- 124 - lib-system.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/124 - lib-system.sh b/124 - lib-system.sh index 496cc3d..f8a362c 100644 --- a/124 - lib-system.sh +++ b/124 - lib-system.sh @@ -7,7 +7,7 @@ # My ref: http://www.linode.com/?r=aadfce9845055011e00f0c6c9a5c01158c452deb function system_install_utils { - aptitude -y install htop bsd-mailx python-software-properties zsh + aptitude -y install htop iotop bsd-mailx python-software-properties zsh } function system_install_build { From 728627344bf3b9e8eb6c2902a1f7cef56bda55d6 Mon Sep 17 00:00:00 2001 From: Filip Wasilewski Date: Wed, 16 May 2012 14:32:32 +0200 Subject: [PATCH 22/35] Small fixes. --- prepare.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/prepare.py b/prepare.py index 594b4fe..9cd8026 100644 --- a/prepare.py +++ b/prepare.py @@ -99,7 +99,7 @@ def expand_script(content, mode="source"): def add_variables(content, args): # Add script variables - variables = "\n".join( + variables = "%s\n" % "\n".join( '%s="%s"' % (k,v) for k,v in sorted(args.__dict__.items()) if k.isupper() ) lines = iter(content.splitlines()) @@ -109,7 +109,8 @@ def add_variables(content, args): content.append(line) else: content.append(variables) - content.extend(list(lines)) + content.append(line) + content.extend(lines) break return "\n".join(content) @@ -130,6 +131,6 @@ def main(stack_script): if __name__ == "__main__": - if len(sys.argv) < 2 or os.path.exists(sys.argv[1]): + if len(sys.argv) < 2 or not os.path.exists(sys.argv[1]): print "First argument must be a valid script name" main(sys.argv[1]) From 554a84de082f0c2ea18410fa4dc196bf829d2ab8 Mon Sep 17 00:00:00 2001 From: Filip Wasilewski Date: Wed, 16 May 2012 16:36:48 +0200 Subject: [PATCH 23/35] Added system_configure_private_network function. --- 123 - lib-system-ubuntu.sh | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/123 - lib-system-ubuntu.sh b/123 - lib-system-ubuntu.sh index 54717a3..b22fcef 100644 --- a/123 - lib-system-ubuntu.sh +++ b/123 - lib-system-ubuntu.sh @@ -105,6 +105,18 @@ function system_security_ufw_configure_basic { ufw enable } +function system_configure_private_network { + # system_configure_private_network(private_ip) + PRIVATE_IP=$1 + NETMASK="255.255.128.0" + cat >>/etc/network/interfaces < Date: Wed, 16 May 2012 16:51:31 +0200 Subject: [PATCH 24/35] Restart networking using init.d. --- 123 - lib-system-ubuntu.sh | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/123 - lib-system-ubuntu.sh b/123 - lib-system-ubuntu.sh index b22fcef..bdcd5c8 100644 --- a/123 - lib-system-ubuntu.sh +++ b/123 - lib-system-ubuntu.sh @@ -115,6 +115,7 @@ iface eth0:0 inet static address $PRIVATE_IP netmask $NETMASK EOF + touch /tmp/restart_initd-networking } function restart_services { @@ -125,6 +126,14 @@ function restart_services { done } +function restart_initd_services { + # restarts upstart services that have a file in /tmp/needs-restart/ + for service_name in $(ls /tmp/restart_initd-* | cut -d- -f2-10); do + /etc/init.d/$service_name restart + rm -f /tmp/restart_initd-$service_name + done +} + # Maintain for compatibility with scripts using this library for Ubuntu 10.04 function system_get_codename { From 0a44852ded3e9d5ea1ae4fa33eaa42eaca166aec Mon Sep 17 00:00:00 2001 From: Filip Wasilewski Date: Wed, 16 May 2012 23:27:16 +0200 Subject: [PATCH 25/35] Updated for Ubuntu 12.04. --- ...tgreSQL, MySQL, MongoDB, Apache, Django.sh | 174 +++++++++++------- 1 file changed, 104 insertions(+), 70 deletions(-) diff --git a/131 - Stack - Security, PostgreSQL, MySQL, MongoDB, Apache, Django.sh b/131 - Stack - Security, PostgreSQL, MySQL, MongoDB, Apache, Django.sh index 01738e6..b6508b3 100644 --- a/131 - Stack - Security, PostgreSQL, MySQL, MongoDB, Apache, Django.sh +++ b/131 - Stack - Security, PostgreSQL, MySQL, MongoDB, Apache, Django.sh @@ -6,36 +6,44 @@ # # My ref: http://www.linode.com/?r=aadfce9845055011e00f0c6c9a5c01158c452deb -# +# + +# # -# +# +# +# + +# + +# -# -# +# +# +# +# -# +# +# +# +# +# -# +# -# -# -# -# +# -# -# -# -# -# +# +# +# +# -# +# -# -# -# -# -# +set -e +set -u +#set -x USER_GROUPS=sudo @@ -43,24 +51,18 @@ exec &> /root/stackscript.log source # StackScript Bash Library system_update -goodstuff - -source # lib-system-ubuntu -system_enable_universe source # lib-system system_install_mercurial -system_start_etc_dir_versioning +system_start_etc_dir_versioning #start recording changes of /etc config files -# source # lib-system-ubuntu # Configure system -system_update_locale_en_US_UTF_8 -system_record_etc_dir_changes "Updated locale" # SS124 +source # lib-system-ubuntu system_update_hostname "$SYS_HOSTNAME" system_record_etc_dir_changes "Updated hostname" # SS124 # Create user account -system_add_user "$USER_NAME" "$USER_PASSWORD" "$USER_GROUPS" +system_add_user "$USER_NAME" "$USER_PASSWORD" "$USER_GROUPS" "$USER_SHELL" if [ "$USER_SSHKEY" ]; then system_user_add_ssh_key "$USER_NAME" "$USER_SSHKEY" fi @@ -69,33 +71,36 @@ system_record_etc_dir_changes "Added unprivileged user account" # SS124 # Configure sshd system_sshd_permitrootlogin "$SSHD_PERMITROOTLOGIN" system_sshd_passwordauthentication "$SSHD_PASSWORDAUTH" -system_sshd_pubkeyauthentication "yes" touch /tmp/restart-ssh system_record_etc_dir_changes "Configured sshd" # SS124 -# Setup firewall -system_security_ufw_install -system_record_etc_dir_changes "Installed UFW" # SS124 -system_security_ufw_configure_basic -system_record_etc_dir_changes "Configured UFW" # SS124 +# Lock user account if not used for login +if [ "SSHD_PERMITROOTLOGIN" == "No" ]; then + system_lock_user "root" + system_record_etc_dir_changes "Locked root account" # SS124 +fi -# Setup fail2ban -system_security_fail2ban -system_record_etc_dir_changes "Installed fail2ban" # SS124 +# Install Postfix +postfix_install_loopback_only # SS1 +system_record_etc_dir_changes "Installed postfix loopback" # SS124 # Setup logcheck system_security_logcheck system_record_etc_dir_changes "Installed logcheck" # SS124 -# Install postfix -postfix_install_loopback_only # SS1 -system_record_etc_dir_changes "Installed postfix loopback" # SS124 +# Setup fail2ban +system_security_fail2ban +system_record_etc_dir_changes "Installed fail2ban" # SS124 + +# Setup firewall +system_security_ufw_configure_basic +system_record_etc_dir_changes "Configured UFW" # SS124 source # lib-python python_install system_record_etc_dir_changes "Installed python" # SS124 -# source # lib-system +# lib-system - SS124 system_install_utils system_install_build system_install_subversion @@ -103,20 +108,20 @@ system_install_git system_record_etc_dir_changes "Installed common utils" # Install and configure apache and mod_wsgi -source # lib-apache -apache_worker_install -system_record_etc_dir_changes "Installed apache" # SS124 -#apache_mod_wsgi_install -apache_mod_wsgi_install_from_source "3.3" # install a more recent mod-wsgi version -system_record_etc_dir_changes "Installed mod-wsgi" # SS124 -apache_cleanup -system_record_etc_dir_changes "Cleaned up apache config" # SS124 +if [ "$SETUP_APACHE" == "Yes" ]; then + source # lib-apache + apache_worker_install + system_record_etc_dir_changes "Installed apache" # SS124 + apache_mod_wsgi_install + system_record_etc_dir_changes "Installed mod-wsgi" # SS124 + apache_cleanup + system_record_etc_dir_changes "Cleaned up apache config" # SS124 +fi # Install PostgreSQL and setup database if [ "$SETUP_POSTGRESQL" == "Yes" ]; then source # lib-postgresql postgresql_install - postgresql_recreate_cluster "$BASE_DATA_DIRECTORY" system_record_etc_dir_changes "Installed PostgreSQL" postgresql_create_user "$POSTGRESQL_USER" "$POSTGRESQL_PASSWORD" postgresql_create_database "$POSTGRESQL_DATABASE" "$POSTGRESQL_USER" @@ -125,63 +130,92 @@ fi # Install MySQL and setup database if [ "$SETUP_MYSQL" == "Yes" ]; then + set +u # ignore undefined variables in Linode's SS1 mysql_install "$MYSQL_DATABASE_PASSWORD" && mysql_tune 30 mysql_create_database "$MYSQL_DATABASE_PASSWORD" "$MYSQL_DATABASE" mysql_create_user "$MYSQL_DATABASE_PASSWORD" "$MYSQL_USER" "$MYSQL_PASSWORD" mysql_grant_user "$MYSQL_DATABASE_PASSWORD" "$MYSQL_USER" "$MYSQL_DATABASE" + set -u system_record_etc_dir_changes "Configured MySQL" fi # Install MongoDB if [ "$SETUP_MONGODB" == "Yes" ]; then source # lib-mongodb - system_configure_mongodb_repository - system_record_etc_dir_changes "Added MongoDB repository to sources.list" - mongodb_install "$BASE_DATA_DIRECTORY" + mongodb_install system_record_etc_dir_changes "Installed MongoDB" fi # Setup and configure sample django project -if [ ! -n "$DJANGO_DOMAIN" ]; then - DJANGO_DOMAIN=$(get_rdns_primary_ip) -fi +DJANGO_PROJECT_PATH="" +RDNS=$(get_rdns_primary_ip) + if [ "$SETUP_DJANGO_PROJECT" == "Yes" ]; then source # lib-django + if [ -z "$DJANGO_DOMAIN" ]; then + DJANGO_DOMAIN=$RDNS + fi + + DJANGO_USER=$(django_get_user_or_default "$DJANGO_USER") DJANGO_PROJECT_PATH=`django_get_project_path "$DJANGO_PROJECT_NAME"` - django_create_project "$DJANGO_PROJECT_NAME" - system_add_system_user "$DJANGO_USER" "$DJANGO_PROJECT_PATH" - chsh -s /bin/bash "$DJANGO_USER" + system_add_system_user "$DJANGO_USER" "$DJANGO_PROJECT_PATH" "$USER_SHELL" + django_create_project "$DJANGO_PROJECT_NAME" - django_configure_apache_virtualhost "$DJANGO_DOMAIN" "$DJANGO_PROJECT_PATH" "$DJANGO_USER" + if [ "$SETUP_APACHE" == "Yes" ]; then + django_configure_apache_virtualhost "$DJANGO_DOMAIN" "$DJANGO_PROJECT_PATH" "$DJANGO_USER" + fi if [ "$SETUP_POSTGRESQL" == "Yes" ]; then django_install_db_driver "$DJANGO_PROJECT_PATH" "psycopg2" - django_configure_db_settings "$DJANGO_PROJECT_PATH" "postgresql_psycopg2" "$POSTGRESQL_DATABASE" "$POSTGRESQL_USER" "$POSTGRESQL_PASSWORD" "127.0.0.1" + django_configure_db_settings "$DJANGO_PROJECT_PATH" "postgresql_psycopg2" "$POSTGRESQL_DATABASE" "$POSTGRESQL_USER" "$POSTGRESQL_PASSWORD" "127.0.0.1" "" fi if [ "$SETUP_MYSQL" == "Yes" ]; then django_install_db_driver "$DJANGO_PROJECT_PATH" "MySQL-python" fi django_change_project_owner "$DJANGO_PROJECT_PATH" "$DJANGO_USER" system_record_etc_dir_changes "Configured django project '$DJANGO_PROJECT_NAME'" - touch /tmp/restart-apache2 + if [ "$SETUP_APACHE" == "Yes" ]; then + touch /tmp/restart-apache2 + fi fi; -restartServices +if [ -n "$SYS_PRIVATE_IP" ]; then + system_configure_private_network "$SYS_PRIVATE_IP" + system_record_etc_dir_changes "Configured private network" +fi +restart_services +restart_initd_services # Send info message -if [ -n "$NOTIFY_EMAIL" ]; then - mail -s "Your Linode VPS is configured" "$NOTIFY_EMAIL" < ~/setup_message <> ~/setup_message <> ~/setup_message < Date: Wed, 16 May 2012 23:29:57 +0200 Subject: [PATCH 26/35] Monit setup and configuration. --- 129 - monit.sh | 223 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 223 insertions(+) create mode 100644 129 - monit.sh diff --git a/129 - monit.sh b/129 - monit.sh new file mode 100644 index 0000000..1fcb74f --- /dev/null +++ b/129 - monit.sh @@ -0,0 +1,223 @@ +#!/bin/bash +# +# Monit system monitoring. See also http://mmonit.com/wiki/Monit/ConfigurationExamples +# +# Copyright (c) 2012 Filip Wasilewski . +# +# My ref: http://www.linode.com/?r=aadfce9845055011e00f0c6c9a5c01158c452deb + + +function monit_install { + aptitude -y install monit +} + +function monit_configure_email { + # system_monit_configure_email(email) +cat </etc/monit/conf.d/email-interface + set mailserver localhost + set alert $1 +EOT +} + +function monit_configure_web { + # system_monit_configure_web(domain) +cat </etc/monit/conf.d/web-interface + set httpd port 2812 and + use address $1 + allow $(randomString 10):$(randomString 30) + allow @sudo readonly +EOT +ufw allow 2812/tcp +} + +function monit_def_system { + # monit_def_system(hostname) +cat </etc/monit/conf.d/system.cfg + check system $1 + if loadavg (1min) > 10 then alert + if loadavg (5min) > 7 then alert + if memory usage > 85% then alert + if swap usage > 25% then alert + if cpu usage (user) > 90% then alert + if cpu usage (system) > 60% then alert + if cpu usage (wait) > 50% then alert + group system +EOT +} + +function monit_def_rootfs { +cat </etc/monit/conf.d/rootfs.cfg + check filesystem rootfs with path / + if space usage > 80% for 5 times within 15 cycles then alert + if inode usage > 85% then alert + group system +EOT +} + +function monit_def_cron { +cat </etc/monit/conf.d/cron.cfg + check process cron with pidfile /var/run/crond.pid + start program = "/sbin/start cron" + stop program = "/sbin/stop cron" + if 5 restarts within 5 cycles then timeout + depends on cron_rc + group system + + check file cron_rc with path /etc/init.d/cron + if failed checksum then unmonitor + if failed permission 755 then unmonitor + if failed uid root then unmonitor + if failed gid root then unmonitor + group system +EOT +} + + +function monit_def_ping_google { +cat </etc/monit/conf.d/ping_google.cfg + check host google-test with address google.com + if failed port 80 proto http then alert + group server +EOT +} + +function monit_def_postfix { +cat </etc/monit/conf.d/postfix.cfg + check process postfix with pidfile /var/spool/postfix/pid/master.pid + start program = "/etc/init.d/postfix start" + stop program = "/etc/init.d/postfix stop" + if cpu > 60% for 2 cycles then alert + if cpu > 80% for 5 cycles then restart + if totalmem > 200.0 MB for 5 cycles then restart + if children > 250 then restart + if loadavg(5min) greater than 10 for 8 cycles then stop + if failed host localhost port 25 protocol smtp with timeout 15 seconds then alert + if failed host localhost port 25 protocol smtp for 3 cycles then restart + if 3 restarts within 5 cycles then timeout + group mail + + check file postfix_rc with path /etc/init.d/postfix + if failed checksum then unmonitor + if failed permission 755 then unmonitor + if failed uid root then unmonitor + if failed gid root then unmonitor + group mail +EOT +} + + +function monit_def_postgresql { +cat </etc/monit/conf.d/postgresql.cfg + check process postgres with pidfile /var/run/postgresql/9.1-main.pid + start program = "/etc/init.d/postgresql start" + stop program = "/etc/init.d/postgresql stop" + if failed unixsocket /var/run/postgresql/.s.PGSQL.5432 protocol pgsql then restart + if failed host localhost port 5432 protocol pgsql then restart + if 5 restarts within 5 cycles then timeout + depends on postgresql_bin + depends on postgresql_rc + group database + + check file postgresql_bin with path /usr/lib/postgresql/9.1/bin/postgres + if failed checksum then unmonitor + if failed permission 755 then unmonitor + if failed uid root then unmonitor + if failed gid root then unmonitor + group database + + check file postgresql_rc with path /etc/init.d/postgresql + if failed checksum then unmonitor + if failed permission 755 then unmonitor + if failed uid root then unmonitor + if failed gid root then unmonitor + group database + + check file postgresql_log with path /var/log/postgresql/postgresql-9.1-main.log + if size > 100 MB then alert + group database +EOT +} + +function monit_def_mysql { +cat < /etc/monit/conf.d/mysql.cfg + check process mysqld with pidfile /var/run/mysqld/mysqld.pid + start program = "/sbin/start mysql" with timeout 20 seconds + stop program = "/sbin/stop mysql" + if failed host localhost port 3306 protocol mysql then restart + if failed unixsocket /var/run/mysqld/mysqld.sock protocol mysql then restart + if 5 restarts within 5 cycles then timeout + depends on mysql_bin + depends on mysql_rc + group database + + check file mysql_bin with path /usr/sbin/mysqld + if failed checksum then unmonitor + if failed permission 755 then unmonitor + if failed uid root then unmonitor + if failed gid root then unmonitor + group database + + check file mysql_rc with path /etc/init.d/mysql + if failed checksum then unmonitor + if failed permission 755 then unmonitor + if failed uid root then unmonitor + if failed gid root then unmonitor + group database +EOT +} + +function monit_def_mongodb { +cat </etc/monit/conf.d/mongodb.cfg + check process mongodb with pidfile /var/lib/mongodb/mongod.lock + start program = "/sbin/start mongodb" + stop program = "/sbin/stop mongodb" + if failed host localhost port 28017 protocol http + and request "/" with timeout 10 seconds then restart + if 5 restarts within 5 cycles then timeout + group database +EOT +} + +function monit_def_memcached { +cat </etc/monit/conf.d/memcached.cfg + check process memcached with pidfile /var/run/memcached.pid + start program = "/etc/init.d/memcached start" + stop program = "/etc/init.d/memcached stop" + if 5 restarts within 5 cycles then timeout + group database +EOT +} + +function monit_def_apache { +cat </etc/monit/conf.d/apache2.cfg + check process apache with pidfile /var/run/apache2.pid + start program = "/etc/init.d/apache2 start" with timeout 30 seconds + stop program = "/etc/init.d/apache2 stop" + if cpu > 60% for 2 cycles then alert + if cpu > 80% for 5 cycles then alert + if totalmem > 200.0 MB for 5 cycles then alert + if children > 250 then alert + if loadavg(5min) greater than 10 for 8 cycles then stop + if failed host localhost port 80 protocol HTTP request / within 5 cycles then restart + if failed host localhost port 80 protocol apache-status + dnslimit > 25% or loglimit > 80% or waitlimit < 20% then alert + if 5 restarts within 5 cycles then timeout + depends on apache_bin + depends on apache_rc + group www + + check file apache_bin with path /usr/sbin/apache2 + if failed checksum then unmonitor + if failed permission 755 then unmonitor + if failed uid root then unmonitor + if failed gid root then unmonitor + group www + + check file apache_rc with path /etc/init.d/apache2 + if failed checksum then unmonitor + if failed permission 755 then unmonitor + if failed uid root then unmonitor + if failed gid root then unmonitor + group www +EOT +} From 75cdbe341a25040b3b962b2bd7bd46738f6e85cc Mon Sep 17 00:00:00 2001 From: Filip Wasilewski Date: Wed, 16 May 2012 23:30:27 +0200 Subject: [PATCH 27/35] Don't log monit requests. --- 127 - lib-django.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/127 - lib-django.sh b/127 - lib-django.sh index 1737f72..3e3e2ce 100644 --- a/127 - lib-django.sh +++ b/127 - lib-django.sh @@ -104,7 +104,8 @@ function django_configure_apache_virtualhost { Alias /robots.txt $PROJECT_PATH/app/webapp/static/robots.txt Alias /favicon.ico $PROJECT_PATH/app/webapp/static/favicon.ico - CustomLog "|/usr/sbin/rotatelogs $PROJECT_PATH/logs/access.log.%Y%m%d-%H%M 5M" combined + SetEnvIf User_Agent "monit/*" dontlog + CustomLog "|/usr/sbin/rotatelogs $PROJECT_PATH/logs/access.log.%Y%m%d-%H%M 5M" combined env=!dontlog ErrorLog "|/usr/sbin/rotatelogs $PROJECT_PATH/logs/error.log.%Y%m%d-%H%M 5M" LogLevel warn From be0b9089ef40f4bac8284c29984ada3ab55c67e8 Mon Sep 17 00:00:00 2001 From: Filip Wasilewski Date: Thu, 17 May 2012 01:18:59 +0200 Subject: [PATCH 28/35] Updated monit rules. --- 129 - monit.sh | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/129 - monit.sh b/129 - monit.sh index 1fcb74f..abd8ef9 100644 --- a/129 - monit.sh +++ b/129 - monit.sh @@ -26,6 +26,7 @@ cat </etc/monit/conf.d/web-interface use address $1 allow $(randomString 10):$(randomString 30) allow @sudo readonly + signature disable EOT ufw allow 2812/tcp } @@ -72,10 +73,19 @@ cat </etc/monit/conf.d/cron.cfg EOT } +function monit_def_sshd { +cat </etc/monit/conf.d/sshd.cfg + check process sshd with pidfile /var/run/sshd.pid + start program "/etc/init.d/ssh start" + stop program "/etc/init.d/ssh stop" + # if failed port 22 protocol ssh then restart + # if 3 restarts within 3 cycles then timeout +EOT +} function monit_def_ping_google { cat </etc/monit/conf.d/ping_google.cfg - check host google-test with address google.com + check host google-ping with address google.com if failed port 80 proto http then alert group server EOT @@ -198,9 +208,9 @@ cat </etc/monit/conf.d/apache2.cfg if totalmem > 200.0 MB for 5 cycles then alert if children > 250 then alert if loadavg(5min) greater than 10 for 8 cycles then stop - if failed host localhost port 80 protocol HTTP request / within 5 cycles then restart + if failed host localhost port 80 protocol HTTP request / within 2 cycles then restart if failed host localhost port 80 protocol apache-status - dnslimit > 25% or loglimit > 80% or waitlimit < 20% then alert + dnslimit > 25% or loglimit > 80% or waitlimit < 20% retry 2 within 2 cycles then alert if 5 restarts within 5 cycles then timeout depends on apache_bin depends on apache_rc From 7bc75c5a533eb437f8bf44082af32b7f6f8524de Mon Sep 17 00:00:00 2001 From: Filip Wasilewski Date: Thu, 17 May 2012 01:21:55 +0200 Subject: [PATCH 29/35] Added monit setup to main script. --- ...tgreSQL, MySQL, MongoDB, Apache, Django.sh | 33 +++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/131 - Stack - Security, PostgreSQL, MySQL, MongoDB, Apache, Django.sh b/131 - Stack - Security, PostgreSQL, MySQL, MongoDB, Apache, Django.sh index b6508b3..84214b0 100644 --- a/131 - Stack - Security, PostgreSQL, MySQL, MongoDB, Apache, Django.sh +++ b/131 - Stack - Security, PostgreSQL, MySQL, MongoDB, Apache, Django.sh @@ -39,7 +39,7 @@ # # - +# set -e set -u @@ -188,6 +188,29 @@ fi restart_services restart_initd_services +if [ "$SETUP_MONIT" == "Yes" ]; then + source # lib-monit + monit_install + system_record_etc_dir_changes "Installed Monit" + + monit_configure_email "$NOTIFY_EMAIL" + monit_configure_web $(system_primary_ip) + system_record_etc_dir_changes "Configured Monit interfaces" + + monit_def_system "$SYS_HOSTNAME" + monit_def_rootfs + monit_def_cron + monit_def_postfix + monit_def_ping_google + if [ "$SETUP_POSTGRESQL" == "Yes" ]; then monit_def_postgresql; fi + if [ "$SETUP_MYSQL" == "Yes" ]; then monit_def_mysql; fi + if [ "$SETUP_MONGODB" == "Yes" ]; then monit_def_mongodb; fi + if [ "$SETUP_APACHE" == "Yes" ]; then monit_def_apache; fi + #if [ "$SETUP_MEMCACHE" == "Yes" ]; then monit_def_memcached; fi + system_record_etc_dir_changes "Created Monit rules for installed services" + monit reload +fi + # Send info message cat > ~/setup_message <> ~/setup_message <> ~/setup_message < Date: Thu, 17 May 2012 15:28:46 +0200 Subject: [PATCH 30/35] Send alert rather than restart apache. --- 129 - monit.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/129 - monit.sh b/129 - monit.sh index abd8ef9..ac30968 100644 --- a/129 - monit.sh +++ b/129 - monit.sh @@ -201,21 +201,21 @@ EOT function monit_def_apache { cat </etc/monit/conf.d/apache2.cfg check process apache with pidfile /var/run/apache2.pid - start program = "/etc/init.d/apache2 start" with timeout 30 seconds + start program = "/etc/init.d/apache2 start" stop program = "/etc/init.d/apache2 stop" if cpu > 60% for 2 cycles then alert if cpu > 80% for 5 cycles then alert if totalmem > 200.0 MB for 5 cycles then alert if children > 250 then alert if loadavg(5min) greater than 10 for 8 cycles then stop - if failed host localhost port 80 protocol HTTP request / within 2 cycles then restart + if failed host localhost port 80 protocol HTTP request / within 2 cycles then alert if failed host localhost port 80 protocol apache-status dnslimit > 25% or loglimit > 80% or waitlimit < 20% retry 2 within 2 cycles then alert - if 5 restarts within 5 cycles then timeout + #if 5 restarts within 5 cycles then timeout depends on apache_bin depends on apache_rc group www - + check file apache_bin with path /usr/sbin/apache2 if failed checksum then unmonitor if failed permission 755 then unmonitor From 94c35dea72fcf6736856e044334da3165b441b74 Mon Sep 17 00:00:00 2001 From: Filip Wasilewski Date: Thu, 17 May 2012 15:34:26 +0200 Subject: [PATCH 31/35] Parametrized paths and removed unnecessary functions. --- 127 - lib-django.sh | 70 +++++++++++++++++++-------------------------- 1 file changed, 29 insertions(+), 41 deletions(-) diff --git a/127 - lib-django.sh b/127 - lib-django.sh index 3e3e2ce..fbaf5c8 100644 --- a/127 - lib-django.sh +++ b/127 - lib-django.sh @@ -6,61 +6,49 @@ # # My ref: http://www.linode.com/?r=aadfce9845055011e00f0c6c9a5c01158c452deb - -function django_get_user_or_default { - # django_get_user_or_default([user]) - if [ -z "$1" ]; - then USER="www-data" - else USER="$1" - fi - echo "$USER" -} - -function django_get_project_path { - # django_get_project_path(project_name) - PROJECT_NAME="$1" - echo "/srv/$PROJECT_NAME" -} +PROJECT_CODE_DIR=app +DJANGO_PROJECT=webapp function django_change_project_owner { # django_change_project_owner(project_path, user) PROJECT_PATH="$1" USER="$2" - GROUP="$USER" - chown -R "$USER:$GROUP" "$PROJECT_PATH" + chown -R "$USER:$USER" "$PROJECT_PATH" } function django_create_project { - # django_create_project(project_name) + # django_create_project(project_path) - PROJECT_NAME="$1" - if [ -z "$PROJECT_NAME" ]; then - echo "django_create_project() requires the project name as the first argument" + PROJECT_PATH="$1" + if [ -z "$PROJECT_PATH" ]; then + echo "django_create_project() requires the project root path as the first argument" return 1; fi - PROJECT_PATH=`django_get_project_path "$PROJECT_NAME"` - mkdir -p "$PROJECT_PATH/app/conf/apache" + mkdir -p "$PROJECT_PATH/$PROJECT_CODE_DIR/conf/apache" mkdir -p "$PROJECT_PATH/logs" "$PROJECT_PATH/run/eggs" virtualenv "$PROJECT_PATH/venv" - $PROJECT_PATH/venv/bin/pip install django + $PROJECT_PATH/venv/bin/pip install Django - pushd "$PROJECT_PATH/app" - "$PROJECT_PATH/venv/bin/python" "$PROJECT_PATH/venv/bin/django-admin.py" startproject webapp . + pushd "$PROJECT_PATH/$PROJECT_CODE_DIR" + "$PROJECT_PATH/venv/bin/python" "$PROJECT_PATH/venv/bin/django-admin.py" startproject "$DJANGO_PROJECT" . popd - mkdir -p "$PROJECT_PATH/app/webapp/static" + mkdir -p "$PROJECT_PATH/$PROJECT_CODE_DIR/$DJANGO_PROJECT/static" + + echo "Django" >> "$PROJECT_PATH/$PROJECT_CODE_DIR/requirements.txt" } function django_install_db_driver { # django_install_db_driver(project_path, driver_package) - $1/venv/bin/pip install django "$2" + $1/venv/bin/pip install "$2" + echo "$2" >> "$PROJECT_PATH/$PROJECT_CODE_DIR/requirements.txt" } function django_configure_db_settings { # django_configure_db_settings(project_path, engine, name, user, password, [host, [port]]) - - SETTINGS="$1/app/webapp/settings.py" + PROJECT_PATH="$1" + SETTINGS="$PROJECT_PATH/$PROJECT_CODE_DIR/$DJANGO_PROJECT/settings.py" sed -i -e "s/'ENGINE': 'django.db.backends.'/'ENGINE': 'django.db.backends.$2'/" "$SETTINGS" sed -i -e "s/'NAME': ''/'NAME': '$3'/" "$SETTINGS" sed -i -e "s/'USER': ''/'USER': '$4'/" "$SETTINGS" @@ -79,7 +67,7 @@ function django_configure_apache_virtualhost { VHOST_HOSTNAME="$1" PROJECT_PATH="$2" USER="$3" - GROUP="$USER" + GROUP="$USER" if [ -z "$VHOST_HOSTNAME" ]; then echo "django_configure_apache_virtualhost() requires the hostname as the first argument" @@ -92,7 +80,7 @@ function django_configure_apache_virtualhost { fi APACHE_CONF="200-$VHOST_HOSTNAME" - APACHE_CONF_PATH="$PROJECT_PATH/app/conf/apache/$APACHE_CONF" + APACHE_CONF_PATH="$PROJECT_PATH/$PROJECT_CODE_DIR/conf/apache/$APACHE_CONF" cat > "$APACHE_CONF_PATH" << EOF @@ -100,28 +88,28 @@ function django_configure_apache_virtualhost { ServerName $VHOST_HOSTNAME ServerSignature Off - Alias /static/ $PROJECT_PATH/app/webapp/static/ - Alias /robots.txt $PROJECT_PATH/app/webapp/static/robots.txt - Alias /favicon.ico $PROJECT_PATH/app/webapp/static/favicon.ico + Alias /static/ $PROJECT_PATH/$PROJECT_CODE_DIR/$DJANGO_PROJECT/static/ + Alias /robots.txt $PROJECT_PATH/$PROJECT_CODE_DIR/$DJANGO_PROJECT/static/robots.txt + Alias /favicon.ico $PROJECT_PATH/$PROJECT_CODE_DIR/$DJANGO_PROJECT/static/favicon.ico SetEnvIf User_Agent "monit/*" dontlog CustomLog "|/usr/sbin/rotatelogs $PROJECT_PATH/logs/access.log.%Y%m%d-%H%M 5M" combined env=!dontlog ErrorLog "|/usr/sbin/rotatelogs $PROJECT_PATH/logs/error.log.%Y%m%d-%H%M 5M" LogLevel warn - WSGIScriptAlias / $PROJECT_PATH/app/webapp/wsgi.py + WSGIScriptAlias / $PROJECT_PATH/$PROJECT_CODE_DIR/$DJANGO_PROJECT/wsgi.py - WSGIDaemonProcess $VHOST_HOSTNAME user=$USER group=$GROUP processes=2 threads=10 maximum-requests=10000 display-name=%{GROUP} python-path=$PROJECT_PATH/app:$PROJECT_PATH/venv/lib/python2.7/site-packages python-eggs=$PROJECT_PATH/run/eggs + WSGIDaemonProcess $VHOST_HOSTNAME user=$USER group=$GROUP processes=2 threads=10 maximum-requests=10000 display-name=%{GROUP} python-path=$PROJECT_PATH/$PROJECT_CODE_DIR:$PROJECT_PATH/venv/lib/python2.7/site-packages python-eggs=$PROJECT_PATH/run/eggs WSGIProcessGroup $VHOST_HOSTNAME - WSGIScriptAlias / $PROJECT_PATH/app/webapp/wsgi.py + WSGIScriptAlias / $PROJECT_PATH/$PROJECT_CODE_DIR/$DJANGO_PROJECT/wsgi.py - + Order deny,allow Allow from all Options -Indexes FollowSymLinks - + Order deny,allow Allow from all @@ -129,6 +117,6 @@ function django_configure_apache_virtualhost { EOF - ln -t /etc/apache2/sites-available/ "$APACHE_CONF_PATH" + ln -s -t /etc/apache2/sites-available/ "$APACHE_CONF_PATH" a2ensite "$APACHE_CONF" } From 8639aac0186488b9427c75b52ebe60c81841096e Mon Sep 17 00:00:00 2001 From: Filip Wasilewski Date: Thu, 17 May 2012 23:34:06 +0200 Subject: [PATCH 32/35] Option to create django project in user's home directory. --- ...tgreSQL, MySQL, MongoDB, Apache, Django.sh | 53 ++++++++++++------- 1 file changed, 34 insertions(+), 19 deletions(-) diff --git a/131 - Stack - Security, PostgreSQL, MySQL, MongoDB, Apache, Django.sh b/131 - Stack - Security, PostgreSQL, MySQL, MongoDB, Apache, Django.sh index 84214b0..876336c 100644 --- a/131 - Stack - Security, PostgreSQL, MySQL, MongoDB, Apache, Django.sh +++ b/131 - Stack - Security, PostgreSQL, MySQL, MongoDB, Apache, Django.sh @@ -33,10 +33,10 @@ # -# +# # # -# +# # # @@ -147,24 +147,43 @@ if [ "$SETUP_MONGODB" == "Yes" ]; then fi # Setup and configure sample django project -DJANGO_PROJECT_PATH="" RDNS=$(get_rdns_primary_ip) +DJANGO_PROJECT_PATH="" -if [ "$SETUP_DJANGO_PROJECT" == "Yes" ]; then +if [ "$SETUP_DJANGO_PROJECT" != "No" ]; then source # lib-django - if [ -z "$DJANGO_DOMAIN" ]; then - DJANGO_DOMAIN=$RDNS - fi - - DJANGO_USER=$(django_get_user_or_default "$DJANGO_USER") - DJANGO_PROJECT_PATH=`django_get_project_path "$DJANGO_PROJECT_NAME"` - - system_add_system_user "$DJANGO_USER" "$DJANGO_PROJECT_PATH" "$USER_SHELL" - django_create_project "$DJANGO_PROJECT_NAME" + if [ -z "$DJANGO_DOMAIN" ]; then DJANGO_DOMAIN=$RDNS; fi + + case "$SETUP_DJANGO_PROJECT" in + Standalone) + DJANGO_PROJECT_PATH="/srv/$DJANGO_PROJECT_NAME" + if [ -n "$DJANGO_USER" ]; then + if [ "$DJANGO_USER" != "$USER_NAME" ]; then + system_add_system_user "$DJANGO_USER" "$DJANGO_PROJECT_PATH" "$USER_SHELL" + else + mkdir -p "$DJANGO_PROJECT_PATH" + fi + else + DJANGO_USER="www-data" + fi + ;; + InUserHome) + DJANGO_USER=$USER_NAME + DJANGO_PROJECT_PATH=$(system_get_user_home "$USER_NAME")/$DJANGO_PROJECT_NAME + ;; + InUserHomeRoot) + DJANGO_USER=$USER_NAME + DJANGO_PROJECT_PATH=$(system_get_user_home "$USER_NAME") + ;; + esac + + django_create_project "$DJANGO_PROJECT_PATH" + django_change_project_owner "$DJANGO_PROJECT_PATH" "$DJANGO_USER" if [ "$SETUP_APACHE" == "Yes" ]; then django_configure_apache_virtualhost "$DJANGO_DOMAIN" "$DJANGO_PROJECT_PATH" "$DJANGO_USER" + touch /tmp/restart-apache2 fi if [ "$SETUP_POSTGRESQL" == "Yes" ]; then django_install_db_driver "$DJANGO_PROJECT_PATH" "psycopg2" @@ -173,12 +192,8 @@ if [ "$SETUP_DJANGO_PROJECT" == "Yes" ]; then if [ "$SETUP_MYSQL" == "Yes" ]; then django_install_db_driver "$DJANGO_PROJECT_PATH" "MySQL-python" fi - django_change_project_owner "$DJANGO_PROJECT_PATH" "$DJANGO_USER" system_record_etc_dir_changes "Configured django project '$DJANGO_PROJECT_NAME'" - if [ "$SETUP_APACHE" == "Yes" ]; then - touch /tmp/restart-apache2 - fi -fi; +fi if [ -n "$SYS_PRIVATE_IP" ]; then system_configure_private_network "$SYS_PRIVATE_IP" @@ -219,7 +234,7 @@ Your Linode VPS configuration is completed. EOD -if [ "$SETUP_DJANGO_PROJECT" == "Yes" ]; then +if [ "$SETUP_DJANGO_PROJECT" != "No" ]; then cat >> ~/setup_message < Date: Tue, 26 Jun 2012 18:51:05 +0200 Subject: [PATCH 33/35] Renamed script to match source id. --- 129 - monit.sh => 130 - monit.sh | 0 ...ck - Security, PostgreSQL, MySQL, MongoDB, Apache, Django.sh | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename 129 - monit.sh => 130 - monit.sh (100%) diff --git a/129 - monit.sh b/130 - monit.sh similarity index 100% rename from 129 - monit.sh rename to 130 - monit.sh diff --git a/131 - Stack - Security, PostgreSQL, MySQL, MongoDB, Apache, Django.sh b/131 - Stack - Security, PostgreSQL, MySQL, MongoDB, Apache, Django.sh index 876336c..bf84b94 100644 --- a/131 - Stack - Security, PostgreSQL, MySQL, MongoDB, Apache, Django.sh +++ b/131 - Stack - Security, PostgreSQL, MySQL, MongoDB, Apache, Django.sh @@ -204,7 +204,7 @@ restart_services restart_initd_services if [ "$SETUP_MONIT" == "Yes" ]; then - source # lib-monit + source # lib-monit monit_install system_record_etc_dir_changes "Installed Monit" From 836aeb7b4fde40b8cb2eaacceee07c6af0f06bcf Mon Sep 17 00:00:00 2001 From: Filip Wasilewski Date: Tue, 26 Jun 2012 18:54:43 +0200 Subject: [PATCH 34/35] Ignore error codes for empty ls response (for `set -e` shell flag). --- 123 - lib-system-ubuntu.sh | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/123 - lib-system-ubuntu.sh b/123 - lib-system-ubuntu.sh index bdcd5c8..775f3a2 100644 --- a/123 - lib-system-ubuntu.sh +++ b/123 - lib-system-ubuntu.sh @@ -84,6 +84,8 @@ function system_update_hostname { function system_security_logcheck { aptitude -y install logcheck logcheck-database + # configure email + # start after setup } function system_security_fail2ban { @@ -119,19 +121,19 @@ EOF } function restart_services { - # restarts upstart services that have a file in /tmp/needs-restart/ - for service_name in $(ls /tmp/restart-* | cut -d- -f2-10); do - service $service_name restart - rm -f /tmp/restart-$service_name - done + # restarts upstart services that have a file in /tmp/needs-restart/ + for service_name in $(ls /tmp/ | grep restart-* | cut -d- -f2-10); do + service $service_name restart + rm -f /tmp/restart-$service_name + done } function restart_initd_services { - # restarts upstart services that have a file in /tmp/needs-restart/ - for service_name in $(ls /tmp/restart_initd-* | cut -d- -f2-10); do - /etc/init.d/$service_name restart - rm -f /tmp/restart_initd-$service_name - done + # restarts upstart services that have a file in /tmp/needs-restart/ + for service_name in $(ls /tmp/ | grep restart_initd-* | cut -d- -f2-10); do + /etc/init.d/$service_name restart + rm -f /tmp/restart_initd-$service_name + done } # Maintain for compatibility with scripts using this library for Ubuntu 10.04 From 52c39cb13fc38d6f401ba2d29080578cd42f5ccd Mon Sep 17 00:00:00 2001 From: Filip Wasilewski Date: Thu, 6 Feb 2014 11:39:13 +0100 Subject: [PATCH 35/35] Update readme --- README => README.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) rename README => README.md (51%) diff --git a/README b/README.md similarity index 51% rename from README rename to README.md index b53bf87..58ac0fe 100644 --- a/README +++ b/README.md @@ -1,3 +1,18 @@ +# Linode StackScripts + + +### Please note + +These scripts may be a bit outdated now although the solution served me well on many occasions. I have now moved to Ansible and other configuration management tools that are just much metter than the bash scripts approach, although you may pick up some configs and scripting ideas from here. + +If there is an interest in a similar full-stack web-server setup go ahead and open a ticket and I can prepare a set of Ansible roles and playbooks with Nginx & uWSGI as the web server. + + +------------------- + +### Original readme + + A Linode.com StackScript shell script that configures a complete web environment with Apache, PostgreSQL/MySQL/MongoDB, Python, mod_wsgi, virtualenv and Django. Optionally creates a PostgreSQL/MySQL user and database and installs MongoDB NoSQL database.