[Script] Automate Apache Virtualhost creation

About

This basic scripts helps automating the creation of domains or subdomains.

Usage: Create a vhost

chmod +x setvhost.sh

Set the domain or subdomain

setvhost.sh —d subdomain3.example.com —u /var/www/mydir/public

or

setvhost.sh --domain subdomain3.example.com --directory /var/www/mydir/public

SSL for subdomains case

I usually use it with subdomains to which I add a wildcard certificate, which you can generate using acme.sh or certbot:

certbot certonly --manual --preferred-challenges=dns --email mail@example.com --server https://acme-v02.api.letsencrypt.org/directory --agree-tos -d example.com -d *.example.com

You will have to add the returned DNS record for verification.

The returned cert has to be added to the SSL part of the skeleton file ‘vhost.skeleton.conf’:

SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem

Addon domains case

In this cas you will have to add to the end of the script an SSL request. For example, when used with certbot: certbot certonly –preferred-challenges http -d example.com

Cetbot instructions: https://certbot.eff.org/


vhost.skeleton.conf

# Auto-generated virtualhost
# @site_domain@

<VirtualHost *:80>
    ServerAdmin webmaster@localhost
    ServerName @site_domain@

    DocumentRoot "@site_directory@"
    
    <Directory @site_directory@>
       Options Indexes FollowSymLinks MultiViews
       AllowOverride All
       Order allow,deny
       Allow from all
    </Directory>
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>


<IfModule mod_ssl.c>
<VirtualHost *:443>
    ServerAdmin webmaster@localhost
    ServerName @site_domain@

    DocumentRoot "@site_directory@"
    
    <Directory @site_directory@>
       Options Indexes FollowSymLinks MultiViews
       AllowOverride All
       Order allow,deny
       Allow from all
    </Directory>
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined

	Include /etc/letsencrypt/options-ssl-apache.conf
	SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
	SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
</VirtualHost>
</IfModule>

setvhost.sh

#!/bin/bash

# Check user permissions
if [ "$(whoami)" != "root" ]; then
	echo "Root privileges are required to run this, try running with sudo..."
	exit 2
fi

# Define useful paths
current_directory="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
available_vh_path="/etc/apache2/sites-available/"
enabled_vh_path="/etc/apache2/sites-enabled/"
vhost_skeleton_path="$current_directory/vhost.skeleton.conf"

# User input passed as options
site_domain=""
web_root=""


# if followed by colon (:), it has a required argument. If followed by (::) it's optional
ARGS=$(getopt --options u:d: --long domain:,directory: -- "$@")
if [[ $? -ne 0 ]]; then
    exit 1;
fi


eval set -- "$ARGS"
while true ; do
  case "$1" in
    -u | --domain )
        site_domain=${2}
        shift 2
        ;;
    -d | --directory )
        web_root=${2}
        shift 2
        ;;
    -- ) shift; 
        break 
        ;;
  esac
done


# prompt if not passed as argument
while [ -z $site_domain ] ; do
	read -p "Please enter the desired domain: " site_domain
done


# Check if the vhost exists, suggest to disable it
if [ -f "$enabled_vh_path$site_domain.conf" ]; then
	while true; do
		read -p $enabled_vh_path$site_domain'.conf already exists and will be updated (CTRL+C to cancel).'$'\n''Would you rather like to disable this config file? [y/n]' yn
		case $yn in
			[Yy]* )
				#a2dissite "$site_domain.conf";
				echo `a2dissite $site_domain`
				echo `service apache2 reload`
				logger "[Script] setvhost > Disabling $site_domain"
				exit;;
			[Nn]* ) break;;
			* ) echo "Please answer yes or no.";;
		esac
	done
fi

# prompt if not passed as argument
while [ -z $web_root ] ; do
	read -p "Please enter its web directory (e.g.: /var/www/$site_domain): " web_root
 done


# create directory if it doesn't exists
if [ ! -d "$web_root" ]; then

	# create directory
	`mkdir -p "$web_root/"`
	`chown -R www-data:www-data "$web_root/"`

	# create index file
	indexfile="$web_root/index.html"
	`touch "$indexfile"`
	echo "<html><head></head><body>Welcome!</body></html>" >> "$indexfile"

	echo "Created directory $web_root/"
fi

# update vhost
vhost=`cat "$vhost_skeleton_path"`
vhost=${vhost//@site_domain@/$site_domain}
vhost=${vhost//@site_directory@/$web_root}

`touch $available_vh_path$site_domain.conf`
echo "$vhost" > "$available_vh_path$site_domain.conf"
echo "Updated vhosts in Apache config"

# restart apache
echo "Enabling site in Apache..."
echo `a2ensite $site_domain`

echo "Reloading Apache..."
echo `service apache2 reload`

echo "Process complete, check out the new site at http://$site_domain"
logger "[Script] setvhost > $site_domain was added or updated."
exit 0

Comments

Leave a Reply

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