Full Code of Mins/TuxLite for AI

master 6fd60bcd3d32 cached
13 files
90.3 KB
26.2k tokens
1 requests
Download .txt
Repository: Mins/TuxLite
Branch: master
Commit: 6fd60bcd3d32
Files: 13
Total size: 90.3 KB

Directory structure:
gitextract_oh2qkkzk/

├── README.md
├── backup.sh
├── config/
│   ├── apache2.conf
│   ├── apache2_ports.conf
│   ├── fastcgi.conf
│   ├── nginx.conf
│   └── nginx_default_vhost.conf
├── domain.sh
├── install.sh
├── options.conf
├── setup.sh
├── varnish.sh
└── wordpress.sh

================================================
FILE CONTENTS
================================================

================================================
FILE: README.md
================================================
### TuxLite Readme

TuxLite is a free collection of shell scripts for rapid deployment of
LAMP and LNMP stacks (Linux, Apache/Nginx, MySQL and PHP) for Debian and
Ubuntu. 

Have you considered upgrading from shared hosting to a VPS or dedicated
server but held off by the costly control panel licenses, or the fear of
managing a Linux server? Now you can leave those worries behind!

TuxLite scripts automate configuration of servers for web hosting,
so your websites can be online within minutes! Ideal for those who
prefer hosting sites on their own server without resorting to expensive
and bloated control panels.

The following are installed:-

-   Apache2 with mpm\_event or Nginx
-   MySQL, MariaDB or Percona
-   PHP-FPM + commonly used PHP modules
-   Postfix mail server (securely configured to be outgoing only)
-   Varnish cache (optional)

For more detailed explanation on the installation, usage and script features, 
kindly refer to these links:-

