Skip to content
Snippets Groups Projects
freedombone-utils-web 47.9 KiB
Newer Older
Bob Mottram's avatar
Bob Mottram committed
#!/bin/bash
Bob Mottram's avatar
Bob Mottram committed
#  _____               _           _
# |   __|___ ___ ___ _| |___ _____| |_ ___ ___ ___
# |   __|  _| -_| -_| . | . |     | . | . |   | -_|
# |__|  |_| |___|___|___|___|_|_|_|___|___|_|_|___|
Bob Mottram's avatar
Bob Mottram committed
#
Bob Mottram's avatar
Bob Mottram committed
#                              Freedom in the Cloud
Bob Mottram's avatar
Bob Mottram committed
#
# Web related functions
#
# License
# =======
#
Bob Mottram's avatar
Bob Mottram committed
# Copyright (C) 2014-2018 Bob Mottram <bob@freedombone.net>
Bob Mottram's avatar
Bob Mottram committed
#
# 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'

Bob Mottram's avatar
Bob Mottram committed
# onion port for the default domain
DEFAULT_DOMAIN_ONION_PORT=8099

Bob Mottram's avatar
Bob Mottram committed
# Whether Let's Encrypt is enabled for all sites
Bob Mottram's avatar
Bob Mottram committed
LETSENCRYPT_ENABLED="yes"
Bob Mottram's avatar
Bob Mottram committed
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"
Bob Mottram's avatar
Bob Mottram committed

# 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"

