844 lines
32 KiB
Bash
Executable File
844 lines
32 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
#######
|
|
### Update NGINX configuration '<tags>' with proper values and optionally copy
|
|
### to updated directory structure
|
|
#######
|
|
|
|
|
|
### text formatting ansi codes
|
|
err="\e[1;31m"
|
|
ok="\e[1;32m"
|
|
warn="\e[93m"
|
|
mag="\e[95m"
|
|
cyan="\e[96m"
|
|
norm="\e[0m"
|
|
|
|
|
|
### set variables
|
|
|
|
# clear all variables
|
|
unset detectedIP
|
|
unset inputIP
|
|
unset IP4
|
|
unset inputServerName
|
|
serverNames_working=()
|
|
serverNames=()
|
|
unset useSSL
|
|
unset useCertbot
|
|
unset inputCertbotDomain
|
|
certbotBadFile=()
|
|
unset CertbotDomain
|
|
certbotFiles=()
|
|
unset inputCertPath
|
|
unset inputKeyPath
|
|
unset inputCAChainPath
|
|
unset CertPath
|
|
unset KeyPath
|
|
unset CAChainPath
|
|
unset noOSCP
|
|
unset inputDHPath
|
|
unset generateDH
|
|
unset DHPath
|
|
unset usePHP
|
|
unset inputPHPType
|
|
unset phpType
|
|
unset inputPHPAddr
|
|
unset inputPHPPort
|
|
unset phpAddr
|
|
unset phpPort
|
|
unset phpSock
|
|
unset dhsuccess
|
|
unset disableDHParam
|
|
unset copysuccess
|
|
|
|
# set variables
|
|
regexIP4="(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])"
|
|
regexIP6="(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))"
|
|
regexHostname="(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])"
|
|
detectedIP=$(ip route get 1 | sed -n 's/^.*src \([0-9.]*\) .*$/\1/p')
|
|
certbotFiles=(cert.pem chain.pem fullchain.pem privkey.pem)
|
|
hostname=$(hostname)
|
|
configPath="./etc.${hostname}"
|
|
useSSL=0
|
|
useCertbot=0
|
|
generateDH=0
|
|
noOSCP=0
|
|
disableDHParam=0
|
|
|
|
# set tags and files to update
|
|
tag_servernames="<server name(s)>"
|
|
file_servernames="nginx/snippets/server_names.conf"
|
|
tag_sslcert="<path/to/your_ssl_certificate_fullchain>"
|
|
tag_sslkey="<path/to/your_certificate_private_key.key>"
|
|
file_ssl="nginx/snippets/ssl/ssl_certs.conf"
|
|
tag_dhparam="<path/to/your_dhparam.pem>"
|
|
tag_cachain="<path/to/your_CA_bundle.crt>"
|
|
file_mozmodern="nginx/conf.d/mozModern_ssl.conf"
|
|
tag_lanip="<lanIP>"
|
|
file_lanip="nginx/nginx.conf"
|
|
file_buffers="nginx/conf.d/buffers.conf"
|
|
file_buffersPHP="nginx/conf.d/buffers_conf_php.insert"
|
|
tag_phphandler="#<insert PHP handler.*>$"
|
|
file_phphandler="nginx/nginx.conf"
|
|
file_phpTCP="nginx/nginx_conf_phphandler_TCP.insert"
|
|
file_phpSock="nginx/nginx_conf_phphandler_SOCK.insert"
|
|
tag_phpAddr="<phpAddr>"
|
|
tag_phpPort="<phpPort>"
|
|
tag_phpSock="<phpSock>"
|
|
|
|
|
|
|
|
### check running as root, otherwise exit
|
|
if [ $(id -u) -ne 0 ]; then
|
|
echo -e "\n${err}This script MUST be run as ROOT. Exiting.${norm}"
|
|
exit 2
|
|
fi
|
|
|
|
|
|
### quick intro for the user
|
|
echo -e "\n${mag}This script will customize the provided NGINX template files for your"
|
|
echo "environment. You will be prompted for all necessary information. After that,"
|
|
echo "default error pages will be copied to your webroot and your NGINX configuration"
|
|
echo -e "directory structure will be customized.${norm}\n"
|
|
echo -e "${warn}You may accept the default option (listed in brackets) by simply"
|
|
echo "pressing ENTER (i.e. no answer)."
|
|
echo -e "You may exit this script at any prompt by typing 'X'${norm}\n"
|
|
|
|
|
|
### get local IP address
|
|
echo -e "\n${mag}In cases where this server will be acting as a (reverse) proxy, NGINX"
|
|
echo "needs to know it's own local IP address so that the logs can properly reflect"
|
|
echo -e "the IP of the remote system(s) instead of this server.${norm}\n"
|
|
while true; do
|
|
read -p "What is this machine's local IP4 address? (${detectedIP}) " inputIP
|
|
case "${inputIP}" in
|
|
'')
|
|
IP4="${detectedIP}"
|
|
break
|
|
;;
|
|
[Xx]*)
|
|
echo -e "\n${cyan}---exiting---\n${norm}"
|
|
exit 1
|
|
;;
|
|
*)
|
|
# check IP for validity
|
|
if [[ "${inputIP}" =~ ^${regexIP4}$ ]]; then
|
|
IP4="${inputIP}"
|
|
break
|
|
else
|
|
echo -e "\n${err}Invalid IP4 format (xxx.xxx.xxx.xxx)${norm}"
|
|
fi
|
|
;;
|
|
esac
|
|
done
|
|
|
|
|
|
### get server names for this installation
|
|
echo -e "\n${mag}To which hostnames should NGINX answer? You can pick as many hostnames as you"
|
|
echo "like. Please ensure you provide fully-qualified domain names unless you"
|
|
echo "understand the impact of not doing so."
|
|
echo -e "\nIf you are setting up SSL on this system make sure the hostnames match what"
|
|
echo "appears on your certificates!"
|
|
echo -e "\n${warn}You will be prompted to enter one hostname at a time."
|
|
echo "Provide a blank-entry (hit enter) when you're done."
|
|
echo -e "'X' will exit the script, as always${norm}\n"
|
|
while true; do
|
|
read -p "Hostname for this server? " inputServerName
|
|
case "${inputServerName}" in
|
|
'')
|
|
# check that at least one name as been provided
|
|
if [ -z "${serverNames_working}" ]; then
|
|
echo -e "\n${err}You must provide at least one hostname${norm}"
|
|
else
|
|
break
|
|
fi
|
|
;;
|
|
[Xx]*)
|
|
echo -e "\n${cyan}---exiting---\n${norm}"
|
|
exit 1
|
|
;;
|
|
*)
|
|
# check hostname for validity
|
|
if [[ ! "${inputServerName}" =~ ^${regexHostname}$ ]]; then
|
|
echo -e "\n${err}Invalid hostname${norm}"
|
|
else
|
|
serverNames_working+=("${inputServerName}")
|
|
fi
|
|
;;
|
|
esac
|
|
done
|
|
# create new array with unqiue values only
|
|
declare -A uniqueSN
|
|
for name in "${serverNames_working[@]}"; do
|
|
uniqueSN["${name}"]=""
|
|
done
|
|
for sn in "${!uniqueSN[@]}"; do
|
|
serverNames+=("${sn}")
|
|
done
|
|
|
|
|
|
### SSL related options
|
|
# enable SSL?
|
|
while true; do
|
|
read -p "Do you want to enable SSL on this server? (default: Yes) " yn
|
|
case "${yn}" in
|
|
[Yy]*|'')
|
|
useSSL=1
|
|
break
|
|
;;
|
|
[Nn]*)
|
|
useSSL=0
|
|
break
|
|
;;
|
|
[Xx]*)
|
|
echo -e "\n${cyan}---exiting---\n${norm}"
|
|
exit 1
|
|
;;
|
|
*)
|
|
echo -e "\n${err}Please answer (Y)es, (N)o, e(X)it or accept default${norm}"
|
|
;;
|
|
esac
|
|
done
|
|
|
|
# using certbot?
|
|
if [ "${useSSL}" -eq 1 ]; then
|
|
echo -e "\n${mag}If you are using Certbot, you only need to provide the primary domain name"
|
|
echo "of your certificate and the script will auto-generate the paths NGINX needs to"
|
|
echo "make everything work."
|
|
echo -e "\nIf you haven't run Certbot yet, you can enter the domain you intend to use"
|
|
echo "as your primary domain and the paths generated by this script will work after"
|
|
echo -e "you run Certbot. In that case, you will have to answer ${warn}'yes'${mag} when asked"
|
|
echo -e "${warn}'Do you want to use this domain setting anyways?'"
|
|
echo -e "\nNote: NGINX will NOT work until you run Certbot to generate your certificates!${norm}\n"
|
|
while true; do
|
|
read -p "Are you using Certbot to handle your SSL certificates? (default: No) " yn
|
|
case "${yn}" in
|
|
[Yy]*)
|
|
useCertbot=1
|
|
break
|
|
;;
|
|
[Nn]*|'')
|
|
useCertbot=0
|
|
unset CertbotDomain
|
|
break
|
|
;;
|
|
[Xx]*)
|
|
echo -e "\n${cyan}---exiting---\n${norm}"
|
|
exit 1
|
|
;;
|
|
*)
|
|
echo -e "\n${err}Please answer (Y)es, (N)o, e(X)it or accept default${norm}"
|
|
;;
|
|
esac
|
|
done
|
|
fi
|
|
|
|
# using Certbot: get primary domain name since that how Certbot determines paths
|
|
if [ "${useCertbot}" -eq 1 ]; then
|
|
while true; do
|
|
read -p "What is the primary domain for your Certbot Certificates? " inputCertbotDomain
|
|
case "${inputCertbotDomain}" in
|
|
'')
|
|
echo -e "\n${err}You cannot have an empty domain name${norm}"
|
|
;;
|
|
[Xx]*)
|
|
echo -e "\n${cyan}---exiting---\n${norm}"
|
|
exit 1
|
|
;;
|
|
*)
|
|
# check hostname for validity
|
|
if [[ ! "${inputCertbotDomain}" =~ ^${regexHostname}$ ]]; then
|
|
echo -e "\n${err}Invalid hostname${norm}"
|
|
else
|
|
# check if Certbot files exist in path implied from hostname
|
|
echo -e "\n${cyan}Verifying Certbot files..."
|
|
echo -e "(/etc/letsencrypt/live/${inputCertbotDomain}/...)${norm}"
|
|
certbotBadFile=()
|
|
for certbotFile in "${certbotFiles[@]}"; do
|
|
if [ -f "/etc/letsencrypt/live/${inputCertbotDomain}/$certbotFile" ]; then
|
|
echo -e "File: ${certbotFile} -- ${ok}OK${norm}"
|
|
else
|
|
echo -e "File: ${certbotFile} -- ${err}X${norm}"
|
|
certbotBadFile+=("${certbotFile}")
|
|
fi
|
|
done
|
|
if [ -z "${certbotBadFile}" ]; then
|
|
echo -e "${cyan}Certbot files seem intact${norm}\n"
|
|
CertbotDomain="${inputCertbotDomain}"
|
|
break
|
|
else
|
|
echo -e "\n${err}The following files are missing from ${inputCertbotDomain}:"
|
|
echo -e "${warn}${certbotBadFile[*]}${norm}"
|
|
echo -e "${err}These files should all be present in a functional Certbot install.${norm}\n"
|
|
while true; do
|
|
read -p "Do you want to use this domain setting anyways? " yn
|
|
case "${yn}" in
|
|
[Yy]*)
|
|
CertbotDomain="${inputCertbotDomain}"
|
|
break
|
|
;;
|
|
[Nn]*)
|
|
break
|
|
;;
|
|
*)
|
|
;;
|
|
esac
|
|
done
|
|
fi
|
|
if [ -n "${CertbotDomain}" ]; then
|
|
break
|
|
fi
|
|
fi
|
|
;;
|
|
esac
|
|
done
|
|
fi
|
|
|
|
# Generate paths from CertbotDomain
|
|
if [ -n "${CertbotDomain}" ]; then
|
|
CertPath="/etc/letsencrypt/live/${CertbotDomain}/fullchain.pem"
|
|
KeyPath="/etc/letsencrypt/live/${CertbotDomain}/privkey.pem"
|
|
CAChainPath="/etc/letsencrypt/live/${CertbotDomain}/chain.pem"
|
|
fi
|
|
|
|
# only process manual certificate paths if using SSL and NOT using Certbot
|
|
if [ "${useSSL}" -eq 1 ] && [ "${useCertbot}" -eq 0 ]; then
|
|
echo -e "\n${mag}NGINX requires the full paths to your PEM formatted certificate and"
|
|
echo "private key in order to serve pages securely and properly over SSL."
|
|
echo "If you haven't generated/copied your certificates yet, you can enter the"
|
|
echo "paths where they will be located and confirm when prompted by the script."
|
|
echo -e "${warn}NGINX will NOT work until these files are actually copied!${norm}\n"
|
|
# not using Certbot: get location of certificate
|
|
while true; do
|
|
read -p "What is the path to your primary SSL certificate? " inputCertPath
|
|
case "${inputCertPath}" in
|
|
'')
|
|
echo -e "\n${err}You cannot have an empty path to your SSL certificate${norm}"
|
|
;;
|
|
[Xx]*)
|
|
echo -e "\n${cyan}---exiting---\n${norm}"
|
|
exit 1
|
|
;;
|
|
/*)
|
|
# validate path
|
|
if [ -f "${inputCertPath}" ]; then
|
|
CertPath="${inputCertPath}"
|
|
break
|
|
else
|
|
echo -e "\n${warn}The file you specified doesn't exist${norm}"
|
|
while true; do
|
|
read -p "Do you want to use this path anyways? " yn
|
|
case $yn in
|
|
[Yy]*)
|
|
CertPath="${inputCertPath}"
|
|
break
|
|
;;
|
|
[Nn]*)
|
|
break
|
|
;;
|
|
*)
|
|
;;
|
|
esac
|
|
done
|
|
if [ -n "${CertPath}" ]; then
|
|
break
|
|
fi
|
|
fi
|
|
;;
|
|
*)
|
|
# path must be absolute and start with a slash
|
|
echo -e "\n${err}Path must be absolute not relative. Please re-enter starting with '/'${norm}"
|
|
;;
|
|
esac
|
|
done
|
|
|
|
# not using Certbot: get location of private key
|
|
while true; do
|
|
read -p "What is the path to your primary SSL private key? " inputKeyPath
|
|
case "${inputKeyPath}" in
|
|
'')
|
|
echo -e "\n${err}You cannot have an empty path to your SSL private key${norm}"
|
|
;;
|
|
[Xx]*)
|
|
echo -e "\n${cyan}---exiting---\n${norm}"
|
|
exit 1
|
|
;;
|
|
/*)
|
|
# validate path
|
|
if [ -f "${inputKeyPath}" ]; then
|
|
KeyPath="${inputKeyPath}"
|
|
break
|
|
else
|
|
echo -e "\n${warn}The file you specified doesn't exist${norm}"
|
|
while true; do
|
|
read -p "Do you want to use this path anyways? " yn
|
|
case $yn in
|
|
[Yy]*)
|
|
KeyPath="${inputKeyPath}"
|
|
break
|
|
;;
|
|
[Nn]*)
|
|
break
|
|
;;
|
|
*)
|
|
;;
|
|
esac
|
|
done
|
|
if [ -n "${KeyPath}" ]; then
|
|
break
|
|
fi
|
|
fi
|
|
;;
|
|
*)
|
|
# path must be absolute and start with a slash
|
|
echo -e "\n${err}Path must be absolute not relative. Please re-enter starting with '/'${norm}"
|
|
;;
|
|
esac
|
|
done
|
|
|
|
# not using Certbot: get location of CA Certificate Chain
|
|
echo -e "\n${mag}Your full Certificate Authority certificate-chain (root and any/all"
|
|
echo "intermediate certificates bundled in one file) is required if you want NGINX"
|
|
echo "to provide OSCP stapling for your visitors. In most cases, you want this."
|
|
echo "If you don't have your CA chain, you can fill in the filename you'll be saving"
|
|
echo "it as in the future and confirm it when the script prompts you. In that"
|
|
echo -e "case, however, ${warn}NGINX will not work until that file actually exists.${mag}"
|
|
echo -e "\nIf you are using a self-signed certificate or do not want OSCP stapling, leave"
|
|
echo -e "this blank ${warn}(hit enter)${mag} and the relevant configuration section will be disabled.${norm}\n"
|
|
while true; do
|
|
read -p "What is the path to your primary SSL CA Chain certificate? " inputCAChainPath
|
|
case "${inputCAChainPath}" in
|
|
'')
|
|
noOSCP=1
|
|
break
|
|
;;
|
|
[Xx]*)
|
|
echo -e "\n${cyan}---exiting---\n${norm}"
|
|
exit 1
|
|
;;
|
|
/*)
|
|
# validate path
|
|
if [ -f "${inputCAChainPath}" ]; then
|
|
CAChainPath="${inputCAChainPath}"
|
|
break
|
|
else
|
|
echo -e "\n${warn}The file you specified doesn't exist${norm}"
|
|
while true; do
|
|
read -p "Do you want to use this path anyways? " yn
|
|
case $yn in
|
|
[Yy]*)
|
|
CAChainPath="${inputCAChainPath}"
|
|
break
|
|
;;
|
|
[Nn]*)
|
|
break
|
|
;;
|
|
*)
|
|
;;
|
|
esac
|
|
done
|
|
if [ -n "${CAChainPath}" ]; then
|
|
break
|
|
fi
|
|
fi
|
|
;;
|
|
*)
|
|
# path must be absolute and start with a slash
|
|
echo -e "\n${err}Path must be absolute not relative. Please re-enter starting with '/'${norm}"
|
|
;;
|
|
esac
|
|
done
|
|
fi
|
|
|
|
# dhparam: get location of DH Parameters file
|
|
if [ "${useSSL}" -eq 1 ]; then
|
|
echo -e "\n${mag}Having your own unique Diffie-Hellman Parameters file makes your SSL"
|
|
echo "communication more secure by pre-generating safe large prime and generator"
|
|
echo "numbers. You shouldn't use any pre-installed dhparam.pem files. You should"
|
|
echo "always generate your own."
|
|
echo -e "\nIf you haven't done that already and would like this script to do it for"
|
|
echo -e "you, please type ${warn}generate${mag} at the prompt instead of a path."
|
|
echo "Please note that although this process uses DSA-primes to speed things up"
|
|
echo "without sacrificing security, the process may still take up to 20+ minutes"
|
|
echo -e "depending on your hardware.${norm}\n"
|
|
while true; do
|
|
read -p "What is the path to your DH Parameters file? (default: /etc/ssl/certs/dhparam.pem) " inputDHPath
|
|
case "${inputDHPath}" in
|
|
'')
|
|
# verify default path exists
|
|
inputDHPath="/etc/ssl/certs/dhparam.pem"
|
|
if [ -f "${inputDHPath}" ]; then
|
|
DHPath="${inputDHPath}"
|
|
break
|
|
else
|
|
echo -e "\n${warn}The file you specified doesn't exist${norm}"
|
|
while true; do
|
|
read -p "Do you want to use this path anyways? " yn
|
|
case $yn in
|
|
[Yy]*)
|
|
DHPath="${inputDHPath}"
|
|
break
|
|
;;
|
|
[Nn]*)
|
|
break
|
|
;;
|
|
*)
|
|
;;
|
|
esac
|
|
done
|
|
if [ -n "${DHPath}" ]; then
|
|
break
|
|
fi
|
|
fi
|
|
;;
|
|
[Xx]*)
|
|
echo -e "\n${cyan}---exiting---\n${norm}"
|
|
exit 1
|
|
;;
|
|
[Gg][Ee][Nn][Ee][Rr][Aa][Tt][Ee]*)
|
|
generateDH=1
|
|
break
|
|
;;
|
|
/*)
|
|
# validate path
|
|
if [ -f "${inputDHPath}" ]; then
|
|
DHPath="${inputDHPath}"
|
|
break
|
|
else
|
|
echo -e "\n${warn}The file you specified doesn't exist${norm}"
|
|
while true; do
|
|
read -p "Do you want to use this path anyways? " yn
|
|
case $yn in
|
|
[Yy]*)
|
|
DHPath="${inputDHPath}"
|
|
break
|
|
;;
|
|
[Nn]*)
|
|
break
|
|
;;
|
|
*)
|
|
;;
|
|
esac
|
|
done
|
|
if [ -n "${DHPath}" ]; then
|
|
break
|
|
fi
|
|
fi
|
|
;;
|
|
*)
|
|
# path must be absolute and start with a slash
|
|
echo -e "\n${err}Path must be absolute not relative. Please re-enter starting with '/'${norm}"
|
|
;;
|
|
esac
|
|
done
|
|
fi
|
|
|
|
|
|
### PHP-FPM related options
|
|
# get PHP-FPM usage status
|
|
echo -e "\n${mag}PHP-FPM allows your server to process and serve dynamic PHP content. If you"
|
|
echo "have PHP-FPM installed, NGINX needs to know how to access it. The following"
|
|
echo "questions will allow the script to auto-configure that for you."
|
|
echo -e "\nIf you have not yet installed PHP-FPM but intend to do so in the future, you"
|
|
echo -e "can answer ${warn}yes${mag} and provide details for your intended setup so the script can"
|
|
echo -e "generate a configuration that will work once your PHP-FPM is set up."
|
|
echo -e "${warn}Note: NGINX WILL STILL WORK if configured to use PHP-FPM but without PHP-FPM"
|
|
echo "actually installed. However, it will throw 500/503 errors if you attempt"
|
|
echo -e "to serve PHP content.${norm}\n"
|
|
while true; do
|
|
read -p "Are you using PHP-FPM? (default: Yes) " yn
|
|
case $yn in
|
|
[Yy]*|'')
|
|
usePHP=1
|
|
break
|
|
;;
|
|
[Nn]*)
|
|
usePHP=0
|
|
break
|
|
;;
|
|
[Xx]*)
|
|
echo -e "\n${cyan}---exiting---\n${norm}"
|
|
exit 1
|
|
;;
|
|
*)
|
|
echo -e "\n${err}Please answer (Y)es, (N)o, e(X)it or accept default${norm}"
|
|
;;
|
|
esac
|
|
done
|
|
|
|
# get PHP-FPM TCP or Sockets configuration
|
|
if [ "${usePHP}" -eq 1 ]; then
|
|
echo -e "\n${mag}PHP-FPM can be set up to respond to requests via TCP or via UNIX sockets."
|
|
echo "If you have no idea what any of this means, then you're probably using the"
|
|
echo -e "default setup which is sockets${norm}\n"
|
|
while true; do
|
|
read -p "Is your PHP-FPM set up to listen via 'TCP' or 'sockets'? (default: sockets) " inputPHPType
|
|
case "${inputPHPType}" in
|
|
[Ss][Oo][Cc][Kk][Ee][Tt][Ss]*|'')
|
|
phpType='sockets'
|
|
break
|
|
;;
|
|
[Tt][Cc][Pp]*)
|
|
phpType='tcp'
|
|
break
|
|
;;
|
|
[Xx]*)
|
|
echo -e "\n${cyan}---exiting---\n${norm}"
|
|
exit 1
|
|
;;
|
|
*)
|
|
echo -e "\n${err}Please enter either 'tcp' or 'sockets' or 'X' to exit script${norm}"
|
|
;;
|
|
esac
|
|
done
|
|
fi
|
|
|
|
# PHP-TCP: get address and port information
|
|
if [ "${phpType}" = "tcp" ]; then
|
|
while true; do
|
|
read -p "What IP address is PHP-FPM listening on? (default: 127.0.0.1) " inputPHPAddr
|
|
case "${inputPHPAddr}" in
|
|
'')
|
|
phpAddr="127.0.0.1"
|
|
break
|
|
;;
|
|
[Xx]*)
|
|
echo -e "\n${cyan}---exiting---\n${norm}"
|
|
exit 1
|
|
;;
|
|
*)
|
|
# check basic format validity and wrap IP6 in [square brackets]
|
|
if [[ "${inputPHPAddr}" =~ ^${regexIP6}$ ]]; then
|
|
phpAddr="[${inputPHPAddr}]"
|
|
break
|
|
elif [[ "${inputPHPAddr}" =~ ^${regexIP4}$ ]]; then
|
|
phpAddr="${inputPHPAddr}"
|
|
break
|
|
else
|
|
echo -e "\n${err}Invalid IP4/IP6 address format${norm}"
|
|
fi
|
|
;;
|
|
esac
|
|
done
|
|
while true; do
|
|
read -p "What port is PHP-FPM listening on? (default: 9000) " inputPHPPort
|
|
case "${inputPHPPort}" in
|
|
'')
|
|
phpPort=9000
|
|
break
|
|
;;
|
|
[Xx]*)
|
|
echo -e "\n${cyan}---exiting---\n${norm}"
|
|
exit 1
|
|
;;
|
|
*)
|
|
## check port range validity
|
|
# check for letters
|
|
if [[ "${inputPHPPort}" =~ .*[a-zA-Z].* ]]; then
|
|
echo -e "\n${err}Port value must be numeric with no letters${norm}"
|
|
elif [ ! "${inputPHPPort}" -ge 0 ] || [ ! "${inputPHPPort}" -le 65535 ]; then
|
|
echo -e "\n${err}Port must be between 0-65535${norm}"
|
|
else
|
|
phpPort="${inputPHPPort}"
|
|
break
|
|
fi
|
|
;;
|
|
esac
|
|
done
|
|
fi
|
|
|
|
# get PHP-FPM socket file from www.conf
|
|
if [ "${phpType}" = "sockets" ]; then
|
|
phpSock=$(find /etc/php/ -name 'www.conf' -type f -exec grep 'listen.*sock$' {} + | sed 's/.*=\ //')
|
|
# check if phpSock is null
|
|
if [ -z "${phpSock}" ]; then
|
|
echo -e "\n${err}Could not auto-detect socket file name${norm}"
|
|
echo -e "PHP handler will be set up but you will have to edit ${warn}nginx.conf${norm}"
|
|
echo "manually to include the proper socket-file name where you see"
|
|
echo -e "${warn}<phpSocketFilename>${norm}"
|
|
phpSock='<phpSocketFilename>'
|
|
fi
|
|
fi
|
|
|
|
|
|
### notify user and generate DHParms if necessary
|
|
if [ "${generateDH}" -eq 1 ]; then
|
|
echo -e "\n${mag}---------------------${norm}"
|
|
echo -e "${cyan}Generating DH-Parameters file... this may take a while${norm}"
|
|
# generate 4096-bit DHParams and store in /etc/ssl/certs/dhparam.pem
|
|
openssl dhparam -dsaparam -out /etc/ssl/certs/dhparam.pem 4096
|
|
dhsuccess=$?
|
|
# verify no error reported and non-zero length file generated
|
|
if [ "${dhsuccess}" -eq 0 ] && [ -s "/etc/ssl/certs/dhparam.pem" ]; then
|
|
echo -e "${ok}-- dhparam.pem generated --${norm}"
|
|
# set DHParam to proper location
|
|
DHPath='/etc/ssl/certs/dhparam.pem'
|
|
else
|
|
echo -e "${err}-- error generating dhparam.pem --"
|
|
echo -e "you should manually generate this file${norm}"
|
|
echo -e "\n${warn}The relevant section of the NGINX configuration will be disabled${norm}\n"
|
|
# set DHPath to default BUT set flag to comment ssl_dhparam in mozModern_ssl.conf
|
|
DHPath='etc/ssl/certs/dhparam.pem'
|
|
disableDHParam=1
|
|
fi
|
|
fi
|
|
|
|
### Write configurations to template files
|
|
# let user know what's happening
|
|
echo -e "\n${mag}---------------------${norm}"
|
|
echo -e "${cyan}Updating template files now...${norm}"
|
|
|
|
# copy template files to working versions
|
|
echo "copying files to dedicated directory for customization:"
|
|
echo -e "${warn}${configPath}${norm}\n"
|
|
rm -rf "${configPath}"
|
|
cp -R ./etc "${configPath}"
|
|
copysuccess=$?
|
|
# check that copy was performed, else exit
|
|
if [ "${copysuccess}" -ne 0 ] || [ ! -d "${configPath}" ]; then
|
|
echo -e "\n${err}There was a problem creating the configuration directory.${norm}"
|
|
echo "Is there a reason ROOT cannot write to this script's directory?"
|
|
echo -e "${err}No changes made. Exiting.${norm}"
|
|
exit 100
|
|
fi
|
|
|
|
# process server_names snippet
|
|
echo -e "updating ${warn}${configPath}/${file_servernames}${norm}"
|
|
for name in "${serverNames[@]}"; do
|
|
sed -i "/${tag_servernames}/a \ \ ${name}" "${configPath}/${file_servernames}"
|
|
done
|
|
sed -i "/${tag_servernames}/d" "${configPath}/${file_servernames}"
|
|
|
|
# process SSL snippet if using SSL
|
|
if [ "${useSSL}" -eq 1 ]; then
|
|
echo -e "updating ${warn}${configPath}/${file_ssl}${norm}"
|
|
sed -i -e "s%${tag_sslcert}%${CertPath}%" "${configPath}/${file_ssl}"
|
|
sed -i -e "s%${tag_sslkey}%${KeyPath}%" "${configPath}/${file_ssl}"
|
|
fi
|
|
|
|
# process mozModern SSL configuration if using SSL
|
|
if [ "${useSSL}" -eq 1 ]; then
|
|
echo -e "updating ${warn}${configPath}/${file_mozmodern}${norm}"
|
|
sed -i -e "s%${tag_dhparam}%${DHPath}%" "${configPath}/${file_mozmodern}"
|
|
sed -i -e "s%${tag_cachain}%${CAChainPath}%" "${configPath}/${file_mozmodern}"
|
|
# comment OSCP lines if noOSCP=1
|
|
if [ "${noOSCP}" -eq 1 ]; then
|
|
sed -i 's/^ssl_stapling/#ssl_stapling/g' "${configPath}/${file_mozmodern}"
|
|
sed -i 's/^ssl_trusted/#ssl_trusted/' "${configPath}/${file_mozmodern}"
|
|
fi
|
|
# comment ssl_dhparam line if error generating dhparam.pem
|
|
if [ "${disableDHParam}" -eq 1 ]; then
|
|
sed -i 's/^ssl_dhparam/#ssl_dhparam/' "${configPath}/${file_mozmodern}"
|
|
fi
|
|
fi
|
|
|
|
# process LAN IP in nginx.conf
|
|
echo -e "updating ${warn}${configPath}/${file_lanip}${norm}"
|
|
sed -i "s/${tag_lanip}/${IP4}/" "${configPath}/${file_lanip}"
|
|
|
|
# if using PHP: process buffers.conf
|
|
if [ "${usePHP}" -eq 1 ]; then
|
|
echo -e "updating ${warn}${configPath}/${file_buffers}${norm}"
|
|
cat "${configPath}/${file_buffersPHP}" >> "${configPath}/${file_buffers}"
|
|
fi
|
|
|
|
## if using PHP-TCP: add upstream handler in nginx.conf
|
|
if [ "${phpType}" = "tcp" ]; then
|
|
echo -e "updating ${warn}${configPath}/${file_phphandler}${norm}"
|
|
# update .insert tags with address and port information
|
|
sed -i "s/${tag_phpAddr}/${phpAddr}/" "${configPath}/${file_phpTCP}"
|
|
sed -i "s/${tag_phpPort}/${phpPort}/" "${configPath}/${file_phpTCP}"
|
|
# copy .insert file into nginx.conf
|
|
sed -i -e "/${tag_phphandler}/{r ${configPath}/${file_phpTCP}" -e 'd}' "${configPath}/${file_phphandler}"
|
|
# add index.php to default index files
|
|
sed -i 's/^\s*index/\ index index.php/' "${configPath}/${file_phphandler}"
|
|
fi
|
|
|
|
# if using PHP-SOCK: add upstream handler in nginx.conf
|
|
if [ "${phpType}" = "sockets" ]; then
|
|
echo -e "updating ${warn}${configPath}/${file_phphandler}${norm}"
|
|
# update .insert file with socket filename or placeholder tag
|
|
sed -i "s%${tag_phpSock}%${phpSock}%" "${configPath}/${file_phpSock}"
|
|
# copy .insert file into nginx.conf
|
|
sed -i -e "/${tag_phphandler}/{r ${configPath}/${file_phpSock}" -e 'd}' "${configPath}/${file_phphandler}"
|
|
# add index.php to default index files
|
|
sed -i 's/^\s*index/\ index index.php/' "${configPath}/${file_phphandler}"
|
|
fi
|
|
|
|
# comment all SSL related entries if NOT using SSL
|
|
if [ "${useSSL}" -eq 0 ]; then
|
|
# comment ssl locations in ssl_certs.conf
|
|
echo -e "disabling SSL paths in ${warn}${configPath}/${file_ssl}${norm}"
|
|
sed -i 's/^ssl_certificate/#ssl_certificate/g' "${configPath}/${file_ssl}"
|
|
# comment ssl_dhparam in mozModern_ssl.conf
|
|
echo -e "disabling DHparams in ${warn}${configPath}/${file_mozmodern}${norm}"
|
|
sed -i 's/^ssl_dhparam/#ssl_dhparam/' "${configPath}/${file_mozmodern}"
|
|
# comment OCSP section in mozModern_ssl.conf
|
|
echo -e "disabling OCSP stapling in ${warn}${configPath}/${file_mozmodern}${norm}"
|
|
sed -i 's/^ssl_stapling/#ssl_stapling/g' "${configPath}/${file_mozmodern}"
|
|
sed -i 's/^ssl_trusted/#ssl_trusted/' "${configPath}/${file_mozmodern}"
|
|
fi
|
|
|
|
# notify user file updates are completed
|
|
echo -e "${ok}...files updated${norm}"
|
|
echo -e "${mag}---------------------${norm}\n"
|
|
|
|
### copy configDir to actual nginx directory after backup
|
|
## backup nginx directory
|
|
echo -e "${cyan}Backing up NGINX configuration directory${norm}"
|
|
echo "copying /etc/nginx --> /etc/nginx.original"
|
|
cp -f -R /etc/nginx /etc/nginx.original
|
|
copysuccess=$?
|
|
# verify new directory created
|
|
if [ "${copysuccess}" -eq 0 ]; then
|
|
echo -e "${ok}--- configuration backup successful ---"
|
|
else
|
|
echo -e "\n${err}Unable to backup existing NGINX configuration${norm}"
|
|
echo -e "Updated configuration has been copied to ${warn}${configPath}${norm}"
|
|
echo -e "but must be manually integrated into ${warn}'/etc/nginx/'${norm}."
|
|
echo "Is this a permissions error?"
|
|
echo -e "\n${err}Exiting now.${norm}"
|
|
exit 101
|
|
fi
|
|
echo -e "${cyan}Integrating updated configuration...${norm}"
|
|
echo "(any errors should appear below)"
|
|
## remove un-needed and/or existing directories and files
|
|
rm -rf /etc/nginx/conf.d
|
|
rm -rf /etc/nginx/enabledSites
|
|
mv -f /etc/nginx/fastcgi_params /etc/nginx/fastcgi_params.original
|
|
mv -f /etc/nginx/nginx.conf /etc/nginx/nginx.conf.original
|
|
cp -f -R "${configPath}"/nginx/* /etc/nginx/
|
|
mkdir /etc/nginx/enabledSites
|
|
mkdir /etc/nginx/conf.d/enabled
|
|
echo -e "${ok}...integration completed${norm}"
|
|
echo -e "${mag}---------------------${norm}\n"
|
|
echo -e "${ok}Setup script completed${norm}"
|
|
|
|
|
|
|
|
# debug section
|
|
if [ "${1}" = "debug" ]; then
|
|
echo -e "\n${mag}---------------------${norm}"
|
|
echo "Local IP4: $IP4"
|
|
echo "Server names: ${serverNames[*]}"
|
|
echo -e "${cyan}--------------------${norm}"
|
|
echo "Using Certbot: $useCertbot"
|
|
echo "CertbotDomain: $CertbotDomain"
|
|
echo -e "${cyan}--------------------${norm}"
|
|
echo "CertPath: $CertPath"
|
|
echo "KeyPath: $KeyPath"
|
|
echo "noOSCP: $noOSCP"
|
|
echo "CA-Chain: $CAChainPath"
|
|
echo "DHPath: $DHPath"
|
|
echo "Generating DH Params: $generateDH"
|
|
echo -e "${cyan}--------------------${norm}"
|
|
echo "usePHP: $usePHP"
|
|
echo "PHP listen type: $phpType"
|
|
echo "PHP address: $phpAddr"
|
|
echo "PHP port: $phpPort"
|
|
echo "PHP socket: $phpSock"
|
|
echo -e "${mag}---------------------${norm}\n"
|
|
fi
|
|
|
|
exit 0 |