initial commit

This commit is contained in:
Matthew Saunders Brown 2021-04-04 13:28:22 -07:00
commit 4226322936
35 changed files with 2059 additions and 0 deletions

19
LICENSE Normal file
View File

@ -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.

17
README.md Normal file
View File

@ -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
```

86
bin/vhost-add.sh Normal file
View File

@ -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

73
bin/vhost-del.sh Normal file
View File

@ -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

98
bin/vhost-deploy.sh Normal file
View File

@ -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

44
bin/vhost-destroy.sh Normal file
View File

@ -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

26
bin/vhost-disable.sh Normal file
View File

@ -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

166
bin/vhost-enable.sh Normal file
View File

@ -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

45
bin/vhost-fix-perms.sh Normal file
View File

@ -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
}

53
bin/vhost-mysql-db-add.sh Normal file
View File

@ -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'"

53
bin/vhost-mysql-db-del.sh Normal file
View File

@ -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'"

67
bin/vhost-user-add.sh Normal file
View File

@ -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

88
bin/vhost-user-del.sh Normal file
View File

@ -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

45
bin/vhost-user-destroy.sh Normal file
View File

@ -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

View File

@ -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

47
bin/vhost-user-jail.sh Normal file
View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,12 @@
Alias /phpMyAdmin /srv/www/html/phpMyAdmin
AddExternalAuth pwauth /usr/sbin/pwauth
SetExternalAuthMethod pwauth pipe
<Location /phpMyAdmin>
AuthType Basic
AuthName "phpMyAdmin"
AuthBasicProvider external
AuthExternal pwauth
Require valid-user
</Location>

View File

@ -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
<Macro VHostHTTP $vhost>
<VirtualHost *:80>
ServerName $vhost
ServerAlias www.$vhost
ServerAlias $vhost.mylampsite.com
DocumentRoot /srv/www/$vhost/html
</VirtualHost>
</Macro>
# VHostHTTPS - HTTPS on Port 443. Inludes Port 80 and ServerAliases for .mylampsite.com subdomain
<Macro VHostHTTPS $vhost>
<VirtualHost *:80>
ServerName $vhost
ServerAlias www.$vhost
ServerAlias $vhost.mylampsite.com
<Location "/">
<If "%{REQUEST_URI} !~ m#^/.well-known/acme-challenge/#">
Redirect 301 "https://%{HTTP_HOST}%{REQUEST_URI}"
</If>
</Location>
</VirtualHost>
<VirtualHost *:443>
ServerName $vhost
ServerAlias www.$vhost
ServerAlias $vhost.mylampsite.com
DocumentRoot /srv/www/$vhost/html
SSLCertificateFile /etc/ssl/letsencrypt/$vhost.pem
</VirtualHost>
</Macro>
# Webmail - HTTP Port 80 Redirects to HTTPS Port 443
<Macro VHostMAIL $vhost>
<VirtualHost *:80>
ServerName mail.$vhost
<If "%{REQUEST_URI} !~ m#^/.well-known/acme-challenge/#">
Redirect / https://mail.$vhost
</If>
</VirtualHost>
<VirtualHost *:443>
ServerName mail.$vhost
DocumentRoot /srv/www/html/webmail/
SSLCertificateFile /etc/ssl/letsencrypt/mail.$vhost.pem
</VirtualHost>
</Macro>

View File

@ -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
<Macro VHostHTTP $vhost $username>
<VirtualHost *:80>
ServerName $vhost
ServerAlias www.$vhost
ServerAlias $vhost.mylampsite.com
DocumentRoot /srv/www/$vhost/html
<FilesMatch ".+\.ph(ar|p|tml)$">
SetHandler "proxy:unix:/run/php/php7.4-fpm-$username.sock|fcgi://localhost"
</FilesMatch>
</VirtualHost>
</Macro>
<Macro VHostSubdomainHTTP $vhost $username $subdomain>
<VirtualHost *:80>
ServerName $subdomain.$vhost
ServerAlias $subdomain.$vhost.mylampsite.com
DocumentRoot /srv/www/$vhost/$subdomain
<FilesMatch ".+\.ph(ar|p|tml)$">
SetHandler "proxy:unix:/run/php/php7.4-fpm-$username.sock|fcgi://localhost"
</FilesMatch>
</VirtualHost>
</Macro>
# VHostHTTPS - HTTPS on Port 443. Inludes Port 80 and ServerAliases for .mylampsite.com subdomain
<Macro VHostHTTPS $vhost $username>
<VirtualHost *:80>
ServerName $vhost
ServerAlias www.$vhost
ServerAlias $vhost.mylampsite.com
DocumentRoot /srv/www/$vhost/html
## <Location "/">
## <If "%{REQUEST_URI} !~ m#^/.well-known/acme-challenge/#">
## Redirect 301 "https://%{HTTP_HOST}%{REQUEST_URI}"
## </If>
## </Location>
<FilesMatch ".+\.ph(ar|p|tml)$">
SetHandler "proxy:unix:/run/php/php7.4-fpm-$username.sock|fcgi://localhost"
</FilesMatch>
</VirtualHost>
<VirtualHost *:443>
ServerName $vhost
ServerAlias www.$vhost
ServerAlias $vhost.mylampsite.com
DocumentRoot /srv/www/$vhost/html
<FilesMatch ".+\.ph(ar|p|tml)$">
SetHandler "proxy:unix:/run/php/php7.4-fpm-$username.sock|fcgi://localhost"
</FilesMatch>
SSLEngine on
SSLCertificateFile /etc/ssl/letsencrypt/$vhost.pem
</VirtualHost>
</Macro>
# VHostSubdomainHTTPS - HTTPS on Port 443. Inludes Port 80 and ServerAliases for .mylampsite.com subdomain
<Macro VHostSubdomainHTTPS $vhost $username $subdomain>
<VirtualHost *:80>
ServerName $subdomain.$vhost
ServerAlias $subdomain.$vhost.mylampsite.com
DocumentRoot /srv/www/$vhost/$subdomain
## <Location "/">
## <If "%{REQUEST_URI} !~ m#^/.well-known/acme-challenge/#">
## Redirect 301 "https://%{HTTP_HOST}%{REQUEST_URI}"
## </If>
## </Location>
<FilesMatch ".+\.ph(ar|p|tml)$">
SetHandler "proxy:unix:/run/php/php7.4-fpm-$username.sock|fcgi://localhost"
</FilesMatch>
</VirtualHost>
<VirtualHost *:443>
ServerName $subdomain.$vhost
ServerAlias $subdomain.$vhost.mylampsite.com
DocumentRoot /srv/www/$vhost/$subdomain
<FilesMatch ".+\.ph(ar|p|tml)$">
SetHandler "proxy:unix:/run/php/php7.4-fpm-$username.sock|fcgi://localhost"
</FilesMatch>
SSLEngine on
SSLCertificateFile /etc/ssl/letsencrypt/$subdomain.$vhost.pem
</VirtualHost>
</Macro>
# VHostHTTPSVarnish - HTTPS on Port 443 proxies to Varnish which then connects to Port 80
<Macro VHostHTTPSVarnish $vhost $username>
<VirtualHost *:80>
ServerName $vhost
ServerAlias www.$vhost
ServerAlias $vhost.mylampsite.com
DocumentRoot /srv/www/$vhost/html
<FilesMatch ".+\.ph(ar|p|tml)$">
SetHandler "proxy:unix:/run/php/php7.4-fpm-$username.sock|fcgi://localhost"
</FilesMatch>
</VirtualHost>
<VirtualHost *:443>
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
</VirtualHost>
</Macro>
# VHostSubdomainHTTPSVarnish - HTTPS on Port 443 proxies to Varnish which then connects to Port 80
<Macro VHostSubdomainHTTPSVarnish $vhost $username $subdomain>
<VirtualHost *:80>
ServerName $subdomain.$vhost
ServerAlias $subdomain.$vhost.mylampsite.com
DocumentRoot /srv/www/$vhost/$subdomain
<FilesMatch ".+\.ph(ar|p|tml)$">
SetHandler "proxy:unix:/run/php/php7.4-fpm-$username.sock|fcgi://localhost"
</FilesMatch>
</VirtualHost>
<VirtualHost *:443>
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
</VirtualHost>
</Macro>
# Webmail - HTTP Port 80 Redirects to HTTPS Port 443
<Macro VMailHTTPS $vhost>
<VirtualHost *:80>
ServerName $vhost
<Location "/">
<If "%{REQUEST_URI} !~ m#^/.well-known/acme-challenge/#">
Redirect / https://$vhost
</If>
</Location>
</VirtualHost>
<VirtualHost *:443>
ServerName $vhost
DocumentRoot /srv/www/html/webmail/
SSLEngine on
SSLCertificateFile /etc/ssl/letsencrypt/$vhost.pem
</VirtualHost>
</Macro>
<Macro RedirectHTTP $vhost $redirect>
<VirtualHost *:80>
ServerName $vhost
ServerAlias www.$vhost
ServerAlias $vhost.mylampsite.com
<Location "/">
<If "%{REQUEST_URI} !~ m#^/.well-known/acme-challenge/#">
Redirect 301 "$redirect%{REQUEST_URI}"
</If>
</Location>
</VirtualHost>
</Macro>
<Macro RedirectHTTPS $vhost $redirect>
<VirtualHost *:80>
ServerName $vhost
ServerAlias www.$vhost
ServerAlias $vhost.mylampsite.com
<Location "/">
<If "%{REQUEST_URI} !~ m#^/.well-known/acme-challenge/#">
Redirect 301 "$redirect%{REQUEST_URI}"
</If>
</Location>
</VirtualHost>
<VirtualHost *:443>
ServerName $vhost
ServerAlias www.$vhost
ServerAlias $vhost.mylampsite.com
<Location "/">
<If "%{REQUEST_URI} !~ m#^/.well-known/acme-challenge/#">
Redirect 301 "$redirect%{REQUEST_URI}"
</If>
</Location>
SSLEngine on
SSLCertificateFile /etc/ssl/letsencrypt/$vhost.pem
</VirtualHost>
</Macro>
<Macro VHostAliasHTTP $vhost $username $alias>
<VirtualHost *:80>
ServerName $vhost
ServerAlias www.$vhost
ServerAlias $vhost.mylampsite.com
DocumentRoot /srv/www/$alias/html
<FilesMatch ".+\.ph(ar|p|tml)$">
SetHandler "proxy:unix:/run/php/php7.4-fpm-$username.sock|fcgi://localhost"
</FilesMatch>
</VirtualHost>
</Macro>
<Macro VHostAliasHTTPS $vhost $username $alias>
<VirtualHost *:80>
ServerName $vhost
ServerAlias www.$vhost
ServerAlias $vhost.mylampsite.com
DocumentRoot /srv/www/$alias/html
## <Location "/">
## <If "%{REQUEST_URI} !~ m#^/.well-known/acme-challenge/#">
## Redirect 301 "https://%{HTTP_HOST}%{REQUEST_URI}"
## </If>
## </Location>
<FilesMatch ".+\.ph(ar|p|tml)$">
SetHandler "proxy:unix:/run/php/php7.4-fpm-$username.sock|fcgi://localhost"
</FilesMatch>
</VirtualHost>
<VirtualHost *:443>
ServerName $vhost
ServerAlias www.$vhost
ServerAlias $vhost.mylampsite.com
DocumentRoot /srv/www/$alias/html
<FilesMatch ".+\.ph(ar|p|tml)$">
SetHandler "proxy:unix:/run/php/php7.4-fpm-$username.sock|fcgi://localhost"
</FilesMatch>
SSLEngine on
SSLCertificateFile /etc/ssl/letsencrypt/$vhost.pem
</VirtualHost>
</Macro>

View File

@ -0,0 +1,4 @@
<IfModule mod_remoteip.c>
RemoteIPHeader X-Forwarded-For
RemoteIPInternalProxy 127.0.0.1
</IfModule>

View File

@ -0,0 +1,85 @@
<IfModule mod_ssl.c>
# 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
</IfModule>
# vim: syntax=apache ts=4 sw=4 sts=4 sr noet

15
etc/varnish/catch-all.vcl Normal file
View File

@ -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);
}

126
etc/varnish/default.vcl Normal file
View File

@ -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";

View File

@ -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
}
}

1
etc/varnish/sites.vcl Normal file
View File

@ -0,0 +1 @@
include "sites.d/example.com.vcl";

View File

@ -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)
}

36
etc/vhost.conf Normal file
View File

@ -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
}

View File

@ -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