#!/bin/bash # # Create Vhosts on VPS3 # #set -e function usage { echo "Usage: ${0}" echo " --domain domain.tld" echo " Domain to use when creating vhost" echo " --root /var/www/html" echo " Root directory of this vhost" echo " --backend http://127.0.0.1:80" echo " URI of the backend server" echo " Note: port must be specified" echo " --listenip x.x.x.x" echo " IP to bind to when listening" echo " --desc x.x.x.x" echo " Description of VHosts" echo " --denotredirect" echo " Do not redirect HTTP to HTTPS" echo " --servicename" echo " The Nginx server service name to use to reload" echo " -d | --debug" echo " Enable debug logging" echo " -h | --help" echo " Show this usage" exit 0 } function get_cert { # should we enable verbose _debug_arg="" if [ "$DEBUG" = "1" ]; then _debug_arg="--debug" fi /root/.acme.sh/acme.sh --issue --domain "$_domain" --webroot /srv/http-content-combined/ --cert-file /etc/ssl/"${_domain}".crt --key-file /etc/ssl/"${_domain}".key --fullchain-file /etc/ssl/"${_domain}"-fullchain.crt $_debug_arg return $? } function reload_nginx { echo -n "Reloading ${_servicename}..." if systemctl reload "${_servicename}" > /dev/null 2>&1; then echo "Success" else echo "Failed" return 1 fi # Wait for nginx to reload sleep 0.5 return 0 } function clean_up { debug "Removing Nginx configuration and logs..." rm "$_vhost_conf_file" rm /var/log/nginx/"$_domain".* > /dev/null 2>&1 reload_nginx err "$1" } function verify_vhost { local target=127.0.0.1 local verify_path=/srv/http-content-combined/.well-known/ local verify_file_name=verify.$_domain.html local verify_full_path=$verify_path$verify_file_name local http_code if test -n "$_listenip"; then target=$_listenip fi mkdir -p $verify_path touch $verify_full_path http_code=$(curl -I -H "Host: $_domain" http://"$target"/.well-known/"$verify_file_name" 2> /dev/null | grep 'HTTP/1.1' | cut -d " " -f 2) if [[ $http_code = '200' ]]; then return 0 else debug "Expected HTTP response code '200' but got '$http_code' instead!" return 1 fi } _cwd="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" _bootstrap=${_cwd}/bootstrap.sh _bb_myname=$(basename "$0") _bb_mypath=$(realpath $BASH_SOURCE) # Init script if test -f "$_bootstrap"; then source "$_bootstrap" 2> /dev/null else echo "Unable to parse BOOTSTRAP: $_bootstrap" exit 1 fi # check if we have the binaries we need to run if ! cmd_exists curl; then err "Missing dependency: curl. Please run 'dnf install -y curl'" fi # gain priviledges become "$@" OPTS=$(getopt -o h,d -l domain:,root:,backend:,listenip:,desc:,donotredirect,servicename:,confpath:,debug -n 'createVhosts' -- "$@") if [ "$?" -gt '0' ]; then echo 'Failed to set command line arguments' exit 1; fi eval set -- "$OPTS" _domain=false _donotredirect=false _root="" _backend="" _listenip="" _debug=false _servicename=nginx while true; do case "$1" in --domain ) _domain=$2 shift ;; --root ) _root=$2 shift ;; --backend ) _backend=$2 shift ;; --listenip ) _listenip=$2 shift ;; --desc ) _desc=$2 shift ;; --donotredirect ) _donotredirect=true shift ;; --servicename ) _servicename=$2 shift ;; --confpath ) _confpath=$2 shift ;; -d | --debug ) _debug=true shift ;; -h | --help ) usage; shift ;; -- ) shift; break ;; * ) shift;; esac done ## ## Begin processing command line arguments ########################################### # Enable debugging if [[ $_debug = true ]]; then DEBUG=1 fi if [[ $_domain = false ]]; then err "You must set domain" fi if test -n "$_root"; then echo -n "Checking if $_root exists?" if ! test -d "$_root"; then echo " Creating..." mkdir -p "$_root" else echo " Yes!" fi _rootpath="root $_root;" fi _check_host=success _locationblock_http="" _locationblock_https="" if test -n "$_backend"; then echo "Verifying backend(s)..." if ! validate_host "$_backend"; then _check_host=failed fi # Include backend for HTTP traffic if donotredirect is enabled # if [ "$_donotredirect" = "true" ]; then ##Begin HEREDOC _locationblock_http=$(cat <<- EOF proxy_pass $_backend; include proxy_params; EOF ) ##End HEREDOC fi if [ "$_check_host" = "success" ]; then # Include backend for HTTP traffic if donotredirect is enabled # if [ "$_donotredirect" = "true" ]; then ##Begin HEREDOC _locationblock_http=$(cat <<- EOF proxy_pass $_backend; include proxy_params; EOF ) ##End HEREDOC fi ##Begin HEREDOC _locationblock_https=$(cat <<- EOF proxy_pass $_backend; include proxy_params; EOF ) ##End HEREDOC else err "Invalid hostname: $_backend. Not resolvable!" fi fi if test -n "$_listenip"; then if ! validate_ip "$_listenip"; then err "Invalid IP: $_listenip" fi _listenip="$_listenip:" else warn "Listen ip not specified, listening on all interfaces." fi if test -z "$_root" -a -z "$_backend"; then err "You must specify either --root or --backend!" fi echo -n "Checking if we should redirect?" if [ "$_donotredirect" = "false" ]; then echo " Yes, enabling redirect!" _locationblock_http=" return 302 https://${_domain}\$request_uri;" else echo " No!" fi echo -n "Checking if conf path '$_confpath' exists? " if test -d "$_confpath"; then echo "Yes!" clean_up else echo "No!" clean_up fi ## ## End processing command line arguments ########################################### ## ## Begin issuing certificate ########################################### echo -n "Checking if /srv/http-content-combined/ exists?" if ! test -d /srv/http-content-combined; then echo " Creating..." mkdir -p /srv/http-content-combined/ else echo " Yes!" fi _vhost_conf_file=$_confpath/conf.d/${_domain}.conf echo -n "Checking if $_vhost_conf_file exists? " if test -f "$_vhost_conf_file"; then echo "Removing!" rm "$_vhost_conf_file" else echo "No!" fi echo "Creating Nginx configuration..." cat << EOF > "$_vhost_conf_file" #### Description ## Type: HTTP ## VHost: $_domain ## $_desc server { listen ${_listenip}80; server_name $_domain; error_log /var/log/nginx/${_domain}.error.log; access_log /var/log/nginx/${_domain}.access.log main; location /.well-known { root /srv/http-content-combined/; autoindex on; } location / { $_locationblock_http } } EOF echo "Setting permissions on conf file..." setfacl -m user:sysadmin:rw "$_vhost_conf_file" if ! reload_nginx; then clean_up "Failed to reload Nginx" fi echo "Verifying vhost..." if ! verify_vhost; then clean_up "Failed to verify vhost" fi echo "Retrieving SSL Certificate..." if ! get_cert; then clean_up "Failed to retrieve certificate!" fi cat << EOF >> "$_vhost_conf_file" server { listen ${_listenip}443 http2 ssl; server_name $_domain; $_rootpath error_log /var/log/nginx/${_domain}.error.log; access_log /var/log/nginx/${_domain}.access.log main; ssl_certificate /etc/ssl/${_domain}-fullchain.crt; ssl_certificate_key /etc/ssl/${_domain}.key; location / { ${_locationblock_https} } } EOF reload_nginx