Bash Script to Create new virtual hosts on Nginx each under a different user

This script is a modified version of the original vhost creator script for nginx posted here (Actually it was a modified version of the original version of this script).

The script below will automatically create a new user on the system and adds the nginx user to the new users group. This allows FTP access to be given to the newly created user and the user will only have access to the their site and not to all vhosts running on your server, however as long as the users group has permission to access the files then nginx will still be able to serve them.

NOTE: This setup only helps lock down access to the vhost directories on a web server hosting only static sites, if CGI of any kind (i.e. PHP) is available then this will also need to be locked down so each user has access to a CGI process or set processes running as that user.

What does the script do:

  • Creates a new system user for the site
  • Creates a new vhost config file for nginx using a basic template
  • Creates a new directory for the site, within the new users home directory
  • Adds a simple index.html file to the new directory to show the site is working.
  • Makes sure the new nginx config syntax is correct before trying to reload nginx
  • Reloads Nginx to allow the new vhost to be detected

How it works:

Under your Nginx config directory (probably /etc/nginx) you need to create two new directories:
  • sites-available
  • sites-enabled

In the “sites-available” dir goes the the individual config files for each vhost, each new vhost using a new file. Under the “sites-enabled” directory goes a symlink to the config file in the sites available directory, this gives you the ability to disable sites without removing the contents of the site or its config. This all works by adding the following line to the end of the “nginx.conf” file (within the http section)

# Load all vhosts !
include /etc/nginx/sites-enabled/*.conf;
Replacing the path of the your nginx configuration if needed.
The hosting directory for the new site can be set by modifying the WEB_DIR value at the top of the script which defaults to /var/www. This is where all vhost users home directories will get created and a public_html directory under that will be created to host the web site.

How to use it:

Simply download the tar file at the end of the this article and extract it. If your not sure how to extract a tar file either read the man pages or use the command below:

tar -xzf create_nginx_vhost.tar.gz

Once you have extracted the archive just run the create_nginx_site.sh script passing to it the domain name as the only parameter (you will need execute permissions), it will prompt you for a username and password for the new user. e.g.

./create_nginx_site.sh example.com
Creating hosting for: example.com
Please specify the username for this site?
example
Please enter a password for the user: example
Changing password for user example.
passwd: all authentication tokens updated successfully.
the configuration file /etc/nginx/nginx.conf syntax is ok
configuration file /etc/nginx/nginx.conf test is successful
Reloading nginx:                                           [  OK  ]
 
Site Created for example.com
--------------------------
Host: sebstestbox
URL: example.com
User: example
--------------------------

 The Script:

#!/bin/bash
# Author: Seb Dangerfield
# URL: http://sebdangerfield.me.uk
#
 
NGINX_ALL_VHOSTS='/etc/nginx/sites-available'
NGINX_ENABLED_VHOSTS='/etc/nginx/sites-enabled'
WEB_DIR='/var/www'
SED=`which sed`
NGINX=`sudo which nginx`
CURRENT_DIR=`dirname $0`
 
if [ -z $1 ]; then
	echo "No domain name given"
	exit 1
fi
DOMAIN=$1
 
# check the domain is valid!
PATTERN="^(([a-zA-Z]|[a-zA-Z][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z]|[A-Za-z][A-Za-z0-9\-]*[A-Za-z0-9])$";
if [[ "$DOMAIN" =~ $PATTERN ]]; then
	DOMAIN=`echo $DOMAIN | tr '[A-Z]' '[a-z]'`
	echo "Creating hosting for:" $DOMAIN
else
	echo "invalid domain name"
	exit 1
fi
 
# Create a new user!
echo "Please specify the username for this site?"
read USERNAME
sudo adduser -d$WEB_DIR/$USERNAME $USERNAME
echo "Please enter a password for the user: $USERNAME"
read -s PASS
sudo echo $PASS | sudo passwd --stdin $USERNAME
 
# Now we need to copy the virtual host template
CONFIG=$NGINX_ALL_VHOSTS/$DOMAIN.conf
sudo cp $CURRENT_DIR/virtual_host.template $CONFIG
sudo $SED -i "s/DOMAIN/$DOMAIN/g" $CONFIG
sudo $SED -i "s#ROOT#$WEB_DIR/$HOME_DIR\/public_html#g" $CONFIG
 
sudo usermod -aG $USERNAME nginx
sudo chmod g+rxs $WEB_DIR/$USERNAME
sudo chmod 600 $CONFIG
 
sudo $NGINX -t
if [ $? -eq 0 ];then
	# Create symlink
	sudo ln -s $CONFIG $NGINX_ENABLED_VHOSTS/$DOMAIN.conf
else
	echo "Could not create new vhost as there appears to be a problem with the newly created nginx config file: $CONFIG";
	exit 1;
fi
 
sudo /etc/init.d/nginx reload
 
# put the template index.html file into the public_html dir!
sudo mkdir /var/www/$HOME_DIR/public_html
 
sudo cp $CURRENT_DIR/index.html.template $WEB_DIR/$HOME_DIR/public_html/index.html
sudo $SED -i "s/SITE/$DOMAIN/g" $WEB_DIR/$HOME_DIR/public_html/index.html
sudo chown $USERNAME:$USERNAME $WEB_DIR/$HOME_DIR/public_html -R
 
echo -e "\nSite Created for $DOMAIN"
echo "--------------------------"
echo "Host: "`hostname`
echo "URL: $DOMAIN"
echo "User: $USERNAME"
echo "--------------------------"
exit 0;

Download:

Please note both downloads contain exactly the same files.

Download (tar.gz)
Download (zip)

Comments or Questions:

Please feel free to leave any comments or questions in the section below.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" highlight="">