#!/bin/bash # ┌──────────────────────────────────────────────────────────────────────────────┐ # │ MIT License │ # │ │ # │ Copyright (c) 2021 Sean Helling │ # │ │ # │ Permission is hereby granted, free of charge, to any person obtaining a │ # │ copy │ # │ of this software and associated documentation files (the "Software"), to │ # │ deal │ # │ in the Software without restriction, including without limitation the │ # │ rights │ # │ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell │ # │ copies of the Software, and to permit persons to whom the Software is │ # │ furnished to do so, subject to the following conditions: │ # │ │ # │ The above copyright notice and this permission notice shall be included in │ # │ all │ # │ copies or substantial portions of the Software. │ # │ │ # │ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR │ # │ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, │ # │ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE │ # │ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER │ # │ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING │ # │ FROM, │ # │ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN │ # │ THE │ # │ SOFTWARE. │ # └──────────────────────────────────────────────────────────────────────────────┘ # ┌──────────────────────────────────────────────────────────────────────────────┐ # │ Apache newsite configurator │ # │ │ # │ This script does the following to create and enable a new Apache │ # │ VirtualHost: │ # │ - Creates directories │ # │ - Creates configuration files │ # │ - Sets permissions │ # │ - Optionally enables and configures SSL encryption via Let's Encrypt │ # │ - Uses Apache's script hooks to enable the VirtualHost │ # └──────────────────────────────────────────────────────────────────────────────┘ # SETTINGS GO HERE BASEROOTDIR="/var/www" WWWUSER="www-data" APACHE_CONFIG_DIR="/etc/apache2/sites-available" LETSENCRYPT_ENABLE_REDIRECT=0 # 0 = redirect, 1 = no redirect, anything else = ask # DO NOT CHANGE ANYTHING BELOW THIS LINE # Assign original ROOTDIR, leaving configured value for comparison ROOTDIR=$BASEROOTDIR usage () { echo -e "\e[1mnewsite\e[0m" echo -e "Usage: $0 -d [-s] [-r ]" echo -e "Options:" echo -e " -d: specify domain name (required)" echo -e " -s: set up SSL via letsencrypt (optional)" echo -e " -r: set up in a different directory from the default [\e[1m$ROOTDIR\e[0m] (optional)"; echo -e " -v: show version information" } # set initial blank values DOMAIN="" DOMAINSTRING="" ALIASES="" while getopts "svd:r:" arg; do case $arg in # Perform letsencrypt SSL setup s) DO_SSL="true" ;; # The domain name itself d) if [[ -z $DOMAIN ]]; then DOMAIN=${OPTARG} else ALIASES="${ALIASES}${OPTARG} " fi DOMAINSTRING="${DOMAINSTRING}-d ${OPTARG} " ;; # If specified, change ROOTDIR r) if [[ ${OPTARG} == /* ]]; then ROOTDIR="${OPTARG}"; else ROOTDIR="$ROOTDIR/${OPTARG}"; fi ;; # Help/instructions h | *) usage exit 0 ;; esac done # I'll leave this here in case getopts sleeps through its alarm if [[ $# -eq 0 ]]; then usage; exit 0; fi # If we specify some flags but not a domain, explain usage, and exit with an error if [[ $DOMAIN == "" ]]; then echo -e "Fatal: you must specify a domain.\n" usage exit 1 fi # Create web directory if it doesn't already exist DIRTARGET="$ROOTDIR/$DOMAIN" HTMLTARGET="$DIRTARGET/html" if [[ -d "$DIRTARGET" ]]; then # If it does, warn the user and then move on echo "Warning: Directory $DIRTARGET already exists" else mkdir -p $DIRTARGET echo "Created directory $DIRTARGET" mkdir -p $HTMLTARGET echo "Created directory $HTMLTARGET" fi # targetpage specification TARGETPAGE=$HTMLTARGET/index.html if [[ -f $TARGETPAGE ]]; then echo "Warning: Target index.html page already exists" else echo -e \ "

It works!

" > $TARGETPAGE fi # touch index.html in case it doesn't exist touch $HTMLTARGET/index.html # chown recursively, regardless if [[ $ROOTDIR != $BASEROOTDIR ]]; then # we are NOT using the default ROOTDIR, make sure we chown both chown $WWWUSER:$WWWUSER $ROOTDIR chown -R $WWWUSER:$WWWUSER $DIRTARGET else # we are using the default ROOTDIR, we can probably safely chown only the new directory chown -R $WWWUSER:$WWWUSER $DIRTARGET fi # set sticky bit on directories find $DIRTARGET -type d -exec chmod 2775 {} \; # allow group write on everything find $DIRTARGET -type f -exec chmod 0664 {} \; # Create and populate Apache configuration file CONFTARGET="$APACHE_CONFIG_DIR/$DOMAIN.conf" if [[ -e $CONFTARGET && -s $CONFTARGET ]]; then # If the file already exists, warn the user and move on echo "Warning: Configuration file $CONFTARGET already exists" else # If we have any aliases if [[ -n $ALIASES ]]; then ALIASLINE="ServerAlias ${ALIASES}\n"; else ALIASLINE=""; fi echo -e \ " ServerAdmin webmaster@$DOMAIN ServerName ${DOMAIN} ${ALIASLINE} DocumentRoot $HTMLTARGET Options -Indexes +FollowSymLinks AllowOverride all Require all granted ErrorLog \${APACHE_LOG_DIR}/$DOMAIN-error.log CustomLog \${APACHE_LOG_DIR}/$DOMAIN-access.log combined " >> $CONFTARGET fi # Enable the site in Apache a2ensite $DOMAIN.conf > /dev/null 2>&1 echo -e "Domain $DOMAIN enabled." service apache2 reload # Check if we want SSL set up, and if so, do it if [[ $DO_SSL == "true" ]]; then if [[ $LETSENCRYPT_ENABLE_REDIRECT -eq 0 ]]; then certbot -n --redirect --apache $DOMAINSTRING elif [[ $LETSENCRYPT_ENABLE_REDIRECT - eq 1 ]]; then certbot -n --no-redirect --apache $DOMAINSTRING else certbot -n --apache $DOMAINSTRING fi fi