nginx/install_nginx.sh

601 lines
13 KiB
Bash
Executable File

#!/usr/bin/env bash
script_name="$(basename $(realpath $0))"
working_dir="$(dirname $(realpath $0))"
log_file="${LOCK_DIR}/${script_name%%.*}.log"
# ----------
# Base Function(s)
# ----------
clean_up() {
# Perform program exit housekeeping
rm -rf "$LOCK_DIR"
blank_line
exit $1
}
echononl(){
if $terminal ; then
echo X\\c > /tmp/shprompt$$
if [ `wc -c /tmp/shprompt$$ | awk '{print $1}'` -eq 1 ]; then
echo -e -n " $*\\c" 1>&2
else
echo -e -n " $*" 1>&2
fi
rm /tmp/shprompt$$
fi
}
fatal(){
echo ""
if $terminal ; then
echo -e " [ \033[31m\033[1mFatal\033[m ] $*"
else
echo -e " [ Fatal ] $*"
fi
echo ""
if $terminal ; then
echo -e " \033[1mScript terminated\033[m.."
else
echo -e " Script terminated.."
fi
echo ""
rm -rf $LOCK_DIR
exit 1
}
error (){
echo ""
if $terminal ; then
echo -e " [ \033[31m\033[1mError\033[m ] $*"
else
echo " [ Error ] $*"
fi
echo ""
}
warn (){
if $LOGGING || $terminal ; then
echo ""
if $terminal ; then
echo -e " [ \033[33m\033[1mWarn\033[m ] $*"
else
echo " [ Warn ] $*"
fi
echo ""
fi
}
info (){
if $LOGGING || $terminal ; then
echo ""
if $terminal ; then
echo -e " [ \033[32m\033[1mInfo\033[m ] $*"
else
echo " [ Info ] $*"
fi
echo ""
fi
}
ok (){
if $LOGGING || $terminal ; then
echo ""
if $terminal ; then
echo -e " [ \033[32m\033[1mOk\033[m ] $*"
else
echo " [ Ok ] $*"
fi
echo ""
fi
}
echo_done() {
if $terminal ; then
echo -e "\033[75G[ \033[32mdone\033[m ]"
fi
}
echo_ok() {
if $terminal ; then
echo -e "\033[75G[ \033[32mok\033[m ]"
fi
}
echo_failed(){
if $terminal ; then
echo -e "\033[75G[ \033[1;31mfailed\033[m ]"
fi
}
echo_skipped() {
if $terminal ; then
echo -e "\033[75G[ \033[33m\033[1mskipped\033[m ]"
fi
}
echo_wait(){
if $terminal ; then
echo -en "\033[75G[ \033[5m\033[1m...\033[m ]"
fi
}
trim() {
local var="$*"
var="${var#"${var%%[![:space:]]*}"}" # remove leading whitespace characters
var="${var%"${var##*[![:space:]]}"}" # remove trailing whitespace characters
echo -n "$var"
}
blank_line() {
if $terminal ; then
echo ""
fi
}
# ----------
# - Jobhandling
# ----------
# - Run 'clean_up' for signals SIGHUP SIGINT SIGTERM
# -
trap clean_up SIGHUP SIGINT SIGTERM
# - Create lock directory '$LOCK_DIR"
#
mkdir "$LOCK_DIR"
# ----------
# - Some checks ..
# ----------
# - Running in a terminal?
# -
if [[ -t 1 ]] ; then
terminal=true
else
terminal=false
fi
# -Is systemd supported on this system?
# -
systemd_supported=false
systemd=$(which systemd)
systemctl=$(which systemctl)
if [[ -n "$systemd" ]] && [[ -n "$systemctl" ]] ; then
systemd_supported=true
fi
# - Is PHP-FPM socket in use
# -
declare -a _php_socket_arr=()
while IFS='' read -r -d '' _socket ; do
echo "socket: $_socket"
_php_major_version="$(echo "$_socket" | cut -d '-' -f2)"
_php_socket_arr+=("${_php_major_version}:$_socket")
done < <(find "/tmp" -type s -name "php*" -print0 | sort -z)
# ==========
# - Begin Main Script
# ==========
# ----------
# - Headline
# ----------
if $terminal ; then
echo ""
echo -e "\033[1m----------\033[m"
echo -e "\033[32m\033[1mRunning script \033[m\033[1m$script_name\033[32m .. \033[m"
echo -e "\033[1m----------\033[m"
fi
_debian_packages="
ssl-cert
ca-certificates
openssl
nginx-extras
"
declare -a deb_package_arr
for _pkg in $_debian_packages ; do
deb_package_arr+=("$_pkg")
done
blank_line
for _debian_pkg in ${deb_package_arr[@]} ; do
echononl "Installing $_debian_pkg .."
if ! dpkg -l $_debian_pkg 2> /dev/null | grep -e "^ii" > /dev/null 2>&1 ; then
DEBIAN_FRONTEND=noninteractive apt-get install -q -y $_debian_pkg > ${log_file} 2>&1
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
else
echo_skipped
fi
done
blank_line
_failed=false
echononl "Generate a dhparam.pem file.."
if [[ -f "/etc/nginx/ssl/dhparam.pem" ]]; then
echo_skipped
else
if [[ ! -d "/etc/nginx/ssl" ]] ; then
mkdir /etc/nginx/ssl > ${log_file} 2>&1
if [[ $? -ne 0 ]] ; then
_failed=true
fi
fi
openssl dhparam -dsaparam -out /etc/nginx/ssl/dhparam.pem 2048 >> ${log_file} 2>&1
if [[ $? -ne 0 ]] ; then
_failed=true
fi
if $_failed ; then
echo_failed
error "$(cat $log_file)"
else
echo_ok
fi
fi
blank_line
echononl "Backup file '/etc/nginx/sites-available/default'"
cp -a /etc/nginx/sites-available/default /etc/nginx/sites-available/default.ORIG > ${log_file} 2>&1
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
_failed=false
echononl "Create new file '/etc/nginx/sites-available/default'"
cat << EOF > /etc/nginx/sites-available/default 2> ${log_file}
##
# You should look at the following URL's in order to grasp a solid understanding
# of Nginx configuration files in order to fully unleash the power of Nginx.
# https://www.nginx.com/resources/wiki/start/
# https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/
# https://wiki.debian.org/Nginx/DirectoryStructure
#
# In most cases, administrators will remove this file from sites-enabled/ and
# leave it as reference inside of sites-available where it will continue to be
# updated by the nginx packaging team.
#
# This file will automatically load configuration files provided by other
# applications, such as Drupal or Wordpress. These applications will be made
# available underneath a path with that package name, such as /drupal8.
#
# Please see /usr/share/doc/nginx-doc/examples/ for more detailed examples.
##
# Default server configuration
#
EOF
if [[ $? -ne 0 ]] ; then
_failed=true
fi
if [[ ${#_php_socket_arr[@]} -gt 0 ]] ; then
cat << EOF >> /etc/nginx/sites-available/default 2> ${log_file}
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _ ;
# Include location directive for Let's Encrypt ACME Challenge
#
# Needed for (automated) updating certificate
#
include snippets/letsencrypt-acme-challenge.conf;
EOF
if [[ $? -ne 0 ]] ; then
_failed=true
fi
for _val in ${_php_socket_arr[@]} ; do
IFS=':' read -a _val_arr <<< "${_val}"
cat << EOF >> /etc/nginx/sites-available/default 2> ${log_file}
location ~ ^/(status-${_val_arr[0]}|ping-${_val_arr[0]})$ {
access_log off;
allow 127.0.0.1;
deny all;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME \$document_root\$fastcgi_script_name;
fastcgi_pass unix:/tmp/php-${_val_arr[0]}-fpm.www.sock;
}
EOF
if [[ $? -ne 0 ]] ; then
_failed=true
fi
done
cat << EOF >> /etc/nginx/sites-available/default 2> ${log_file}
}
server {
# Listen on primary IP address
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
server_name _ ;
#if (\$scheme = http) {
# return 301 https://\$host\$request_uri;
#}
EOF
else
cat << EOF >> /etc/nginx/sites-available/default 2> ${log_file}
server {
# Listen on primary IP address
listen 80 default_server;
listen [::]:80 default_server;
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
server_name _ ;
if (\$scheme = http) {
return 301 https://\$host\$request_uri;
}
EOF
if [[ $? -ne 0 ]] ; then
_failed=true
fi
fi
cat << EOF >> /etc/nginx/sites-available/default 2> ${log_file}
# Include location directive for Let's Encrypt ACME Challenge
#
# Needed for (automated) updating certificate
#
include snippets/letsencrypt-acme-challenge.conf;
# Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits
#
# To generate a dhparam.pem file, run in a terminal
# openssl dhparam -dsaparam -out /etc/nginx/ssl/dhparam.pem 2048
#
ssl_dhparam /etc/nginx/ssl/dhparam.pem;
# Eable session resumption to improve https performance
ssl_session_cache shared:SSL:50m;
ssl_session_timeout 10m;
ssl_session_tickets off;
#ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # omit SSLv3 because of POODLE
# omit SSLv3 because of POODLE
# omit TLSv1 TLSv1.1
ssl_protocols TLSv1.2 TLSv1.3;
# ECDHE better than DHE (faster) ECDHE & DHE GCM better than CBC (attacks on AES)
# Everything better than SHA1 (deprecated)
#
#ssl_ciphers HIGH:MEDIUM:!MD5:!RC4:!3DES;
ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-CCM8:ECDHE-ECDSA-AES256-CCM:ECDHE-ECDSA-ARIA256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-CCM8:ECDHE-ECDSA-AES128-CCM:ECDHE-ECDSA-ARIA128-GCM-SHA256;
ssl_prefer_server_ciphers on;
EOF
if [[ $? -ne 0 ]] ; then
_failed=true
fi
if [[ -f "/var/lib/dehydrated/certs/$(hostname -f)/fullchain.pem" ]] \
&& [[ -f "/var/lib/dehydrated/certs/$(hostname -f)/privkey.pem" ]]; then
cat << EOF >> /etc/nginx/sites-available/default 2>> ${log_file}
ssl_certificate /var/lib/dehydrated/certs/$(hostname -f)/fullchain.pem;
ssl_certificate_key /var/lib/dehydrated/certs/$(hostname -f)/privkey.pem;
EOF
if [[ $? -ne 0 ]] ; then
_failed=true
fi
else
cat << EOF >> /etc/nginx/sites-available/default 2>> ${log_file}
ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;
EOF
if [[ $? -ne 0 ]] ; then
_failed=true
fi
fi
cat << EOF >> /etc/nginx/sites-available/default 2>> ${log_file}
# HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months)
#
add_header Strict-Transport-Security "max-age=31536000" always;
add_header X-XSS-Protection "1; mode=block";
add_header X-Content-Type-Options nosniff;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header Content-Security-Policy "default-src 'self';" always;
add_header Referrer-Policy "strict-origin-when-cross-origin";
add_header Permissions-Policy "usb=()";
root /var/www/html;
# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html;
#location = /favicon.ico {
# return 204;
# log_not_found off;
# access_log off;
#}
location = /robots.txt {
log_not_found off;
access_log off;
}
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files \$uri \$uri/ =404;
}
}
EOF
if [[ $? -ne 0 ]] ; then
_failed=true
fi
if $_failed ; then
echo_failed
error "$(cat $log_file)"
echononl "continue anyway [yes/no]: "
read OK
OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')"
while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do
echononl "Wrong entry! - repeat [yes/no]: "
read OK
done
[[ $OK = "yes" ]] || fatal "Abbruch durch User"
else
echo_ok
fi
echononl "Create default index.html .."
cat <<EOF > /var/www/html/index.html 2> ${log_file}
<!doctype html>
<html>
<head>
<title>HTTP Error 404 / Http Fehler 404</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<style type="text/css">
body {
background: #eee;
font: normal normal 16px/140% Arial, Helvetica, Trebuchet MS, Geneva, sans-serif;
word-wrap: break-word;
}
h1 {
font-size: 30px;
font-weight: bold;
line-height: 100%;
}
h2 {
font-size: 18px;
font-weight: bold;
line-height: 100%;
}
.Container {
background: #fff;
width: 825px;
}
.Content {
background: #fff;
font-size: 12px;
height: 400px;
line-height: 16px;
padding: 10px 20px;
}
</style>
<link rel="shortcut icon" href="/favicon.ico" />
</head>
<body>
<div class="Container">
<div class="Logo"></div>
<div class="Content">
<h1>HTTP Error 404</h1>
<h2>The site you have requestet was not found on this Server</h2>
<p>Please check your spelling and ry again.</p>
<p>Thank You very much!</p>
<h1>HTTP Fehler 404</h1>
<h2>Die von Ihnen aufgerufene Seite gibt es leider nicht - Sorry</h2>
<p>Bitte pr&uuml;fen Sie die Adresse und versuchen es nochmals.</p>
<p>Vielen Dank f&uuml;r Ihr Verst&auml;ndnis!</p>
</div><!-- .Content -->
</div><!-- .Container -->
</body>
</html>
EOF
if [[ $? -eq 0 ]] ; then
echo_ok
else
echo_failed
error "$(cat $log_file)"
fi
# - Stop Nginx Service
# -
echononl "Stop Nginx WebsService"
if $systemd_supported ; then
$systemctl stop nginx > "$log_file" 2>&1
if [[ $? -ne 0 ]]; then
echo_failed
error "$(cat $log_file)"
else
echo_ok
fi
else
/etc/init.d/nginx stop > "$log_file" 2>&1
if [[ $? -ne 0 ]]; then
echo_failed
error "$(cat $log_file)"
else
echo_ok
fi
fi
if [[ ! -f "/etc/nginx/snippets/letsencrypt-acme-challenge.conf" ]]; then
warn "Befor startin nginx service again, take care 'dehydrated' is installed."
else
# - Start Nginx Service
# -
echononl "Start Nginx WebsService"
if $systemd_supported ; then
$systemctl start nginx > "$log_file" 2>&1
if [[ $? -ne 0 ]]; then
echo_failed
error "$(cat $log_file)"
else
echo_ok
fi
else
/etc/init.d/nginx start > "$log_file" 2>&1
if [[ $? -ne 0 ]]; then
echo_failed
error "$(cat $log_file)"
else
echo_ok
fi
fi
fi
clean_up 0