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
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.