Newer
Older
# _____ _ _
# | __|___ ___ ___ _| |___ _____| |_ ___ ___ ___
# | __| _| -_| -_| . | . | | . | . | | -_|
# |__| |_| |___|___|___|___|_|_|_|___|___|_|_|___|
#
# Web related functions
#
# License
# =======
#
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# default search engine for command line browser
DEFAULT_SEARCH='https://searx.laquadrature.net'
# onion port for the default domain
DEFAULT_DOMAIN_ONION_PORT=8099
LETSENCRYPT_SERVER='https://acme-v01.api.letsencrypt.org/directory'
# list of encryption protocols
SSL_PROTOCOLS="TLSv1 TLSv1.1 TLSv1.2"
# Mozilla recommended default ciphers. These work better on Android
# See https://wiki.mozilla.org/Security/Server_Side_TLS
SSL_CIPHERS="ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS"
# some mobile apps (eg. NextCloud) have not very good cipher compatibility.
# These ciphers can be used for those cases
SSL_CIPHERS_MOBILE="ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES128-SHA"
NGINX_ENSITE_REPO="https://github.com/perusio/nginx_ensite"
NGINX_ENSITE_COMMIT='fa4d72ce1c0a490442c8474e9c8dc21ed52c93d0'
# memory limit for php in MB
MAX_PHP_MEMORY=64
# logging level for Nginx
WEBSERVER_LOG_LEVEL='warn'
# test a domain name to see if it's valid
function validate_domain_name {
# count the number of dots in the domain name
dots=${TEST_DOMAIN_NAME//[^.]}
no_of_dots=${#dots}
TEST_DOMAIN_NAME=$"The domain $TEST_DOMAIN_NAME has too many subdomains. It should be of the type w.x.y.z, x.y.z or y.z"
fi
TEST_DOMAIN_NAME=$"The domain $TEST_DOMAIN_NAME has no top level domain. It should be of the type w.x.y.z, x.y.z or y.z"
fi
domain_name=$1
filename=/etc/nginx/sites-available/$domain_name
{ echo ' add_header X-Frame-Options DENY;';
echo ' add_header X-Content-Type-Options nosniff;';
echo ' add_header X-XSS-Protection "1; mode=block";';
echo ' add_header X-Robots-Tag none;';
echo ' add_header X-Download-Options noopen;';
echo ' add_header X-Permitted-Cross-Domain-Policies none;';
max_body=$2
fi
filename=/etc/nginx/sites-available/$domain_name
{ echo " client_max_body_size ${max_body};";
echo ' client_body_buffer_size 128k;';
echo ' limit_conn conn_limit_per_ip 10;';
echo ' limit_req zone=req_limit_per_ip burst=10 nodelay;';
{ echo " ssl_stapling on;";
echo ' ssl_stapling_verify on;';
echo " ssl_trusted_certificate /etc/ssl/certs/${domain_name}.pem;";
echo ''; } >> "$filename"
# redirect port 80 to https
domain_name=$1
filename=/etc/nginx/sites-available/$domain_name
{ echo 'server {';
echo ' listen 80;';
echo ' listen [::]:80;';
echo " server_name ${domain_name};";
echo " root /var/www/${domain_name}/htdocs;";
echo ' access_log /dev/null;';
echo " error_log /dev/null;"; } > "$filename"
{ echo " rewrite ^ https://\$server_name\$request_uri? permanent;";
echo '}';
echo ''; } >> "$filename"
function nginx_compress {
domain_name=$1
filename=/etc/nginx/sites-available/$domain_name
{ echo ' gzip on;';
echo ' gzip_min_length 1000;';
echo ' gzip_proxied expired no-cache no-store private auth;';
echo ' gzip_types text/plain application/xml;'; } >> "$filename"
# creates the SSL/TLS section for a website
domain_name=$1
mobile_ciphers=$2
{ echo ' ssl_stapling off;';
echo ' ssl_stapling_verify off;';
echo ' ssl on;';
echo " ssl_certificate /etc/letsencrypt/live/${domain_name}/fullchain.pem;";
echo " ssl_certificate_key /etc/letsencrypt/live/${domain_name}/privkey.pem;";
echo " ssl_dhparam /etc/ssl/certs/${domain_name}.dhparam;";
echo '';
echo ' ssl_session_cache builtin:1000 shared:SSL:10m;';
echo ' ssl_session_timeout 60m;';
echo ' ssl_prefer_server_ciphers on;';
echo " ssl_protocols $SSL_PROTOCOLS;"; } >> "$filename"
if [ "$mobile_ciphers" ]; then
echo " # Mobile compatible ciphers" >> "$filename"
echo " ssl_ciphers '$SSL_CIPHERS_MOBILE';" >> "$filename"
echo " add_header Content-Security-Policy \"default-src https:; script-src https: 'unsafe-inline'; style-src https: 'unsafe-inline'\";" >> "$filename"
}
# check an individual domain name
function test_domain_name {
if [[ $TEST_DOMAIN_NAME != 'ttrss' ]]; then
function_check validate_domain_name
validate_domain_name
echo $"Invalid domain name $TEST_DOMAIN_NAME"
exit 8528
fi
}
# Checks whether certificates were generated for the given hostname
function check_certificates {
echo $'No certificate name provided'
exit 3568736585683
if [[ $USE_LETSENCRYPT == 'no' || "$ONION_ONLY" != 'no' ]]; then
echo $"Private certificate for ${CHECK_HOSTNAME} was not created"
echo $"Public certificate for ${CHECK_HOSTNAME} was not created"
if grep -q "${1}.pem" "/etc/nginx/sites-available/${1}"; then
sed -i "s|${1}.pem|${1}.crt|g" "/etc/nginx/sites-available/${1}"
echo $"Private certificate for ${CHECK_HOSTNAME} was not created"
echo $"Public certificate for ${CHECK_HOSTNAME} was not created"
if grep -q "${1}.crt" "/etc/nginx/sites-available/${1}"; then
sed -i "s|${1}.crt|${1}.pem|g" "/etc/nginx/sites-available/${1}"
echo $"DiffieHellman parameters for ${CHECK_HOSTNAME} were not created"
if [ -f "/etc/letsencrypt/live/${1}/fullchain.${cert_type}" ]; then
fi
}
function create_self_signed_cert {
if [ ! "${SITE_DOMAIN_NAME}" ]; then
echo $'No site domain specified for self signed cert'
exit 4638565385
fi
"${PROJECT_NAME}-addcert" -h "${SITE_DOMAIN_NAME}" --dhkey "${DH_KEYLENGTH}"
if [ ! "${SITE_DOMAIN_NAME}" ]; then
echo $'No site domain specified for letsencrypt cert'
exit 246824624
fi
if ! "${PROJECT_NAME}-addcert" -e "${SITE_DOMAIN_NAME}" -s "${LETSENCRYPT_SERVER}" --dhkey "${DH_KEYLENGTH}" --email "${MY_EMAIL_ADDRESS}"; then
if [[ ${NO_SELF_SIGNED} == 'no' ]]; then
echo $"Lets Encrypt failed for ${SITE_DOMAIN_NAME}, so try making a self-signed cert"
"${PROJECT_NAME}-addcert" -h "${SITE_DOMAIN_NAME}" --dhkey "${DH_KEYLENGTH}"
else
echo $"Lets Encrypt failed for $SITE_DOMAIN_NAME"
if [ -f "/etc/nginx/sites-available/$SITE_DOMAIN_NAME" ]; then
nginx_dissite "$SITE_DOMAIN_NAME"
exit 682529
fi
return
fi
function_check check_certificates
SITE_DOMAIN_NAME="$1"
# if yes then only "valid" certs are allowed, not self-signed
NO_SELF_SIGNED='no'
NO_SELF_SIGNED="$2"
fi
if [[ $ONION_ONLY == "no" ]]; then
create_letsencrypt_cert
fi
else
if [[ $LETSENCRYPT_ENABLED == "yes" ]]; then
}
# script to automatically renew any Let's Encrypt certificates
function letsencrypt_renewals {
if [[ $ONION_ONLY != "no" ]]; then
return
fi
renewals_script=/tmp/renewals_letsencrypt
renewals_retry_script=/tmp/renewals_retry_letsencrypt
renewal_failure_msg=$'The certificate for $LETSENCRYPT_DOMAIN could not be renewed'
renewal_email_title=$'${PROJECT_NAME} Lets Encrypt certificate renewal'
# the main script tries to renew once per month
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
{ echo '#!/bin/bash';
echo '';
echo "PROJECT_NAME='${PROJECT_NAME}'";
echo "COMPLETION_FILE=\$HOME/\${PROJECT_NAME}-completed.txt";
echo '';
echo 'if [ -d /etc/letsencrypt ]; then';
echo ' if [ -f ~/letsencrypt_failed ]; then';
echo ' rm ~/letsencrypt_failed';
echo ' fi';
echo -n " ADMIN_USERNAME=\$(cat \$COMPLETION_FILE | grep \"Admin user\" | ";
echo -n "awk -F ':' '{print ";
echo -n "\$2";
echo "}')";
echo " ADMIN_EMAIL_ADDRESS=\$ADMIN_USERNAME@\$HOSTNAME";
echo ' for d in /etc/letsencrypt/live/*/ ; do';
echo -n " LETSENCRYPT_DOMAIN=\$(echo \"\$d\" | ";
echo -n "awk -F '/' '{print ";
echo -n "\$5";
echo "}')";
echo " if [ -f /etc/nginx/sites-available/\$LETSENCRYPT_DOMAIN ]; then";
echo " \${PROJECT_NAME}-renew-cert -h \$LETSENCRYPT_DOMAIN -p letsencrypt";
echo ' if [ ! "$?" = "0" ]; then';
echo " echo \"${renewal_failure_msg}\" > ~/temp_renewletsencrypt.txt";
echo ' echo "" >> ~/temp_renewletsencrypt.txt';
echo " \${PROJECT_NAME}-renew-cert -h \$LETSENCRYPT_DOMAIN -p letsencrypt 2>> ~/temp_renewletsencrypt.txt";
echo -n " cat ~/temp_renewletsencrypt.txt | mail -s \"${renewal_email_title}\" ";
echo "\$ADMIN_EMAIL_ADDRESS";
echo ' rm ~/temp_renewletsencrypt.txt';
echo ' if [ ! -f ~/letsencrypt_failed ]; then';
echo ' touch ~/letsencrypt_failed';
echo ' fi';
echo ' fi';
echo ' fi';
echo ' done';
echo 'fi'; } > "$renewals_script"
chmod +x "$renewals_script"
if [ ! -f /etc/cron.monthly/letsencrypt ]; then
cp $renewals_script /etc/cron.monthly/letsencrypt
else
HASH1=$(sha256sum $renewals_script | awk -F ' ' '{print $1}')
HASH2=$(sha256sum /etc/cron.monthly/letsencrypt | awk -F ' ' '{print $1}')
if [[ "$HASH1" != "$HASH2" ]]; then
cp $renewals_script /etc/cron.monthly/letsencrypt
fi
fi
rm $renewals_script
# a secondary script keeps trying to renew after a failure
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
{ echo '#!/bin/bash';
echo '';
echo "PROJECT_NAME='${PROJECT_NAME}'";
echo "COMPLETION_FILE=\$HOME/\${PROJECT_NAME}-completed.txt";
echo '';
echo 'if [ -d /etc/letsencrypt ]; then';
echo ' if [ -f ~/letsencrypt_failed ]; then';
echo ' rm ~/letsencrypt_failed';
echo -n " ADMIN_USERNAME=\$(cat \$COMPLETION_FILE | grep \"Admin user\" | ";
echo -n "awk -F ':' '{print ";
echo -n "\$2";
echo "}')";
echo " ADMIN_EMAIL_ADDRESS=\$ADMIN_USERNAME@\$HOSTNAME";
echo ' for d in /etc/letsencrypt/live/*/ ; do';
echo -n " LETSENCRYPT_DOMAIN=\$(echo \"\$d\" | ";
echo -n "awk -F '/' '{print ";
echo -n "\$5";
echo "}')";
echo " if [ -f /etc/nginx/sites-available/\$LETSENCRYPT_DOMAIN ]; then";
echo " \${PROJECT_NAME}-renew-cert -h \$LETSENCRYPT_DOMAIN -p letsencrypt";
echo ' if [ ! "$?" = "0" ]; then';
echo " echo \"${renewal_failure_msg}\" > ~/temp_renewletsencrypt.txt";
echo ' echo "" >> ~/temp_renewletsencrypt.txt';
echo " \${PROJECT_NAME}-renew-cert -h \$LETSENCRYPT_DOMAIN -p letsencrypt 2>> ~/temp_renewletsencrypt.txt";
echo -n " cat ~/temp_renewletsencrypt.txt | mail -s \"${renewal_email_title}\" ";
echo "\$ADMIN_EMAIL_ADDRESS";
echo ' rm ~/temp_renewletsencrypt.txt';
echo ' if [ ! -f ~/letsencrypt_failed ]; then';
echo ' touch ~/letsencrypt_failed';
echo ' fi';
echo ' fi';
echo ' fi';
echo ' done';
echo ' fi';
echo 'fi'; } > "$renewals_retry_script"
chmod +x "$renewals_retry_script"
if [ ! -f /etc/cron.daily/letsencrypt ]; then
cp $renewals_retry_script /etc/cron.daily/letsencrypt
else
HASH1=$(sha256sum $renewals_retry_script | awk -F ' ' '{print $1}')
HASH2=$(sha256sum /etc/cron.daily/letsencrypt | awk -F ' ' '{print $1}')
if [[ "$HASH1" != "$HASH2" ]]; then
cp $renewals_retry_script /etc/cron.daily/letsencrypt
fi
fi
rm $renewals_retry_script
sed -i "s/memory_limit =.*/memory_limit = ${MAX_PHP_MEMORY}M/g" /etc/php/7.0/fpm/php.ini
sed -i 's/;cgi.fix_pathinfo=1/cgi.fix_pathinfo=0/g' /etc/php/7.0/fpm/php.ini
sed -i "s/memory_limit =.*/memory_limit = ${MAX_PHP_MEMORY}M/g" /etc/php/7.0/cli/php.ini
sed -i "s/upload_max_filesize =.*/upload_max_filesize = 50M/g" /etc/php/7.0/fpm/php.ini
sed -i "s/upload_max_filesize =.*/upload_max_filesize = 50M/g" /etc/php/7.0/cli/php.ini
sed -i "s/post_max_size =.*/post_max_size = 50M/g" /etc/php/7.0/fpm/php.ini
{ echo '#%PAM-1.0';
echo '@include common-auth';
echo '@include common-account';
echo '@include common-session'; } > /etc/pam.d/nginx
function upgrade_inadyn_config {
if [ ! -f "${INADYN_CONFIG_FILE}" ]; then
return
fi
if grep -q "{" "${INADYN_CONFIG_FILE}"; then
return
fi
read_config_param DDNS_PROVIDER
read_config_param DDNS_USERNAME
read_config_param DDNS_PASSWORD
read_config_param DEFAULT_DOMAIN_NAME
grep "alias " "${INADYN_CONFIG_FILE}" | sed 's| alias ||g' > ~/.inadyn_existing_sites
if [[ "$DDNS_PROVIDER" == "default@freedns.afraid.org" ]]; then
DDNS_PROVIDER='freedns'
write_config_param DDNS_PROVIDER "$DDNS_PROVIDER"
fi
{ echo 'period = 300';
echo '';
echo "provider $DDNS_PROVIDER {";
echo " ssl = true";
echo " username = $DDNS_USERNAME";
echo " password = $DDNS_PASSWORD";
echo ' wildcard = true';
echo " hostname = $DEFAULT_DOMAIN_NAME";
echo '}'; } > "${INADYN_CONFIG_FILE}"
}
if [[ $ONION_ONLY != "no" ]]; then
return
fi
if grep -q "INADYN_REPO" "$CONFIGURATION_FILE"; then
sed -i '/INADYN_REPO/d' "$CONFIGURATION_FILE"
fi
if grep -q "INADYN_COMMIT" "$CONFIGURATION_FILE"; then
sed -i '/INADYN_COMMIT/d' "$CONFIGURATION_FILE"
if [ -f /usr/local/sbin/inadyn ]; then
if grep -q "inadyn commit" "$COMPLETION_FILE"; then
else
CURR_INADYN_COMMIT=$(get_completion_param "inadyn commit")
if [[ "${CURR_INADYN_COMMIT}" == "${INADYN_COMMIT}" ]]; then
return
fi
if [ -f /usr/local/sbin/inadyn ]; then
if [ -d "$INSTALL_DIR/inadyn" ]; then
rm -rf "$INSTALL_DIR/inadyn"
fi
if [ -d /repos/inadyn ]; then
rm -rf /repos/inadyn
fi
else
# update to the next commit
function_check set_repo_commit
set_repo_commit "$INSTALL_DIR/inadyn" "inadyn commit" "$INADYN_COMMIT" "$INADYN_REPO"
# Here we compile from source because the current package
# doesn't support https, which could result in passwords
# being leaked
# Debian version 1.99.4-1
# https version 1.99.8
apt-get -yq install build-essential curl libgnutls28-dev automake1.11
apt-get -yq install gnutls-dev libconfuse-dev pkg-config libtool
mkdir "$INSTALL_DIR/inadyn"
cp -r -p /repos/inadyn/. "$INSTALL_DIR/inadyn"
cd "$INSTALL_DIR/inadyn" || exit 2462874684
echo 'inadyn repo not cloned'
echo -n | openssl s_client -showcerts -connect github.com:443 -CApath /etc/ssl/certs
exit 6785
fi
cd "$INSTALL_DIR/inadyn" || exit 246824684
git checkout "$INADYN_COMMIT" -b "$INADYN_COMMIT"
if ! ./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var; then
exit 3785
fi
# create a configuration file
if [ ! -f "${INADYN_CONFIG_FILE}" ]; then
{ echo 'period = 300';
echo ''; } > "${INADYN_CONFIG_FILE}"
fi
echo 'Description=Internet Dynamic DNS Client';
echo 'Documentation=man:inadyn';
echo 'Documentation=man:inadyn.conf';
echo 'Documentation=https://github.com/troglobit/inadyn';
echo 'ConditionPathExists=/etc/inadyn.conf';
echo 'After=network-online.target';
echo 'Requires=network-online.target';
echo "ExecStart=/usr/sbin/inadyn -C -n -s --loglevel=err --config ${INADYN_CONFIG_FILE}";
echo 'Restart=on-failure';
echo 'RestartSec=10';
echo '';
echo '[Install]';
echo 'WantedBy=multi-user.target'; } > /etc/systemd/system/inadyn.service
systemctl start inadyn
# Remove old version of inadyn
if [ -f /usr/local/sbin/inadyn ]; then
rm /usr/local/sbin/inadyn
upgrade_inadyn_config
fi
function update_default_search_engine {
for d in /home/*/ ; do
USERNAME=$(echo "$d" | awk -F '/' '{print $3}')
if [[ $(is_valid_user "$USERNAME") == "1" ]]; then
if ! grep -q "WWW_HOME" "/home/$USERNAME/.bashrc"; then
if ! grep -q 'controluser' "/home/$USERNAME/.bashrc"; then
if ! grep -q 'export WWW_HOME=' "/home/$USERNAME/.bashrc"; then
echo "export WWW_HOME=$DEFAULT_SEARCH" >> "/home/$USERNAME/.bashrc"
sed -i "s|export WWW_HOME=.*|export WWW_HOME=$DEFAULT_SEARCH|g" "/home/$USERNAME/.bashrc"
if ! grep -q 'export WWW_HOME=' "/home/$USERNAME/.bashrc"; then
sed -i "/controluser/i export WWW_HOME=$DEFAULT_SEARCH" "/home/$USERNAME/.bashrc"
sed -i "s|export WWW_HOME=.*|export WWW_HOME=$DEFAULT_SEARCH|g" "/home/$USERNAME/.bashrc"
fi
fi
fi
done
}
function install_command_line_browser {
if [[ $(is_completed "${FUNCNAME[0]}") == "1" ]]; then
echo $'Unable to install web server'
exit 346825
fi
mesh_web_server
return
fi
# update to the next commit
function_check set_repo_commit
set_repo_commit "$INSTALL_DIR/nginx_ensite" "nginx-ensite commit" "$NGINX_ENSITE_COMMIT" $NGINX_ENSITE_REPO
if [[ $(is_completed "${FUNCNAME[0]}") == "1" ]]; then
if [ -d /etc/apache2 ]; then
rm -rf /etc/apache2
fi
# install nginx
# Turn off logs by default
sed -i 's|access_log.*|access_log = /dev/null;|g' /etc/nginx/nginx.conf
sed -i 's|error_log.*|error_log = /dev/null;|g' /etc/nginx/nginx.conf
sed -i 's/; process.max =.*/process.max = 32/g' /etc/php/7.0/fpm/php-fpm.conf
#sed -i 's/;process_control_timeout =.*/process_control_timeout = 300/g' /etc/php/7.0/fpm/php-fpm.conf
sed -i 's|;systemd_interval.*|systemd_interval = 10|g' /etc/php/7.0/fpm/php-fpm.conf
sed -i 's|;emergency_restart_threshold.*|emergency_restart_threshold = 2|g' /etc/php/7.0/fpm/php-fpm.conf
sed -i 's|emergency_restart_threshold.*|emergency_restart_threshold = 2|g' /etc/php/7.0/fpm/php-fpm.conf
sed -i 's|;emergency_restart_interval.*|emergency_restart_interval = 1m|g' /etc/php/7.0/fpm/php-fpm.conf
sed -i 's|emergency_restart_interval.*|emergency_restart_interval = 1m|g' /etc/php/7.0/fpm/php-fpm.conf
sed -i 's|;process_control_timeout.*|process_control_timeout = 10s|g' /etc/php/7.0/fpm/php-fpm.conf
sed -i 's|process_control_timeout.*|process_control_timeout = 10s|g' /etc/php/7.0/fpm/php-fpm.conf
if ! grep -q "pm.max_children" /etc/php/7.0/fpm/php-fpm.conf; then
{ echo 'pm = static';
echo 'pm.max_children = 10';
echo 'pm.start_servers = 2';
echo 'pm.min_spare_servers = 2';
echo 'pm.max_spare_servers = 5';
echo 'pm.max_requests = 10'; } >> /etc/php/7.0/fpm/php-fpm.conf
if ! grep -q "request_terminate_timeout" /etc/php/7.0/fpm/php-fpm.conf; then
echo 'request_terminate_timeout = 30' >> /etc/php/7.0/fpm/php-fpm.conf
else
sed -i 's|request_terminate_timeout =.*|request_terminate_timeout = 30|g' >> /etc/php/7.0/fpm/php-fpm.conf
fi
sed -i 's|max_execution_time =.*|max_execution_time = 30|g' /etc/php/7.0/fpm/php.ini
if [ ! -d /etc/nginx ]; then
echo $"ERROR: nginx does not appear to have installed. $CHECK_MESSAGE"
exit 51
fi
# Nginx settings
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
{ echo 'user www-data;';
#echo "worker_processes; $CPU_CORES";
echo 'pid /run/nginx.pid;';
echo '';
echo 'events {';
echo ' worker_connections 50;';
echo ' # multi_accept on;';
echo '}';
echo '';
echo 'http {';
echo ' # limit the number of connections per single IP';
echo " limit_conn_zone \$binary_remote_addr zone=conn_limit_per_ip:10m;";
echo '';
echo ' # limit the number of requests for a given session';
echo " limit_req_zone \$binary_remote_addr zone=req_limit_per_ip:10m rate=140r/s;";
echo '';
echo ' # if the request body size is more than the buffer size, then the entire (or partial) request body is written into a temporary file';
echo ' client_body_buffer_size 128k;';
echo '';
echo ' # headerbuffer size for the request header from client, its set for testing purpose';
echo ' client_header_buffer_size 3m;';
echo '';
echo ' # maximum number and size of buffers for large headers to read from client request';
echo ' large_client_header_buffers 4 256k;';
echo '';
echo ' # read timeout for the request body from client, its set for testing purpose';
echo ' client_body_timeout 3m;';
echo '';
echo ' # how long to wait for the client to send a request header, its set for testing purpose';
echo ' client_header_timeout 3m;';
echo '';
echo ' ##';
echo ' # Basic Settings';
echo ' ##';
echo '';
echo ' sendfile on;';
echo ' tcp_nopush on;';
echo ' tcp_nodelay on;';
echo ' keepalive_timeout 65;';
echo ' types_hash_max_size 2048;';
echo ' server_tokens off;';
echo '';
echo ' # server_names_hash_bucket_size 64;';
echo ' # server_name_in_redirect off;';
echo '';
echo ' include /etc/nginx/mime.types;';
echo ' default_type application/octet-stream;';
echo '';
echo ' ##';
echo ' # Logging Settings';
echo ' ##';
echo '';
echo ' access_log /dev/null;';
echo ' error_log /dev/null;';
echo '';
echo ' ###';
echo ' # Gzip Settings';
echo ' ##';
echo ' gzip on;';
echo ' gzip_disable "msie6";';
echo '';
echo ' # gzip_vary on;';
echo ' # gzip_proxied any;';
echo ' # gzip_comp_level 6;';
echo ' # gzip_buffers 16 8k;';
echo ' # gzip_http_version 1.1;';
echo ' # gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;';
echo '';
echo ' ##';
echo ' # Virtual Host Configs';
echo ' ##';
echo '';
echo ' include /etc/nginx/conf.d/*.conf;';
echo ' include /etc/nginx/sites-enabled/*;';
echo '}'; } > /etc/nginx/nginx.conf
# install a script to easily enable and disable nginx virtual hosts
git_clone "$NGINX_ENSITE_REPO" "$INSTALL_DIR/nginx_ensite"
cd "$INSTALL_DIR/nginx_ensite" || exit 2468748223
git checkout "$NGINX_ENSITE_COMMIT" -b "$NGINX_ENSITE_COMMIT"
set_completion_param "nginx-ensite commit" "$NGINX_ENSITE_COMMIT"
make install
nginx_dissite default
function_check configure_firewall_for_web_access
configure_firewall_for_web_access
function remove_certs {
domain_name=$1
if [ -f "/etc/ssl/certs/${domain_name}.dhparam" ]; then
rm "/etc/ssl/certs/${domain_name}.dhparam"
if [ -f "/etc/ssl/certs/${domain_name}.pem" ]; then
rm "/etc/ssl/certs/${domain_name}.pem"
if [ -f "/etc/ssl/certs/${domain_name}.crt" ]; then
rm "/etc/ssl/certs/${domain_name}.crt"
if [ -f "/etc/ssl/private/${domain_name}.key" ]; then
rm "/etc/ssl/private/${domain_name}.key"
function configure_firewall_for_web_access {
if [[ $(is_completed "${FUNCNAME[0]}") == "1" ]]; then
return
fi
if [[ $INSTALLED_WITHIN_DOCKER == "yes" ]]; then
# docker does its own firewalling
return
fi
if [[ $ONION_ONLY != "no" ]]; then
return
fi
firewall_add HTTP 80 tcp
firewall_add HTTPS 443 tcp
if [[ $ONION_ONLY == 'no' ]]; then
if [ -f /etc/mumble-server.ini ]; then
if [ ! -f "/etc/letsencrypt/live/${DEFAULT_DOMAIN_NAME}/fullchain.pem" ]; then
if ! grep -q "mumble.pem" /etc/mumble-server.ini; then
sed -i 's|sslCert=.*|sslCert=/var/lib/mumble-server/mumble.pem|g' /etc/mumble-server.ini
sed -i 's|sslKey=.*|sslKey=/var/lib/mumble-server/mumble.key|g' /etc/mumble-server.ini
systemctl restart mumble
fi
else
if ! grep -q "${DEFAULT_DOMAIN_NAME}/fullchain.pem" /etc/mumble-server.ini; then
usermod -a -G ssl-cert mumble-server
sed -i "s|sslCert=.*|sslCert=/etc/letsencrypt/live/${DEFAULT_DOMAIN_NAME}/fullchain.pem|g" /etc/mumble-server.ini
sed -i "s|sslKey=.*|sslKey=/etc/letsencrypt/live/${DEFAULT_DOMAIN_NAME}/privkey.pem|g" /etc/mumble-server.ini
systemctl restart mumble
fi
if [ -d /etc/prosody ]; then
if [ ! -d /etc/prosody/certs ]; then
mkdir /etc/prosody/certs
fi
cp /etc/ssl/private/xmpp* /etc/prosody/certs
cp /etc/ssl/certs/xmpp* /etc/prosody/certs
if [ -f "/etc/letsencrypt/live/${DEFAULT_DOMAIN_NAME}/fullchain.pem" ]; then
if grep -q "/etc/prosody/certs/xmpp.key" /etc/prosody/conf.avail/xmpp.cfg.lua; then
sed -i "s|/etc/prosody/certs/xmpp.key|/etc/letsencrypt/live/${DEFAULT_DOMAIN_NAME}/privkey.pem|g" /etc/prosody/conf.avail/xmpp.cfg.lua
fi
if grep -q "/etc/prosody/certs/xmpp.crt" /etc/prosody/conf.avail/xmpp.cfg.lua; then
sed -i "s|/etc/prosody/certs/xmpp.crt|/etc/letsencrypt/live/${DEFAULT_DOMAIN_NAME}/fullchain.pem|g" /etc/prosody/conf.avail/xmpp.cfg.lua
if grep -q "/etc/prosody/certs/xmpp.key" /etc/prosody/prosody.cfg.lua; then
sed -i "s|/etc/prosody/certs/xmpp.key|/etc/letsencrypt/live/${DEFAULT_DOMAIN_NAME}/privkey.pem|g" /etc/prosody/prosody.cfg.lua
fi
if grep -q "/etc/prosody/certs/xmpp.crt" /etc/prosody/prosody.cfg.lua; then
sed -i "s|/etc/prosody/certs/xmpp.crt|/etc/letsencrypt/live/${DEFAULT_DOMAIN_NAME}/fullchain.pem|g" /etc/prosody/prosody.cfg.lua
if grep -q "/etc/prosody/certs/${DEFAULT_DOMAIN_NAME}.key" /etc/prosody/conf.avail/xmpp.cfg.lua; then
sed -i "s|/etc/prosody/certs/${DEFAULT_DOMAIN_NAME}.key|/etc/letsencrypt/live/${DEFAULT_DOMAIN_NAME}/privkey.pem|g" /etc/prosody/conf.avail/xmpp.cfg.lua
fi
if grep -q "/etc/prosody/certs/${DEFAULT_DOMAIN_NAME}.pem" /etc/prosody/conf.avail/xmpp.cfg.lua; then
sed -i "s|/etc/prosody/certs/${DEFAULT_DOMAIN_NAME}.pem|/etc/letsencrypt/live/${DEFAULT_DOMAIN_NAME}/fullchain.pem|g" /etc/prosody/conf.avail/xmpp.cfg.lua
fi
if grep -q "/etc/prosody/certs/${DEFAULT_DOMAIN_NAME}.key" /etc/prosody/prosody.cfg.lua; then
sed -i "s|/etc/prosody/certs/${DEFAULT_DOMAIN_NAME}.key|/etc/letsencrypt/live/${DEFAULT_DOMAIN_NAME}/privkey.pem|g" /etc/prosody/prosody.cfg.lua
fi
if grep -q "/etc/prosody/certs/${DEFAULT_DOMAIN_NAME}.pem" /etc/prosody/prosody.cfg.lua; then
sed -i "s|/etc/prosody/certs/${DEFAULT_DOMAIN_NAME}.pem|/etc/letsencrypt/live/${DEFAULT_DOMAIN_NAME}/fullchain.pem|g" /etc/prosody/prosody.cfg.lua
fi
chmod -R 700 /etc/prosody/certs/*
cp -r "$INSTALL_DIR/prosody-modules/"* /var/lib/prosody/prosody-modules/
cp -r "$INSTALL_DIR/prosody-modules/"* /usr/lib/prosody/modules/
chown -R prosody:prosody /var/lib/prosody/prosody-modules
chown -R prosody:prosody /usr/lib/prosody/modules
if [ -d /home/znc/.znc ]; then
echo $'znc found'
if [ -f "/etc/letsencrypt/live/${DEFAULT_DOMAIN_NAME}/fullchain.pem" ]; then
cat "/etc/ssl/certs/${DEFAULT_DOMAIN_NAME}.pem" "/etc/ssl/private/${DEFAULT_DOMAIN_NAME}.key" > /home/znc/.znc/znc.pem
chown znc:znc /home/znc/.znc/znc.pem
chmod 700 /home/znc/.znc/znc.pem
sed -i "s|CertFile =.*|CertFile = /etc/letsencrypt/live/${DEFAULT_DOMAIN_NAME}/fullchain.pem" /etc/ngircd/ngircd.conf
sed -i "s|DHFile =.*|DHFile = /etc/ssl/certs/${DEFAULT_DOMAIN_NAME}.dhparam" /etc/ngircd/ngircd.conf
sed -i "s|KeyFile =.*|KeyFile = /etc/letsencrypt/live/${DEFAULT_DOMAIN_NAME}/privkey.pem" /etc/ngircd/ngircd.conf
echo $'irc certificates updated'
systemctl restart ngircd
su -c 'znc' - znc
fi
if [ ${#DEFAULT_DOMAIN_NAME} -gt 0 ]; then
if [ -f "/etc/letsencrypt/live/${DEFAULT_DOMAIN_NAME}/fullchain.pem" ]; then
if [ -d /etc/dovecot ]; then
if ! grep -q "ssl_cert = </etc/letsencrypt/live/${DEFAULT_DOMAIN_NAME}/fullchain.pem" /etc/dovecot/conf.d/10-ssl.conf; then
sed -i "s|#ssl_cert =.*|ssl_cert = </etc/letsencrypt/live/${DEFAULT_DOMAIN_NAME}/fullchain.pem|g" /etc/dovecot/conf.d/10-ssl.conf
sed -i "s|ssl_cert =.*|ssl_cert = </etc/letsencrypt/live/${DEFAULT_DOMAIN_NAME}/fullchain.pem|g" /etc/dovecot/conf.d/10-ssl.conf
systemctl restart dovecot
fi
fi
if [ -d /etc/exim4 ]; then
# Unfortunately there doesn't appear to be any other way than copying certs here
cp "/etc/letsencrypt/live/${DEFAULT_DOMAIN_NAME}/{fullchain,privkey}.pem" /etc/exim4/
chown root:Debian-exim /etc/exim4/*.pem
chmod 640 /etc/exim4/*.pem
sed -i "s|MAIN_TLS_CERTIFICATE =.*|MAIN_TLS_CERTIFICATE = /etc/exim4/fullchain.pem|g" /etc/exim4/conf.d/main/03_exim4-config_tlsoptions
sed -i "s|MAIN_TLS_CERTIFICATE =.*|MAIN_TLS_CERTIFICATE = /etc/exim4/fullchain.pem|g" /etc/exim4/exim4.conf.template
sed -i "s|MAIN_TLS_PRIVATEKEY =.*|MAIN_TLS_PRIVATEKEY = /etc/exim4/privkey.pem|g" /etc/exim4/conf.d/main/03_exim4-config_tlsoptions
sed -i "s|MAIN_TLS_PRIVATEKEY =.*|MAIN_TLS_PRIVATEKEY = /etc/exim4/privkey.pem|g" /etc/exim4/exim4.conf.template
systemctl restart exim4
if [ ! -f "/etc/nginx/sites-available/${DEFAULT_DOMAIN_NAME}" ]; then
if [ ! -d "/var/www/${DEFAULT_DOMAIN_NAME}/htdocs" ]; then
mkdir -p "/var/www/${DEFAULT_DOMAIN_NAME}/htdocs"
if [ -d "/root/${PROJECT_NAME}" ]; then
cd "/root/${PROJECT_NAME}/website" || exit 24687246468
./deploy.sh EN "/var/www/${DEFAULT_DOMAIN_NAME}/htdocs"
if [ -d "/home/${MY_USERNAME}/${PROJECT_NAME}" ]; then
cd "/home/${MY_USERNAME}/${PROJECT_NAME}" || exit 2462874624
./deploy.sh EN "/var/www/${DEFAULT_DOMAIN_NAME}/htdocs"
fi
fi
fi
# add a config for the default domain
nginx_site=/etc/nginx/sites-available/$DEFAULT_DOMAIN_NAME
if [[ $ONION_ONLY == "no" ]]; then
function_check nginx_http_redirect
nginx_http_redirect "$DEFAULT_DOMAIN_NAME"
{ echo 'server {';
echo ' listen 443 ssl;';
echo ' #listen [::]:443 ssl;';
echo " server_name $DEFAULT_DOMAIN_NAME;";
echo '';
echo ' # Security'; } >> "$nginx_site"
function_check nginx_security_options
nginx_security_options "$DEFAULT_DOMAIN_NAME"
{ echo ' add_header Strict-Transport-Security max-age=15768000;';
echo '';
echo ' # Logs';
echo ' access_log /dev/null;';
echo ' error_log /dev/null;';
echo '';
echo ' # Root';
echo " root /var/www/$DEFAULT_DOMAIN_NAME/htdocs;";
echo '';
echo ' # Index';
echo ' index index.html;';
echo '';
echo ' # Location';
echo ' location / {'; } >> "$nginx_site"
nginx_limits "$DEFAULT_DOMAIN_NAME" '15m'
{ echo ' }';
echo '';
echo ' # Restrict access that is unnecessary anyway';
echo ' location ~ /\.(ht|git) {';
echo ' deny all;';
echo ' }';
echo '}'; } >> "$nginx_site"