[Installation](http://tuxlite.com/installation/)

[Script features](http://tuxlite.com/script-details/)

[Download](http://tuxlite.com/download/)

### Quick Install (Git)

    # Install git and clone TuxLite
    apt-get -y install git
    git clone https://github.com/Mins/TuxLite.git
    cd TuxLite
    
    # Edit options to enter server IP, MySQL password etc.
    nano options.conf
    
    # Make all scripts executable.
    chmod 700 *.sh
    chmod 700 options.conf
    
    # Install LAMP or LNMP stack.
    ./install.sh
    
    # Add a new Linux user and add domains to the user.
    adduser johndoe
    ./domain.sh add johndoe yourdomain.com
    ./domain.sh add johndoe subdomain.yourdomain.com
    
    # Install Adminer or phpMyAdmin
    ./setup.sh dbgui
    
    # Enable/disable public viewing of Adminer/phpMyAdmin
    ./domain.sh dbgui on
    ./domain.sh dbgui off

### Requirements

-   Supports Debian 6, 7 and 8, Ubuntu 12.04, 12.10, 13.04, 13.10 and 14.04.
-   A server with at least 80MB RAM. 256MB and above recommended.
-   Basic Linux knowledge. You will need know how to connect to your
    server remotely.
-   Basic text editor knowledge. For beginners, learning GNU nano is
    recommended.

If this is your first time with a Linux server, I suggest spending a day
reading the "getting started" tutorials in Linode Library.

### Why use TuxLite?

-   TuxLite LAMP stack configures Apache with mpm\_event and PHP with
    fastcgi (PHP-FPM). This gives much higher performance and lower memory
    consumption than the regular LAMP tutorials/guides using mod\_php.
-   Uses official distribution packages. You are not at the mercy of the
    script maintainer to keep your servers updated. All installed
    software are tuned, optimized and secured.
-   Minimal resource usage. Fresh install requires only 50-60MB RAM.
-   Free from unnecessary or custom changes to your server. Everything
    is configured according to Debian/Ubuntu standards.
-   Automatic virtualhost configuration with log rotation, AWStats
    traffic statistics and phpMyAdmin for managing MySQL.
-   Varnish cache script included to turbo charge your websites.
-   Free and open source! Coded in a human readable manner and
    modular, making custom modifications extremely easy.


================================================
FILE: backup.sh
================================================
#!/bin/bash

FIND_PATH="/home/*/domains/*"
# Used to filter database name from its full system path
# (1)/var(2)/lib(3)/mysql(4)/dbname(5)
AWK_DB_POS="5"
# Used to filter domain name from its full system path
# E.g. (1)/home(2)/john(3)/domains(4)/johndomain.com(5)
AWK_DOMAIN_POS="5"


source ./options.conf


function ask_interval {

    # Ask user how often do they want the backup jobs to run?
    echo "How often do you want the backups/cleanups to run?"
    echo "1. Daily"
    echo "2. Weekly"
    echo "3. Monthly"

    # Initialize variable with an alphabet
    SELECT_INTERVAL="a"
    # Keep looping until user enters a number that is greater than 0 and less than 3
    until  [[ "$SELECT_INTERVAL" =~ [0-9]+ ]] && [ $SELECT_INTERVAL -gt 0 ] && [ $SELECT_INTERVAL -le 3 ]; do
        echo -n "Selection (integer) : "
        read SELECT_INTERVAL
    done

    if [ $SELECT_INTERVAL -eq 1 ]; then
        INTERVAL="daily"
    elif [ $SELECT_INTERVAL -eq 2 ]; then
        INTERVAL="weekly"
    elif [ $SELECT_INTERVAL -eq 3 ]; then
        INTERVAL="monthly"
    fi
} # End of ask_interval

function find_available_domains {

    # Initialize variable
    DOMAINS_AVAILABLE=0

    # First check to see if there are domains available. Suppress exit status.
    find $FIND_PATH -maxdepth 0 &> /dev/null

    # If exit status is 0, there are domains available
    # Collect available domains to a temporary file
    if [ $? -eq 0 ]; then
        find $FIND_PATH -maxdepth 0 > /tmp/domain.txt
        DOMAINS_AVAILABLE=`cat /tmp/domain.txt | wc -l`
    # Remove fcgi-bin directory as available domain. #Not used for multiuser scripts
        # sed -i '/\/srv\/www\/fcgi-bin.d/ d' /tmp/domain.txt
    fi

    # Exit status of find command is 1, ask user to add domain first
    if [ $DOMAINS_AVAILABLE -eq 0 ]; then
        echo "No domains available for backup. Please add a domain first."
        exit
    fi

} # End of find_available_domains

function find_available_databases {

    # Initialize variable
    DATABASES_AVAILABLE=0

    # First search for available mysql databases
    find /var/lib/mysql/* -maxdepth 0 -type d > /tmp/database.txt

    # Remove mysql and phpmyadmin as available databases
    sed -i '/\/var\/lib\/mysql\/mysql/ d' /tmp/database.txt
    sed -i '/\/var\/lib\/mysql\/phpmyadmin/ d' /tmp/database.txt
    DATABASES_AVAILABLE=`cat /tmp/database.txt | wc -l`

    # No databases found, ask user to add database first
    if [ $DATABASES_AVAILABLE -eq 0 ]; then
        echo "No databases available for backup. Please add a database first."
        exit
    fi

} # End of find_available_databases


function create_backup_directory {

    # First check if Linux user exists
    # If yes, create backup folders
    if [ -d "/home/$USER" ]; then
        mkdir -p /home/$USER/backup/{databases,domains}
        chown -R $USER:$USER /home/$USER/backup
        echo -e "\033[35;1mBackup folders created in /home/$USER/backup.\033[0m"
    else
        # If not, exit and inform user
        echo -e "\033[35;1mERROR: User /home/$USER doesn't exist.\033[0m"
        exit 1
    fi

} # End of create_backup_directory

function cron_backupdb {

    # First check if backup location exists. Exit if not found.
    if [ ! -d "/home/$USER/backup/databases" ]; then
        echo -e "\033[35;1mERROR: Database folder /home/$USER/backup/databases doesn't exist, please create it first.\033[0m"
        exit 1
    fi

    # Initialize selection value when listing available databases to user
    counter=1
    # Check how many databases are available
    DB_AVAILABLE=`cat /tmp/database.txt | wc -l`

    # Print out available databases
    echo ""
    echo "Select the database you want to backup, 1 to $DB_AVAILABLE"
    while read LINE; do
        # For each domain path, use AWK to get only the domain name and leave out the full path
        data=`echo $LINE | awk -F"/" '{ print $'${AWK_DB_POS}' }'`
        echo "$counter. $data"
        # Increment counter for next iteration
        let counter+=1
    done < "/tmp/database.txt"

    # Reduce counter by 1 for next function
    let counter-=1

    # Ensure that the user inputs a valid integer
    # Initialize variable with a alphabet
    SELECTDB="a"

    # Keep on looping until input is a number that is greater than 0 and less than the number of available databases
    until  [[ "$SELECTDB" =~ [0-9]+ ]] && [ $SELECTDB -gt 0 ] && [ $SELECTDB -le $counter ]; do
        echo -n "Selection (integer) : "
        read SELECTDB
    done

    # Capture database name from its full path using AWK
    DATABASE=`cat /tmp/database.txt | awk NR==$SELECTDB | awk -F"/" '{ print $'${AWK_DB_POS}' }'`
    # Remove temporary file
    rm -rf /tmp/database.txt

    # Check to see if database is already backed up under cronjobs
    # First dump cron contents to temporary file
    crontab -l > /tmp/tmpcron.txt

    # Then search for existing string
    tmp=`grep -w "@$INTERVAL mysqldump -hlocalhost -uroot -p$MYSQL_ROOT_PASSWORD $DATABASE" /tmp/tmpcron.txt | wc -l`
    command rm /tmp/tmpcron.txt

    # If cron entry already exists, abort
    if [ $tmp -gt 0 ]; then
        echo -e "\033[35;1mERROR: Database backup already exists, please remove it from crontab -e before entering again.\033[0m"
        exit 1
    fi

    # If not, then append a cronjob for it
    crontab -l > /tmp/tmpcron.txt
    cat >> /tmp/tmpcron.txt <<EOF
@$INTERVAL mysqldump -hlocalhost -uroot -p$MYSQL_ROOT_PASSWORD $DATABASE | gzip -9 > /home/$USER/backup/databases/$DATABASE.\`/bin/date +\%Y\%m\%d\`.sql.gz; chown $USER:$USER /home/$USER/backup/databases/*
EOF

    # Load job commands back to crontab
    crontab /tmp/tmpcron.txt
    # Remove temporary file
    command rm /tmp/tmpcron.txt
    echo -e "\033[35;1mDatabase $DATABASE will be backed up to /home/$USER/backup/databases/$DATABASE $INTERVAL.\033[0m"
    echo -e "\033[35;1mTo verify, enter crontab -e.\033[0m"

} # End of cron_backupdb


function cron_backupdomain {

    # First check if backup location exists. Exit if not found.
    if [ ! -d "/home/$USER/backup/domains" ]; then
        echo -e "\033[35;1mERROR: Backup folder /home/$USER/backup/domains doesn't exist, please create it first.\033[0m"
        exit 1
    fi

    # Print out available domains and
    # Ensure that the user inputs a valid integer

    # Initialize counter
    counter=1
    DOMAINS_AVAILABLE=`cat /tmp/domain.txt | wc -l`
    echo ""
    echo "Select the domain you want to backup, 1 to $DOMAINS_AVAILABLE"

    # Print out domains. Use AWK to filter out domain name from full paths
    while read LINE; do
        data=`echo $LINE | awk -F"/" '{ print $'${AWK_DOMAIN_POS}' }'`
        echo "$counter. $data"
        let counter+=1
    done < "/tmp/domain.txt"

    # Set counter for next function
    let counter-=1

    # Ensure that the user inputs a valid integer
    # Initialize variable with a alphabet
    SELECTDOMAIN="a"

    # Keep on looping until input is a number that is greater than 0 and less than the number of available databases
    until  [[ "$SELECTDOMAIN" =~ [0-9]+ ]] && [ $SELECTDOMAIN -gt 0 ] && [ $SELECTDOMAIN -le $counter ]; do
        echo -n "Selection (integer) : "
        read SELECTDOMAIN
    done

    # Get full path to domain e.g /home/user/domains/domain.com
    DOMAIN=`cat /tmp/domain.txt | awk NR==$SELECTDOMAIN`
    # Remove first forward slash so that tar doesn't output anything during backup
    DOMAIN=`echo $DOMAIN | cut -c2-`
    # Get domain name without its system path. Used for naming the backup file
    DOMAIN_URL=`cat /tmp/domain.txt | awk NR==$SELECTDOMAIN | awk -F"/" '{ print $'${AWK_DOMAIN_POS}' }'`
    rm -rf /tmp/domain.txt

    # Check to see if cronjob already exists
    # Load crontab contents into temporary file and grep the domain name
    crontab -l > /tmp/tmpcron.txt
    tmp=`grep -w "$DOMAIN" /tmp/tmpcron.txt | wc -l`
    command rm /tmp/tmpcron.txt

    # If cron entry already exists then exit
    if [ $tmp -gt 0 ]; then
        echo -e "\033[35;1mERROR: Domain backup cronjob already exists, please remove it from crontab -e before trying again.\033[0m"
        exit 1
    fi

    # Dump out contents of crontab, and add new line to it
    crontab -l > /tmp/tmpcron.txt
    cat >> /tmp/tmpcron.txt <<EOF
@$INTERVAL tar -czf /home/$USER/backup/domains/$DOMAIN_URL.\`/bin/date +\%Y\%m\%d\`.tar.gz -C / $DOMAIN; chown $USER:$USER /home/$USER/backup/domains/*
EOF

    # Restore cron contents from temporary file
    crontab /tmp/tmpcron.txt
    # Remove temporary file
    command rm /tmp/tmpcron.txt

    echo -e "\033[35;1mDomain $DOMAIN_URL will be backed up to /home/$USER/backup/domains/$DOMAIN_URL $INTERVAL.\033[0m"
    echo -e "\033[35;1mTo verify, enter crontab -e.\033[0m"

} # End of cron_backupdomain

function cron_cleanbackup {

    if [ ! -d "/home/$USER" ]; then
        echo -e "\033[35;1mERROR: Folder /home/$USER/backup doesn't exist, please enter a valid system user.\033[0m"
        return 1
    fi

    if ! [[ "$DAYS" =~ ^[0-9]+$ ]]; then
        echo -e "\033[35;1mERROR: Please enter a valid \"Old\" integer.\033[0m"
        return 1
    fi

    # Dump out contents of crontab, and add new line to it
    crontab -l > /tmp/tmpcron.txt
    cat >> /tmp/tmpcron.txt <<EOF
@$INTERVAL find /home/$USER/backup/* -type f -mtime +$DAYS -exec rm -rfv {} \; > /home/$USER/cleanbackup.log; chown $USER:$USER /home/$USER/cleanbackup.log
EOF
    crontab /tmp/tmpcron.txt
    command rm /tmp/tmpcron.txt
    echo -e "\033[35;1mBackup files older than $DAYS days will be removed from /home/$USER/backup.\033[0m"
    echo -e "\033[35;1mTo verify, enter crontab -e.\033[0m"

}


# Start main program
if [ ! -n "$1" ]; then
    echo ""
    echo -n  "$0"
    echo -ne "\033[36m dir User\033[0m"
    echo     " - Create backup /home/User/backup/{domains,databases} directories to store backup files from cronjob."

    echo -n  "$0"
    echo -ne "\033[36m db User\033[0m"
    echo     " - Set up cronjob to mysqldump a database to USER's backup directory."

    echo -n  "$0"
    echo -ne "\033[36m site User\033[0m"
    echo     " - Set up cronjob to tar.gz a domain's public_html to User's backup directory."

    echo -n  "$0"
    echo -ne "\033[36m cleanup Old User\033[0m"
    echo     " - Set up cronjob to remove backups files that are older than \"Old\"(integer) days from User's backup directory."

    echo ""
    exit
fi


case $1 in
dir)
    # Make sure user inputs all the backup command and the user
    if [ ! $# -eq 2 ]; then
        echo -e "\033[35;1mPlease enter all required parameters\033[0m"
        exit 1
    else
        USER=$2
        create_backup_directory
    fi
    ;;
db)
    # Make sure user inputs all the backup command and the user
    if [ ! $# -eq 2 ]; then
        echo -e "\033[35;1mPlease enter all required parameters\033[0m"
        exit 1
    else
        USER=$2
        find_available_databases
        ask_interval
        cron_backupdb
    fi
    ;;
site)
    # Make sure user inputs all the backup command and the user
    if [ ! $# -eq 2 ]; then
        echo -e "\033[35;1mPlease enter all required parameters\033[0m"
        exit 1
    else
        USER=$2
        find_available_domains
        ask_interval
        cron_backupdomain
    fi
    ;;
cleanup)
    # Make sure user inputs all the backup command, the user and the days params
    if [ ! $# -eq 3 ]; then
        echo -e "\033[35;1mPlease enter all required parameters\033[0m"
        exit 1
    else
        USER=$3
        DAYS=$2
        ask_interval
        cron_cleanbackup
    fi
    ;;
esac


================================================
FILE: config/apache2.conf
================================================
# This is the main Apache server configuration file.  It contains the
# configuration directives that give the server its instructions.
# See http://httpd.apache.org/docs/2.2/ for detailed information about
# the directives and /usr/share/doc/apache2-common/README.Debian.gz about
# Debian specific hints.
#
#
# Summary of how the Apache 2 configuration works in Debian:
# The Apache 2 web server configuration in Debian is quite different to
# upstream's suggested way to configure the web server. This is because Debian's
# default Apache2 installation attempts to make adding and removing modules,
# virtual hosts, and extra configuration directives as flexible as possible, in
# order to make automating the changes and administering the server as easy as
# possible.

# It is split into several files forming the configuration hierarchy outlined
# below, all located in the /etc/apache2/ directory:
#
#	/etc/apache2/
#	|-- apache2.conf
#	|	`--  ports.conf
#	|-- mods-enabled
#	|	|-- *.load
#	|	`-- *.conf
#	|-- conf.d
#	|	`-- *
# 	`-- sites-enabled
#	 	`-- *
#
#
# * apache2.conf is the main configuration file (this file). It puts the pieces
#   together by including all remaining configuration files when starting up the
#   web server.
#
#   In order to avoid conflicts with backup files, the Include directive is
#   adapted to ignore files that:
#   - do not begin with a letter or number
#   - contain a character that is neither letter nor number nor _-:.
#   - contain .dpkg
#
#   Yet we strongly suggest that all configuration files either end with a
#   .conf or .load suffix in the file name. The next Debian release will
#   ignore files not ending with .conf (or .load for mods-enabled).
#
# * ports.conf is always included from the main configuration file. It is
#   supposed to determine listening ports for incoming connections, and which
#   of these ports are used for name based virtual hosts.
#
# * Configuration files in the mods-enabled/ and sites-enabled/ directories
#   contain particular configuration snippets which manage modules or virtual
#   host configurations, respectively.
#
#   They are activated by symlinking available configuration files from their
#   respective *-available/ counterparts. These should be managed by using our
#   helpers a2enmod/a2dismod, a2ensite/a2dissite. See
#   their respective man pages for detailed information.
#
# * Configuration files in the conf.d directory are either provided by other
#   packages or may be added by the local administrator. Local additions
#   should start with local- or end with .local.conf to avoid name clashes. All
#   files in conf.d are considered (excluding the exceptions noted above) by
#   the Apache 2 web server.
#
# * The binary is called apache2. Due to the use of environment variables, in
#   the default configuration, apache2 needs to be started/stopped with
#   /etc/init.d/apache2 or apache2ctl. Calling /usr/bin/apache2 directly will not
#   work with the default configuration.


# Global configuration
#

#
# ServerRoot: The top of the directory tree under which the server's
# configuration, error, and log files are kept.
#
# NOTE!  If you intend to place this on an NFS (or otherwise network)
# mounted filesystem then please read the LockFile documentation (available
# at <URL:http://httpd.apache.org/docs/2.2/mod/mpm_common.html#lockfile>);
# you will save yourself a lot of trouble.
#
# Do NOT add a slash at the end of the directory path.
#
#ServerRoot "/etc/apache2"

#
# The accept serialization lock file MUST BE STORED ON A LOCAL DISK.
#
Mutex file:${APACHE_LOCK_DIR} default

#
# PidFile: The file in which the server should record its process
# identification number when it starts.
# This needs to be set in /etc/apache2/envvars
#
PidFile ${APACHE_PID_FILE}

#
# Timeout: The number of seconds before receives and sends time out.
#
Timeout 300

#
# KeepAlive: Whether or not to allow persistent connections (more than
# one request per connection). Set to "Off" to deactivate.
#
KeepAlive On

#
# MaxKeepAliveRequests: The maximum number of requests to allow
# during a persistent connection. Set to 0 to allow an unlimited amount.
# We recommend you leave this number high, for maximum performance.
#
MaxKeepAliveRequests 100

#
# KeepAliveTimeout: Number of seconds to wait for the next request from the
# same client on the same connection.
#
KeepAliveTimeout 5

##
## Server-Pool Size Regulation (MPM specific)
##

# prefork MPM
# StartServers: number of server processes to start
# MinSpareServers: minimum number of server processes which are kept spare
# MaxSpareServers: maximum number of server processes which are kept spare
# MaxRequestWorkers: maximum number of server processes allowed to start
# MaxConnectionsPerChild: maximum number of requests a server process serves
<IfModule mpm_prefork_module>
    StartServers          5
    MinSpareServers       5
    MaxSpareServers      10
    MaxRequestWorkers    150
    MaxConnectionsPerChild   0
</IfModule>

# worker MPM
# StartServers: initial number of server processes to start
# MinSpareThreads: minimum number of worker threads which are kept spare
# MaxSpareThreads: maximum number of worker threads which are kept spare
# ThreadLimit: ThreadsPerChild can be changed to this maximum value during a
#              graceful restart. ThreadLimit can only be changed by stopping
#              and starting Apache.
# ThreadsPerChild: constant number of worker threads in each server process
# MaxRequestWorkers: maximum number of simultaneous client connections
# MaxConnectionsPerChild: maximum number of requests a server process serves
<IfModule mpm_worker_module>
    StartServers          2
    MinSpareThreads      25
    MaxSpareThreads      75
    ThreadLimit          64
    ThreadsPerChild      25
    MaxRequestWorkers    150
    MaxConnectionsPerChild   0
</IfModule>

# event MPM
# StartServers: initial number of server processes to start
# MinSpareThreads: minimum number of worker threads which are kept spare
# MaxSpareThreads: maximum number of worker threads which are kept spare
# ThreadsPerChild: constant number of worker threads in each server process
# MaxRequestWorkers: maximum number of simultaneous client connections
# MaxConnectionsPerChild: maximum number of requests a server process serves
<IfModule mpm_event_module>
    StartServers          1
    MinSpareThreads       2
    MaxSpareThreads       5
    ThreadLimit           20
    ThreadsPerChild       20
    MaxRequestWorkers     60
    MaxConnectionsPerChild   5000
</IfModule>

# These need to be set in /etc/apache2/envvars
User ${APACHE_RUN_USER}
Group ${APACHE_RUN_GROUP}

#
# AccessFileName: The name of the file to look for in each directory
# for additional configuration directives.  See also the AllowOverride
# directive.
#

AccessFileName .htaccess

#
# The following lines prevent .htaccess and .htpasswd files from being
# viewed by Web clients.
#
<Files ~ "^\.ht">
    Require all denied
    Satisfy all
</Files>

# TuxLite. Better to put this block here compared to Debian's default
<Directory />
    Options Indexes FollowSymLinks
    AllowOverride All
    Require all granted
</Directory>

#
# DefaultType is the default MIME type the server will use for a document
# if it cannot otherwise determine one, such as from filename extensions.
# If your server contains mostly text or HTML documents, "text/plain" is
# a good value.  If most of your content is binary, such as applications
# or images, you may want to use "application/octet-stream" instead to
# keep browsers from trying to display binary files as though they are
# text.
#
# It is also possible to omit any default MIME type and let the
# client's browser guess an appropriate action instead. Typically the
# browser will decide based on the file's extension then. In cases
# where no good assumption can be made, letting the default MIME type
# unset is suggested  instead of forcing the browser to accept
# incorrect  metadata.
#
DefaultType None


#
# HostnameLookups: Log the names of clients or just their IP addresses
# e.g., www.apache.org (on) or 204.62.129.132 (off).
# The default is off because it'd be overall better for the net if people
# had to knowingly turn this feature on, since enabling it means that
# each client request will result in AT LEAST one lookup request to the
# nameserver.
#
HostnameLookups Off

# ErrorLog: The location of the error log file.
# If you do not specify an ErrorLog directive within a <VirtualHost>
# container, error messages relating to that virtual host will be
# logged here.  If you *do* define an error logfile for a <VirtualHost>
# container, that host's errors will be logged there and not here.
#
ErrorLog ${APACHE_LOG_DIR}/error.log

#
# LogLevel: Control the number of messages logged to the error_log.
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
#
LogLevel warn

# Include module configuration:
Include mods-enabled/*.load
Include mods-enabled/*.conf

# Include list of ports to listen on and which to use for name based vhosts
Include ports.conf

#
# The following directives define some format nicknames for use with
# a CustomLog directive (see below).
# If you are behind a reverse proxy, you might want to change %h into %{X-Forwarded-For}i
#
LogFormat "%v:%p %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined
LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%h %l %u %t \"%r\" %>s %O" common
LogFormat "%{Referer}i -> %U" referer
LogFormat "%{User-agent}i" agent

# Include of directories ignores editors' and dpkg's backup files,
# see the comments above for details.

# Include generic snippets of statements
IncludeOptional conf-enabled/

# Include the virtual host configurations:
IncludeOptional sites-enabled/


================================================
FILE: config/apache2_ports.conf
================================================
# If you just change the port or add more ports here, you will likely also
# have to change the VirtualHost statement in
# /etc/apache2/sites-enabled/000-default
# This is also true if you have upgraded from before 2.2.9-3 (i.e. from
# Debian etch). See /usr/share/doc/apache2.2-common/NEWS.Debian.gz and
# README.Debian.gz

NameVirtualHost *:80
Listen 80

<IfModule mod_ssl.c>
    # If you add NameVirtualHost *:443 here, you will also have to change
    # the VirtualHost statement in /etc/apache2/sites-available/default-ssl
    # to <VirtualHost *:443>
    # Server Name Indication for SSL named virtual hosts is currently not
    # supported by MSIE on Windows XP.
    NameVirtualHost *:443
    Listen 443
</IfModule>

<IfModule mod_gnutls.c>
    Listen 443
</IfModule>

================================================
FILE: config/fastcgi.conf
================================================
#Original fastcgi.conf contents
#<IfModule mod_fastcgi.c>
#  AddHandler fastcgi-script .fcgi
#  #FastCgiWrapper /usr/lib/apache2/suexec
#  FastCgiIpcDir /var/lib/apache2/fastcgi
#</IfModule>

<IfModule mod_fastcgi.c>
    FastCgiIpcDir /var/lib/apache2/fastcgi
    FastCGIExternalServer /srv/www/fcgi-bin.d/php5-fpm -pass-header Authorization -idle-timeout 120 -socket /var/run/php5-fpm-www-data.sock

    Alias /php5-fcgi /srv/www/fcgi-bin.d
    AddType application/x-httpd-php5 .php

    <FilesMatch "\.php$">
        SetHandler php-fpm
    </FilesMatch>
    Action php-fpm /php5-fcgi/php5-fpm

    <Location "/php5-fcgi/php5-fpm">
        Order deny,allow
        Deny from All
        Allow from env=REDIRECT_STATUS
    </Location>
</IfModule>

================================================
FILE: config/nginx.conf
================================================
user www-data;
worker_processes 1;
pid /var/run/nginx.pid;

events {
    worker_connections 1024;
    # multi_accept on;
}

http {

    ## Basic Settings ##

    client_max_body_size 50m;
    client_header_timeout 5;
    keepalive_timeout 5;
    port_in_redirect off;
    sendfile on;
    server_name_in_redirect off;
    # server_names_hash_bucket_size 64;
    server_tokens off;
    tcp_nopush on;
    tcp_nodelay on;
    types_hash_max_size 2048;


    ## MIME ##

    include /etc/nginx/mime.types;
    default_type application/octet-stream;


    ## Logging Settings ##

    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;


    ## Gzip Settings ##

    gzip on;
    gzip_disable "msie6";
    gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
    gzip_min_length 1400;
    # gzip_vary on;
    # gzip_proxied any;
    # gzip_comp_level 6;
    # gzip_buffers 16 8k;
    # gzip_http_version 1.1;


    ## nginx-naxsi config ##
    ## Uncomment it if you installed nginx-naxsi

    #include /etc/nginx/naxsi_core.rules;


    ## Virtual Host Configs ##

    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
}



================================================
FILE: config/nginx_default_vhost.conf
================================================
# You may add here your
# server {
#       ...
# }
# statements for each of your virtual hosts to this file

##
# You should look at the following URL's in order to grasp a solid understanding
# of Nginx configuration files in order to fully unleash the power of Nginx.
# http://wiki.nginx.org/Pitfalls
# http://wiki.nginx.org/QuickStart
# http://wiki.nginx.org/Configuration
#
# Generally, you will want to move this file somewhere, and start with a clean
# file but keep this around for reference. Or just disable in sites-enabled.
#
# Please see /usr/share/doc/nginx-doc/examples/ for more detailed examples.
##

server {
        listen   80 default_server; ## listen for ipv4; this line is default and implied
        #listen   [::]:80 default_server ipv6only=on; ## listen for ipv6

        root /usr/share/nginx/www;
        index index.html index.htm;

        # Make site accessible from http://localhost/
        server_name localhost;

        location / {
                # First attempt to serve request as file, then
                # as directory, then fall back to displaying a 404.
                try_files $uri $uri/ /index.html;
                # Uncomment to enable naxsi on this location
                # include /etc/nginx/naxsi.rules
        }

        location /doc/ {
                alias /usr/share/doc/;
                autoindex on;
                allow 127.0.0.1;
                allow ::1;
                deny all;
        }

        # Only for nginx-naxsi used with nginx-naxsi-ui : process denied requests
        #location /RequestDenied {
        #       proxy_pass http://127.0.0.1:8080;
        #}

        #error_page 404 /404.html;

        # redirect server error pages to the static page /50x.html
        #
        #error_page 500 502 503 504 /50x.html;
        #location = /50x.html {
        #       root /usr/share/nginx/www;
        #}

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        #location ~ \.php$ {
        #       fastcgi_split_path_info ^(.+\.php)(/.+)$;
        #       # NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
        #
        #       # With php5-cgi alone:
        #       fastcgi_pass 127.0.0.1:9000;
        #       # With php5-fpm:
        #       fastcgi_pass unix:/var/run/php5-fpm.sock;
        #       fastcgi_index index.php;
        #       include fastcgi_params;
        #}

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        #       deny all;
        #}
}


# another virtual host using mix of IP-, name-, and port-based configuration
#
#server {
#       listen 8000;
#       listen somename:8080;
#       server_name somename alias another.alias;
#       root html;
#       index index.html index.htm;
#
#       location / {
#               try_files $uri $uri/ =404;
#       }
#}


# HTTPS server
#
#server {
#       listen 443;
#       server_name localhost;
#
#       root html;
#       index index.html index.htm;
#
#       ssl on;
#       ssl_certificate cert.pem;
#       ssl_certificate_key cert.key;
#
#       ssl_session_timeout 5m;
#
#       ssl_protocols SSLv3 TLSv1;
#       ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv3:+EXP;
#       ssl_prefer_server_ciphers on;
#
#       location / {
#               try_files $uri $uri/ =404;
#       }
#}



================================================
FILE: domain.sh
================================================
#!/bin/bash
######################################################################
# TuxLite virtualhost script                                         #
# Easily add/remove domains or subdomains                            #
# Configures logrotate, AWStats and PHP5-FPM                         #
# Enables/disables public viewing of AWStats and Adminer/phpMyAdmin  #
######################################################################

source ./options.conf

# Seconds to wait before removing a domain/virtualhost
REMOVE_DOMAIN_TIMER=10

# Check domain to see if it contains invalid characters. Option = yes|no.
DOMAIN_CHECK_VALIDITY="yes"

#### First initialize some static variables ####

# Specify path to database management tool
if [ $DB_GUI -eq 1 ]; then
    DB_GUI_PATH="/usr/local/share/phpmyadmin/"
else
    DB_GUI_PATH="/usr/local/share/adminer/"
fi


# Logrotate Postrotate for Nginx
# From options.conf, nginx = 1, apache = 2
if [ $WEBSERVER -eq 1 ]; then
    POSTROTATE_CMD='[ ! -f /var/run/nginx.pid ] || kill -USR1 `cat /var/run/nginx.pid`'
else
    POSTROTATE_CMD='/etc/init.d/apache2 reload > /dev/null'
fi

# Variables for AWStats/Adminer|phpMyAdmin functions
# The path to find for Adminer|phpMyAdmin and Awstats symbolic links
PUBLIC_HTML_PATH="/home/*/domains/*/public_html"
VHOST_PATH="/home/*/domains/*"

#### Functions Begin ####

function initialize_variables {

    # Initialize variables based on user input. For add/rem functions displayed by the menu
    DOMAINS_FOLDER="/home/$DOMAIN_OWNER/domains"
    DOMAIN_PATH="/home/$DOMAIN_OWNER/domains/$DOMAIN"
    GIT_PATH="/home/$DOMAIN_OWNER/repos/$DOMAIN.git"

    # From options.conf, nginx = 1, apache = 2
    if [ $WEBSERVER -eq 1 ]; then
        DOMAIN_CONFIG_PATH="/etc/nginx/sites-available/$DOMAIN"
        DOMAIN_ENABLED_PATH="/etc/nginx/sites-enabled/$DOMAIN"
    else
        DOMAIN_CONFIG_PATH="/etc/apache2/sites-available/$DOMAIN"
        DOMAIN_ENABLED_PATH="/etc/apache2/sites-enabled/$DOMAIN"
    fi

    # Awstats command to be placed in logrotate file
    if [ $AWSTATS_ENABLE = 'yes' ]; then
        AWSTATS_CMD="/usr/share/awstats/tools/awstats_buildstaticpages.pl -update -config=$DOMAIN -dir=$DOMAIN_PATH/awstats -awstatsprog=/usr/lib/cgi-bin/awstats.pl > /dev/null"
    else
        AWSTATS_CMD=""
    fi

    # Name of the logrotate file
    LOGROTATE_FILE="domain-$DOMAIN"

}


function reload_webserver {

    # From options.conf, nginx = 1, apache = 2
    if [ $WEBSERVER -eq 1 ]; then
        service nginx reload
    else
        apache2ctl graceful
    fi

} # End function reload_webserver


function php_fpm_add_user {

    # Copy over FPM template for this Linux user if it doesn't exist
    if [ ! -e /etc/php5/fpm/pool.d/$DOMAIN_OWNER.conf ]; then
        cp /etc/php5/fpm/pool.d/{www.conf,$DOMAIN_OWNER.conf}

        # Change pool user, group and socket to the domain owner
        sed -i 's/^\[www\]$/\['${DOMAIN_OWNER}'\]/' /etc/php5/fpm/pool.d/$DOMAIN_OWNER.conf
        sed -i 's/^listen =.*/listen = \/var\/run\/php5-fpm-'${DOMAIN_OWNER}'.sock/' /etc/php5/fpm/pool.d/$DOMAIN_OWNER.conf
        sed -i 's/^user = www-data$/user = '${DOMAIN_OWNER}'/' /etc/php5/fpm/pool.d/$DOMAIN_OWNER.conf
        sed -i 's/^group = www-data$/group = '${DOMAIN_OWNER}'/' /etc/php5/fpm/pool.d/$DOMAIN_OWNER.conf
        sed -i 's/^;listen.mode =.*/listen.mode = 0660/' /etc/php5/fpm/pool.d/$DOMAIN_OWNER.conf

       if [ $USE_NGINX_ORG_REPO = "yes" ]; then
            sed -i 's/^;listen.owner =.*/listen.owner = nginx/' /etc/php5/fpm/pool.d/$DOMAIN_OWNER.conf
            sed -i 's/^;listen.group =.*/listen.group = nginx/' /etc/php5/fpm/pool.d/$DOMAIN_OWNER.conf
        else
            sed -i 's/^;listen.owner =.*/listen.owner = www-data/' /etc/php5/fpm/pool.d/$DOMAIN_OWNER.conf
            sed -i 's/^;listen.group =.*/listen.group = www-data/' /etc/php5/fpm/pool.d/$DOMAIN_OWNER.conf
        fi
    fi

    service php5-fpm restart

} # End function php_fpm_add_user


function add_domain {

    # Create public_html and log directories for domain
    mkdir -p $DOMAIN_PATH/{logs,public_html}
    touch $DOMAIN_PATH/logs/{access.log,error.log}

    cat > $DOMAIN_PATH/public_html/index.html <<EOF
<html>
<head>
<title>Welcome to $DOMAIN</title>
</head>
<body>
<h1>Welcome to $DOMAIN</h1>
<p>This page is simply a placeholder for your domain. Place your content in the appropriate directory to see it here. </p>
<p>Please replace or delete index.html when uploading or creating your site.</p>
</body>
</html>
EOF

    # Setup awstats directories
    if [ $AWSTATS_ENABLE = 'yes' ]; then
        mkdir -p $DOMAIN_PATH/{awstats,awstats/.data}
        cd $DOMAIN_PATH/awstats/
        # Create a symbolic link to awstats generated report named index.html
        ln -s awstats.$DOMAIN.html index.html
        # Create link to the icons folder so that reports icons can be loaded
        ln -s /usr/share/awstats/icon awstats-icon
        cd - &> /dev/null
    fi

    # Set permissions
    chown $DOMAIN_OWNER:$DOMAIN_OWNER $DOMAINS_FOLDER
    chown -R $DOMAIN_OWNER:$DOMAIN_OWNER $DOMAIN_PATH
    # Allow execute permissions to group and other so that the webserver can serve files
    chmod 711 $DOMAINS_FOLDER
    chmod 711 $DOMAIN_PATH

    # Virtualhost entry
    # From options.conf, nginx = 1, apache = 2
    if [ $WEBSERVER -eq 1 ]; then
        # Nginx webserver. Use Nginx vHost config
        cat > $DOMAIN_CONFIG_PATH <<EOF
server {
        listen 80;
        #listen [::]:80 default ipv6only=on;

        server_name www.$DOMAIN $DOMAIN;
        root $DOMAIN_PATH/public_html;
        access_log $DOMAIN_PATH/logs/access.log;
        error_log $DOMAIN_PATH/logs/error.log;

        index index.php index.html index.htm;
        error_page 404 /404.html;

        location / {
            try_files \$uri \$uri/ /index.php?\$args;
        }

        # Pass PHP scripts to PHP-FPM
        location ~ \.php$ {
            try_files \$uri =403;
            fastcgi_pass unix:/var/run/php5-fpm-$DOMAIN_OWNER.sock;
            include fastcgi_params;
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME  \$document_root\$fastcgi_script_name;
        }

        # Enable browser cache for CSS / JS
        location ~* \.(?:css|js)$ {
            expires 30d;
            add_header Pragma "public";
            add_header Cache-Control "public";
            add_header Vary "Accept-Encoding";
        }

        # Enable browser cache for static files
        location ~* \.(?:ico|jpg|jpeg|gif|png|bmp|webp|tiff|svg|svgz|pdf|mp3|flac|ogg|mid|midi|wav|mp4|webm|mkv|ogv|wmv|eot|otf|woff|ttf|rss|atom|zip|7z|tgz|gz|rar|bz2|tar|exe|doc|docx|xls|xlsx|ppt|pptx|rtf|odt|ods|odp)$ {
            expires 60d;
            add_header Pragma "public";
            add_header Cache-Control "public";
        }

        # Deny access to hidden files
        location ~ (^|/)\. {
            deny all;
        }

        # Prevent logging of favicon and robot request errors
        location = /favicon.ico { log_not_found off; access_log off; }
        location = /robots.txt  { log_not_found off; access_log off; }
}


server {
        listen 443 ssl spdy;
        server_name www.$DOMAIN $DOMAIN;
        root $DOMAIN_PATH/public_html;
        access_log $DOMAIN_PATH/logs/access.log;
        error_log $DOMAIN_PATH/logs/error.log;

        index index.php index.html index.htm;
        error_page 404 /404.html;

        include /etc/nginx/ssl.conf;

        location / {
            try_files \$uri \$uri/ /index.php?\$args;
        }

        location ~ \.php$ {
            try_files \$uri =403;
            fastcgi_pass unix:/var/run/php5-fpm-$DOMAIN_OWNER.sock;
            include fastcgi_params;
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME  \$document_root\$fastcgi_script_name;
        }

        # Enable browser cache for CSS / JS
        location ~* \.(?:css|js)$ {
            expires 30d;
            add_header Pragma "public";
            add_header Cache-Control "public";
            add_header Vary "Accept-Encoding";
        }

        # Enable browser cache for static files
        location ~* \.(?:ico|jpg|jpeg|gif|png|bmp|webp|tiff|svg|svgz|pdf|mp3|flac|ogg|mid|midi|wav|mp4|webm|mkv|ogv|wmv|eot|otf|woff|ttf|rss|atom|zip|7z|tgz|gz|rar|bz2|tar|exe|doc|docx|xls|xlsx|ppt|pptx|rtf|odt|ods|odp)$ {
            expires 60d;
            add_header Pragma "public";
            add_header Cache-Control "public";
        }

        # Deny access to hidden files
        location ~ (^|/)\. {
            deny all;
        }

        # Prevent logging of favicon and robot request errors
        location = /favicon.ico { log_not_found off; access_log off; }
        location = /robots.txt  { log_not_found off; access_log off; }
}
EOF
    else # Use Apache vHost config
        cat > $DOMAIN_CONFIG_PATH <<EOF
<VirtualHost *:80>

    ServerName $DOMAIN
    ServerAlias www.$DOMAIN
    ServerAdmin admin@$DOMAIN
    DocumentRoot $DOMAIN_PATH/public_html/
    ErrorLog $DOMAIN_PATH/logs/error.log
    CustomLog $DOMAIN_PATH/logs/access.log combined

    FastCGIExternalServer $DOMAIN_PATH/php5-fpm -pass-header Authorization -idle-timeout 120 -socket /var/run/php5-fpm-$DOMAIN_OWNER.sock
    Alias /php5-fcgi $DOMAIN_PATH

</VirtualHost>


<IfModule mod_ssl.c>
<VirtualHost *:443>

    ServerName $DOMAIN
    ServerAlias www.$DOMAIN
    ServerAdmin admin@$DOMAIN
    DocumentRoot $DOMAIN_PATH/public_html/
    ErrorLog $DOMAIN_PATH/logs/error.log
    CustomLog $DOMAIN_PATH/logs/access.log combined

    # With PHP5-FPM, you need to create another PHP5-FPM pool for SSL connections
    # Adding the same fastcgiexternalserver line here will result in an error
    Alias /php5-fcgi $DOMAIN_PATH

    SSLEngine on
    SSLCertificateFile    /etc/ssl/localcerts/webserver.pem
    SSLCertificateKeyFile /etc/ssl/localcerts/webserver.key
    SSLProtocol           all -SSLv3 -SSLv2

    <FilesMatch "\.(cgi|shtml|phtml|php)$">
        SSLOptions +StdEnvVars
    </FilesMatch>

    BrowserMatch "MSIE [2-6]" nokeepalive ssl-unclean-shutdown downgrade-1.0 force-response-1.0
    BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown

</VirtualHost>
</IfModule>
EOF
    fi # End if $WEBSERVER -eq 1

    if [ $AWSTATS_ENABLE = 'yes' ]; then
        # Configure Awstats for domain
        cp /etc/awstats/awstats.conf /etc/awstats/awstats.$DOMAIN.conf
        sed -i 's/^SiteDomain=.*/SiteDomain="'${DOMAIN}'"/' /etc/awstats/awstats.$DOMAIN.conf
        sed -i 's/^LogFile=.*/\#Deleted LogFile parameter. Appended at the bottom of this config file instead./' /etc/awstats/awstats.$DOMAIN.conf
        sed -i 's/^LogFormat=.*/LogFormat=1/' /etc/awstats/awstats.$DOMAIN.conf
        sed -i 's/^DirData=.*/\#Deleted DirData parameter. Appended at the bottom of this config file instead./' /etc/awstats/awstats.$DOMAIN.conf
        sed -i 's/^DirIcons=.*/DirIcons=".\/awstats-icon"/' /etc/awstats/awstats.$DOMAIN.conf
        sed -i '/Include \"\/etc\/awstats\/awstats\.conf\.local\"/ d' /etc/awstats/awstats.$DOMAIN.conf
        echo "LogFile=\"$DOMAIN_PATH/logs/access.log\"" >> /etc/awstats/awstats.$DOMAIN.conf
        echo "DirData=\"$DOMAIN_PATH/awstats/.data\"" >> /etc/awstats/awstats.$DOMAIN.conf
    fi

    # Add new logrotate entry for domain
    cat > /etc/logrotate.d/$LOGROTATE_FILE <<EOF
$DOMAIN_PATH/logs/*.log {
    daily
    missingok
    rotate 10
    compress
    delaycompress
    notifempty
    create 0660 $DOMAIN_OWNER $DOMAIN_OWNER
    sharedscripts
    prerotate
        $AWSTATS_CMD
    endscript
    postrotate
        $POSTROTATE_CMD
    endscript
}
EOF
    # Enable domain from sites-available to sites-enabled
    ln -s $DOMAIN_CONFIG_PATH $DOMAIN_ENABLED_PATH

    # GIT
    if [ $GIT_ENABLE = 'yes' ]; then
        mkdir -p $GIT_PATH
        cd $GIT_PATH
        git init --bare
        cat > hooks/post-receive <<EOF
#!/bin/sh
    GIT_WORK_TREE=$DOMAIN_PATH git checkout -f
EOF
        chmod +x hooks/post-receive
        cd - &> /dev/null

        # Set permissions
        chown -R $DOMAIN_OWNER:$DOMAIN_OWNER $GIT_PATH
        echo -e "\033[35;1mSuccesfully Created git repository \033[0m"
        echo -e "\033[35;1mgit remote add web ssh://$DOMAIN_OWNER@$HOSTNAME_FQDN:$SSHD_PORT/$GIT_PATH \033[0m"
    fi


} # End function add_domain


function remove_domain {

    echo -e "\033[31;1mWARNING: This will permanently delete everything related to $DOMAIN\033[0m"
    echo -e "\033[31mIf you wish to stop it, press \033[1mCTRL+C\033[0m \033[31mto abort.\033[0m"
    sleep $REMOVE_DOMAIN_TIMER

    # First disable domain and reload webserver
    echo -e "* Disabling domain: \033[1m$DOMAIN\033[0m"
    sleep 1
    rm -rf $DOMAIN_ENABLED_PATH
    reload_webserver

    # Then delete all files and config files
    if [ $AWSTATS_ENABLE = 'yes' ]; then
        echo -e "* Removing awstats config: \033[1m/etc/awstats/awstats.$DOMAIN.conf\033[0m"
        sleep 1
        rm -rf /etc/awstats/awstats.$DOMAIN.conf
    fi

    echo -e "* Removing domain files: \033[1m$DOMAIN_PATH\033[0m"
    sleep 1
    rm -rf $DOMAIN_PATH

    echo -e "* Removing vhost file: \033[1m$DOMAIN_CONFIG_PATH\033[0m"
    sleep 1
    rm -rf $DOMAIN_CONFIG_PATH

    echo -e "* Removing logrotate file: \033[1m/etc/logrotate.d/$LOGROTATE_FILE\033[0m"
    sleep 1
    rm -rf /etc/logrotate.d/$LOGROTATE_FILE

    echo -e "* Removing git repository: \033[1m$GIT_PATH\033[0m"
    sleep 1
    rm -rf $GIT_PATH

} # End function remove_domain


function check_domain_exists {

    # If virtualhost config exists in /sites-available or the vhost directory exists,
    # Return 0 if files exists, otherwise return 1
    if [ -e "$DOMAIN_CONFIG_PATH" ] || [ -e "$DOMAIN_PATH" ]; then
        return 0
    else
        return 1
    fi

} # End function check_domain_exists


function check_domain_valid {

    # Check if the domain entered is actually valid as a domain name
    # NOTE: to disable, set "DOMAIN_CHECK_VALIDITY" to "no" at the start of this script
    if [ "$DOMAIN_CHECK_VALIDITY" = "yes" ]; then
        if [[ "$DOMAIN" =~ [\~\!\@\#\$\%\^\&\*\(\)\_\+\=\{\}\|\\\;\:\'\"\<\>\?\,\/\[\]] ]]; then
            echo -e "\033[35;1mERROR: Domain check failed. Please enter a valid domain.\033[0m"
            echo -e "\033[35;1mERROR: If you are certain this domain is valid, then disable domain checking option at the beginning of the script.\033[0m"
            return 1
        else
            return 0
        fi
    else
    # If $DOMAIN_CHECK_VALIDITY is "no", simply exit
        return 0
    fi

} # End function check_domain_valid


function awstats_on {

    # Search virtualhost directory to look for "stats". In case the user created a stats folder, we do not want to overwrite it.
    stats_folder=`find $PUBLIC_HTML_PATH -maxdepth 1 -name "stats" -print0 | xargs -0 -I path echo path | wc -l`

    # If no stats folder found, find all available public_html folders and create symbolic link to the awstats folder
    if [ $stats_folder -eq 0 ]; then
        find $VHOST_PATH -maxdepth 1 -name "public_html" -type d | xargs -L1 -I path ln -sv ../awstats path/stats
        echo -e "\033[35;1mAwstats enabled.\033[0m"
    else
        echo -e "\033[35;1mERROR: Failed to enable AWStats for all domains. \033[0m"
        echo -e "\033[35;1mERROR: AWStats is already enabled for at least 1 domain. \033[0m"
        echo -e "\033[35;1mERROR: Turn AWStats off again before re-enabling. \033[0m"
        echo -e "\033[35;1mERROR: Also ensure that all your public_html(s) do not have a manually created \"stats\" folder. \033[0m"
    fi

} # End function awstats_on


function awstats_off {

    # Search virtualhost directory to look for "stats" symbolic links
    find $PUBLIC_HTML_PATH -maxdepth 1 -name "stats" -type l -print0 | xargs -0 -I path echo path > /tmp/awstats.txt

    # Remove symbolic links
    while read LINE; do
        rm -rfv $LINE
    done < "/tmp/awstats.txt"
    rm -rf /tmp/awstats.txt

    echo -e "\033[35;1mAwstats disabled. If you do not see any \"removed\" messages, it means it has already been disabled.\033[0m"

} # End function awstats_off


function dbgui_on {

    # Search virtualhost directory to look for "dbgui". In case the user created a "dbgui" folder, we do not want to overwrite it.
    dbgui_folder=`find $PUBLIC_HTML_PATH -maxdepth 1 -name "dbgui" -print0 | xargs -0 -I path echo path | wc -l`

    # If no "dbgui" folders found, find all available public_html folders and create "dbgui" symbolic link to /usr/local/share/adminer|phpmyadmin
    if [ $dbgui_folder -eq 0 ]; then
        find $VHOST_PATH -maxdepth 1 -name "public_html" -type d | xargs -L1 -I path ln -sv $DB_GUI_PATH path/dbgui
        echo -e "\033[35;1mAdminer or phpMyAdmin enabled.\033[0m"
    else
        echo -e "\033[35;1mERROR: Failed to enable Adminer or phpMyAdmin for all domains. \033[0m"
        echo -e "\033[35;1mERROR: It is already enabled for at least 1 domain. \033[0m"
        echo -e "\033[35;1mERROR: Turn it off again before re-enabling. \033[0m"
        echo -e "\033[35;1mERROR: Also ensure that all your public_html(s) do not have a manually created \"dbgui\" folder. \033[0m"
    fi

} # End function dbgui_on


function dbgui_off {

    # Search virtualhost directory to look for "dbgui" symbolic links
    find $PUBLIC_HTML_PATH -maxdepth 1 -name "dbgui" -type l -print0 | xargs -0 -I path echo path > /tmp/dbgui.txt

    # Remove symbolic links
    while read LINE; do
        rm -rfv $LINE
    done < "/tmp/dbgui.txt"
    rm -rf /tmp/dbgui.txt

    echo -e "\033[35;1mAdminer or phpMyAdmin disabled. If \"removed\" messages do not appear, it has been previously disabled.\033[0m"

} # End function dbgui_off


#### Main program begins ####

# Show Menu
if [ ! -n "$1" ]; then
    echo ""
    echo -e "\033[35;1mSelect from the options below to use this script:- \033[0m"
    echo -n  "$0"
    echo -ne "\033[36m add user Domain.tld\033[0m"
    echo     " - Add specified domain to \"user's\" home directory. AWStats(optional) and log rotation will be configured."

    echo -n  "$0"
    echo -ne "\033[36m rem user Domain.tld\033[0m"
    echo     " - Remove everything for Domain.tld including stats and public_html. If necessary, backup domain files before executing!"

    echo -n  "$0"
    echo -ne "\033[36m dbgui on|off\033[0m"
    echo     " - Disable or enable public viewing of Adminer or phpMyAdmin."

    echo -n  "$0"
    echo -ne "\033[36m stats on|off\033[0m"
    echo     " - Disable or enable public viewing of AWStats."

    echo ""
    exit 0
fi
# End Show Menu


case $1 in
add)
    # Add domain for user
    # Check for required parameters
    if [ $# -ne 3 ]; then
        echo -e "\033[31;1mERROR: Please enter the required parameters.\033[0m"
        exit 1
    fi

    # Set up variables
    DOMAIN_OWNER=$2
    DOMAIN=$3
    initialize_variables

    # Check if user exists on system
    if [ ! -d /home/$DOMAIN_OWNER ]; then
        echo -e "\033[31;1mERROR: User \"$DOMAIN_OWNER\" does not exist on this system.\033[0m"
        echo -e " - \033[34mUse \033[1madduser\033[0m \033[34m to add the user to the system.\033[0m"
        echo -e " - \033[34mFor more information, please see \033[1mman adduser\033[0m"
        exit 1
    fi

    # Check if domain is valid
    check_domain_valid
    if [ $? -ne 0 ]; then
        exit 1
    fi

    # Check if domain config files exist
    check_domain_exists
    if [  $? -eq 0  ]; then
        echo -e "\033[31;1mERROR: $DOMAIN_CONFIG_PATH or $DOMAIN_PATH already exists. Please remove before proceeding.\033[0m"
        exit 1
    fi

    add_domain
    php_fpm_add_user
    reload_webserver
    echo -e "\033[35;1mSuccesfully added \"${DOMAIN}\" to user \"${DOMAIN_OWNER}\" \033[0m"
    echo -e "\033[35;1mYou can now upload your site to $DOMAIN_PATH/public_html.\033[0m"
    echo -e "\033[35;1mAdminer/phpMyAdmin is DISABLED by default. URL = http://$DOMAIN/dbgui.\033[0m"
    echo -e "\033[35;1mAWStats is DISABLED by default. URL = http://$DOMAIN/stats.\033[0m"
    echo -e "\033[35;1mStats update daily. Allow 24H before viewing stats or you will be greeted with an error page. \033[0m"
    echo -e "\033[35;1mIf Varnish cache is enabled, please disable & enable it again to reconfigure this domain. \033[0m"
    ;;
rem)
    # Add domain for user
    # Check for required parameters
    if [ $# -ne 3 ]; then
        echo -e "\033[31;1mERROR: Please enter the required parameters.\033[0m"
        exit 1
    fi

    # Set up variables
    DOMAIN_OWNER=$2
    DOMAIN=$3
    initialize_variables

    # Check if user exists on system
    if [ ! -d /home/$DOMAIN_OWNER ]; then
        echo -e "\033[31;1mERROR: User \"$DOMAIN_OWNER\" does not exist on this system.\033[0m"
        exit 1
    fi

    # Check if domain config files exist
    check_domain_exists
    # If domain doesn't exist
    if [ $? -ne 0 ]; then
        echo -e "\033[31;1mERROR: $DOMAIN_CONFIG_PATH and/or $DOMAIN_PATH does not exist, exiting.\033[0m"
        echo -e " - \033[34;1mNOTE:\033[0m \033[34mThere may be files left over. Please check manually to ensure everything is deleted.\033[0m"
        exit 1
    fi

    remove_domain
    ;;
dbgui)
    if [ "$2" = "on" ]; then
        dbgui_on
    elif [ "$2" = "off" ]; then
        dbgui_off
    fi
    ;;
stats)
    if [ "$2" = "on" ]; then
        awstats_on
    elif [ "$2" = "off" ]; then
        awstats_off
    fi
    ;;
esac


================================================
FILE: install.sh
================================================
#!/bin/bash

# First uninstall any unnecessary packages.
apt-get update
apt-get -y install nano
apt-get -y install lsb-release
service apache2 stop
service sendmail stop
service bind9 stop
service nscd stop
apt-get -y purge nscd bind9 sendmail apache2 apache2.2-common

echo ""
echo "Configuring /etc/apt/sources.list."
sleep 5
./setup.sh apt

echo ""
echo "Installing updates & configuring SSHD / hostname."
sleep 5
./setup.sh basic

echo ""
echo "Installing LAMP or LNMP stack."
sleep 5
./setup.sh install

echo ""
echo "Optimizing AWStats, PHP, logrotate & webserver config."
sleep 5
./setup.sh optimize

## Uncomment to secure /tmp folder
#echo ""
#echo "Securing /tmp directory."
## Use tmpdd here if your server has under 256MB memory. Tmpdd will consume a 1GB disk space for /tmp
#./setup.sh tmpfs

echo ""
echo "Installation complete!"
echo "Root login disabled."
echo "Please add a normal user now using the \"adduser\" command."


================================================
FILE: options.conf
================================================
# Hostname can be anything. E.g. "vps", "zeus", "jupiter"
# FQDN can be any domain that you own and doesn't have to be hosted on this server
HOSTNAME=srv1
HOSTNAME_FQDN=srv1.yourdomain.com
SERVER_IP="0.0.0.0"
SSHD_PORT=22

# Set an admin email account to be used for various system notifications and alerts
ADMIN_EMAIL="admin@yourdomain.com"

# Choose whether you want to maintain 'root login' or not. Options = yes|no
ROOT_LOGIN=no

# Configure /etc/apt/sources.list to use redirector/geolocation mirrors
# Improves package download speeds. Options = yes|no
CONFIGURE_APT=no

# Nginx = 1, Apache = 2
WEBSERVER=1

# Oracle MySQL = 1, MariaDB = 2, Percona = 3
DBSERVER=1

# MariaDB 5.5 options
# Generate preferred repo from https://downloads.mariadb.org/mariadb/repositories/
# Specify repository's hostname if using another mirror. Required for APT pinning
MARIADB_REPO='http://ftp.osuosl.org/pub/mariadb/repo/5.5/'
MARIADB_REPO_HOSTNAME='ftp.osuosl.org'

# Enable official nginx.org repository. Options = yes|no
# Faster nginx updates, fewer compiled in modules
USE_NGINX_ORG_REPO=no

# Root password for MySQL, MariaDB or Percona
MYSQL_ROOT_PASSWORD=abcd1234

# phpMyAdmin = 1, Adminer = 2
DB_GUI=1

# Set amount of RAM for Varnish cache
VARNISH_CACHE_SIZE=50M
# Varnish version. Only used for Debian stable or Ubuntu LTS.
VARNISH_VER=3.0


#########################################################
# You may simply use the defaults for the options below #
#########################################################

# Enable or disable AWStats. Options = yes|no
AWSTATS_ENABLE=yes

# Enable or disable Git. Options = yes|no
GIT_ENABLE=no

# Any other packages that you wish to install. Leave empty if nothing more is needed
# Eg. MISC_PACKAGES="htop dnsutils vim tmux imagemagick"
MISC_PACKAGES=""

# Configure PHP. Recommended to leave PHP_BASE unchanged
# You may safely remove all the modules in PHP_EXTRAS
PHP_BASE="php5-fpm php5-common php-apc php5-mysqlnd php5-dev"
PHP_EXTRAS="php5-memcache php5-curl php5-mcrypt php5-xsl php5-gd php5-imagick php5-snmp php5-xmlrpc"

# Settings for php.ini
PHP_MEMORY_LIMIT=96M
PHP_MAX_EXECUTION_TIME=120
PHP_MAX_INPUT_TIME=300
PHP_POST_MAX_SIZE=25M
PHP_UPLOAD_MAX_FILESIZE=25M

# Settings for PHP5-FPM's pool
FPM_MAX_CHILDREN=5
FPM_START_SERVERS=1
FPM_MIN_SPARE_SERVERS=1
FPM_MAX_SPARE_SERVERS=2
FPM_MAX_REQUESTS=5000

# Size of the /tmp folder if you use "tmpdd" instead of "tmpfs". Default is 1GB
# Increase if you need larger but your free disk space will be reduced accordingly
TMP_SIZE=1000000



================================================
FILE: setup.sh
================================================
###############################################################################################
# TuxLite - Complete LNMP/LAMP setup script for Debian/Ubuntu                                 #
# Nginx/Apache + PHP5-FPM + MySQL                                                             #
# Stack is optimized/tuned for a 256MB server                                                 #
# Email your questions to s@tuxlite.com                                                       #
###############################################################################################

source ./options.conf

# Detect distribution. Debian or Ubuntu
DISTRO=`lsb_release -i -s`
# Distribution's release. Squeeze, wheezy, precise etc
RELEASE=`lsb_release -c -s`
if  [ $DISTRO = "" ]; then
    echo -e "\033[35;1mPlease run 'apt-get -y install lsb-release' before using this script.\033[0m"
    exit 1
fi


#### Functions Begin ####

function basic_server_setup {

    apt-get update && apt-get -y safe-upgrade

    # Reconfigure sshd - change port and disable root login
    sed -i 's/^Port [0-9]*/Port '${SSHD_PORT}'/' /etc/ssh/sshd_config
    if  [ $ROOT_LOGIN = "no" ]; then
        sed -i 's/PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config
    fi;
    service ssh reload

    # Set hostname and FQDN
    sed -i 's/'${SERVER_IP}'.*/'${SERVER_IP}' '${HOSTNAME_FQDN}' '${HOSTNAME}'/' /etc/hosts
    echo "$HOSTNAME" > /etc/hostname

    if [ $DISTRO = "Debian" ]; then
        # Debian system, use hostname.sh
        service hostname.sh start
    else
        # Ubuntu system, use hostname
        service hostname start
    fi

    # Basic hardening of sysctl.conf
    sed -i 's/^#net.ipv4.conf.all.accept_source_route = 0/net.ipv4.conf.all.accept_source_route = 0/' /etc/sysctl.conf
    sed -i 's/^net.ipv4.conf.all.accept_source_route = 1/net.ipv4.conf.all.accept_source_route = 0/' /etc/sysctl.conf
    sed -i 's/^#net.ipv6.conf.all.accept_source_route = 0/net.ipv6.conf.all.accept_source_route = 0/' /etc/sysctl.conf
    sed -i 's/^net.ipv6.conf.all.accept_source_route = 1/net.ipv6.conf.all.accept_source_route = 0/' /etc/sysctl.conf
    if  [ $ROOT_LOGIN = "no" ]; then
        echo -e "\033[35;1m Root login disabled, SSH port set to $SSHD_PORT. Hostname set to $HOSTNAME and FQDN to $HOSTNAME_FQDN. \033[0m"
        echo -e "\033[35;1m Remember to create a normal user account for login or you will be locked out from your box! \033[0m"
    else
        echo -e "\033[35;1m Root login active, SSH port set to $SSHD_PORT. Hostname set to $HOSTNAME and FQDN to $HOSTNAME_FQDN. \033[0m"
    fi

} # End function basic_server_setup


function setup_apt {

    # If user enables apt option in options.conf
    if [ $CONFIGURE_APT = "yes" ]; then
        cp /etc/apt/{sources.list,sources.list.bak}

        if [ $DISTRO = "Debian" ]; then
            # Debian system, use Debian sources.list
            echo -e "\033[35;1mConfiguring APT for Debian. \033[0m"
            cat > /etc/apt/sources.list <<EOF
# Main repo
deb http://http.debian.net/debian $RELEASE main non-free contrib
deb-src http://http.debian.net/debian $RELEASE main non-free contrib
# Security
deb http://security.debian.org/ $RELEASE/updates main contrib non-free
deb-src http://security.debian.org/ $RELEASE/updates main contrib non-free

EOF
        fi # End if DISTRO = Debian


        if [ $DISTRO = "Ubuntu" ]; then
            # Ubuntu system, use Ubuntu sources.list
            echo -e "\033[35;1mConfiguring APT for Ubuntu. \033[0m"
            cat > /etc/apt/sources.list <<EOF
# Main repo
deb mirror://mirrors.ubuntu.com/mirrors.txt $RELEASE main restricted universe multiverse
deb-src mirror://mirrors.ubuntu.com/mirrors.txt $RELEASE main restricted universe multiverse

# Security & updates
deb mirror://mirrors.ubuntu.com/mirrors.txt $RELEASE-updates main restricted universe multiverse
deb-src mirror://mirrors.ubuntu.com/mirrors.txt $RELEASE-updates main restricted universe multiverse
deb mirror://mirrors.ubuntu.com/mirrors.txt $RELEASE-security main restricted universe multiverse
deb-src mirror://mirrors.ubuntu.com/mirrors.txt $RELEASE-security main restricted universe multiverse

EOF
        fi # End if DISTRO = Ubuntu


        #  Report error if detected distro is not yet supported
        if [ $DISTRO  != "Ubuntu" ] && [ $DISTRO  != "Debian" ]; then
            echo -e "\033[35;1mSorry, Distro: $DISTRO and Release: $RELEASE is not supported at this time. \033[0m"
            exit 1
        fi

    fi # End if CONFIGURE_APT = yes


    ## Third party mirrors ##

    # Need to add Dotdeb repo for installing PHP5-FPM when using Debian 6.0 (squeeze)
    if  [ $DISTRO = "Debian" ] && [ $RELEASE = "squeeze" ]; then
        echo -e "\033[35;1mEnabling DotDeb repo for Debian 6.0 Squeeze. \033[0m"
        cat > /etc/apt/sources.list.d/dotdeb.list <<EOF
# Dotdeb
deb http://packages.dotdeb.org squeeze all
deb-src http://packages.dotdeb.org squeeze all

EOF
        wget http://www.dotdeb.org/dotdeb.gpg
        cat dotdeb.gpg | apt-key add -
    fi # End if DISTRO = Debian && RELEASE = squeeze


    # If user wants to install nginx from official repo and webserver=nginx
    if  [ $USE_NGINX_ORG_REPO = "yes" ] && [ $WEBSERVER = 1 ]; then
        echo -e "\033[35;1mEnabling nginx.org repo for Debian $RELEASE. \033[0m"
        cat > /etc/apt/sources.list.d/nginx.list <<EOF
# Official Nginx.org repository
deb http://nginx.org/packages/`echo $DISTRO | tr '[:upper:]' '[:lower:]'`/ $RELEASE nginx
deb-src http://nginx.org/packages/`echo $DISTRO | tr '[:upper:]' '[:lower:]'`/ $RELEASE nginx

EOF

        # Set APT pinning for Nginx package
        cat > /etc/apt/preferences.d/Nginx <<EOF
# Prevent potential conflict with main repo/dotdeb
# Always install from official nginx.org repo
Package: nginx
Pin: origin nginx.org
Pin-Priority: 1000

EOF
        wget http://nginx.org/packages/keys/nginx_signing.key
        cat nginx_signing.key | apt-key add -
    fi # End if USE_NGINX_ORG_REPO = yes && WEBSERVER = 1


    # If user wants to install MariaDB instead of MySQL
    if [ $DBSERVER = 2 ]; then
        echo -e "\033[35;1mEnabling MariaDB.org repo for $DISTRO $RELEASE. \033[0m"
        cat > /etc/apt/sources.list.d/MariaDB.list <<EOF
# http://mariadb.org/mariadb/repositories/
deb $MARIADB_REPO`echo $DISTRO | tr [:upper:] [:lower:]` $RELEASE main
deb-src $MARIADB_REPO`echo $DISTRO | tr [:upper:] [:lower:]` $RELEASE main

EOF

        # Set APT pinning for MariaDB packages
        cat > /etc/apt/preferences.d/MariaDB <<EOF
# Prevent potential conflict with main repo that causes
# MariaDB to be uninstalled when upgrading mysql-common
Package: *
Pin: origin $MARIADB_REPO_HOSTNAME
Pin-Priority: 1000

EOF

        # Import MariaDB signing key
        apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 0xcbcb082a1bb943db
    fi # End if user wants to install MariaDB

    # If user wants to install Percona instead of MySQL
    if [ $DBSERVER = 3 ]; then
        echo -e "\033[35;1mEnabling Percona.com repo for $DISTRO $RELEASE. \033[0m"
        cat > /etc/apt/sources.list.d/Percona.list <<EOF
# Percona 5.6 repository list
# http://www.percona.com/doc/percona-server/5.6/installation/apt_repo.html
deb http://repo.percona.com/apt $RELEASE main
deb-src http://repo.percona.com/apt $RELEASE main

EOF

        # Set APT pinning for Percona packages
        cat > /etc/apt/preferences.d/Percona <<EOF
# Prevent potential conflict with main repo that causes
# Percona to be uninstalled when upgrading mysql-common
Package: *
Pin: release o=Percona Development Team
Pin-Priority: 1001

EOF

        # Import Percona signing key
        apt-key adv --keyserver keys.gnupg.net --recv-keys 1C4CBDCDCD2EFD2A
    fi # End if user wants to install Percona


    apt-get update
    echo -e "\033[35;1m Successfully configured /etc/apt/sources.list \033[0m"

} # End function setup_apt


function install_webserver {

    # From options.conf, nginx = 1, apache = 2
    if [ $WEBSERVER = 1 ]; then
        apt-get -y install nginx

        if  [ $USE_NGINX_ORG_REPO = "yes" ]; then
            mkdir /etc/nginx/sites-available
            mkdir /etc/nginx/sites-enabled

           # Disable vhost that isn't in the sites-available folder. Put a hash in front of any line.
           sed -i 's/^[^#]/#&/' /etc/nginx/conf.d/default.conf

           # Enable default vhost in /etc/nginx/sites-available
           ln -s /etc/nginx/sites-available/default /etc/nginx/sites-enabled/default
        fi

        # Add a catch-all default vhost
        cat ./config/nginx_default_vhost.conf > /etc/nginx/sites-available/default

        # Change default vhost root directory to /usr/share/nginx/html;
        sed -i 's/\(root \/usr\/share\/nginx\/\).*/\1html;/' /etc/nginx/sites-available/default

        # Create common SSL config file
        cat > /etc/nginx/ssl.conf <<EOF
ssl on;
ssl_certificate /etc/ssl/localcerts/webserver.pem;
ssl_certificate_key /etc/ssl/localcerts/webserver.key;

ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
EOF

    else
        apt-get -y install libapache2-mod-fastcgi apache2-mpm-event

        a2dismod php4
        a2dismod php5
        a2dismod fcgid
        a2enmod actions
        a2enmod fastcgi
        a2enmod ssl
        a2enmod rewrite

        cat ./config/fastcgi.conf > /etc/apache2/mods-available/fastcgi.conf

        # Create the virtual directory for the external server
        mkdir -p /srv/www/fcgi-bin.d
    fi

} # End function install_webserver


function install_php {

    # Install PHP packages and extensions specified in options.conf
    apt-get -y install $PHP_BASE
    apt-get -y install $PHP_EXTRAS

} # End function install_php


function install_extras {

    if [ $AWSTATS_ENABLE = 'yes' ]; then
        apt-get -y install awstats
    fi

    # Install any other packages specified in options.conf
    apt-get -y install $MISC_PACKAGES

} # End function install_extras


function install_mysql {

    if [ $DBSERVER = 3 ]; then
        echo "percona-server-server-5.6 percona-server-server/root_password password $MYSQL_ROOT_PASSWORD" | debconf-set-selections
        echo "percona-server-server-5.6 percona-server-server/root_password_again password $MYSQL_ROOT_PASSWORD" | debconf-set-selections
    else
        echo "mysql-server mysql-server/root_password password $MYSQL_ROOT_PASSWORD" | debconf-set-selections
        echo "mysql-server mysql-server/root_password_again password $MYSQL_ROOT_PASSWORD" | debconf-set-selections
    fi

    if [ $DBSERVER = 2 ]; then
        apt-get -y install mariadb-server mariadb-client
    elif [ $DBSERVER = 3 ]; then
        apt-get -y install percona-server-server-5.6 percona-server-client-5.6
    else
        apt-get -y install mysql-server mysql-client
    fi

    echo -e "\033[35;1m Securing MySQL... \033[0m"
    sleep 5

    apt-get -y install expect

    SECURE_MYSQL=$(expect -c "
        set timeout 10
        spawn mysql_secure_installation
        expect \"Enter current password for root (enter for none):\"
        send \"$MYSQL_ROOT_PASSWORD\r\"
        expect \"Change the root password?\"
        send \"n\r\"
        expect \"Remove anonymous users?\"
        send \"y\r\"
        expect \"Disallow root login remotely?\"
        send \"y\r\"
        expect \"Remove test database and access to it?\"
        send \"y\r\"
        expect \"Reload privilege tables now?\"
        send \"y\r\"
        expect eof
    ")

    echo "$SECURE_MYSQL"
    apt-get -y purge expect

} # End function install_mysql


function optimize_stack {

    # If using Nginx, copy over nginx.conf
    if [ $WEBSERVER = 1 ]; then
        cat ./config/nginx.conf > /etc/nginx/nginx.conf

        # Change nginx user from  "www-data" to "nginx". Not really necessary
        # because "www-data" user is created when installing PHP5-FPM
        if  [ $USE_NGINX_ORG_REPO = "yes" ]; then
            sed -i 's/^user\s*www-data/user nginx/' /etc/nginx/nginx.conf
        fi

        # Change logrotate for nginx log files to keep 10 days worth of logs
        nginx_file=`find /etc/logrotate.d/ -maxdepth 1 -name "nginx*"`
        sed -i 's/\trotate .*/\trotate 10/' $nginx_file

    # If using Apache, copy over apache2.conf
    else
        cat ./config/apache2.conf > /etc/apache2/apache2.conf

        # Change logrotate for Apache2 log files to keep 10 days worth of logs
        sed -i 's/\tweekly/\tdaily/' /etc/logrotate.d/apache2
        sed -i 's/\trotate .*/\trotate 10/' /etc/logrotate.d/apache2

        # Remove Apache server information from headers.
        sed -i 's/ServerTokens .*/ServerTokens Prod/' /etc/apache2/conf.d/security
        sed -i 's/ServerSignature .*/ServerSignature Off/' /etc/apache2/conf.d/security

        # Add *:443 to ports.conf
        cat ./config/apache2_ports.conf > /etc/apache2/ports.conf
    fi

    if [ $AWSTATS_ENABLE = 'yes' ]; then
        # Configure AWStats
        temp=`grep -i sitedomain /etc/awstats/awstats.conf.local | wc -l`
        if [ $temp -lt 1 ]; then
            echo SiteDomain="$HOSTNAME_FQDN" >> /etc/awstats/awstats.conf.local
        fi
        # Disable Awstats from executing every 10 minutes. Put a hash in front of any line.
        sed -i 's/^[^#]/#&/' /etc/cron.d/awstats
    fi

    service php5-fpm stop
    php_fpm_conf="/etc/php5/fpm/pool.d/www.conf"
    # Limit FPM processes
    sed -i 's/^pm.max_children.*/pm.max_children = '${FPM_MAX_CHILDREN}'/' $php_fpm_conf
    sed -i 's/^pm.start_servers.*/pm.start_servers = '${FPM_START_SERVERS}'/' $php_fpm_conf
    sed -i 's/^pm.min_spare_servers.*/pm.min_spare_servers = '${FPM_MIN_SPARE_SERVERS}'/' $php_fpm_conf
    sed -i 's/^pm.max_spare_servers.*/pm.max_spare_servers = '${FPM_MAX_SPARE_SERVERS}'/' $php_fpm_conf
    sed -i 's/\;pm.max_requests.*/pm.max_requests = '${FPM_MAX_REQUESTS}'/' $php_fpm_conf
    # Change to socket connection for better performance
    sed -i 's/^listen =.*/listen = \/var\/run\/php5-fpm-www-data.sock/' $php_fpm_conf

    php_ini_dir="/etc/php5/fpm/php.ini"
    # Tweak php.ini based on input in options.conf
    sed -i 's/^max_execution_time.*/max_execution_time = '${PHP_MAX_EXECUTION_TIME}'/' $php_ini_dir
    sed -i 's/^memory_limit.*/memory_limit = '${PHP_MEMORY_LIMIT}'/' $php_ini_dir
    sed -i 's/^max_input_time.*/max_input_time = '${PHP_MAX_INPUT_TIME}'/' $php_ini_dir
    sed -i 's/^post_max_size.*/post_max_size = '${PHP_POST_MAX_SIZE}'/' $php_ini_dir
    sed -i 's/^upload_max_filesize.*/upload_max_filesize = '${PHP_UPLOAD_MAX_FILESIZE}'/' $php_ini_dir
    sed -i 's/^expose_php.*/expose_php = Off/' $php_ini_dir
    sed -i 's/^disable_functions.*/disable_functions = exec,system,passthru,shell_exec,escapeshellarg,escapeshellcmd,proc_close,proc_open,dl,popen,show_source/' $php_ini_dir

    # Generating self signed SSL certs for securing phpMyAdmin, script logins etc
    echo -e " "
    echo -e "\033[35;1m Generating self signed SSL cert... \033[0m"
    mkdir /etc/ssl/localcerts

    apt-get -y install expect

    GENERATE_CERT=$(expect -c "
        set timeout 10
        spawn openssl req -new -x509 -days 3650 -nodes -out /etc/ssl/localcerts/webserver.pem -keyout /etc/ssl/localcerts/webserver.key
        expect \"Country Name (2 letter code) \[AU\]:\"
        send \"\r\"
        expect \"State or Province Name (full name) \[Some-State\]:\"
        send \"\r\"
        expect \"Locality Name (eg, city) \[\]:\"
        send \"\r\"
        expect \"Organization Name (eg, company) \[Internet Widgits Pty Ltd\]:\"
        send \"\r\"
        expect \"Organizational Unit Name (eg, section) \[\]:\"
        send \"\r\"
        expect \"Common Name (eg, YOUR name) \[\]:\"
        send \"\r\"
        expect \"Email Address \[\]:\"
        send \"\r\"
        expect eof
    ")

    echo "$GENERATE_CERT"
    apt-get -y purge expect

    # Tweak my.cnf. Commented out. Best to let users configure my.cnf on their own
    #cp /etc/mysql/{my.cnf,my.cnf.bak}
    #if [ -e /usr/share/doc/mysql-server-5.1/examples/my-medium.cnf.gz ]; then
    #gunzip /usr/share/doc/mysql-server-5.1/examples/my-medium.cnf.gz
    #cp /usr/share/doc/mysql-server-5.1/examples/my-medium.cnf /etc/mysql/my.cnf
    #else
    #gunzip /usr/share/doc/mysql-server-5.0/examples/my-medium.cnf.gz
    #cp /usr/share/doc/mysql-server-5.0/examples/my-medium.cnf /etc/mysql/my.cnf
    #fi
    #sed -i '/myisam_sort_buffer_size/ a\skip-innodb' /etc/mysql/my.cnf
    #sleep 1
    #service mysql restart

    restart_webserver
    sleep 2
    service php5-fpm start
    sleep 2
    service php5-fpm restart
    echo -e "\033[35;1m Optimize complete! \033[0m"

} # End function optimize


function install_postfix {

    # Install postfix
    echo "postfix postfix/main_mailer_type select Internet Site" | debconf-set-selections
    echo "postfix postfix/mailname string $HOSTNAME_FQDN" | debconf-set-selections
    echo "postfix postfix/destinations string localhost.localdomain, localhost" | debconf-set-selections
    apt-get -y install postfix

    # Allow mail delivery from localhost only
    /usr/sbin/postconf -e "inet_interfaces = loopback-only"

    sleep 1
    postfix stop
    sleep 1
    postfix start

} # End function install_postfix



function install_dbgui {

    # If user selected phpMyAdmin in options.conf
    if [ $DB_GUI = 1  ]; then
        mkdir /tmp/phpmyadmin
        PMA_VER="`wget -q -O - https://www.phpmyadmin.net/downloads/|grep -m 1 '<h2>phpMyAdmin'|sed -r 's/^[^3-9]*([0-9.]*).*/\1/'`"
        wget -O - "https://files.phpmyadmin.net/phpMyAdmin/${PMA_VER}/phpMyAdmin-${PMA_VER}-all-languages.tar.gz" | tar zxf - -C /tmp/phpmyadmin

        # Check exit status to see if download is successful
        if [ $? = 0  ]; then
            mkdir /usr/local/share/phpmyadmin
            rm -rf /usr/local/share/phpmyadmin/*
            cp -Rpf /tmp/phpmyadmin/*/* /usr/local/share/phpmyadmin
            cp /usr/local/share/phpmyadmin/{config.sample.inc.php,config.inc.php}
            rm -rf /tmp/phpmyadmin

            # Generate random blowfish string
            LENGTH="20"
            MATRIX="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
            while [ "${n:=1}" -le "$LENGTH" ]; do
                BLOWFISH="$BLOWFISH${MATRIX:$(($RANDOM%${#MATRIX})):1}"
                let n+=1
            done

            # Configure phpmyadmin blowfish variable
            sed -i "s/blowfish_secret'] = ''/blowfish_secret'] = \'$BLOWFISH\'/"  /usr/local/share/phpmyadmin/config.inc.php
            echo -e "\033[35;1mphpMyAdmin installed/upgraded.\033[0m"
        else
            echo -e "\033[35;1mInstall/upgrade failed. Perhaps phpMyAdmin download link is temporarily down. Update link in options.conf and try again.\033[0m"
        fi

    else # User selected Adminer

        mkdir -p /usr/local/share/adminer
        cd /usr/local/share/adminer
        rm -rf /usr/local/share/adminer/*
        wget http://www.adminer.org/latest.php
        if [ $? = 0  ]; then
            mv latest.php index.php
            echo -e "\033[35;1m Adminer installed. \033[0m"
        else
            echo -e "\033[35;1mInstall/upgrade failed. Perhaps http://adminer.org is down. Try again later.\033[0m"
        fi
        cd - &> /dev/null
    fi # End if DB_GUI

} # End function install_dbgui


function check_tmp_secured {

    temp1=`grep -w "/var/tempFS /tmp ext3 loop,nosuid,noexec,rw 0 0" /etc/fstab | wc -l`
    temp2=`grep -w "tmpfs /tmp tmpfs rw,noexec,nosuid 0 0" /etc/fstab | wc -l`

    if [ $temp1  -gt 0 ] || [ $temp2 -gt 0 ]; then
        return 1
    else
        return 0
    fi

} # End function check_tmp_secured


function secure_tmp_tmpfs {

    cp /etc/fstab /etc/fstab.bak
    # Backup /tmp
    cp -Rpf /tmp /tmpbackup

    rm -rf /tmp
    mkdir /tmp

    mount -t tmpfs -o rw,noexec,nosuid tmpfs /tmp
    chmod 1777 /tmp
    echo "tmpfs /tmp tmpfs rw,noexec,nosuid 0 0" >> /etc/fstab

    # Restore /tmp
    cp -Rpf /tmpbackup/* /tmp/ >/dev/null 2>&1

    #Remove old tmp dir
    rm -rf /tmpbackup

    # Backup /var/tmp and link it to /tmp
    mv /var/tmp /var/tmpbackup
    ln -s /tmp /var/tmp

    # Copy the old data back
    cp -Rpf /var/tmpold/* /tmp/ >/dev/null 2>&1
    # Remove old tmp dir
    rm -rf /var/tmpbackup

    echo -e "\033[35;1m /tmp and /var/tmp secured using tmpfs. \033[0m"

} # End function secure_tmp_tmpfs


function secure_tmp_dd {

    cp /etc/fstab /etc/fstab.bak

    # Create 1GB space for /tmp, change count if you want smaller/larger size
    dd if=/dev/zero of=/var/tempFS bs=1024 count=$TMP_SIZE
    # Make space as a ext3 filesystem
    /sbin/mkfs.ext3 /var/tempFS

    # Backup /tmp
    cp -Rpf /tmp /tmpbackup

    # Secure /tmp
    mount -o loop,noexec,nosuid,rw /var/tempFS /tmp
    chmod 1777 /tmp
    echo "/var/tempFS /tmp ext3 loop,nosuid,noexec,rw 0 0" >> /etc/fstab

    # Restore /tmp
    cp -Rpf /tmpbackup/* /tmp/ >/dev/null 2>&1

    # Remove old tmp dir
    rm -rf /tmpbackup

    # Backup /var/tmp and link it to /tmp
    mv /var/tmp /var/tmpbackup
    ln -s /tmp /var/tmp

    # Copy the old data back
    cp -Rpf /var/tmpold/* /tmp/ >/dev/null 2>&1
    # Remove old tmp dir
    rm -rf /var/tmpbackup

    echo -e "\033[35;1m /tmp and /var/tmp secured using file created using dd. \033[0m"

} # End function secure_tmp_tmpdd


function restart_webserver {

    # From options.conf, nginx = 1, apache = 2
    if [ $WEBSERVER = 1 ]; then
        service nginx restart
    else
        apache2ctl graceful
    fi

} # End function restart_webserver



#### Main program begins ####

# Show Menu
if [ ! -n "$1" ]; then
    echo ""
    echo -e  "\033[35;1mNOTICE: Edit options.conf before using\033[0m"
    echo -e  "\033[35;1mA standard setup would be: apt + basic + install + optimize\033[0m"
    echo ""
    echo -e  "\033[35;1mSelect from the options below to use this script:- \033[0m"

    echo -n "$0"
    echo -ne "\033[36m apt\033[0m"
    echo     " - Reconfigure or reset /etc/apt/sources.list."

    echo -n  "$0"
    echo -ne "\033[36m basic\033[0m"
    echo     " - Disable root SSH logins, change SSH port and set hostname."

    echo -n "$0"
    echo -ne "\033[36m install\033[0m"
    echo     " - Installs LNMP or LAMP stack. Also installs Postfix MTA."

    echo -n "$0"
    echo -ne "\033[36m optimize\033[0m"
    echo     " - Optimizes webserver.conf, php.ini, AWStats & logrotate. Also generates self signed SSL certs."

    echo -n "$0"
    echo -ne "\033[36m dbgui\033[0m"
    echo     " - Installs or updates Adminer/phpMyAdmin."

    echo -n "$0"
    echo -ne "\033[36m tmpfs\033[0m"
    echo     " - Secures /tmp and /var/tmp using tmpfs. Not recommended for servers with less than 512MB dedicated RAM."

    echo -n "$0"
    echo -ne "\033[36m tmpdd\033[0m"
    echo     " - Secures /tmp and /var/tmp using a file created on disk. Tmp size is defined in options.conf."

    echo ""
    exit
fi
# End Show Menu


case $1 in
apt)
    setup_apt
    ;;
basic)
    basic_server_setup
    ;;
install)
    install_webserver
    install_mysql
    install_php
    install_extras
    install_postfix
    restart_webserver
    service php5-fpm restart
    echo -e "\033[35;1m Webserver + PHP-FPM + MySQL install complete! \033[0m"
    ;;
optimize)
    optimize_stack
    ;;
dbgui)
    install_dbgui
    ;;
tmpdd)
    check_tmp_secured
    if [ $? = 0  ]; then
        secure_tmp_dd
    else
        echo -e "\033[35;1mFunction canceled. /tmp already secured. \033[0m"
    fi
    ;;
tmpfs)
    check_tmp_secured
    if [ $? = 0  ]; then
        secure_tmp_tmpfs
    else
        echo -e "\033[35;1mFunction canceled. /tmp already secured. \033[0m"
    fi
    ;;
esac




================================================
FILE: varnish.sh
================================================
#!/bin/bash

source ./options.conf

# Detect distribution. Debian or Ubuntu
DISTRO=`lsb_release -i -s`
# Distribution's release. Squeeze, wheezy, precise etc
RELEASE=`lsb_release -c -s`
if  [ $DISTRO = "" ]; then
    echo -e "\033[35;1mPlease run 'apt-get -y install lsb-release' before using this script.\033[0m"
    exit 1
fi

function setup_varnish {

    # Use official varnish-cache.org repo for Debian stable and Ubuntu LTS.
    # Otherwise, install from distro's repo
    if [ $DISTRO = "Debian" ]; then
        if [ $RELEASE = "squeeze" ] || [ $RELEASE = "wheezy" ]; then
            apt-get update && apt-get -y install curl
            curl http://repo.varnish-cache.org/debian/GPG-key.txt | apt-key add -
            echo "deb http://repo.varnish-cache.org/debian/ ${RELEASE} varnish-${VARNISH_VER}" > /etc/apt/sources.list.d/varnish.list
        fi
    fi

    if [ $DISTRO = "Ubuntu" ]; then
        if [ $RELEASE = "lucid" ] || [ $RELEASE = "precise" ]; then
            apt-get update && apt-get -y install curl
            curl http://repo.varnish-cache.org/debian/GPG-key.txt | apt-key add -
            echo "deb http://repo.varnish-cache.org/ubuntu/ ${RELEASE} varnish-${VARNISH_VER}" > /etc/apt/sources.list.d/varnish.list
        fi
    fi

    apt-get update
    apt-get -y install varnish

    # If using Apache, install mod_rpaf to get remote IP of forwarded requests
    if [ $WEBSERVER -eq 2 ]; then
        apt-get -y install libapache2-mod-rpaf
    fi

    # Create a backup copy of the original config file. Don't do anything if file exists
    if [ ! -e /etc/default/varnish_original.backup ]; then
        cp /etc/default/{varnish,varnish_original.backup}
    fi

    # Clear config file
    > /etc/default/varnish

    # Configure varnish to listen on port 80, with user specified cache size in options.conf
    cat > /etc/default/varnish <<EOF
START=no
NFILES=131072
MEMLOCK=82000

DAEMON_OPTS="-a :80 \\
             -T localhost:6082 \\
             -f /etc/varnish/default.vcl \\
             -S /etc/varnish/secret \\
             -s malloc,${VARNISH_CACHE_SIZE}"
EOF

    # Stop Varnish first since this is only the install function
    service varnish stop

} # End function setup_varnish

function varnish_on {

    # Allow Varnish to start
    sed -i 's/START=no/START=yes/' /etc/default/varnish
    # From options.conf, nginx = 1, apache = 2
    if [ $WEBSERVER -eq 1 ]; then
        # Change Nginx virtualhost ports to 8080
        echo 'Changing "Listen 80;" to "Listen 8080;" for vhosts in /etc/nginx/sites-available/'
        # First fix broken "default" vhost listen directive added by Debian package managers
        sed -i 's/#listen\s*80;/listen 8080;/' /etc/nginx/sites-available/*
        # Change the rest of the vhost to listen on port 8080
        sed -i 's/listen\s*80;/listen 8080;/' /etc/nginx/sites-available/*
        # TuxLite optimized default vhost uses a catch-all (default_server) listen directive.
        sed -i 's/listen\s*80\s*default_server;/listen 8080 default_server;/' /etc/nginx/sites-available/*

        # Make sure external IP is forwarded to Nginx instead of Varnish's 127.0.0.1 IP.
        sed -i '/http {/ a\    set_real_ip_from 127.0.0.1\;' /etc/nginx/nginx.conf
        sed -i '/http {/ a\    real_ip_header X-Forwarded-For\;' /etc/nginx/nginx.conf

        service nginx restart
        sleep 2
        service varnish start
    else
        # Change Apache virtualhost ports to 8080
        echo 'Changing port 80 to 8080 for vhosts in /etc/apache2/sites-available/'
        sed -i 's/:80$/:8080/' /etc/apache2/ports.conf
        sed -i 's/Listen 80$/Listen 8080/' /etc/apache2/ports.conf
        sed -i 's/:80>$/:8080>/' /etc/apache2/sites-available/*

        apache2ctl restart
        sleep 2
        service varnish start
    fi


} # End function varnish_on


function varnish_off {

    # Deny Varnish from starting
    sed -i 's/START=yes/START=no/' /etc/default/varnish

    # From options.conf, nginx = 1, apache = 2
    if [ $WEBSERVER -eq 1 ]; then
        # Revert Nginx virtualhost ports to 80
        echo 'Changing "Listen 8080;" to "Listen 80;" for vhosts in /etc/nginx/sites-available/'
        sed -i 's/listen\s*8080;/listen 80;/' /etc/nginx/sites-available/*
        # TuxLite optimized default vhost uses a catch-all (default_server) listen directive.
        sed -i 's/listen\s*8080\s*default_server;/listen 80 default_server;/' /etc/nginx/sites-available/*

        # Remove IP forwarding.
        sed -i '/set_real_ip_from 127.0.0.1\;/ d' /etc/nginx/nginx.conf
        sed -i '/real_ip_header X-Forwarded-For\;/ d' /etc/nginx/nginx.conf

        service varnish stop
        sleep 2
        service nginx restart
    else
        #Revert Apache virtualhost ports to 80
        echo 'Changing port 8080 to 80 for vhosts in /etc/apache2/sites-available/'
        sed -i 's/:8080$/:80/' /etc/apache2/ports.conf
        sed -i 's/Listen 8080/Listen 80/' /etc/apache2/ports.conf
        sed -i 's/:8080>$/:80>/' /etc/apache2/sites-available/*

        service varnish stop
        sleep 2
        apache2ctl restart
    fi

} # End function varnish_off

# Start main program
if [ ! -n "$1" ]; then
    echo ""

    echo -n "$0"
    echo -ne "\033[36m install\033[0m"
    echo     " - Installs and configures Varnish cache."

    echo -n "$0"
    echo -ne "\033[36m on\033[0m"
    echo     " - Starts Varnish. Changes vhost ports to 8080."

    echo -n "$0"
    echo -ne "\033[36m off\033[0m"
    echo     " - Stops Varnish. Reverts vhost ports back to 80."

    echo ""
    exit
fi

case $1 in
install)
    setup_varnish
    echo -e "\033[35;1m Varnish now installed and configured with a ${VARNISH_CACHE_SIZE} cache size. \033[0m"
  ;;
on)
    varnish_on
    echo -e "\033[35;1m Varnish now enabled. \033[0m"
  ;;
off)
    varnish_off
    echo -e "\033[35;1m Varnish disabled. \033[0m"
  ;;
esac


================================================
FILE: wordpress.sh
================================================
#!/bin/bash

source ./options.conf

FIND_PATH="/home/*/domains/*/public_html/"
AWK_DOMAIN_POS="5"

# Used variables
DB_NAME=""
DB_USER=""
DB_USER_PASS=""
WP_FOLDER=""
DOMAIN=""
DOMAIN_OWNER=""
INSTALL_PATH="${DOMAIN}${WP_FOLDER}"
DOMAIN_URL=""

function check_mysql_installed {

    mysql=`which mysql`
    if [ -x $mysql ]; then
        echo "MySQL server installed. OK."
        return 0
    else
        return 1
    fi

} # End function check_mysql_installed


function check_wordpress_exists {

    # Need to check if existing wordpress is installed on the desired path

    if [ -e $INSTALL_PATH/wp-config.php ]; then
        return 1
    else
        return 0
    fi

} # End function check_wordpress_exists

function check_database_exists {

    # Check if database already exists

    if [ -d /var/lib/mysql/$DB_NAME ]; then
        return 1
    else
        return 0
    fi

} # End function check_database_exists

function get_latest_wordpress {

    # Downlod latest wordpress version to tmp and extract
    mkdir /tmp/wordpress
    wget -O - http://wordpress.org/latest.tar.gz | tar zxf - -C /tmp/wordpress &> /dev/null

    # Create new path for wordpress and copy files to it
    mkdir $INSTALL_PATH &> /dev/null
    mv /tmp/wordpress/wordpress/* $INSTALL_PATH

    # Create wp-config.php file
    cp $INSTALL_PATH/{wp-config-sample.php,wp-config.php}
    chown -R $DOMAIN_OWNER:$DOMAIN_OWNER $DOMAIN

    # Edit wp-config.php file with mysql data
    sed -i 's/database_name_here/'${DB_NAME}'/' $INSTALL_PATH/wp-config.php
    sed -i 's/username_here/'${DB_USER}'/' $INSTALL_PATH/wp-config.php
    sed -i ' s/password_here/'${DB_USER_PASS}'/' $INSTALL_PATH/wp-config.php

    rm -rf /tmp/wordpress

} # End function get_latest_wordpress


function add_mysqldb_and_user {

    # Form SQL query string
    Q1="CREATE DATABASE IF NOT EXISTS $DB_NAME;"
    Q2="GRANT ALL ON $DB_NAME.* TO '$DB_USER'@'localhost' IDENTIFIED BY '$DB_USER_PASS';"
    Q3="FLUSH PRIVILEGES;"
    SQL="${Q1}${Q2}${Q3}"

    # Execute the query
    mysql -uroot -p$MYSQL_ROOT_PASSWORD -e "$SQL"

} # End function add_mysqldb_and_user


function find_available_domains {

    DOMAINS_AVAILABLE=0
    find $FIND_PATH -maxdepth 0 &> /dev/null

    # First check to see if there are domains available. Suppress exit status.
    if [ $? -eq 0 ]; then
        find $FIND_PATH -maxdepth 0 > /tmp/domain.txt
        DOMAINS_AVAILABLE=`cat /tmp/domain.txt | wc -l`
    fi

    if [ $DOMAINS_AVAILABLE -eq 0 ]; then
        echo "No domains available for install. Please add a domain first."
        exit
    fi

} # End function find_available_domains

function new_or_existing_domain {

    echo "Would you like to install wordpress on a new domain or an existing one?"
    echo "1. Existing"
    echo "2. New"

    ADD_DOMAIN="a"
    until [[ $ADD_DOMAIN =~ [0-9]+ ]]; do
        echo -n "Selection :"
        read ADD_DOMAIN
    done

    if [[ "$ADD_DOMAIN" = 2 ]]; then
        echo "Please enter the domain you wish to add. Format is domain.tld."
        echo -n "Domain : "
        read DOMAIN_TO_BE_ADDED
        `/root/domainsetup.sh add $DOMAIN_TO_BE_ADDED &> /dev/null`
    fi

} # End function new_or_existing_domain


function generate_random_pass {

    LENGTH="10"
    MATRIX="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"

    while [ "${n:=1}" -le "$LENGTH" ]; do
        PASS="$PASS${MATRIX:$(($RANDOM%${#MATRIX})):1}"
        let n+=1
    done

    DB_USER_PASS=$PASS

} # End function generate_random_pass


function user_input {

    # Ask user which domain to install WP

    counter=1
    DOMAINS_AVAILABLE=`cat /tmp/domain.txt | wc -l`
    echo ""
    echo "Select the domain you want to install wordpress on, 1 to $DOMAINS_AVAILABLE"
    while read LINE; do
        data=`echo $LINE | awk -F"/" '{ print $'${AWK_DOMAIN_POS}' }'`
        echo "$counter. $data"
        let counter+=1
    done < "/tmp/domain.txt"

    let counter-=1

    # Make sure user inputs a valid domain
    SELECTDOMAIN="a"
    until  [[ "$SELECTDOMAIN" =~ [0-9]+ ]] && [ $SELECTDOMAIN -gt 0 ] && [ $SELECTDOMAIN -le $counter ]; do
        echo -n "Selection (integer) : "
        read SELECTDOMAIN
    done

    # Get full system path to domain
    DOMAIN=`cat /tmp/domain.txt | awk NR==$SELECTDOMAIN`

    # Get domain URL
    DOMAIN_URL=`cat /tmp/domain.txt | awk NR==$SELECTDOMAIN | awk -F"/" '{ print $'${AWK_DOMAIN_POS}' }'`

    # Get domain owner
    DOMAIN_OWNER=`cat /tmp/domain.txt | awk NR==$SELECTDOMAIN | awk -F"/" '{ print $3 }'`
    rm -rf /tmp/domain.txt

    # Ask database name for Wordpress
    echo ""
    echo "Enter a database name for the wordpress install. E.g domainwp, wordpress, wpdomain"
    DB_NAME=""
    until  [[ "$DB_NAME" =~ [0-9a-zA-Z]+ ]]; do
        echo -n "Database name : "
        read DB_NAME
    done

    # Ask folder name for Wordpress
    echo ""
    echo "Specify a folder name if you wish to install wordpress to its own folder, \"wordpress\" is recommended. Leave blank to install to root directory."
    echo "The root directory for your selected domain = $DOMAIN"

    echo ""
    echo -n "Folder name : "
    read WP_FOLDER


    # Set database user the same as the database name
    DB_USER=$DB_NAME
    # Get full system path for installation
    INSTALL_PATH="${DOMAIN}${WP_FOLDER}"

} # End function user_input


### Main Program Begins ###

# First generate a random password for the mysql database
generate_random_pass
# Check  to see if any domains are available, or exit
find_available_domains
# Ask user database and folder settings
user_input

echo ""
echo ""
echo "Wordpress setup is ready to begin. Please check to see if the entered details are correct."
echo ""
echo "Install path = $INSTALL_PATH"
echo "Database name = $DB_NAME"
echo "Database user = $DB_USER"
echo "Database Password = $DB_USER_PASS (randomly generated)"
echo ""
echo -n "Is everything correct [y/n] : "

read DECISION

if [[ "$DECISION" = [yY] ]]; then

    check_wordpress_exists
    if [ $? -eq 1 ]; then
       echo "Wordpress already installed in your specified path. Exiting."
       exit
    fi

    check_database_exists
    if [ $? -eq 1 ]; then
       echo "Database \"$DB_NAME\" already exists. Exiting."
       exit
    fi

    check_mysql_installed
    if [ $? -eq 1 ]; then
       echo "MySQL is not installed. Exiting."
       exit
    fi

    echo ""
    echo "Downloading latest version of wordpress..."
    get_latest_wordpress
    echo "Done."

    echo "Setting up MySQL..."
    add_mysqldb_and_user
    echo "Done."
    echo ""

    echo "Wordpress installed successfully!"
    echo "Please browse http://$DOMAIN_URL/$WP_FOLDER to complete the installation."

elif  [[ "$DECISION" = [nN] ]]; then
    echo "Install aborted. Please run the script again if you want to restart the setup."
fi
Download .txt
gitextract_oh2qkkzk/

├── README.md
├── backup.sh
├── config/
│   ├── apache2.conf
│   ├── apache2_ports.conf
│   ├── fastcgi.conf
│   ├── nginx.conf
│   └── nginx_default_vhost.conf
├── domain.sh
├── install.sh
├── options.conf
├── setup.sh
├── varnish.sh
└── wordpress.sh
Condensed preview — 13 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (97K chars).
[
  {
    "path": "README.md",
    "chars": 3335,
    "preview": "### TuxLite Readme\r\n\r\nTuxLite is a free collection of shell scripts for rapid deployment of\r\nLAMP and LNMP stacks (Linux"
  },
  {
    "path": "backup.sh",
    "chars": 11594,
    "preview": "#!/bin/bash\n\nFIND_PATH=\"/home/*/domains/*\"\n# Used to filter database name from its full system path\n# (1)/var(2)/lib(3)/"
  },
  {
    "path": "config/apache2.conf",
    "chars": 9865,
    "preview": "# This is the main Apache server configuration file.  It contains the\n# configuration directives that give the server it"
  },
  {
    "path": "config/apache2_ports.conf",
    "chars": 774,
    "preview": "# If you just change the port or add more ports here, you will likely also\n# have to change the VirtualHost statement in"
  },
  {
    "path": "config/fastcgi.conf",
    "chars": 746,
    "preview": "#Original fastcgi.conf contents\n#<IfModule mod_fastcgi.c>\n#  AddHandler fastcgi-script .fcgi\n#  #FastCgiWrapper /usr/lib"
  },
  {
    "path": "config/nginx.conf",
    "chars": 1251,
    "preview": "user www-data;\nworker_processes 1;\npid /var/run/nginx.pid;\n\nevents {\n    worker_connections 1024;\n    # multi_accept on;"
  },
  {
    "path": "config/nginx_default_vhost.conf",
    "chars": 3414,
    "preview": "# You may add here your\n# server {\n#       ...\n# }\n# statements for each of your virtual hosts to this file\n\n##\n# You sh"
  },
  {
    "path": "domain.sh",
    "chars": 21452,
    "preview": "#!/bin/bash\n######################################################################\n# TuxLite virtualhost script         "
  },
  {
    "path": "install.sh",
    "chars": 939,
    "preview": "#!/bin/bash\n\n# First uninstall any unnecessary packages.\napt-get update\napt-get -y install nano\napt-get -y install lsb-r"
  },
  {
    "path": "options.conf",
    "chars": 2544,
    "preview": "# Hostname can be anything. E.g. \"vps\", \"zeus\", \"jupiter\"\n# FQDN can be any domain that you own and doesn't have to be h"
  },
  {
    "path": "setup.sh",
    "chars": 23783,
    "preview": "###############################################################################################\n# TuxLite - Complete LNM"
  },
  {
    "path": "varnish.sh",
    "chars": 5901,
    "preview": "#!/bin/bash\n\nsource ./options.conf\n\n# Detect distribution. Debian or Ubuntu\nDISTRO=`lsb_release -i -s`\n# Distribution's "
  },
  {
    "path": "wordpress.sh",
    "chars": 6842,
    "preview": "#!/bin/bash\n\nsource ./options.conf\n\nFIND_PATH=\"/home/*/domains/*/public_html/\"\nAWK_DOMAIN_POS=\"5\"\n\n# Used variables\nDB_N"
  }
]

About this extraction

This page contains the full source code of the Mins/TuxLite GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 13 files (90.3 KB), approximately 26.2k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!