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 < /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 < /tmp/tmpcron.txt cat >> /tmp/tmpcron.txt < /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 ); # 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 StartServers 5 MinSpareServers 5 MaxSpareServers 10 MaxRequestWorkers 150 MaxConnectionsPerChild 0 # 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 StartServers 2 MinSpareThreads 25 MaxSpareThreads 75 ThreadLimit 64 ThreadsPerChild 25 MaxRequestWorkers 150 MaxConnectionsPerChild 0 # 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 StartServers 1 MinSpareThreads 2 MaxSpareThreads 5 ThreadLimit 20 ThreadsPerChild 20 MaxRequestWorkers 60 MaxConnectionsPerChild 5000 # 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. # Require all denied Satisfy all # TuxLite. Better to put this block here compared to Debian's default Options Indexes FollowSymLinks AllowOverride All Require all granted # # 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 # container, error messages relating to that virtual host will be # logged here. If you *do* define an error logfile for a # 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 # If you add NameVirtualHost *:443 here, you will also have to change # the VirtualHost statement in /etc/apache2/sites-available/default-ssl # to # Server Name Indication for SSL named virtual hosts is currently not # supported by MSIE on Windows XP. NameVirtualHost *:443 Listen 443 Listen 443 ================================================ FILE: config/fastcgi.conf ================================================ #Original fastcgi.conf contents # # AddHandler fastcgi-script .fcgi # #FastCgiWrapper /usr/lib/apache2/suexec # FastCgiIpcDir /var/lib/apache2/fastcgi # 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 SetHandler php-fpm Action php-fpm /php5-fcgi/php5-fpm Order deny,allow Deny from All Allow from env=REDIRECT_STATUS ================================================ 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 < Welcome to $DOMAIN

Welcome to $DOMAIN

This page is simply a placeholder for your domain. Place your content in the appropriate directory to see it here.

Please replace or delete index.html when uploading or creating your site.

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 <
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 SSLOptions +StdEnvVars BrowserMatch "MSIE [2-6]" nokeepalive ssl-unclean-shutdown downgrade-1.0 force-response-1.0 BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown 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 < hooks/post-receive < /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 < /etc/apt/sources.list < /etc/apt/sources.list.d/dotdeb.list < /etc/apt/sources.list.d/nginx.list < /etc/apt/preferences.d/Nginx < /etc/apt/sources.list.d/MariaDB.list < /etc/apt/preferences.d/MariaDB < /etc/apt/sources.list.d/Percona.list < /etc/apt/preferences.d/Percona < /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 < /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 '

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 <$/: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