commit 4226322936805d53ce597831bc4c9f8aa4663dd5 Author: Matthew Saunders Brown Date: Sun Apr 4 13:28:22 2021 -0700 initial commit diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..156bfd4 --- /dev/null +++ b/LICENSE @@ -0,0 +1,19 @@ +MIT License Copyright (c) 2021 Matthew Saunders Brown + +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 (including the next +paragraph) 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. diff --git a/README.md b/README.md new file mode 100644 index 0000000..7fd2b8e --- /dev/null +++ b/README.md @@ -0,0 +1,17 @@ +# vhost-stack + +apt install apache php + + + + +### mini_sendmail +``` +wget http://www.acme.com/software/mini_sendmail/mini_sendmail-1.3.6.tar.gz +tar zxvf mini_sendmail-1.3.6.tar.gz +cd mini_sendmail-1.3.6/ +make +cp mini_sendmail /usr/local/bin +gzip mini_sendmail.8 +cp mini_sendmail.8.gz /usr/local/share/man/man8 +``` diff --git a/bin/vhost-add.sh b/bin/vhost-add.sh new file mode 100644 index 0000000..4179d5c --- /dev/null +++ b/bin/vhost-add.sh @@ -0,0 +1,86 @@ +#!/bin/bash +# +# vhost-stack +# https://git.stack-source.com/msb/vhost-stack +# MIT License Copyright (c) 2021 Matthew Saunders Brown + +# load config +source /usr/local/etc/vhost.conf || echo "ERROR: Either you do not have vhost user permissions or the config file is missing." && exit + +# check for and set virtualhost +if [ -n "$1" ]; then + virtualhost=$1 +else + echo "virtualhost not set" + exit 1 +fi + +# check for and set username +if [ -n "$2" ]; then + username=$2 +else + echo "username not set" + exit 1 +fi + +if [ ! -d /home/$username ]; then + echo "home dir for $username does not exist" + exit 1 +fi + +if [ -d /srv/www/$virtualhost ]; then + chown $username:$username /srv/www/$virtualhost + chmod 755 /srv/www/$virtualhost +else + install -d -o $username -g $username -m 755 /srv/www/$virtualhost +fi + +if [ -d /srv/www/$virtualhost/html ]; then + chown $username:$username /srv/www/$virtualhost/html + chmod 755 /srv/www/$virtualhost/html +else + install -d -o $username -g $username -m 755 /srv/www/$virtualhost/html +fi + +if [ ! -e /home/$username/$virtualhost ]; then + ln -s /srv/www/$virtualhost /home/$username/$virtualhost + chown -h $username:$username /home/$username/$virtualhost +fi + +if [ -d /usr/jails/$username ]; then + if [ ! -d /usr/jails/$username/srv/www/$virtualhost ]; then + install -d -o $username -g $username -m 755 /usr/jails/$username/srv/www/$virtualhost + mount --bind /srv/www/$virtualhost /usr/jails/$username/srv/www/$virtualhost + echo "/srv/www/$virtualhost /usr/jails/$username/srv/www/$virtualhost none bind 0 0" >> /etc/fstab + fi +fi + +# php-fpm pool +vhost::set-phpVersion +if [ ! -f /etc/php/$phpVersion/fpm/pool.d/$username.conf ]; then + # create /etc/php/$phpVersion/fpm/pool.d/$username.conf + echo "[$username]" > /etc/php/$phpVersion/fpm/pool.d/$username.conf + echo "user = $username" >> /etc/php/$phpVersion/fpm/pool.d/$username.conf + echo "group = $username" >> /etc/php/$phpVersion/fpm/pool.d/$username.conf + if [ -d /usr/jails/$username ]; then + echo "chroot = /usr/jails/$username" >> /etc/php/$phpVersion/fpm/pool.d/$username.conf + fi + echo "listen = /run/php/php$phpVersion-fpm-$username.sock" >> /etc/php/$phpVersion/fpm/pool.d/$username.conf + echo "listen.owner = www-data" >> /etc/php/$phpVersion/fpm/pool.d/$username.conf + echo "listen.group = www-data" >> /etc/php/$phpVersion/fpm/pool.d/$username.conf + echo "pm = ondemand" >> /etc/php/$phpVersion/fpm/pool.d/$username.conf + echo "pm.max_children = 12" >> /etc/php/$phpVersion/fpm/pool.d/$username.conf + echo "pm.process_idle_timeout = 3s;" >> /etc/php/$phpVersion/fpm/pool.d/$username.conf + echo "php_admin_value[sendmail_path] = /usr/sbin/sendmail -t -fwebmaster@$virtualhost" >> /etc/php/$phpVersion/fpm/pool.d/$username.conf + # restart php$phpVersion-fpm + if systemctl is-active --quiet php$phpVersion-fpm ; then + if /usr/sbin/php-fpm$phpVersion -t >/dev/null 2>&1 ; then + systemctl reload php$phpVersion-fpm + else + echo "WARNING: php-fpm$phpVersion configuration test failed" + fi + fi +fi + +# create & enable apache config +/usr/local/bin/vhost-enable.sh VHostHTTP $virtualhost diff --git a/bin/vhost-del.sh b/bin/vhost-del.sh new file mode 100644 index 0000000..3741709 --- /dev/null +++ b/bin/vhost-del.sh @@ -0,0 +1,73 @@ +#!/bin/bash +# +# vhost-stack +# https://git.stack-source.com/msb/vhost-stack +# MIT License Copyright (c) 2021 Matthew Saunders Brown + +# load config +source /etc/vhost.conf || echo "ERROR: Either you do not have vhost user permissions or the config file is missing." && exit + +# check for and set virtualhost +if [ -n "$1" ]; then + virtualhost=$1 +else + echo "virtualhost not set" + exit 1 +fi + +# remove virtualhost dir +if [ ! -d /srv/www/$virtualhost ]; then + echo "virtualhost dir does not exist" + exit 1 +fi + +username=$(stat -c '%U' /srv/www/$virtualhost) + +# disable the apache conf and reload apache +if [ -h /etc/apache2/sites-enabled/$virtualhost.conf ]; then + a2dissite --quiet $virtualhost + systemctl --quiet is-active apache2 && systemctl --quiet reload apache2 +fi + +# remove the apache config +if [ -f /etc/apache2/sites-available/$virtualhost.conf ]; then + rm /etc/apache2/sites-available/$virtualhost.conf +fi + +# remove varnish config +if [ -f /etc/varnish/sites.d/$virtualhost.vcl ]; then + rm /etc/varnish/sites.d/$virtualhost.vcl + /usr/local/bin/varnish-update-sites.sh + # don't bother to restart varnish as it will clear cache unnecessarily +fi + +# if virtualhost is mounted in a jail, unmount it +if grep -q "^/dev/sda /usr/jails/$username/srv/www/$virtualhost " /etc/mtab; then + umount /usr/jails/$username/srv/www/$virtualhost +fi + +# if virtualhost mount in fstab exists remove it +if grep -q "/usr/jails/$username/srv/www/$virtualhost" /etc/fstab; then + sed -i "\|/usr/jails/$username/srv/www/$virtualhost|d" /etc/fstab +fi + +# if virtualhost symlink exists in jail remove it +if [ -h /usr/jails/$username/home/$username/$virtualhost ]; then + unlink /usr/jails/$username/home/$username/$virtualhost +fi + +# if virtualhost symlink exists in home dir remove it +if [ -h /home/$username/$virtualhost ]; then + unlink /home/$username/$virtualhost +fi + +# if virtualhost dir exists in jail remove it +if [ -d /usr/jails/$username/srv/www/$virtualhost ]; then + rm -r /usr/jails/$username/srv/www/$virtualhost +fi + +# remove virtualhost dir +if [ -d /srv/www/$virtualhost ]; then + rm -r /srv/www/$virtualhost +fi + diff --git a/bin/vhost-deploy.sh b/bin/vhost-deploy.sh new file mode 100644 index 0000000..b626a6d --- /dev/null +++ b/bin/vhost-deploy.sh @@ -0,0 +1,98 @@ +#!/bin/bash +# +# vhost-stack +# https://git.stack-source.com/msb/vhost-stack +# MIT License Copyright (c) 2021 Matthew Saunders Brown + +# load config +source /etc/vhost.conf || echo "ERROR: Either you do not have vhost user permissions or the config file is missing." && exit + +# -v virtualhost (required) +# -u username (optional) +# -p password (optional) +# -j jail (true or false, optional) + +while getopts ":v:u:p:j:" opt; do + case "${opt}" in + v ) + virtualhost=${OPTARG} + ;; + u ) + username=${OPTARG} + ;; + p ) + password=${OPTARG} + ;; + j ) + jail=${OPTARG} + ;; + \? ) + echo "Invalid option: $OPTARG" + exit 1 + ;; + : ) + echo "Invalid option: $OPTARG requires an argument" + exit 1 + ;; + esac +done + +# check virtualhost +if [ ! -n "$virtualhost" ]; then + echo "virtualhost not set" + exit 1 +elif [ -d /srv/www/$virtualhost ] || [ -f /etc/apache2/sites-available/$virtualhost.conf ]; then + echo "virtualhost for $virtualhost already installed" + exit 1 +fi + +# check for and set username +if [ ! -n "$username" ]; then + username=`echo $virtualhost | sed 's|\.||'` + username=`echo ${username:0:8}` +fi + +if ! grep -q "^$username:" /etc/passwd; then + # check for and set password + if [ ! -n "$password" ]; then + password=`/usr/bin/pwgen 12 1` + fi + # set userid + userid=`awk -F: '{uid[$3]=1}END{for(x=1000; x<=65534; x++) {if(uid[x] != ""){}else{print x; exit;}}}' /etc/passwd` + # cylce thru each node and add user + vhost::set-clusterNodes all + for n in "${clusterNodes[@]}" + do + if [ $n = `hostname -s` ]; then + /usr/local/bin/user-add.sh $username "$password" $userid + else + ssh $n.lan "/usr/local/bin/user-add.sh $username \"$password\" $userid" + fi + done + # if jail option is set cylce thru each node and jail user + if [[ $jail = true ]]; then + vhost::set-clusterNodes nds + for n in "${clusterNodes[@]}" + do + if [ $n = `hostname -s` ]; then + /usr/local/bin/user-jail.sh $username > /dev/null 2>&1 & + else + ssh $n.lan "/usr/local/bin/user-jail.sh $username > /dev/null 2>&1 &" & + fi + done + # Wait for jails to be created. As of now they take about 30 seconds. + vhost::countdown 60 + fi +fi + +# cylce thru each node and add virtualhost +vhost::set-clusterNodes all +for n in "${clusterNodes[@]}" +do + if [ $n = `hostname -s` ]; then + /usr/local/bin/vhost-add.sh $virtualhost $username > /dev/null 2>&1 & + else + ssh $n.lan "/usr/local/bin/vhost-add.sh $virtualhost $username > /dev/null 2>&1 &" + fi +done + diff --git a/bin/vhost-destroy.sh b/bin/vhost-destroy.sh new file mode 100644 index 0000000..c8bbd07 --- /dev/null +++ b/bin/vhost-destroy.sh @@ -0,0 +1,44 @@ +#!/bin/bash +# +# vhost-stack +# https://git.stack-source.com/msb/vhost-stack +# MIT License Copyright (c) 2021 Matthew Saunders Brown + +# load config +source /etc/vhost.conf || echo "ERROR: Either you do not have vhost user permissions or the config file is missing." && exit + +# check for and set virtualhost +if [ -n "$1" ]; then + virtualhost=$1 +else + echo "virtualhost not set" + exit 1 +fi + +# First check for virtualhost. Redundant +# as vhost-del.sh run later does this same check +# but prevents connecting to all nodes unnecessarily +if [ ! -d /srv/www/$virtualhost ]; then + echo "virtualhost dir does not exist" + exit 1 +fi + +# check for userdel option and set username if enabled +if [ -n "$2" ] && [ $2 = "userdel" ]; then + username=$(stat -c '%U' /srv/www/$virtualhost) +fi + +vhost::set-clusterNodes all +for n in "${clusterNodes[@]}" +do + if [ $n = `hostname -s` ]; then + /usr/local/bin/vhost-del.sh $virtualhost + else + ssh $n.lan "/usr/local/bin/vhost-del.sh $virtualhost" + fi +done + +# check for userdel option +if [ -n "$2" ] && [ $2 = "userdel" ] && [ -n $username ]; then + /usr/local/bin/user-destroy.sh $username +fi diff --git a/bin/vhost-disable.sh b/bin/vhost-disable.sh new file mode 100644 index 0000000..bb45208 --- /dev/null +++ b/bin/vhost-disable.sh @@ -0,0 +1,26 @@ +#!/bin/bash +# +# vhost-stack +# https://git.stack-source.com/msb/vhost-stack +# MIT License Copyright (c) 2021 Matthew Saunders Brown + +# load config +source /etc/vhost.conf || echo "ERROR: Either you do not have vhost user permissions or the config file is missing." && exit + +# check for and set virtualhost +if [ -n "$1" ]; then + virtualhost=$1 +else + echo "virtualhost not set" + exit 1 +fi + +vhost::set-clusterNodes all +for n in "${clusterNodes[@]}" +do + if [ $n = `hostname -s` ]; then + [[ -h /etc/apache2/sites-enabled/$virtualhost.conf ]] && a2dissite --quiet $virtualhost && systemctl --quiet is-active apache2 && systemctl --quiet reload apache2 + else + ssh $n.lan "[[ -h /etc/apache2/sites-enabled/$virtualhost.conf ]] && a2dissite --quiet $virtualhost && systemctl --quiet is-active apache2 && systemctl --quiet reload apache2" + fi +done diff --git a/bin/vhost-enable.sh b/bin/vhost-enable.sh new file mode 100644 index 0000000..f25d061 --- /dev/null +++ b/bin/vhost-enable.sh @@ -0,0 +1,166 @@ +#!/bin/bash +# +# vhost-stack +# https://git.stack-source.com/msb/vhost-stack +# MIT License Copyright (c) 2021 Matthew Saunders Brown + +# load config + +source /etc/vhost.conf || echo "ERROR: Either you do not have vhost user permissions or the config file is missing." && exit + +# vhost-enable.sh macro_name vhost [subdomain|alias] +# vhost-enable.sh VHostHTTPS example.com +# vhost-enable.sh VHostSubdomainHTTPS example.com staging +# vhost-enable.sh VHostAliasHTTPS example.com existingsite +# vhost-enable.sh VMailHTTPS mail.example.com +# vhost-enable.sh RedirectHTTPS example.com https://my.newsite.com/path/page.html +# +# mod_macro config will look like: +# Use VHostHTTP $vhost $username +# Use VHostHTTPS $vhost $username +# Use VHostHTTPSVarnish $vhost $username +# Use VHostSubdomainHTTP $vhost $username $subdomain +# Use VHostSubdomainHTTPS $vhost $username $subdomain +# Use VHostSubdomainHTTPSVarnish $vhost $username $subdomain +# Use VHostAliasHTTP $vhost $username $alias +# Use VHostAliasHTTPS $vhost $username $alias +# Use VHostAliasHTTPSVarnish $vhost $username $alias +# Use VMailHTTPS $vhost +# Use RedirectHTTP $vhost $redirect +# Use RedirectHTTPS $vhost $redirect +# +# $username is autodetected from vhost dir ownership + +macro_array=($(grep Macro /etc/apache2/mods-available/macro.conf |cut -d ' ' -f 2|grep -v Macro)) +macro_vhost_line="Use" + +# check for and set mode +if [ -n "$1" ]; then + macro_name=$1 + if [[ " ${macro_array[@]} " =~ " ${macro_name} " ]]; then + macro_vhost_line="$macro_vhost_line $macro_name" + else + echo "invalid macro name" + exit 1 + fi +else + echo "macro name not set" + exit 1 +fi + +# check for and set vhost +if [ -n "$2" ]; then + vhost=$2 + macro_vhost_line="$macro_vhost_line $vhost" + vhost_conf="$vhost.conf" +else + echo "vhost not set" + exit 1 +fi + +# set username for all VHost macros +if [[ "$macro_name" == *"VHost"* ]]; then + # check for vhost dir + if [ -d "/srv/www/$vhost" ]; then + # get and set $username + username=$(stat -c '%U' /srv/www/$vhost) + macro_vhost_line="$macro_vhost_line $username" + else + echo "vhost dir for $vhost does not exist" + exit 1 + fi + # check for and set Subdomain + if [[ "$macro_name" == *"Subdomain"* ]]; then + if [ -n "$3" ]; then + subdomain=$3 + # make sure Subdomain isn't already installed + if [ -d "/srv/www/$subdomain.$vhost" ]; then + echo "$subdomain.$vhost is already installed as it's own vhost" + exit 1 + fi + if [ ! -d "/srv/www/$vhost/$subdomain" ]; then + echo "subdomain directory (/srv/www/$vhost/$subdomain) does not exist" + exit 1 + fi + macro_vhost_line="$macro_vhost_line $subdomain" + vhost_conf="$subdomain.$vhost_conf" + else + echo "subdomain not set" + exit 1 + fi + fi + # check for and set Alias + if [[ "$macro_name" == *"Alias"* ]]; then + if [ -n "$3" ]; then + # make sure Alias domain isn't already installed as it's own vhost + if [ -d "/srv/www/$vhost" ]; then + echo "$alias is already installed as it's own vhost" + exit 1 + else + alias=$3 + macro_vhost_line="$macro_vhost_line $alias" + fi + else + echo "alias not set" + exit 1 + fi + fi + # check for varnish config + if [[ "$macro_name" == *"Varnish"* ]]; then + varnish_host=$vhost + if [[ "$macro_name" == *"Subdomain"* ]]; then + varnish_host="$subdomain.$varnish_host" + fi + if [ ! -f "/etc/varnish/sites.d/$varnish_host.vcl" ]; then + echo "$varnish_config_file Varnish config file does not exist" + exit 1 + fi + fi +fi + +# check for and set redirect +if [[ "$macro_name" == *"Redirect"* ]]; then + if [ -n "$3" ]; then + redirect=$3 + # make sure Redirect domain isn't already installed as it's own vhost + if [ -d "/srv/www/$vhost" ]; then + echo "$vhost is already installed as it's own vhost" + exit 1 + else + macro_vhost_line="$macro_vhost_line $redirect" + fi + else + echo "redirect not set" + exit 1 + fi +fi + +# if https check for le cert +if [[ "$macro_name" == *"HTTPS"* ]]; then + cert_host=$vhost + if [[ "$macro_name" == *"Subdomain"* ]]; then + cert_host="$subdomain.$cert_host" + fi + if [ ! -f "/etc/ssl/letsencrypt/$cert_host.pem" ]; then + echo "cert file for $cert_host does not exist" + exit 1 + fi +fi + +# create / edit apache conf +echo "$macro_vhost_line" > /etc/apache2/sites-available/$vhost_conf + +# enable apache conf +if [[ ! -h /etc/apache2/sites-enabled/$vhost_conf ]]; then + a2ensite --quiet $vhost_conf +fi + +# restart apache +if systemctl --quiet is-active apache2 ; then + if /usr/sbin/apachectl -t >/dev/null 2>&1 ; then + systemctl --quiet reload apache2 + else + echo "apache config test failed, not doing restart" + exit 2 + fi +fi diff --git a/bin/vhost-fix-perms.sh b/bin/vhost-fix-perms.sh new file mode 100644 index 0000000..376e38a --- /dev/null +++ b/bin/vhost-fix-perms.sh @@ -0,0 +1,45 @@ +#!/bin/bash +# +# vhost-stack +# https://git.stack-source.com/msb/vhost-stack +# MIT License Copyright (c) 2021 Matthew Saunders Brown + +# load config + +source /etc/vhost.conf || echo "ERROR: Either you do not have vhost user permissions or the config file is missing." && exit + +if [ -n "$1" ]; then + if [ "$1" = '--verbose' ] || [ "$1" = '-v' ]; then + mode=verbose + elif [ "$1" = '--dry-run' ] || [ "$1" = '-n' ]; then + mode=dry-run + fi +fi + +for VHOST in /srv/www/*/; { + + # get username + USER=$(stat -c '%U' $VHOST) + # make sure all files & dirs are owned by user + if [ "$mode" = "verbose" ] || [ "$mode" = "dry-run" ]; then + /usr/bin/find $VHOST ! -user $USER + fi + if [ "$mode" != "dry-run" ]; then + /usr/bin/find $VHOST ! -user $USER -exec chown $USER {} + + fi + +} + +for HOME in /home/*/; { + + # get username + USER=$(stat -c '%U' $HOME) + # make sure all files & dirs are owned by user + if [ "$mode" = "verbose" ] || [ "$mode" = "dry-run" ]; then + /usr/bin/find $HOME ! -user $USER + fi + if [ "$mode" != "dry-run" ]; then + /usr/bin/find $HOME ! -user $USER -exec chown $USER {} + + fi + +} diff --git a/bin/vhost-mysql-db-add.sh b/bin/vhost-mysql-db-add.sh new file mode 100644 index 0000000..190e95d --- /dev/null +++ b/bin/vhost-mysql-db-add.sh @@ -0,0 +1,53 @@ +#!/bin/bash +# +# vhost-stack +# https://git.stack-source.com/msb/vhost-stack +# MIT License Copyright (c) 2021 Matthew Saunders Brown + +# load config +source /usr/local/etc/vhost.conf || echo "ERROR: Either you do not have vhost user permissions or the config file is missing." && exit + +# check for and set virtualhost +if [ -n "$1" ]; then + virtualhost=$1 +else + echo "virtualhost not set" + exit 1 +fi + +# make sure virtualhost exists +if [ ! -d /srv/www/$virtualhost ]; then + echo "virtualhost $virtualhost does not exist" + exit 1 +fi + +# set database name +database=${virtualhost//./dot} +database=${database//-/dash} + +# make sure database doesn't already exist +if [ -d /var/lib/mysql/$database ]; then + echo "database $database already exists" + exit 1 +fi + +# check for and set mysql username +if [ -n "$2" ]; then + username=$2 +else + username=$(stat -c '%U' /srv/www/$virtualhost)@$virtualhost +fi + +# check for and set mysql password +if [ -n "$3" ]; then + password=$3 +else + password=`/usr/bin/pwgen 16 1` +fi + +mysqladmin create $database +mysql -e "CREATE USER '$username'@'localhost' IDENTIFIED BY '$password';" +mysql -e "GRANT ALL PRIVILEGES ON $database.* TO '$username'@'localhost';" +mysqladmin flush-privileges + +echo "database '$database' created with username '$username' and password '$password'" diff --git a/bin/vhost-mysql-db-del.sh b/bin/vhost-mysql-db-del.sh new file mode 100644 index 0000000..bc3c46d --- /dev/null +++ b/bin/vhost-mysql-db-del.sh @@ -0,0 +1,53 @@ +#!/bin/bash +# +# vhost-stack +# https://git.stack-source.com/msb/vhost-stack +# MIT License Copyright (c) 2021 Matthew Saunders Brown + +# load config +source /usr/local/etc/vhost.conf || echo "ERROR: Either you do not have vhost user permissions or the config file is missing." && exit + +# # check for and set virtualhost +# if [ -n "$1" ]; then +# virtualhost=$1 +# else +# echo "virtualhost not set" +# exit 1 +# fi +# +# # make sure virtualhost exists +# if [ ! -d /srv/www/$virtualhost ]; then +# echo "virtualhost $virtualhost does not exist" +# exit 1 +# fi +# +# # set database name +# database=${virtualhost//./dot} +# database=${database//-/dash} +# +# # make sure database doesn't already exist +# if [ -d /var/lib/mysql/$database ]; then +# echo "database $database already exists" +# exit 1 +# fi +# +# # check for and set mysql username +# if [ -n "$2" ]; then +# username=$2 +# else +# username=$(stat -c '%U' /srv/www/$virtualhost)@$virtualhost +# fi +# +# # check for and set mysql password +# if [ -n "$3" ]; then +# password=$3 +# else +# password=`/usr/bin/pwgen 16 1` +# fi +# +# mysqladmin create $database +# mysql -e "CREATE USER '$username'@'localhost' IDENTIFIED BY '$password';" +# mysql -e "GRANT ALL PRIVILEGES ON $database.* TO '$username'@'localhost';" +# mysqladmin flush-privileges +# +# echo "database '$database' created with username '$username' and password '$password'" diff --git a/bin/vhost-user-add.sh b/bin/vhost-user-add.sh new file mode 100644 index 0000000..214060f --- /dev/null +++ b/bin/vhost-user-add.sh @@ -0,0 +1,67 @@ +#!/bin/bash +# +# vhost-stack +# https://git.stack-source.com/msb/vhost-stack +# MIT License Copyright (c) 2021 Matthew Saunders Brown + +# load config +source /usr/local/etc/vhost.conf || echo "ERROR: Either you do not have vhost user permissions or the config file is missing." && exit + +# check for and set username +if [ -n "$1" ]; then + username=$1 +else + echo "username not set" + exit 1 +fi + +# check for and set password +if [ -n "$2" ]; then + password=$2 +else + echo "password not set" + exit 1 +fi + +# check for and set userid +if [ -n "$3" ]; then + userid=$3 +else + echo "userid not set" + exit 1 +fi + +if ! /bin/grep -q "^$username:" /etc/passwd; then + newusers="$username:$password:$userid:$userid::/home/$username:/bin/bash" + echo "$newusers"|newusers + pwck -s + grpck -s +fi + +if [[ ! -d "/home/$username" ]]; then + install -d -o $username -g $username -m 755 /home/$username +else + chown -R $username:$username /home/$username +fi + +if [[ ! -f "/home/$username/.bash_logout" ]]; then + install -o $username -g $username -m 640 /etc/skel/.bash_logout /home/$username +fi + +if [[ ! -f "/home/$username/.bashrc" ]]; then + install -o $username -g $username -m 640 /etc/skel/.bashrc /home/$username + echo '' >> /home/$username/.bashrc + echo '# local settings' >> /home/$username/.bashrc + echo '' >> /home/$username/.bashrc + echo 'export TERM=xterm-256color' >> /home/$username/.bashrc + echo '' >> /home/$username/.bashrc + echo 'command_not_found_handle () {' >> /home/$username/.bashrc + echo ' /usr/local/bin/command-not-found-handle $@' >> /home/$username/.bashrc + echo ' return 127' >> /home/$username/.bashrc + echo '}' >> /home/$username/.bashrc +fi + +if [[ ! -f "/home/$username/.profile" ]]; then + install -o $username -g $username -m 640 /etc/skel/.profile /home/$username +fi + diff --git a/bin/vhost-user-del.sh b/bin/vhost-user-del.sh new file mode 100644 index 0000000..c9c7d90 --- /dev/null +++ b/bin/vhost-user-del.sh @@ -0,0 +1,88 @@ +#!/bin/bash +# +# vhost-stack +# https://git.stack-source.com/msb/vhost-stack +# MIT License Copyright (c) 2021 Matthew Saunders Brown + +# load config +source /usr/local/etc/vhost.conf || echo "ERROR: Either you do not have vhost user permissions or the config file is missing." && exit + +# check for and set username +if [ -n "$1" ]; then + username=$1 +else + echo "username not set" + exit 1 +fi + +if ! /bin/grep -q "^$username:" /etc/passwd; then + echo user \"$username\" does not exist + exit 1 +fi + +vhost::set-virtualhostArray +for v in "${virtualhostArray[@]}" +do + if [ $(stat -c '%U' /srv/www/$v) = $username ]; then + echo "$username has one or more installed virtualhosts ($v)" + exit 1 + fi +done + +# check for jailed vhost mount +if /bin/grep -q "^/dev/sda /usr/jails/$username/srv/www/" /etc/mtab; then + echo user \"$username\" has one or more jailed vhosts mounted + exit 1 +fi + +# check for virtualhost jail mount(s) in fstab +if /bin/grep -q " /usr/jails/$username/srv/www/" /etc/fstab; then + echo user \"$username\" has one or more jailed vhost mounts + exit 1 +fi + +# checks complete, start removing stuff + +# check for php-fpm pool conf +vhost::set-phpVersion +if [[ -f "/etc/php/$phpVersion/fpm/pool.d/$username.conf" ]]; then + rm /etc/php/$phpVersion/fpm/pool.d/$username.conf + # restart php$phpVersion-fpm if it's running + if systemctl is-active --quiet php$phpVersion-fpm ; then + if /usr/sbin/php-fpm$phpVersion -t >/dev/null 2>&1 ; then + systemctl reload php$phpVersion-fpm + else + echo "WARNING: php-fpm$phpVersion configuration test failed" + fi + fi +fi + +# if users home dir is mounted in a jail, unmount it +if grep -q "^/dev/sda /usr/jails/$username/home/$username " /etc/mtab; then + umount /usr/jails/$username/home/$username +fi + +# if user home dir mount in fstab exists remove it +if grep -q "^/home/$username /usr/jails/$username/home/$username " /etc/fstab; then + sed -i "\|/home/$username /usr/jails/$username/home/$username|d" /etc/fstab +fi + +# delete user +/usr/sbin/userdel $username + +# delete users home dir if it still exists +if [[ -d "/home/$username" ]]; then + rm -r /home/$username +fi + +# delete users jail dir if it exists +if [[ -d "/usr/jails/$username" ]]; then + rm -r /usr/jails/$username +fi + +# remove jailkit socket if it exists +if grep -q "\[/usr/jails/$username/dev/log\]" /etc/jailkit/jk_socketd.ini; then + sed -i '/\/usr\/jails\/$username\/dev\/log/,+3 d' /etc/jailkit/jk_socketd.ini + killall jk_socketd + jk_socketd +fi diff --git a/bin/vhost-user-destroy.sh b/bin/vhost-user-destroy.sh new file mode 100644 index 0000000..b972dc8 --- /dev/null +++ b/bin/vhost-user-destroy.sh @@ -0,0 +1,45 @@ +#!/bin/bash +# +# vhost-stack +# https://git.stack-source.com/msb/vhost-stack +# MIT License Copyright (c) 2021 Matthew Saunders Brown + +# load config +source /usr/local/etc/vhost.conf || echo "ERROR: Either you do not have vhost user permissions or the config file is missing." && exit + + +# check for and set username +if [ -n "$1" ]; then + username=$1 +else + echo "username not set" + exit 1 +fi + +# First run a couple of basic checks. Redundant +# as user-del.sh run later does these same checks +# but prevents connecting to all nodes unnecessarily +if ! /bin/grep -q "^$username:" /etc/passwd; then + echo user \"$username\" does not exist + exit 1 +fi + +vhost::set-virtualhostArray +for v in "${virtualhostArray[@]}" +do + if [ $(stat -c '%U' /srv/www/$v) = $username ]; then + echo "$username has one or more installed virtualhosts ($v)" + exit 1 + fi +done + +# delete user from each node +vhost::set-clusterNodes all +for n in "${clusterNodes[@]}" +do + if [ $n = `hostname -s` ]; then + /usr/local/bin/user-del.sh $username + else + ssh $n.lan "/usr/local/bin/user-del.sh $username" + fi +done diff --git a/bin/vhost-user-jail-reset.sh b/bin/vhost-user-jail-reset.sh new file mode 100644 index 0000000..fe0602e --- /dev/null +++ b/bin/vhost-user-jail-reset.sh @@ -0,0 +1,75 @@ +#!/bin/bash +# +# vhost-stack +# https://git.stack-source.com/msb/vhost-stack +# MIT License Copyright (c) 2021 Matthew Saunders Brown + +# load config +source /usr/local/etc/vhost.conf || echo "ERROR: Either you do not have vhost user permissions or the config file is missing." && exit + +# check for and set username +if [ -n "$1" ]; then + username=$1 +else + echo "username not set" + exit 1 +fi + +if ! grep -q "^$username:" /etc/passwd; then + echo "$username is not installed on this server" + exit 1 +fi + +if [[ ! -d /home/$username ]]; then + echo "/home/$username does not exists" + exit 1 +fi + +if [[ ! -d "/usr/jails/$username" ]]; then + echo "/usr/jails/$username does not exists" + exit 1 +fi + +if ! grep -q ":/usr/jails/$username/./home/$username:" /etc/passwd; then + echo "$username does not have jail home dir set" + exit 1 +fi + +# check if any virtualhosts exist +if [ "$(ls -A /usr/jails/$username/var/www)" ]; then + # set virtualhosts array + cd /usr/jails/$username/srv/www/ + virtualhosts=(*) + # unmount virtualhost dir(s) + for virtualhost in "${!virtualhosts[@]}" + do + virtualhost=${virtualhosts[$virtualhost]} +echo umount /usr/jails/$username/srv/www/$virtualhost + done +fi + +# unmount jail home dir +echo umount /usr/jails/$username/home/$username + +# del jail dir +echo rm -r /usr/jails/$username + +# (re)create jail +echo jk_init -k -j /usr/jails/$username shellstack +echo mkdir -p /usr/jails/$username/opt /usr/jails/$username/usr/sbin /usr/jails/$username/tmp /usr/jails/$username/var/www +echo ln -s /usr/local/bin/mini_sendmail /usr/jails/$username/usr/sbin/sendmail +echo chmod a+rwx /usr/jails/$username/tmp +echo install -d -o $username -g $username -m 755 /usr/jails/$username/home/$username +echo jk_jailuser -n -j /usr/jails/$username -s /bin/bash $username + +# remount dirs +echo mount /usr/jails/$username/home/$username +virtualhostcount=${#virtualhosts[@]} +if [ "$virtualhostcount" -gt 0 ]; then + for virtualhost in "${!virtualhosts[@]}" + do + virtualhost=${virtualhosts[$virtualhost]} +echo install -d -o $username -g $username -m 755 /usr/jails/$username/srv/www/$virtualhost +echo mount /usr/jails/$username/srv/www/$virtualhost + done +fi diff --git a/bin/vhost-user-jail.sh b/bin/vhost-user-jail.sh new file mode 100644 index 0000000..6c263a1 --- /dev/null +++ b/bin/vhost-user-jail.sh @@ -0,0 +1,47 @@ +#!/bin/bash +# +# vhost-stack +# https://git.stack-source.com/msb/vhost-stack +# MIT License Copyright (c) 2021 Matthew Saunders Brown + +# load config +source /usr/local/etc/vhost.conf || echo "ERROR: Either you do not have vhost user permissions or the config file is missing." && exit + +# check for and set username +if [ -n "$1" ]; then + username=$1 +else + echo "username not set" + exit 1 +fi + +if ! grep -q "^$username:" /etc/passwd; then + echo "$username is not installed on this server" + exit 1 +fi + +if [[ ! -d /home/$username ]]; then + echo "/home/$username does not exists" + exit 1 +fi + +if [[ -d "/usr/jails/$username" ]]; then + echo "/usr/jails/$username already exists" + exit 1 +fi + +if grep -q ":/usr/jails/$username/./home/$username:" /etc/passwd; then + echo "$username already has jail home dir set" + exit 1 +fi + +jk_init -k -j /usr/jails/$username shellstack +mkdir -p /usr/jails/$username/opt /usr/jails/$username/usr/sbin /usr/jails/$username/tmp /usr/jails/$username/var/www +ln -s /usr/local/bin/mini_sendmail /usr/jails/$username/usr/sbin/sendmail +chmod a+rwx /usr/jails/$username/tmp +install -d -o $username -g $username -m 755 /usr/jails/$username/home/$username +mount --bind /home/$username /usr/jails/$username/home/$username +echo "/home/$username /usr/jails/$username/home/$username none bind 0 0" >> /etc/fstab +killall jk_socketd +jk_socketd +jk_jailuser -n -j /usr/jails/$username -s /bin/bash $username diff --git a/bin/vhost-user-jails-cp.sh b/bin/vhost-user-jails-cp.sh new file mode 100644 index 0000000..2e1928a --- /dev/null +++ b/bin/vhost-user-jails-cp.sh @@ -0,0 +1,45 @@ +#!/bin/bash +# +# vhost-stack +# https://git.stack-source.com/msb/vhost-stack +# MIT License Copyright (c) 2021 Matthew Saunders Brown + +# load config +source /usr/local/etc/vhost.conf || echo "ERROR: Either you do not have vhost user permissions or the config file is missing." && exit + +# check for and set file to be copied in to jails +if [ -n "$1" ]; then + cpfile=$1 +else + echo "file to copy in to jails not set" + exit 1 +fi + +# make sure file exists +if [ ! -f "$cpfile" ]; then + echo "invalid file for copying in to jails" + exit 1 +fi + +# make sure jails dir exists +if [[ ! -e /usr/jails/ ]]; then + echo "/usr/jails does not exist" + exit 1 +fi + +# check for /usr/sbin/jk_cp +if [[ ! -x "/usr/sbin/jk_cp" ]]; then + echo "/usr/sbin/jk_cp does not exist or is not executable" + exit 1 +fi + +# get list of jails +cd /usr/jails/ +jails=(*) + +for jail in "${!jails[@]}" +do + jail=${jails[$jail]} + echo "adding $cpfile to $jail" + jk_cp -k -j /usr/jails/$jail $cpfile +done diff --git a/bin/vhost-user-jails-reset.sh b/bin/vhost-user-jails-reset.sh new file mode 100644 index 0000000..bc9254a --- /dev/null +++ b/bin/vhost-user-jails-reset.sh @@ -0,0 +1,36 @@ +#!/bin/bash +# +# vhost-stack +# https://git.stack-source.com/msb/vhost-stack +# MIT License Copyright (c) 2021 Matthew Saunders Brown + +# load config +source /usr/local/etc/vhost.conf || echo "ERROR: Either you do not have vhost user permissions or the config file is missing." && exit + +# make sure jails dir exists +if [[ ! -e /usr/jails/ ]]; then + echo "/usr/jails does not exist" + exit 1 +fi + +# check if any jails exist +if [ ! "$(ls -A /usr/jails/)" ]; then + echo "no jails exist" + exit 1 +fi + +# check for /usr/sbin/jk_update +if [[ ! -x "/usr/sbin/jk_update" ]]; then + echo "/usr/sbin/jk_update does not exist or is not executable" + exit 1 +fi + +# get list of jails +cd /usr/jails/ +jails=(*) + +for jail in "${!jails[@]}" +do + jail=${jails[$jail]} + echo /usr/local/bin/user-jail-reset.sh $jail +done diff --git a/bin/vhost-user-jails-sync.sh b/bin/vhost-user-jails-sync.sh new file mode 100644 index 0000000..9b200a4 --- /dev/null +++ b/bin/vhost-user-jails-sync.sh @@ -0,0 +1,51 @@ +#!/bin/bash +# +# vhost-stack +# https://git.stack-source.com/msb/vhost-stack +# MIT License Copyright (c) 2021 Matthew Saunders Brown + +# load config +source /usr/local/etc/vhost.conf || echo "ERROR: Either you do not have vhost user permissions or the config file is missing." && exit + +mode=q + +if [ -n "$1" ]; then + if [ "$1" = 'verbose' ] || [ "$1" = 'v' ]; then + mode=i + elif [ "$1" = 'dry-run' ] || [ "$1" = 'n' ]; then + mode=vn + fi +fi + +# check that node is "active" +vhost::set-nodeRole +if [ "$nodeRole" != "active" ]; then + echo "NOTICE: node role not 'active'. bailing out" + exit 1 +fi + +# make sure jails dir exists +if [[ ! -e /usr/jails/ ]]; then + echo "/usr/jails does not exist" + exit 1 +fi + +# check if any jails exist +if [ ! "$(ls -A /usr/jails/)" ]; then + echo "no jails exist" + exit 1 +fi + +# get list of jails +cd /usr/jails/ +jails=(*) + +vhost::set-clusterNodes other + +for jail in "${jails[@]}" +do + for node in "${clusterNodes[@]}" + do + rsync -$mode --archive --no-times --hard-links --exclude=/usr/jails/$jail/home --exclude=/usr/jails/$jail/var/www --relative --delete --rsh=/usr/bin/ssh /usr/jails/$jail root@$node.lan:/ + done +done diff --git a/bin/vhost-user-jails-update.sh b/bin/vhost-user-jails-update.sh new file mode 100644 index 0000000..e668607 --- /dev/null +++ b/bin/vhost-user-jails-update.sh @@ -0,0 +1,40 @@ +#!/bin/bash +# +# vhost-stack +# https://git.stack-source.com/msb/vhost-stack +# MIT License Copyright (c) 2021 Matthew Saunders Brown + +# load config +source /usr/local/etc/vhost.conf || echo "ERROR: Either you do not have vhost user permissions or the config file is missing." && exit + +# make sure jails dir exists +if [[ ! -e /usr/jails/ ]]; then + echo "/usr/jails does not exist" + exit 1 +fi + +# check if any jails exist +if [ ! "$(ls -A /usr/jails/)" ]; then + echo "no jails exist" + exit 1 +fi + +# check for /usr/sbin/jk_update +if [[ ! -x "/usr/sbin/jk_update" ]]; then + echo "/usr/sbin/jk_update does not exist or is not executable" + exit 1 +fi + +# get list of jails +cd /usr/jails/ +jails=(*) + +for jail in "${!jails[@]}" +do + jail=${jails[$jail]} + echo "updating $jail" + /usr/sbin/jk_update -j /usr/jails/$jail + /usr/sbin/jk_update -j /usr/jails/$jail /lib64/ + /usr/sbin/jk_update -s /etc/passwd -s /etc/group -s /etc/ld.so.cache -j /usr/jails/$jail /etc/ + /sbin/ldconfig.real -r /usr/jails/$jail +done diff --git a/bin/vhost-varnish-disable.sh b/bin/vhost-varnish-disable.sh new file mode 100644 index 0000000..288ac22 --- /dev/null +++ b/bin/vhost-varnish-disable.sh @@ -0,0 +1,47 @@ +#!/bin/bash +# +# vhost-stack +# https://git.stack-source.com/msb/vhost-stack +# MIT License Copyright (c) 2021 Matthew Saunders Brown + +# load config +source /usr/local/etc/vhost.conf || echo "ERROR: Either you do not have vhost user permissions or the config file is missing." && exit + +# varnish-disable.sh virtualhost + +# check for and set virtualhost +if [ -n "$1" ]; then + virtualhost=$1 +else + echo "virtualhost not set" + exit 1 +fi + +# grab macro line from virtualhost config +if macro_vhost_line=`grep -m 1 "Use .*" /etc/apache2/sites-available/$virtualhost.conf` ; then + macro_name=`echo "$macro_vhost_line" | awk '{print $2}'` +else + echo "$virtualhost is not configured with mod_macro" + exit 1 +fi + +# make sure Varnish is already enabled +if [[ $macro_name =~ ^.*Varnish$ ]]; then + # set new macro_name + macro_name=`echo $macro_name | sed -e 's|Varnish$||'` + vhost_enable="$macro_name $virtualhost" +else + echo "Varnish is not enabled for $virtualhost" + exit 1 +fi + +# check if VHost macro is for a Subdomain or Alias +if [[ "$macro_name" == *"Subdomain"* ]] || [[ "$macro_name" == *"Alias"* ]]; then + macro_var=`echo "$macro_vhost_line" | awk '{print $5}'` + vhost_enable="$vhost_enable $macro_var" +fi + +# uncomment to flush varnish cache +# systemctl is-active --quiet varnish && systemctl reload --quiet varnish + +echo /usr/local/bin/vhost-enable.sh $vhost_enable diff --git a/bin/vhost-varnish-enable.sh b/bin/vhost-varnish-enable.sh new file mode 100644 index 0000000..fab3f8c --- /dev/null +++ b/bin/vhost-varnish-enable.sh @@ -0,0 +1,92 @@ +#!/bin/bash +# +# vhost-stack +# https://git.stack-source.com/msb/vhost-stack +# MIT License Copyright (c) 2021 Matthew Saunders Brown + +# load config +source /usr/local/etc/vhost.conf || echo "ERROR: Either you do not have vhost user permissions or the config file is missing." && exit + +# check for and set virtualhost +if [ -n "$1" ]; then + virtualhost=$1 +else + echo "virtualhost not set" + exit 1 +fi + +# make sure virtualhost is enabled via symlink +if [ ! -h "/etc/apache2/sites-enabled/$virtualhost.conf" ]; then + echo "virtualhost is not enabled" + exit 1 +fi + +# make sure virtualhost config is in standard location +if [ ! -f "/etc/apache2/sites-available/$virtualhost.conf" ]; then + echo "virtualhost config for $virtualhost not in /etc/apache2/sites-available/" + exit 1 +fi + +# grab macro line from virtualhost config +if macro_vhost_line=`grep -m 1 "Use .*" /etc/apache2/sites-available/$virtualhost.conf` ; then + macro_name=`echo "$macro_vhost_line" | awk '{print $2}'` +else + echo "$virtualhost is not configured with mod_macro" + exit 1 +fi + +# make sure Varnish is not already enabled +if [[ $macro_name =~ ^.*Varnish$ ]]; then + echo "Varnish already enabled for $virtualhost" + exit 1 +fi + +# check for valid HTTPS VHost macro +if [[ $macro_name =~ ^VHost[[:alpha:]]*HTTPS$ ]]; then + macro_name_new="${macro_name}Varnish" + vhost_enable="$macro_name_new $virtualhost" +else + echo "$virtualhost must be enabled with an HTTPS VHost macro" + exit 1 +fi + +# check if VHost macro is for a Subdomain +if [[ "$macro_name" == *"Subdomain"* ]]; then + vhost_subdomain=`echo "$macro_vhost_line" | awk '{print $5}'` + vhost_enable=$(echo "$vhost_enable" | sed -e "s/ $vhost_subdomain\./ /") + vhost_enable="$vhost_enable $vhost_subdomain" +fi + +# check if VHost macro is for an Alias +if [[ "$macro_name" == *"Alias"* ]]; then + vhost_alias=`echo "$macro_vhost_line" | awk '{print $5}'` + vhost_enable="$vhost_enable $vhost_alias" +fi + +# check for ssl cert +if [ ! -f "/etc/ssl/letsencrypt/$virtualhost.pem" ]; then + echo "$virtualhost.pem cert file does not exist" + exit 1 +fi + +# make sure varnish is installed +if [ ! -f /etc/varnish/sites.d/example.com.vcl ]; then + echo "Varnish not installed & configured on this server" + exit 1 +fi + +# check for / create varnish config +if [ ! -f "/etc/varnish/sites.d/$virtualhost.vcl" ]; then + # create varnish config + echo "sub vcl_recv {" > /etc/varnish/sites.d/$virtualhost.vcl + echo " if (req.http.host == \"$virtualhost\" || req.http.host == \"www.$virtualhost\") {" >> /etc/varnish/sites.d/$virtualhost.vcl + echo " # Uncomment next line to bypass varnish cache" >> /etc/varnish/sites.d/$virtualhost.vcl + echo " #return (pass);" >> /etc/varnish/sites.d/$virtualhost.vcl + echo " call wordpress;" >> /etc/varnish/sites.d/$virtualhost.vcl + echo " }" >> /etc/varnish/sites.d/$virtualhost.vcl + echo "}" >> /etc/varnish/sites.d/$virtualhost.vcl + /usr/local/bin/varnish-update-sites.sh + systemctl is-active --quiet varnish && systemctl reload --quiet varnish +fi + +/usr/local/bin/vhost-enable.sh $vhost_enable diff --git a/bin/vhost-varnish-update-sites.sh b/bin/vhost-varnish-update-sites.sh new file mode 100644 index 0000000..669ce98 --- /dev/null +++ b/bin/vhost-varnish-update-sites.sh @@ -0,0 +1,27 @@ +#!/bin/bash +# +# vhost-stack +# https://git.stack-source.com/msb/vhost-stack +# MIT License Copyright (c) 2021 Matthew Saunders Brown + +# load config +source /usr/local/etc/vhost.conf || echo "ERROR: Either you do not have vhost user permissions or the config file is missing." && exit + +if [ ! -f /etc/varnish/sites.d/example.com.vcl ]; then + + echo "ERROR: example.vlc does not exist" + exit 1 + +fi + +sitesArray=(`ls -1 /etc/varnish/sites.d/`) +truncate -s 0 /etc/varnish/sites.vcl + +for site in "${sitesArray[@]}" +do + + echo include \"sites.d/$site\"\; >> /etc/varnish/sites.vcl + +done + +exit 0 diff --git a/etc/apache2/conf-available/phpMyAdmin.conf b/etc/apache2/conf-available/phpMyAdmin.conf new file mode 100644 index 0000000..4876513 --- /dev/null +++ b/etc/apache2/conf-available/phpMyAdmin.conf @@ -0,0 +1,12 @@ +Alias /phpMyAdmin /srv/www/html/phpMyAdmin + +AddExternalAuth pwauth /usr/sbin/pwauth +SetExternalAuthMethod pwauth pipe + + + AuthType Basic + AuthName "phpMyAdmin" + AuthBasicProvider external + AuthExternal pwauth + Require valid-user + diff --git a/etc/apache2/mods-available/macro-redirect.conf b/etc/apache2/mods-available/macro-redirect.conf new file mode 100644 index 0000000..27f4915 --- /dev/null +++ b/etc/apache2/mods-available/macro-redirect.conf @@ -0,0 +1,50 @@ +# VHostHTTP for http only +# VHostHTTPS for http & https w/ optional http to https redirect +# only use one of the above at at time +# VHostMAIL for webmail at mail. subdomain assumes/requires https w/ valid cert + +# VHostHTTP - HTTP on Port 80. Includes ServerAlias for .mylampsite.com subdomain + + + ServerName $vhost + ServerAlias www.$vhost + ServerAlias $vhost.mylampsite.com + DocumentRoot /srv/www/$vhost/html + + + +# VHostHTTPS - HTTPS on Port 443. Inludes Port 80 and ServerAliases for .mylampsite.com subdomain + + + ServerName $vhost + ServerAlias www.$vhost + ServerAlias $vhost.mylampsite.com + + + Redirect 301 "https://%{HTTP_HOST}%{REQUEST_URI}" + + + + + ServerName $vhost + ServerAlias www.$vhost + ServerAlias $vhost.mylampsite.com + DocumentRoot /srv/www/$vhost/html + SSLCertificateFile /etc/ssl/letsencrypt/$vhost.pem + + + +# Webmail - HTTP Port 80 Redirects to HTTPS Port 443 + + + ServerName mail.$vhost + + Redirect / https://mail.$vhost + + + + ServerName mail.$vhost + DocumentRoot /srv/www/html/webmail/ + SSLCertificateFile /etc/ssl/letsencrypt/mail.$vhost.pem + + diff --git a/etc/apache2/mods-available/macro.conf b/etc/apache2/mods-available/macro.conf new file mode 100644 index 0000000..300ad9a --- /dev/null +++ b/etc/apache2/mods-available/macro.conf @@ -0,0 +1,240 @@ +# VHostHTTP for http only +# VHostHTTPS for http & https w/ optional http to https redirect +# VHostHTTPSVarnish for https -> Varnish -> http +# VHostSubdomainHTTP +# VHostSubdomainHTTPS +# VHostSubdomainHTTPSVarnish +# *only use one of the VHost options above at at time* +# +# VMailHTTPS for webmail at mail. subdomain assumes & requires https w/ valid cert +# +# RedirectHTTP for http only +# RedirectHTTPS for http & https +# *only use one of the Redirect options above at at time* +# +# VHostAliasHTTP for http only +# VHostAliasHTTPS for http & https +# VHostAliasHTTPSVarnish for http & https +# *only use one of the Alias options above at at time* + +# VHostHTTP - HTTP on Port 80. Includes ServerAlias for .mylampsite.com subdomain + + + ServerName $vhost + ServerAlias www.$vhost + ServerAlias $vhost.mylampsite.com + DocumentRoot /srv/www/$vhost/html + + SetHandler "proxy:unix:/run/php/php7.4-fpm-$username.sock|fcgi://localhost" + + + + + + + ServerName $subdomain.$vhost + ServerAlias $subdomain.$vhost.mylampsite.com + DocumentRoot /srv/www/$vhost/$subdomain + + SetHandler "proxy:unix:/run/php/php7.4-fpm-$username.sock|fcgi://localhost" + + + + +# VHostHTTPS - HTTPS on Port 443. Inludes Port 80 and ServerAliases for .mylampsite.com subdomain + + + ServerName $vhost + ServerAlias www.$vhost + ServerAlias $vhost.mylampsite.com + DocumentRoot /srv/www/$vhost/html +## +## +## Redirect 301 "https://%{HTTP_HOST}%{REQUEST_URI}" +## +## + + SetHandler "proxy:unix:/run/php/php7.4-fpm-$username.sock|fcgi://localhost" + + + + ServerName $vhost + ServerAlias www.$vhost + ServerAlias $vhost.mylampsite.com + DocumentRoot /srv/www/$vhost/html + + SetHandler "proxy:unix:/run/php/php7.4-fpm-$username.sock|fcgi://localhost" + + SSLEngine on + SSLCertificateFile /etc/ssl/letsencrypt/$vhost.pem + + + +# VHostSubdomainHTTPS - HTTPS on Port 443. Inludes Port 80 and ServerAliases for .mylampsite.com subdomain + + + ServerName $subdomain.$vhost + ServerAlias $subdomain.$vhost.mylampsite.com + DocumentRoot /srv/www/$vhost/$subdomain +## +## +## Redirect 301 "https://%{HTTP_HOST}%{REQUEST_URI}" +## +## + + SetHandler "proxy:unix:/run/php/php7.4-fpm-$username.sock|fcgi://localhost" + + + + ServerName $subdomain.$vhost + ServerAlias $subdomain.$vhost.mylampsite.com + DocumentRoot /srv/www/$vhost/$subdomain + + SetHandler "proxy:unix:/run/php/php7.4-fpm-$username.sock|fcgi://localhost" + + SSLEngine on + SSLCertificateFile /etc/ssl/letsencrypt/$subdomain.$vhost.pem + + + +# VHostHTTPSVarnish - HTTPS on Port 443 proxies to Varnish which then connects to Port 80 + + + ServerName $vhost + ServerAlias www.$vhost + ServerAlias $vhost.mylampsite.com + DocumentRoot /srv/www/$vhost/html + + SetHandler "proxy:unix:/run/php/php7.4-fpm-$username.sock|fcgi://localhost" + + + + ServerName $vhost + ServerAlias www.$vhost + ServerAlias $vhost.mylampsite.com + RequestHeader set X-Forwarded-Proto https + ProxyPreserveHost On + ProxyPass / http://127.0.0.1:6081/ + ProxyPassReverse / http://127.0.0.1:6081/ + SSLEngine on + SSLCertificateFile /etc/ssl/letsencrypt/$vhost.pem + + + +# VHostSubdomainHTTPSVarnish - HTTPS on Port 443 proxies to Varnish which then connects to Port 80 + + + ServerName $subdomain.$vhost + ServerAlias $subdomain.$vhost.mylampsite.com + DocumentRoot /srv/www/$vhost/$subdomain + + SetHandler "proxy:unix:/run/php/php7.4-fpm-$username.sock|fcgi://localhost" + + + + ServerName $subdomain.$vhost + ServerAlias $subdomain.$vhost.mylampsite.com + RequestHeader set X-Forwarded-Proto https + ProxyPreserveHost On + ProxyPass / http://127.0.0.1:6081/ + ProxyPassReverse / http://127.0.0.1:6081/ + SSLEngine on + SSLCertificateFile /etc/ssl/letsencrypt/$subdomain.$vhost.pem + + + +# Webmail - HTTP Port 80 Redirects to HTTPS Port 443 + + + ServerName $vhost + + + Redirect / https://$vhost + + + + + ServerName $vhost + DocumentRoot /srv/www/html/webmail/ + SSLEngine on + SSLCertificateFile /etc/ssl/letsencrypt/$vhost.pem + + + + + + ServerName $vhost + ServerAlias www.$vhost + ServerAlias $vhost.mylampsite.com + + + Redirect 301 "$redirect%{REQUEST_URI}" + + + + + + + + ServerName $vhost + ServerAlias www.$vhost + ServerAlias $vhost.mylampsite.com + + + Redirect 301 "$redirect%{REQUEST_URI}" + + + + + ServerName $vhost + ServerAlias www.$vhost + ServerAlias $vhost.mylampsite.com + + + Redirect 301 "$redirect%{REQUEST_URI}" + + + SSLEngine on + SSLCertificateFile /etc/ssl/letsencrypt/$vhost.pem + + + + + + ServerName $vhost + ServerAlias www.$vhost + ServerAlias $vhost.mylampsite.com + DocumentRoot /srv/www/$alias/html + + SetHandler "proxy:unix:/run/php/php7.4-fpm-$username.sock|fcgi://localhost" + + + + + + + ServerName $vhost + ServerAlias www.$vhost + ServerAlias $vhost.mylampsite.com + DocumentRoot /srv/www/$alias/html +## +## +## Redirect 301 "https://%{HTTP_HOST}%{REQUEST_URI}" +## +## + + SetHandler "proxy:unix:/run/php/php7.4-fpm-$username.sock|fcgi://localhost" + + + + ServerName $vhost + ServerAlias www.$vhost + ServerAlias $vhost.mylampsite.com + DocumentRoot /srv/www/$alias/html + + SetHandler "proxy:unix:/run/php/php7.4-fpm-$username.sock|fcgi://localhost" + + SSLEngine on + SSLCertificateFile /etc/ssl/letsencrypt/$vhost.pem + + diff --git a/etc/apache2/mods-available/remoteip.conf b/etc/apache2/mods-available/remoteip.conf new file mode 100644 index 0000000..e06662e --- /dev/null +++ b/etc/apache2/mods-available/remoteip.conf @@ -0,0 +1,4 @@ + + RemoteIPHeader X-Forwarded-For + RemoteIPInternalProxy 127.0.0.1 + diff --git a/etc/apache2/mods-available/ssl.conf b/etc/apache2/mods-available/ssl.conf new file mode 100644 index 0000000..7e36463 --- /dev/null +++ b/etc/apache2/mods-available/ssl.conf @@ -0,0 +1,85 @@ + + + # Pseudo Random Number Generator (PRNG): + # Configure one or more sources to seed the PRNG of the SSL library. + # The seed data should be of good random quality. + # WARNING! On some platforms /dev/random blocks if not enough entropy + # is available. This means you then cannot use the /dev/random device + # because it would lead to very long connection times (as long as + # it requires to make more entropy available). But usually those + # platforms additionally provide a /dev/urandom device which doesn't + # block. So, if available, use this one instead. Read the mod_ssl User + # Manual for more details. + # + SSLRandomSeed startup builtin + SSLRandomSeed startup file:/dev/urandom 512 + SSLRandomSeed connect builtin + SSLRandomSeed connect file:/dev/urandom 512 + + ## + ## SSL Global Context + ## + ## All SSL configuration in this context applies both to + ## the main server and all SSL-enabled virtual hosts. + ## + + # + # Some MIME-types for downloading Certificates and CRLs + # + AddType application/x-x509-ca-cert .crt + AddType application/x-pkcs7-crl .crl + + # Pass Phrase Dialog: + # Configure the pass phrase gathering process. + # The filtering dialog program (`builtin' is a internal + # terminal dialog) has to provide the pass phrase on stdout. + SSLPassPhraseDialog exec:/usr/share/apache2/ask-for-passphrase + + # Inter-Process Session Cache: + # Configure the SSL Session Cache: First the mechanism + # to use and second the expiring timeout (in seconds). + # (The mechanism dbm has known memory leaks and should not be used). + #SSLSessionCache dbm:${APACHE_RUN_DIR}/ssl_scache + SSLSessionCache shmcb:${APACHE_RUN_DIR}/ssl_scache(512000) + SSLSessionCacheTimeout 300 + + # Semaphore: + # Configure the path to the mutual exclusion semaphore the + # SSL engine uses internally for inter-process synchronization. + # (Disabled by default, the global Mutex directive consolidates by default + # this) + #Mutex file:${APACHE_LOCK_DIR}/ssl_mutex ssl-cache + + + # SSL Cipher Suite: + # List the ciphers that the client is permitted to negotiate. See the + # ciphers(1) man page from the openssl package for list of all available + # options. + # Enable only secure ciphers: + SSLCipherSuite HIGH:!aNULL + + # SSL server cipher order preference: + # Use server priorities for cipher algorithm choice. + # Clients may prefer lower grade encryption. You should enable this + # option if you want to enforce stronger encryption, and can afford + # the CPU cost, and did not override SSLCipherSuite in a way that puts + # insecure ciphers first. + # Default: Off + #SSLHonorCipherOrder on + + # The protocols to enable. + # Available values: all, SSLv3, TLSv1, TLSv1.1, TLSv1.2 + # SSL v2 is no longer supported + SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1 + + # Allow insecure renegotiation with clients which do not yet support the + # secure renegotiation protocol. Default: Off + #SSLInsecureRenegotiation on + + # Whether to forbid non-SNI clients to access name based virtual hosts. + # Default: Off + #SSLStrictSNIVHostCheck On + + + +# vim: syntax=apache ts=4 sw=4 sts=4 sr noet diff --git a/etc/varnish/catch-all.vcl b/etc/varnish/catch-all.vcl new file mode 100644 index 0000000..2f83e0b --- /dev/null +++ b/etc/varnish/catch-all.vcl @@ -0,0 +1,15 @@ +sub vcl_recv { + + # default request, not handled by a specific vhost config + + # uncomment to bypass cache entirely by default + # return (pass); + + # use this for default varnish config + if (req.http.Cookie) { + /* Not cacheable by default */ + return (pass); + } + return (hash); + +} diff --git a/etc/varnish/default.vcl b/etc/varnish/default.vcl new file mode 100644 index 0000000..e7dfdfa --- /dev/null +++ b/etc/varnish/default.vcl @@ -0,0 +1,126 @@ +# +# This is an example VCL file for Varnish. +# +# It does not do anything by default, delegating control to the +# builtin VCL. The builtin VCL is called when there is no explicit +# return statement. +# +# See the VCL chapters in the Users Guide at https://www.varnish-cache.org/docs/ +# and https://www.varnish-cache.org/trac/wiki/VCLExamples for more examples. +# +# validate config with: +# varnishd -C -f /etc/varnish/default.vcl +# https://varnish-cache.org/docs/6.2/ +# +# Marker to tell the VCL compiler that this VCL has been adapted to the +# new 4.0 format. +vcl 4.0; + +import std; + +# Default backend definition. Set this to point to your content server. +backend default { + .host = "127.0.0.1"; + .port = "80"; +} + +sub vcl_recv { + # Happens before we check if we have this in cache already. + # + # Typically you clean up the request here, removing cookies you don't need, + # rewriting the request, etc. + + # Normalize the header - lowercase & remove the port + set req.http.host = std.tolower(req.http.host); + set req.http.host = regsub(req.http.host, ":[0-9]+", ""); + # Do not remove www as depending on WP url setting this can cause a 301 redirect loop. + #set req.http.host = regsub(req.http.host, "^www\.", ""); + + if (req.method == "PRI") { + /* This will never happen in properly formed traffic (see: RFC7540) */ + return (synth(405)); + } + + if (!req.http.host && req.esi_level == 0 && req.proto ~ "^(?i)HTTP/1.1") { + /* In HTTP/1.1, Host is required. */ + return (synth(400)); + } + + if (req.method != "GET" && + req.method != "HEAD" && + req.method != "PUT" && + req.method != "POST" && + req.method != "TRACE" && + req.method != "OPTIONS" && + req.method != "DELETE" && + req.method != "PATCH") { + /* Non-RFC2616 or CONNECT which is weird. */ + return (pipe); + } + + if (req.method != "GET" && req.method != "HEAD") { + /* We only deal with GET and HEAD by default */ + return (pass); + } + + if (req.http.Authorization) { + /* Not cacheable by default */ + return (pass); + } + + # HTTP verification passthrough (Let'sEncrypt/Certbot /acme-challenge/ URL already handled by HAProxy) + if (req.url ~ "^/\.well-known/") { + return (pass); + } + + +# # Don't cache status checks. +# if (req.url ~ "^/status\.php") { +# return(pass); +# } + +# # "fix" X-Forwarded-For. Not needed +# if (req.http.x-client-ip) { +# set req.http.X-Forwarded-For = req.http.X-Client-IP; +# } else { +# set req.http.X-Forwarded-For = client.ip; +# } + +} + +sub vcl_backend_response { + # Happens after we have read the response headers from the backend. + # + # Here you clean the response headers, removing silly Set-Cookie headers + # and other mistakes your backend does. +} + +sub vcl_deliver { + # Happens when we have all the pieces we need, and are about to send the + # response to the client. + # + # You can do accounting or modifying the final object here. + if (obj.hits > 0) { + set resp.http.X-Cache = "HIT"; + set resp.http.X-Cache-Hits = obj.hits; + } else { + set resp.http.X-Cache = "MISS"; + } +} + +sub vcl_hash { + + if (req.http.X-Forwarded-Proto) { + hash_data(req.http.X-Forwarded-Proto); + } elseif (req.http.X-Forwarded-Port) { + hash_data(req.http.X-Forwarded-Port); + } else { + hash_data(std.port(server.ip)); + } + +} + +# include configs & vhosts +include "wordpress-sub.vcl"; +include "sites.vcl"; +include "catch-all.vcl"; diff --git a/etc/varnish/sites.d/example.com.vcl b/etc/varnish/sites.d/example.com.vcl new file mode 100644 index 0000000..86b9adc --- /dev/null +++ b/etc/varnish/sites.d/example.com.vcl @@ -0,0 +1,5 @@ +sub vcl_recv { + if (req.http.host == "example.com" || req.http.host == "www.example.com") { + call wordpress; # add site specific custom configs before/after wordpress sub call + } +} diff --git a/etc/varnish/sites.vcl b/etc/varnish/sites.vcl new file mode 100644 index 0000000..3bb76b0 --- /dev/null +++ b/etc/varnish/sites.vcl @@ -0,0 +1 @@ +include "sites.d/example.com.vcl"; diff --git a/etc/varnish/wordpress-sub.vcl b/etc/varnish/wordpress-sub.vcl new file mode 100644 index 0000000..712ede1 --- /dev/null +++ b/etc/varnish/wordpress-sub.vcl @@ -0,0 +1,128 @@ +# +# Default WordPress config +# +# Much of this taken from: +# https://www.serverlab.ca/tutorials/linux/web-servers-linux/how-to-configure-varnish-4-for-wordpress/ +# https://github.com/mattiasgeniar/varnish-6.0-configuration-templates/blob/master/default.vcl +# +sub wordpress { + + # Do not cache AJAX requests + if (req.http.X-Requested-With == "XMLHttpRequest") { + return(pass); + } + + # Bypass REST API + if (req.url ~ "^/wp-json/") { + return (pass); + } + + # Do not cache previews + if (req.url ~ "preview=true") { + return (pass); + } + + # Do not cache cron + if (req.url ~ "/wp-cron.php") { + return (pass); + } + + # Don't cache uploads. Should only be static files that apache can serve efficiently. + # Use mod_expires via .htaccess so that static files are cached by clients. + if (req.url ~ "/wp-content/uploads/") { + return (pass); + } + + # Undecided on these. Disabled for now, keep an eye out for issues. +# # don't cache rss feed +# if (req.url ~ "/feed(/)?") { +# return ( pass ); +# } +# +# # Don't cache search results +# if (req.url ~ "/\?s\=") { +# return ( pass ); +# } + + # Remove the Google Analytics added parameters, not needed by backend + if (req.url ~ "(\?|&)(utm_source|utm_medium|utm_campaign|utm_content|gclid|cx|ie|cof|siteurl)=") { + set req.url = regsuball(req.url, "&(utm_source|utm_medium|utm_campaign|utm_content|gclid|cx|ie|cof|siteurl)=([A-z0-9_\-\.%25]+)", ""); + set req.url = regsuball(req.url, "\?(utm_source|utm_medium|utm_campaign|utm_content|gclid|cx|ie|cof|siteurl)=([A-z0-9_\-\.%25]+)", "?"); + set req.url = regsub(req.url, "\?&", "?"); + set req.url = regsub(req.url, "\?$", ""); + } + + # Strip hash, server doesn't need it. + if (req.url ~ "\#") { + set req.url = regsub(req.url, "\#.*$", ""); + } + + # Strip a trailing ? if it exists + if (req.url ~ "\?$") { + set req.url = regsub(req.url, "\?$", ""); + } + + # Normalize the query arguments (but exclude for WordPress' backend) + if (req.url !~ "wp-admin") { + set req.url = std.querysort(req.url); + } + + # Remove unneeded WP cookies + set req.http.Cookie = regsuball(req.http.Cookie, "wordpress_test_cookie=[^;]+(; )?", ""); + set req.http.cookie = regsuball(req.http.cookie, "wp-settings-\d+=[^;]+(; )?", ""); + set req.http.cookie = regsuball(req.http.cookie, "wp-settings-time-\d+=[^;]+(; )?", ""); + + # Remove the "has_js" cookie + set req.http.Cookie = regsuball(req.http.Cookie, "has_js=[^;]+(; )?", ""); + + # Remove any Google Analytics based cookies + set req.http.Cookie = regsuball(req.http.Cookie, "__utm.=[^;]+(; )?", ""); + set req.http.Cookie = regsuball(req.http.Cookie, "_ga=[^;]+(; )?", ""); + set req.http.Cookie = regsuball(req.http.Cookie, "_gat=[^;]+(; )?", ""); + set req.http.Cookie = regsuball(req.http.Cookie, "utmctr=[^;]+(; )?", ""); + set req.http.Cookie = regsuball(req.http.Cookie, "utmcmd.=[^;]+(; )?", ""); + set req.http.Cookie = regsuball(req.http.Cookie, "utmccn.=[^;]+(; )?", ""); + + # Remove DoubleClick cookies + set req.http.Cookie = regsuball(req.http.Cookie, "__gads=[^;]+(; )?", ""); + + # Remove the Quant Capital cookies (added by some plugin, all __qca) + set req.http.Cookie = regsuball(req.http.Cookie, "__qc.=[^;]+(; )?", ""); + + # Remove the AddThis cookies + set req.http.Cookie = regsuball(req.http.Cookie, "__atuv.=[^;]+(; )?", ""); + + # Remove a ";" prefix in the cookie if present + set req.http.Cookie = regsuball(req.http.Cookie, "^;\s*", ""); + + # Remove any cookies left with only spaces or that are empty + if (req.http.cookie ~ "^ *$") { + unset req.http.cookie; + } + + # Remove all cookies for static files and cache now + # Note that we already skipped the 'uploads' dir, so this really only applies to files included in WP Core, Themes & Plugins. + # Could disable skipping of 'uploads' dir to cache all static files. Has potential to fill up varnish cache, but could be useful in some specific cases. + if (std.tolower(req.url) ~ "^[^?]*\.(7z|avi|bmp|bz2|css|csv|doc|docx|eot|flac|flv|gif|gz|ico|jpeg|jpg|js|less|mka|mkv|mov|mp3|mp4|mpeg|mpg|odt|ogg|ogm|opus|otf|pdf|png|ppt|pptx|rar|rtf|svg|svgz|swf|tar|tbz|tgz|ttf|txt|txz|wav|webm|webp|woff|woff2|xls|xlsx|xml|xz|zip)(\?.*)?$") { + unset req.http.Cookie; + return (hash); + } + + # Do not cache the admin or login pages + if (req.url ~ "^/wp-admin/|^/wp-login\.php") { + return (pass); + } + + # Check for wordpress cookies that should indicate no-cache. + if (req.http.Cookie ~ "wordpress_logged_in_" || req.http.Cookie ~ "comment_" || req.http.Cookie ~ "resetpass") { + return (pass); + } + + # check for woocommerce cookies + if (req.http.Cookie ~ "(woocommerce_cart_hash|woocommerce_items_in_cart|wp_woocommerce_session_[a-zA-Z0-9]+)") { + return (pass); + } + + # catch-all will run next. if cookie (pass) else (hash) + +} diff --git a/etc/vhost.conf b/etc/vhost.conf new file mode 100644 index 0000000..ac24833 --- /dev/null +++ b/etc/vhost.conf @@ -0,0 +1,36 @@ +# vhost configs + +# any script that includes this conf file will force user to be root +if [ "$USER" != "root" ]; then + #exec sudo -u root $0 $@ + exec sudo $0 $@ +fi + +# constants + +# functions + +function vhost::set-virtualhostArray () { + + cd /srv/www + virtualhostArray=(`ls -1|grep -v ^html$`) + +} + +function vhost::set-phpVersion () { + + PHP_MAJOR_VERSION=`php -r "echo PHP_MAJOR_VERSION;"` + PHP_MINOR_VERSION=`php -r "echo PHP_MINOR_VERSION;"` + phpVersion=$PHP_MAJOR_VERSION.$PHP_MINOR_VERSION + +} + +# crude but good enough domain name format validation +function vhost::validate_domain () { + local my_domain=$1 + if [[ $my_domain =~ ^(([a-zA-Z](-?[a-zA-Z0-9])*)\.)+[a-zA-Z]{2,}$ ]] ; then + return 0 + else + return 1 + fi +} diff --git a/libexec/command-not-found-handle b/libexec/command-not-found-handle new file mode 100644 index 0000000..7943857 --- /dev/null +++ b/libexec/command-not-found-handle @@ -0,0 +1,17 @@ +#!/bin/bash + +echo +echo $1: command not found +echo +echo " Note this is a secure chroot jail which" +echo " only includes a limited set of commands." +echo +if [[ "$1" =~ "passwd" ]]; then + echo " To change your password please contact" + echo " support." +else + echo " If you are trying to execute a command that" + echo " you believe should be included in this chroot" + echo " jail please contact support." +fi +echo