Bob Mottram's avatar
Bob Mottram committed
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 {
Bob Mottram's avatar
Bob Mottram committed
    # count the number of dots in the domain name
    dots=${TEST_DOMAIN_NAME//[^.]}
    no_of_dots=${#dots}
Bob Mottram's avatar
Bob Mottram committed
    if (( no_of_dots > 3 )); then
Bob Mottram's avatar
Bob Mottram committed
        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
Bob Mottram's avatar
Bob Mottram committed
    if (( no_of_dots == 0 )); then
Bob Mottram's avatar
Bob Mottram committed
        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
Bob Mottram's avatar
Bob Mottram committed
}

Bob Mottram's avatar
Bob Mottram committed
function nginx_security_options {
Bob Mottram's avatar
Bob Mottram committed
    domain_name=$1
    filename=/etc/nginx/sites-available/$domain_name
Bob Mottram's avatar
Bob Mottram committed
    { 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;';
Bob Mottram's avatar
Bob Mottram committed
      echo ''; } >> "$filename"
Bob Mottram's avatar
Bob Mottram committed
}

function nginx_limits {
Bob Mottram's avatar
Bob Mottram committed
    domain_name=$1
    max_body='20m'
Bob Mottram's avatar
Bob Mottram committed
    if [ "$2" ]; then
Bob Mottram's avatar
Bob Mottram committed
        max_body=$2
    fi
    filename=/etc/nginx/sites-available/$domain_name
Bob Mottram's avatar
Bob Mottram committed
    { echo "        client_max_body_size ${max_body};";
      echo '        client_body_buffer_size 128k;';
Bob Mottram's avatar
Bob Mottram committed
      echo '';
Bob Mottram's avatar
Bob Mottram committed
      echo '        limit_conn conn_limit_per_ip 10;';
      echo '        limit_req zone=req_limit_per_ip burst=10 nodelay;';
Bob Mottram's avatar
Bob Mottram committed
      echo ''; } >> "$filename"
Bob Mottram's avatar
Bob Mottram committed
}

function nginx_stapling {
Bob Mottram's avatar
Bob Mottram committed
    domain_name="$1"
Bob Mottram's avatar
Bob Mottram committed
    filename=/etc/nginx/sites-available/$domain_name
Bob Mottram's avatar
Bob Mottram committed
    { echo "    ssl_stapling on;";
      echo '    ssl_stapling_verify on;';
      echo "    ssl_trusted_certificate /etc/ssl/certs/${domain_name}.pem;";
      echo ''; } >> "$filename"
Bob Mottram's avatar
Bob Mottram committed
}

function nginx_http_redirect {
Bob Mottram's avatar
Bob Mottram committed
    # redirect port 80 to https
    domain_name=$1
    filename=/etc/nginx/sites-available/$domain_name
Bob Mottram's avatar
Bob Mottram committed
    { 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"
Bob Mottram's avatar
Bob Mottram committed
    function_check nginx_limits
Bob Mottram's avatar
Bob Mottram committed
    nginx_limits "$domain_name"
    if [ ${#2} -gt 0 ]; then
Bob Mottram's avatar
Bob Mottram committed
        echo "    $2;" >> "$filename"
Bob Mottram's avatar
Bob Mottram committed
    { echo "    rewrite ^ https://\$server_name\$request_uri? permanent;";
      echo '}';
      echo ''; } >> "$filename"
function nginx_compress {
    domain_name=$1
    filename=/etc/nginx/sites-available/$domain_name

Bob Mottram's avatar
Bob Mottram committed
    { 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"
Bob Mottram's avatar
Bob Mottram committed
function nginx_ssl {
Bob Mottram's avatar
Bob Mottram committed
    # creates the SSL/TLS section for a website
    domain_name=$1
Bob Mottram's avatar
Bob Mottram committed
    filename=/etc/nginx/sites-available/$domain_name
Bob Mottram's avatar
Bob Mottram committed
    { 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"
Bob Mottram's avatar
Bob Mottram committed
        echo "    ssl_ciphers '$SSL_CIPHERS';" >> "$filename"
    echo "    add_header Content-Security-Policy \"default-src https:; script-src https: 'unsafe-inline'; style-src https: 'unsafe-inline'\";" >> "$filename"
Bob Mottram's avatar
Bob Mottram committed
    #nginx_stapling $1
Bob Mottram's avatar
Bob Mottram committed
}

# check an individual domain name
function test_domain_name {
Bob Mottram's avatar
Bob Mottram committed
    if [ "$1" ]; then
Bob Mottram's avatar
Bob Mottram committed
        TEST_DOMAIN_NAME=$1
Bob Mottram's avatar
Bob Mottram committed
        if [[ $TEST_DOMAIN_NAME != 'ttrss' ]]; then
            function_check validate_domain_name
            validate_domain_name
Bob Mottram's avatar
Bob Mottram committed
            if [[ "$TEST_DOMAIN_NAME" != "$1" ]]; then
Bob Mottram's avatar
Bob Mottram committed
                echo $"Invalid domain name $TEST_DOMAIN_NAME"
                exit 8528
            fi
Bob Mottram's avatar
Bob Mottram committed
        fi
    fi
Bob Mottram's avatar
Bob Mottram committed
}

# Checks whether certificates were generated for the given hostname
function check_certificates {
Bob Mottram's avatar
Bob Mottram committed
    if [ ! "$1" ]; then
        echo $'No certificate name provided'
        exit 3568736585683
Bob Mottram's avatar
Bob Mottram committed
    fi
    USE_LETSENCRYPT='no'
Bob Mottram's avatar
Bob Mottram committed
    if [ "$2" ]; then
        USE_LETSENCRYPT="$2"
Bob Mottram's avatar
Bob Mottram committed
    fi
    if [[ $USE_LETSENCRYPT == 'no' || "$ONION_ONLY" != 'no' ]]; then
Bob Mottram's avatar
Bob Mottram committed
        if [ ! -f "/etc/ssl/private/${1}.key" ]; then
            echo $"Private certificate for ${CHECK_HOSTNAME} was not created"
Bob Mottram's avatar
Bob Mottram committed
            exit 63959
        fi
Bob Mottram's avatar
Bob Mottram committed
        if [ ! -f "/etc/ssl/certs/${1}.crt" ]; then
            echo $"Public certificate for ${CHECK_HOSTNAME} was not created"
Bob Mottram's avatar
Bob Mottram committed
            exit 7679
        fi
Bob Mottram's avatar
Bob Mottram committed
        if grep -q "${1}.pem" "/etc/nginx/sites-available/${1}"; then
            sed -i "s|${1}.pem|${1}.crt|g" "/etc/nginx/sites-available/${1}"
Bob Mottram's avatar
Bob Mottram committed
    else
Bob Mottram's avatar
Bob Mottram committed
        if [ ! -f "/etc/letsencrypt/live/${1}/privkey.pem" ]; then
            echo $"Private certificate for ${CHECK_HOSTNAME} was not created"
Bob Mottram's avatar
Bob Mottram committed
            exit 6282
        fi
Bob Mottram's avatar
Bob Mottram committed
        if [ ! -f "/etc/letsencrypt/live/${1}/fullchain.pem" ]; then
            echo $"Public certificate for ${CHECK_HOSTNAME} was not created"
Bob Mottram's avatar
Bob Mottram committed
            exit 5328
        fi
Bob Mottram's avatar
Bob Mottram committed
        if grep -q "${1}.crt" "/etc/nginx/sites-available/${1}"; then
            sed -i "s|${1}.crt|${1}.pem|g" "/etc/nginx/sites-available/${1}"
Bob Mottram's avatar
Bob Mottram committed
    fi
Bob Mottram's avatar
Bob Mottram committed
    if [ ! -f "/etc/ssl/certs/${1}.dhparam" ]; then
Bob Mottram's avatar
Bob Mottram committed
        echo $"DiffieHellman parameters for ${CHECK_HOSTNAME} were not created"
Bob Mottram's avatar
Bob Mottram committed
        exit 5989
    fi
Bob Mottram's avatar
Bob Mottram committed
function cert_exists {
    cert_type='dhparam'
Bob Mottram's avatar
Bob Mottram committed
    if [ "$2" ]; then
Bob Mottram's avatar
Bob Mottram committed
        cert_type="$2"
    fi
Bob Mottram's avatar
Bob Mottram committed
    if [ -f "/etc/ssl/certs/${1}.${cert_type}" ]; then
Bob Mottram's avatar
Bob Mottram committed
        echo "1"
    else
Bob Mottram's avatar
Bob Mottram committed
        if [ -f "/etc/letsencrypt/live/${1}/fullchain.${cert_type}" ]; then
            echo "1"
        else
            echo "0"
        fi
Bob Mottram's avatar
Bob Mottram committed
    fi
}

function create_self_signed_cert {
    if [ ! "${SITE_DOMAIN_NAME}" ]; then
        echo $'No site domain specified for self signed cert'
        exit 4638565385
    fi
Bob Mottram's avatar
Bob Mottram committed
    "${PROJECT_NAME}-addcert" -h "${SITE_DOMAIN_NAME}" --dhkey "${DH_KEYLENGTH}"
Bob Mottram's avatar
Bob Mottram committed
    function_check check_certificates
Bob Mottram's avatar
Bob Mottram committed
    check_certificates "${SITE_DOMAIN_NAME}"
Bob Mottram's avatar
Bob Mottram committed
}

function create_letsencrypt_cert {
    if [ ! "${SITE_DOMAIN_NAME}" ]; then
        echo $'No site domain specified for letsencrypt cert'
        exit 246824624
    fi

Bob Mottram's avatar
Bob Mottram committed
    if ! "${PROJECT_NAME}-addcert" -e "${SITE_DOMAIN_NAME}" -s "${LETSENCRYPT_SERVER}" --dhkey "${DH_KEYLENGTH}" --email "${MY_EMAIL_ADDRESS}"; then
Bob Mottram's avatar
Bob Mottram committed
        if [[ ${NO_SELF_SIGNED} == 'no' ]]; then
            echo $"Lets Encrypt failed for ${SITE_DOMAIN_NAME}, so try making a self-signed cert"
Bob Mottram's avatar
Bob Mottram committed
            "${PROJECT_NAME}-addcert" -h "${SITE_DOMAIN_NAME}" --dhkey "${DH_KEYLENGTH}"
Bob Mottram's avatar
Bob Mottram committed
            function_check check_certificates
            CHECK_HOSTNAME="${SITE_DOMAIN_NAME}"
Bob Mottram's avatar
Bob Mottram committed
            check_certificates "${SITE_DOMAIN_NAME}"
Bob Mottram's avatar
Bob Mottram committed
        else
            echo $"Lets Encrypt failed for $SITE_DOMAIN_NAME"
Bob Mottram's avatar
Bob Mottram committed
            if [ -f "/etc/nginx/sites-available/$SITE_DOMAIN_NAME" ]; then
                nginx_dissite "$SITE_DOMAIN_NAME"
                systemctl restart nginx
            fi
Bob Mottram's avatar
Bob Mottram committed
            exit 682529
        fi
        return
    fi

    function_check check_certificates
    CHECK_HOSTNAME="${SITE_DOMAIN_NAME}"
Bob Mottram's avatar
Bob Mottram committed
    check_certificates "${SITE_DOMAIN_NAME}" 'yes'
Bob Mottram's avatar
Bob Mottram committed
function create_site_certificate {
Bob Mottram's avatar
Bob Mottram committed
    SITE_DOMAIN_NAME="$1"

    # if yes then only "valid" certs are allowed, not self-signed
    NO_SELF_SIGNED='no'
Bob Mottram's avatar
Bob Mottram committed
    if [ "$2" ]; then
Bob Mottram's avatar
Bob Mottram committed
        NO_SELF_SIGNED="$2"
    fi

    if [[ $ONION_ONLY == "no" ]]; then
Bob Mottram's avatar
Bob Mottram committed
        if [[ "$(cert_exists "${SITE_DOMAIN_NAME}")" == "0" ]]; then
Bob Mottram's avatar
Bob Mottram committed
            if [[ $LETSENCRYPT_ENABLED != "yes" ]]; then
Bob Mottram's avatar
Bob Mottram committed
                create_self_signed_cert
Bob Mottram's avatar
Bob Mottram committed
            else
Bob Mottram's avatar
Bob Mottram committed
                create_letsencrypt_cert
            fi
        else
            if [[ $LETSENCRYPT_ENABLED == "yes" ]]; then
Bob Mottram's avatar
Bob Mottram committed
                if [[ "$(cert_exists "${SITE_DOMAIN_NAME}" pem)" == "0" ]]; then
Bob Mottram's avatar
Bob Mottram committed
                    create_letsencrypt_cert
Bob Mottram's avatar
Bob Mottram committed
}

# script to automatically renew any Let's Encrypt certificates
function letsencrypt_renewals {
Bob Mottram's avatar
Bob Mottram committed
    if [[ $ONION_ONLY != "no" ]]; then
        return
    fi

    renewals_script=/tmp/renewals_letsencrypt
    renewals_retry_script=/tmp/renewals_retry_letsencrypt
Bob Mottram's avatar
Bob Mottram committed
    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
Bob Mottram's avatar
Bob Mottram committed
    { 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

Bob Mottram's avatar
Bob Mottram committed
    # a secondary script keeps trying to renew after a failure
Bob Mottram's avatar
Bob Mottram committed
    { 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
Bob Mottram's avatar
Bob Mottram committed
}

function configure_php {
    sed -i "s/memory_limit =.*/memory_limit = ${MAX_PHP_MEMORY}M/g" /etc/php/7.0/fpm/php.ini
Bob Mottram's avatar
Bob Mottram committed
    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
Bob Mottram's avatar
Bob Mottram committed
}

function install_web_server_access_control {
Bob Mottram's avatar
Bob Mottram committed
    if [ ! -f /etc/pam.d/nginx ]; then
Bob Mottram's avatar
Bob Mottram committed
        { echo '#%PAM-1.0';
          echo '@include common-auth';
          echo '@include common-account';
          echo '@include common-session'; } > /etc/pam.d/nginx
Bob Mottram's avatar
Bob Mottram committed
    fi
function upgrade_inadyn_config {
    if [ ! -f "${INADYN_CONFIG_FILE}" ]; then
        return
    fi

Bob Mottram's avatar
Bob Mottram committed
    if [ ! -f /usr/sbin/inadyn ]; 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}"
}

Bob Mottram's avatar
Bob Mottram committed
function install_dynamicdns {
Bob Mottram's avatar
Bob Mottram committed
    if [[ $SYSTEM_TYPE == "mesh"* ]]; then
Bob Mottram's avatar
Bob Mottram committed
        return
    fi
Bob Mottram's avatar
Bob Mottram committed

Bob Mottram's avatar
Bob Mottram committed
    if [[ $ONION_ONLY != "no" ]]; then
        return
    fi

    if grep -q "INADYN_REPO" "$CONFIGURATION_FILE"; then
        sed -i '/INADYN_REPO/d' "$CONFIGURATION_FILE"
    fi
Bob Mottram's avatar
Bob Mottram committed
    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
Bob Mottram's avatar
Bob Mottram committed
            sed -i '/inadyn commit/d' "$COMPLETION_FILE"
Bob Mottram's avatar
Bob Mottram committed
    else
        CURR_INADYN_COMMIT=$(get_completion_param "inadyn commit")
        if [[ "${CURR_INADYN_COMMIT}" == "${INADYN_COMMIT}" ]]; then
            return
        fi
Bob Mottram's avatar
Bob Mottram committed
    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"
Bob Mottram's avatar
Bob Mottram committed
    # 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

Bob Mottram's avatar
Bob Mottram committed
    apt-get -yq install build-essential curl libgnutls28-dev automake1.11
    apt-get -yq install gnutls-dev libconfuse-dev pkg-config libtool
Bob Mottram's avatar
Bob Mottram committed
    if [ ! -d "$INSTALL_DIR/inadyn" ]; then
Bob Mottram's avatar
Bob Mottram committed
        if [ -d /repos/inadyn ]; then
Bob Mottram's avatar
Bob Mottram committed
            mkdir "$INSTALL_DIR/inadyn"
            cp -r -p /repos/inadyn/. "$INSTALL_DIR/inadyn"
            cd "$INSTALL_DIR/inadyn" || exit 2462874684
Bob Mottram's avatar
Bob Mottram committed
            git pull
        else
Bob Mottram's avatar
Bob Mottram committed
            git_clone "$INADYN_REPO" "$INSTALL_DIR/inadyn"
Bob Mottram's avatar
Bob Mottram committed
        fi
Bob Mottram's avatar
Bob Mottram committed
    fi
Bob Mottram's avatar
Bob Mottram committed
    if [ ! -d "$INSTALL_DIR/inadyn" ]; then
Bob Mottram's avatar
Bob Mottram committed
        echo 'inadyn repo not cloned'
        echo -n | openssl s_client -showcerts -connect github.com:443 -CApath /etc/ssl/certs
        exit 6785
    fi
Bob Mottram's avatar
Bob Mottram committed
    cd "$INSTALL_DIR/inadyn" || exit 246824684
    git checkout "$INADYN_COMMIT" -b "$INADYN_COMMIT"
Bob Mottram's avatar
Bob Mottram committed
    set_completion_param "inadyn commit" "$INADYN_COMMIT"
    if ! ./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var; then
Bob Mottram's avatar
Bob Mottram committed
        exit 74890
    fi
    if ! make -j5; then
Bob Mottram's avatar
Bob Mottram committed
        exit 74858
    fi
    if ! make install-strip; then
Bob Mottram's avatar
Bob Mottram committed
        exit 3785
    fi

    # create a configuration file
    if [ ! -f "${INADYN_CONFIG_FILE}" ]; then
        { echo 'period          = 300';
          echo ''; } > "${INADYN_CONFIG_FILE}"
    fi
    chmod 600 "${INADYN_CONFIG_FILE}"
Bob Mottram's avatar
Bob Mottram committed
    { echo '[Unit]';
Bob Mottram's avatar
Bob Mottram committed
      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';
Bob Mottram's avatar
Bob Mottram committed
      echo '';
      echo '[Service]';
Bob Mottram's avatar
Bob Mottram committed
      echo 'Type=simple';
      echo "ExecStart=/usr/sbin/inadyn -C -n -s --loglevel=err --config ${INADYN_CONFIG_FILE}";
      echo 'Restart=on-failure';
      echo 'RestartSec=10';
Bob Mottram's avatar
Bob Mottram committed
      echo '';
      echo '[Install]';
      echo 'WantedBy=multi-user.target'; } > /etc/systemd/system/inadyn.service
Bob Mottram's avatar
Bob Mottram committed
    systemctl daemon-reload
    systemctl enable inadyn
    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
Bob Mottram's avatar
Bob Mottram committed
            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"
Bob Mottram's avatar
Bob Mottram committed
                        sed -i "s|export WWW_HOME=.*|export WWW_HOME=$DEFAULT_SEARCH|g" "/home/$USERNAME/.bashrc"
Bob Mottram's avatar
Bob Mottram committed
                    if ! grep -q 'export WWW_HOME=' "/home/$USERNAME/.bashrc"; then
                        sed -i "/controluser/i export WWW_HOME=$DEFAULT_SEARCH" "/home/$USERNAME/.bashrc"
Bob Mottram's avatar
Bob Mottram committed
                        sed -i "s|export WWW_HOME=.*|export WWW_HOME=$DEFAULT_SEARCH|g" "/home/$USERNAME/.bashrc"
function install_command_line_browser {
Bob Mottram's avatar
Bob Mottram committed
    if [[ $(is_completed "${FUNCNAME[0]}") == "1" ]]; then
Bob Mottram's avatar
Bob Mottram committed
        return
    fi
Bob Mottram's avatar
Bob Mottram committed
    apt-get -yq install elinks
    update_default_search_engine
Bob Mottram's avatar
Bob Mottram committed
    mark_completed "${FUNCNAME[0]}"
}

function mesh_web_server {
Bob Mottram's avatar
Bob Mottram committed
    if [ -d /etc/apache2 ]; then
Bob Mottram's avatar
Bob Mottram committed
        # shellcheck disable=SC2154
Bob Mottram's avatar
Bob Mottram committed
        chroot "$rootdir" apt-get -yq remove --purge apache2
Bob Mottram's avatar
Bob Mottram committed
        chroot "$rootdir" rm -rf /etc/apache2
    fi
Bob Mottram's avatar
Bob Mottram committed
    chroot "$rootdir" apt-get -yq install nginx
Bob Mottram's avatar
Bob Mottram committed
    if [ ! -d "$rootdir/etc/nginx" ]; then
Bob Mottram's avatar
Bob Mottram committed
        echo $'Unable to install web server'
        exit 346825
    fi
Bob Mottram's avatar
Bob Mottram committed
function install_web_server {
Bob Mottram's avatar
Bob Mottram committed
    if [ "$INSTALLING_MESH" ]; then
Bob Mottram's avatar
Bob Mottram committed
        mesh_web_server
        return
    fi

    # update to the next commit
    function_check set_repo_commit
Bob Mottram's avatar
Bob Mottram committed
    set_repo_commit "$INSTALL_DIR/nginx_ensite" "nginx-ensite commit" "$NGINX_ENSITE_COMMIT" $NGINX_ENSITE_REPO
Bob Mottram's avatar
Bob Mottram committed
    if [[ $(is_completed "${FUNCNAME[0]}") == "1" ]]; then
Bob Mottram's avatar
Bob Mottram committed
        return
    fi
    # remove apache
Bob Mottram's avatar
Bob Mottram committed
    apt-get -yq remove --purge apache2
Bob Mottram's avatar
Bob Mottram committed
    if [ -d /etc/apache2 ]; then
        rm -rf /etc/apache2
    fi
    # install nginx
Bob Mottram's avatar
Bob Mottram committed
    apt-get -yq install nginx
Bob Mottram's avatar
Bob Mottram committed
    apt-get -yq install php-fpm git
    # 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

Bob Mottram's avatar
Bob Mottram committed
    # limit the number of php processes
Bob Mottram's avatar
Bob Mottram committed
    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
Bob Mottram's avatar
Bob Mottram committed
    sed -i 's|;systemd_interval.*|systemd_interval = 10|g' /etc/php/7.0/fpm/php-fpm.conf
Bob Mottram's avatar
Bob Mottram committed
    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
Bob Mottram's avatar
Bob Mottram committed

    if ! grep -q "pm.max_children" /etc/php/7.0/fpm/php-fpm.conf; then
Bob Mottram's avatar
Bob Mottram committed
        { 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
Bob Mottram's avatar
Bob Mottram committed
    fi
Bob Mottram's avatar
Bob Mottram committed
    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
Bob Mottram's avatar
Bob Mottram committed

    if [ ! -d /etc/nginx ]; then
        echo $"ERROR: nginx does not appear to have installed. $CHECK_MESSAGE"
        exit 51
    fi

    # Nginx settings
Bob Mottram's avatar
Bob Mottram committed
    { 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
Bob Mottram's avatar
Bob Mottram committed

    # install a script to easily enable and disable nginx virtual hosts
Bob Mottram's avatar
Bob Mottram committed
    if [ ! -d "$INSTALL_DIR" ]; then
        mkdir "$INSTALL_DIR"
Bob Mottram's avatar
Bob Mottram committed
    fi
Bob Mottram's avatar
Bob Mottram committed
    cd "$INSTALL_DIR" || exit 2798462846827
Bob Mottram's avatar
Bob Mottram committed
    function_check git_clone
Bob Mottram's avatar
Bob Mottram committed
    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"
Bob Mottram's avatar
Bob Mottram committed

    set_completion_param "nginx-ensite commit" "$NGINX_ENSITE_COMMIT"
Bob Mottram's avatar
Bob Mottram committed

    make install
    nginx_dissite default

    function_check configure_firewall_for_web_access
    configure_firewall_for_web_access

Bob Mottram's avatar
Bob Mottram committed
    mark_completed "${FUNCNAME[0]}"
function remove_certs {
    domain_name=$1

Bob Mottram's avatar
Bob Mottram committed
    if [ ! "$domain_name" ]; then
Bob Mottram's avatar
Bob Mottram committed
    if [ -f "/etc/ssl/certs/${domain_name}.dhparam" ]; then
        rm "/etc/ssl/certs/${domain_name}.dhparam"
Bob Mottram's avatar
Bob Mottram committed
    if [ -f "/etc/ssl/certs/${domain_name}.pem" ]; then
        rm "/etc/ssl/certs/${domain_name}.pem"
Bob Mottram's avatar
Bob Mottram committed
    if [ -f "/etc/ssl/certs/${domain_name}.crt" ]; then
        rm "/etc/ssl/certs/${domain_name}.crt"
Bob Mottram's avatar
Bob Mottram committed
    if [ -f "/etc/ssl/private/${domain_name}.key" ]; then
        rm "/etc/ssl/private/${domain_name}.key"
function configure_firewall_for_web_access {
Bob Mottram's avatar
Bob Mottram committed
    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
Bob Mottram's avatar
Bob Mottram committed
    mark_completed "${FUNCNAME[0]}"
function update_default_domain {
Bob Mottram's avatar
Bob Mottram committed
    echo $'Updating default domain'
    if [[ $ONION_ONLY == 'no' ]]; then
        if [ -f /etc/mumble-server.ini ]; then
Bob Mottram's avatar
Bob Mottram committed
            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
            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
Bob Mottram's avatar
Bob Mottram committed
            if [ -f "/etc/letsencrypt/live/${DEFAULT_DOMAIN_NAME}/fullchain.pem" ]; then
                usermod -a -G ssl-cert prosody
                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
Bob Mottram's avatar
Bob Mottram committed
                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
Bob Mottram's avatar
Bob Mottram committed
                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
Bob Mottram's avatar
Bob Mottram committed
                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
Bob Mottram's avatar
Bob Mottram committed
                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
            chown -R prosody:default /etc/prosody
            chmod -R 700 /etc/prosody/certs/*
            chmod 600 /etc/prosody/prosody.cfg.lua
Bob Mottram's avatar
Bob Mottram committed
            if [ -d "$INSTALL_DIR/prosody-modules" ]; then
Bob Mottram's avatar
Bob Mottram committed
                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
            systemctl reload prosody
Bob Mottram's avatar
Bob Mottram committed

        if [ -d /home/znc/.znc ]; then
            echo $'znc found'
Bob Mottram's avatar
Bob Mottram committed
            if [ -f "/etc/letsencrypt/live/${DEFAULT_DOMAIN_NAME}/fullchain.pem" ]; then
Bob Mottram's avatar
Bob Mottram committed
                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
Bob Mottram's avatar
Bob Mottram committed
        fi
Bob Mottram's avatar
Bob Mottram committed

        if [ ${#DEFAULT_DOMAIN_NAME} -gt 0 ]; then
Bob Mottram's avatar
Bob Mottram committed
            if [ -f "/etc/letsencrypt/live/${DEFAULT_DOMAIN_NAME}/fullchain.pem" ]; 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
Bob Mottram's avatar
Bob Mottram committed
                    cp "/etc/letsencrypt/live/${DEFAULT_DOMAIN_NAME}/{fullchain,privkey}.pem" /etc/exim4/
                    chown root:Debian-exim /etc/exim4/*.pem
                    chmod 640 /etc/exim4/*.pem

Bob Mottram's avatar
Bob Mottram committed
                    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
Bob Mottram's avatar
Bob Mottram committed
        fi
    fi
Bob Mottram's avatar
Bob Mottram committed
function create_default_web_site {
Bob Mottram's avatar
Bob Mottram committed
    if [ ! -f "/etc/nginx/sites-available/${DEFAULT_DOMAIN_NAME}" ]; then
Bob Mottram's avatar
Bob Mottram committed
        # create a web site for the default domain
Bob Mottram's avatar
Bob Mottram committed
        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"
Bob Mottram's avatar
Bob Mottram committed
            else
Bob Mottram's avatar
Bob Mottram committed
                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"
Bob Mottram's avatar
Bob Mottram committed
                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
Bob Mottram's avatar
Bob Mottram committed
            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"
Bob Mottram's avatar
Bob Mottram committed
            function_check nginx_ssl
Bob Mottram's avatar
Bob Mottram committed
            nginx_ssl "$DEFAULT_DOMAIN_NAME" mobile
Bob Mottram's avatar
Bob Mottram committed

Bob Mottram's avatar
Bob Mottram committed
            function_check nginx_security_options
            nginx_security_options "$DEFAULT_DOMAIN_NAME"
Bob Mottram's avatar
Bob Mottram committed

            { 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"
Bob Mottram's avatar
Bob Mottram committed
            function_check nginx_limits
Bob Mottram's avatar
Bob Mottram committed
            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"
Bob Mottram's avatar
Bob Mottram committed
        else