| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080 | 
							- #!/bin/bash
 - #
 - # .---.                  .              .
 - # |                      |              |
 - # |--- .--. .-.  .-.  .-.|  .-. .--.--. |.-.  .-. .--.  .-.
 - # |    |   (.-' (.-' (   | (   )|  |  | |   )(   )|  | (.-'
 - # '    '     --'  --'  -' -  -' '  '   -' -'   -' '   -  --'
 - #
 - #                    Freedom in the Cloud
 - #
 - # Web related functions
 - #
 - # License
 - # =======
 - #
 - # Copyright (C) 2014-2018 Bob Mottram <bob@freedombone.net>
 - #
 - # 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
 - 
 - # Whether Let's Encrypt is enabled for all sites
 - LETSENCRYPT_ENABLED="yes"
 - 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}
 -     if (( no_of_dots > 3 )); then
 -         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
 -     if (( no_of_dots == 0 )); then
 -         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
 - }
 - 
 - function nginx_disable_sniffing {
 -     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 ''; } >> "$filename"
 - }
 - 
 - function nginx_limits {
 -     domain_name=$1
 -     max_body='20m'
 -     if [ "$2" ]; then
 -         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 '';
 -       echo '    limit_conn conn_limit_per_ip 10;';
 -       echo '    limit_req zone=req_limit_per_ip burst=10 nodelay;';
 -       echo ''; } >> "$filename"
 - }
 - 
 - function nginx_stapling {
 -     domain_name="$1"
 -     filename=/etc/nginx/sites-available/$domain_name
 -     { echo "    ssl_stapling on;";
 -       echo '    ssl_stapling_verify on;';
 -       echo "    ssl_trusted_certificate /etc/ssl/certs/${domain_name}.pem;";
 -       echo ''; } >> "$filename"
 - }
 - 
 - function nginx_http_redirect {
 -     # 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"
 -     function_check nginx_limits
 -     nginx_limits "$domain_name"
 -     if [ ${#2} -gt 0 ]; then
 -         echo "    $2;" >> "$filename"
 -     fi
 -     { 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"
 - }
 - 
 - function nginx_ssl {
 -     # creates the SSL/TLS section for a website
 -     domain_name=$1
 -     mobile_ciphers=$2
 -     filename=/etc/nginx/sites-available/$domain_name
 - 
 -     { 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"
 -     else
 -         echo "    ssl_ciphers '$SSL_CIPHERS';" >> "$filename"
 -     fi
 -     { echo "    add_header Content-Security-Policy \"default-src https:; script-src https: 'unsafe-inline'; style-src https: 'unsafe-inline'\";";
 -       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;'; } >> "$filename"
 - 
 -     #nginx_stapling $1
 - }
 - 
 - # check an individual domain name
 - function test_domain_name {
 -     if [ "$1" ]; then
 -         TEST_DOMAIN_NAME=$1
 -         if [[ $TEST_DOMAIN_NAME != 'ttrss' ]]; then
 -             function_check validate_domain_name
 -             validate_domain_name
 -             if [[ "$TEST_DOMAIN_NAME" != "$1" ]]; then
 -                 echo $"Invalid domain name $TEST_DOMAIN_NAME"
 -                 exit 8528
 -             fi
 -         fi
 -     fi
 - }
 - 
 - # Checks whether certificates were generated for the given hostname
 - function check_certificates {
 -     if [ ! "$1" ]; then
 -         return
 -     fi
 -     USE_LETSENCRYPT='no'
 -     if [ "$2" ]; then
 -         USE_LETSENCRYPT="$2"
 -     fi
 -     if [[ $USE_LETSENCRYPT == 'no' ]]; then
 -         if [ ! -f "/etc/ssl/private/${1}.key" ]; then
 -             echo $"Private certificate for ${CHECK_HOSTNAME} was not created"
 -             exit 63959
 -         fi
 -         if [ ! -f "/etc/ssl/certs/${1}.crt" ]; then
 -             echo $"Public certificate for ${CHECK_HOSTNAME} was not created"
 -             exit 7679
 -         fi
 - 
 -         if grep -q "${1}.pem" "/etc/nginx/sites-available/${1}"; then
 -             sed -i "s|${1}.pem|${1}.crt|g" "/etc/nginx/sites-available/${1}"
 -         fi
 -     else
 -         if [ ! -f "/etc/letsencrypt/live/${1}/privkey.pem" ]; then
 -             echo $"Private certificate for ${CHECK_HOSTNAME} was not created"
 -             exit 6282
 -         fi
 -         if [ ! -f "/etc/letsencrypt/live/${1}/fullchain.pem" ]; then
 -             echo $"Public certificate for ${CHECK_HOSTNAME} was not created"
 -             exit 5328
 -         fi
 -         if grep -q "${1}.crt" "/etc/nginx/sites-available/${1}"; then
 -             sed -i "s|${1}.crt|${1}.pem|g" "/etc/nginx/sites-available/${1}"
 -         fi
 -     fi
 -     if [ ! -f "/etc/ssl/certs/${1}.dhparam" ]; then
 -         echo $"Diffie–Hellman parameters for ${CHECK_HOSTNAME} were not created"
 -         exit 5989
 -     fi
 - }
 - 
 - function cert_exists {
 -     cert_type='dhparam'
 -     if [ "$2" ]; then
 -         cert_type="$2"
 -     fi
 -     if [ -f "/etc/ssl/certs/${1}.${cert_type}" ]; then
 -         echo "1"
 -     else
 -         if [ -f "/etc/letsencrypt/live/${1}/fullchain.${cert_type}" ]; then
 -             echo "1"
 -         else
 -             echo "0"
 -         fi
 -     fi
 - }
 - 
 - function create_self_signed_cert {
 -     "${PROJECT_NAME}-addcert" -h "${SITE_DOMAIN_NAME}" --dhkey "${DH_KEYLENGTH}"
 -     function_check check_certificates
 -     check_certificates "${SITE_DOMAIN_NAME}"
 - }
 - 
 - function create_letsencrypt_cert {
 -     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}"
 -             function_check check_certificates
 -             check_certificates "${SITE_DOMAIN_NAME}"
 -         else
 -             echo $"Lets Encrypt failed for $SITE_DOMAIN_NAME"
 -             if [ -f "/etc/nginx/sites-available/$SITE_DOMAIN_NAME" ]; then
 -                 nginx_dissite "$SITE_DOMAIN_NAME"
 -                 systemctl restart nginx
 -             fi
 -             exit 682529
 -         fi
 -         return
 -     fi
 - 
 -     function_check check_certificates
 -     check_certificates "${SITE_DOMAIN_NAME}" 'yes'
 - }
 - 
 - function create_site_certificate {
 -     SITE_DOMAIN_NAME="$1"
 - 
 -     # if yes then only "valid" certs are allowed, not self-signed
 -     NO_SELF_SIGNED='no'
 -     if [ "$2" ]; then
 -         NO_SELF_SIGNED="$2"
 -     fi
 - 
 -     if [[ $ONION_ONLY == "no" ]]; then
 -         if [[ "$(cert_exists "${SITE_DOMAIN_NAME}")" == "0" ]]; then
 -             if [[ $LETSENCRYPT_ENABLED != "yes" ]]; then
 -                 create_self_signed_cert
 -             else
 -                 create_letsencrypt_cert
 -             fi
 -         else
 -             if [[ $LETSENCRYPT_ENABLED == "yes" ]]; then
 -                 if [[ "$(cert_exists "${SITE_DOMAIN_NAME}" pem)" == "0" ]]; then
 -                     create_letsencrypt_cert
 -                 fi
 -             fi
 -         fi
 -     fi
 - }
 - 
 - # 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
 -     { 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
 -     { 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
 - }
 - 
 - function configure_php {
 -     sed -i "s/memory_limit = 128M/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 = -1/memory_limit = ${MAX_PHP_MEMORY}M/g" /etc/php/7.0/cli/php.ini
 -     sed -i "s/upload_max_filesize = 2M/upload_max_filesize = 50M/g" /etc/php/7.0/fpm/php.ini
 -     sed -i "s/post_max_size = 8M/post_max_size = 50M/g" /etc/php/7.0/fpm/php.ini
 - }
 - 
 - function install_web_server_access_control {
 -     if [ ! -f /etc/pam.d/nginx ]; then
 -         { echo '#%PAM-1.0';
 -           echo '@include common-auth';
 -           echo '@include common-account';
 -           echo '@include common-session'; } > /etc/pam.d/nginx
 -     fi
 - }
 - 
 - function install_dynamicdns {
 -     if [[ $SYSTEM_TYPE == "mesh"* ]]; then
 -         return
 -     fi
 -     if [[ $ONION_ONLY != "no" ]]; then
 -         return
 -     fi
 - 
 -     CURR_INADYN_COMMIT=$(get_completion_param "inadyn commit")
 -     if [[ "${CURR_INADYN_COMMIT}" == "${INADYN_COMMIT}" ]]; then
 -         return
 -     fi
 - 
 -     # update to the next commit
 -     function_check set_repo_commit
 -     set_repo_commit "$INSTALL_DIR/inadyn" "inadyn commit" "$INADYN_COMMIT" "$INADYN_REPO"
 - 
 -     if [[ $(is_completed "${FUNCNAME[0]}") == "1" ]]; then
 -         return
 -     fi
 - 
 -     # 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
 -     if [ ! -d "$INSTALL_DIR/inadyn" ]; then
 -         if [ -d /repos/inadyn ]; then
 -             mkdir "$INSTALL_DIR/inadyn"
 -             cp -r -p /repos/inadyn/. "$INSTALL_DIR/inadyn"
 -             cd "$INSTALL_DIR/inadyn" || exit 2462874684
 -             git pull
 -         else
 -             git_clone "$INADYN_REPO" "$INSTALL_DIR/inadyn"
 -         fi
 -     fi
 -     if [ ! -d "$INSTALL_DIR/inadyn" ]; then
 -         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"
 -     set_completion_param "inadyn commit" "$INADYN_COMMIT"
 - 
 -     #./autogen.sh
 -     if ! ./configure; then
 -         exit 74890
 -     fi
 -     if ! USE_OPENSSL=1 make; then
 -         exit 74858
 -     fi
 -     if ! make install; then
 -         exit 3785
 -     fi
 - 
 -     # create an unprivileged user
 -     #chmod 600 /etc/shadow
 -     #chmod 600 /etc/gshadow
 -     #useradd -r -s /bin/false debian-inadyn
 -     #chmod 0000 /etc/shadow
 -     #chmod 0000 /etc/gshadow
 - 
 -     # create a configuration file
 -     { echo 'background';
 -       echo 'verbose        1';
 -       echo 'period         300';
 -       echo 'startup-delay  60';
 -       echo 'cache-dir      /run/inadyn';
 -       echo 'logfile        /dev/null'; } > /etc/inadyn.conf
 -     chmod 600 /etc/inadyn.conf
 - 
 -     { echo '[Unit]';
 -       echo 'Description=inadyn (DynDNS updater)';
 -       echo 'After=network.target';
 -       echo '';
 -       echo '[Service]';
 -       echo 'ExecStart=/usr/local/sbin/inadyn --config /etc/inadyn.conf';
 -       echo 'Restart=always';
 -       echo 'Type=forking';
 -       echo '';
 -       echo '[Install]';
 -       echo 'WantedBy=multi-user.target'; } > /etc/systemd/system/inadyn.service
 -     systemctl enable inadyn
 -     systemctl start inadyn
 -     systemctl daemon-reload
 - 
 -     mark_completed "${FUNCNAME[0]}"
 - }
 - 
 - 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"
 -                     else
 -                         sed -i "s|export WWW_HOME=.*|export WWW_HOME=$DEFAULT_SEARCH|g" "/home/$USERNAME/.bashrc"
 -                     fi
 -                 else
 -                     if ! grep -q 'export WWW_HOME=' "/home/$USERNAME/.bashrc"; then
 -                         sed -i "/controluser/i export WWW_HOME=$DEFAULT_SEARCH" "/home/$USERNAME/.bashrc"
 -                     else
 -                         sed -i "s|export WWW_HOME=.*|export WWW_HOME=$DEFAULT_SEARCH|g" "/home/$USERNAME/.bashrc"
 -                     fi
 -                 fi
 -             fi
 -         fi
 -     done
 - }
 - 
 - function install_command_line_browser {
 -     if [[ $(is_completed "${FUNCNAME[0]}") == "1" ]]; then
 -         return
 -     fi
 -     apt-get -yq install elinks
 -     update_default_search_engine
 - 
 -     mark_completed "${FUNCNAME[0]}"
 - }
 - 
 - function mesh_web_server {
 -     if [ -d /etc/apache2 ]; then
 -         # shellcheck disable=SC2154
 -         chroot "$rootdir" apt-get -yq remove --purge apache2
 -         chroot "$rootdir" rm -rf /etc/apache2
 -     fi
 - 
 -     chroot "$rootdir" apt-get -yq install nginx
 - 
 -     if [ ! -d "$rootdir/etc/nginx" ]; then
 -         echo $'Unable to install web server'
 -         exit 346825
 -     fi
 - }
 - 
 - function install_web_server {
 -     if [ "$INSTALLING_MESH" ]; then
 -         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
 -         return
 -     fi
 -     # remove apache
 -     apt-get -yq remove --purge apache2
 -     if [ -d /etc/apache2 ]; then
 -         rm -rf /etc/apache2
 -     fi
 -     # install nginx
 -     apt-get -yq install nginx
 -     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
 - 
 -     # limit the number of php processes
 -     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
 -     fi
 -     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
 -     { 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
 -     if [ ! -d "$INSTALL_DIR" ]; then
 -         mkdir "$INSTALL_DIR"
 -     fi
 -     cd "$INSTALL_DIR" || exit 2798462846827
 -     function_check git_clone
 -     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
 - 
 -     mark_completed "${FUNCNAME[0]}"
 - }
 - 
 - function remove_certs {
 -     domain_name=$1
 - 
 -     if [ ! "$domain_name" ]; then
 -         return
 -     fi
 - 
 -     if [ -f "/etc/ssl/certs/${domain_name}.dhparam" ]; then
 -         rm "/etc/ssl/certs/${domain_name}.dhparam"
 -     fi
 - 
 -     if [ -f "/etc/ssl/certs/${domain_name}.pem" ]; then
 -         rm "/etc/ssl/certs/${domain_name}.pem"
 -     fi
 - 
 -     if [ -f "/etc/ssl/certs/${domain_name}.crt" ]; then
 -         rm "/etc/ssl/certs/${domain_name}.crt"
 -     fi
 - 
 -     if [ -f "/etc/ssl/private/${domain_name}.key" ]; then
 -         rm "/etc/ssl/private/${domain_name}.key"
 -     fi
 - }
 - 
 - 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
 -     mark_completed "${FUNCNAME[0]}"
 - }
 - 
 - function update_default_domain {
 -     echo $'Updating default domain'
 -     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
 -             fi
 -         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
 -                 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
 -                 fi
 - 
 -                 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
 -                 fi
 - 
 -                 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
 -             fi
 - 
 -             chown -R prosody:default /etc/prosody
 -             chmod -R 700 /etc/prosody/certs/*
 -             chmod 600 /etc/prosody/prosody.cfg.lua
 -             if [ -d "$INSTALL_DIR/prosody-modules" ]; then
 -                 cp -r "$INSTALL_DIR/prosody-modules/*" /var/lib/prosody/prosody-modules/
 -                 cp -r "$INSTALL_DIR/prosody-modules/*" /usr/lib/prosody/modules/
 -             fi
 -             chown -R prosody:prosody /var/lib/prosody/prosody-modules
 -             chown -R prosody:prosody /usr/lib/prosody/modules
 -             systemctl reload prosody
 -         fi
 - 
 -         if [ -d /home/znc/.znc ]; then
 -             echo $'znc found'
 -             if [ -f "/etc/letsencrypt/live/${DEFAULT_DOMAIN_NAME}/fullchain.pem" ]; then
 -                 pkill znc
 -                 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
 -         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
 -                 fi
 -             fi
 -         fi
 -     fi
 - }
 - 
 - function create_default_web_site {
 -     if [ ! -f "/etc/nginx/sites-available/${DEFAULT_DOMAIN_NAME}" ]; then
 -         # create a web site for the default domain
 -         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"
 -             else
 -                 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_ssl
 -             nginx_ssl "$DEFAULT_DOMAIN_NAME" mobile
 - 
 -             function_check nginx_disable_sniffing
 -             nginx_disable_sniffing "$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"
 -             function_check nginx_limits
 -             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"
 -         else
 -             echo -n '' > "$nginx_site"
 -         fi
 -         { echo 'server {';
 -           echo "    listen 127.0.0.1:$DEFAULT_DOMAIN_ONION_PORT default_server;";
 -           echo "    server_name $DEFAULT_DOMAIN_NAME;";
 -           echo ''; } >> "$nginx_site"
 -         function_check nginx_disable_sniffing
 -         nginx_disable_sniffing "$DEFAULT_DOMAIN_NAME"
 -         { 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 '  # Location';
 -           echo '  location / {'; } >> "$nginx_site"
 -         function_check nginx_limits
 -         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"
 - 
 -         if [ ! -f "/etc/ssl/certs/${DEFAULT_DOMAIN_NAME}.pem" ]; then
 -             function_check create_site_certificate
 -             create_site_certificate "$DEFAULT_DOMAIN_NAME" 'yes'
 -         fi
 - 
 -         nginx_ensite "$DEFAULT_DOMAIN_NAME"
 -     fi
 - }
 - 
 - function install_composer {
 -     # curl -sS https://getcomposer.org/installer | php
 -     if [ -f "${HOME}/${PROJECT_NAME}/image_build/composer_install" ]; then
 -         php < "${HOME}/${PROJECT_NAME}/image_build/composer_install"
 -     else
 -         if [ -f "/home/$MY_USERNAME/${PROJECT_NAME}/image_build/composer_install" ]; then
 -             php < "/home/$MY_USERNAME/${PROJECT_NAME}/image_build/composer_install"
 -         fi
 -     fi
 -     if [ -f composer.phar ]; then
 -         cp composer.phar composer
 -     fi
 -     if ! php composer.phar install; then
 -         echo $'Unable to run composer install'
 -         exit 7252198
 -     fi
 - }
 - 
 - function email_disable_chunking {
 -     if [ -f /etc/exim4/conf.d/main/04_exim4-config_chunking ]; then
 -         return
 -     fi
 -     echo "chunking_advertise_hosts =" > /etc/exim4/conf.d/main/04_exim4-config_chunking
 -     update-exim4.conf
 -     dpkg-reconfigure --frontend noninteractive exim4-config
 -     systemctl restart exim4
 - }
 - 
 - function email_install_tls {
 -     tls_config_file=/etc/exim4/conf.d/main/03_exim4-config_tlsoptions
 -     tls_auth_config_file=/etc/exim4/conf.d/auth/30_exim4-config_examples
 -     email_config_changed=
 - 
 -     if [ ! -f $tls_config_file ]; then
 -         tls_config_file=/etc/exim4/exim4.conf.template
 -         tls_auth_config_file=$tls_config_file
 -     fi
 -     if [ ! -f /etc/ssl/certs/exim.dhparam ]; then
 -         "${PROJECT_NAME}-addcert" -h exim --dhkey "$DH_KEYLENGTH"
 -         check_certificates exim
 -         cp /etc/ssl/certs/exim.dhparam /etc/exim4
 -         chown root:Debian-exim /etc/exim4/exim.dhparam
 -         chmod 640 /etc/exim4/exim.key /etc/exim4/exim.crt /etc/exim4/exim.dhparam
 -         email_config_changed=1
 -     fi
 -     if ! grep -q 'MAIN_TLS_ENABLE = true' $tls_config_file; then
 -         sed -i "/.ifdef MAIN_HARDCODE_PRIMARY_HOSTNAME/i\\MAIN_HARDCODE_PRIMARY_HOSTNAME =\\nMAIN_TLS_ENABLE = true" "$tls_config_file"
 -         email_config_changed=1
 -     fi
 -     if ! grep -q "tls_on_connect_ports=465" $tls_config_file; then
 -         sed -i '/SSL configuration for exim/i\tls_on_connect_ports=465' $tls_config_file
 -         email_config_changed=1
 -     fi
 -     if grep -q '# login_saslauthd_server' $tls_auth_config_file; then
 -         sed -i '/login_saslauthd_server/,/.endif/ s/# *//' $tls_auth_config_file
 -         email_config_changed=1
 -     fi
 -     if [ -f "/etc/ssl/certs/${DEFAULT_DOMAIN_NAME}.pem" ]; then
 -         cp "/etc/letsencrypt/live/${DEFAULT_DOMAIN_NAME}/fullchain.pem" /etc/exim4/
 -         chown root:Debian-exim /etc/exim4/*.pem
 -         chmod 640 /etc/exim4/*.pem
 - 
 -         if ! grep -q "MAIN_TLS_CERTIFICATE = /etc/exim4/fullchain.pem" $tls_config_file; then
 -             sed -i "/.ifdef MAIN_TLS_CERTKEY/i\\MAIN_TLS_CERTIFICATE = /etc/exim4/fullchain.pem" $tls_config_file
 -             email_config_changed=1
 -         fi
 -     fi
 -     if [ -f "/etc/ssl/private/${DEFAULT_DOMAIN_NAME}.key" ]; then
 -         cp "/etc/letsencrypt/live/${DEFAULT_DOMAIN_NAME}/privkey.pem" /etc/exim4/
 -         chown root:Debian-exim /etc/exim4/*.pem
 -         chmod 640 /etc/exim4/*.pem
 - 
 -         if ! grep -q "MAIN_TLS_PRIVATEKEY = /etc/exim4/privkey.pem" $tls_config_file; then
 -             sed -i "/.ifndef MAIN_TLS_PRIVATEKEY/i\\MAIN_TLS_PRIVATEKEY = /etc/exim4/privkey.pem" $tls_config_file
 -             email_config_changed=1
 -         fi
 -     fi
 -     if ! grep -q "SMTPLISTENEROPTIONS='-oX 465:25:587" /etc/default/exim4; then
 -         sed -i "s|SMTPLISTENEROPTIONS=.*|SMTPLISTENEROPTIONS='-oX 465:25:587 -oP /var/run/exim4/exim.pid'|g" /etc/default/exim4
 -         email_config_changed=1
 -     fi
 -     if [ $email_config_changed ]; then
 -         systemctl restart saslauthd
 -         systemctl restart exim4
 -     fi
 - }
 - 
 - function install_web_local_user_interface {
 -     # TODO
 -     # This is intended as a placeholder for a potential local web user interface
 -     # similar to Plinth or the yunohost admin interface
 -     local_hostname=$(grep 'host-name' /etc/avahi/avahi-daemon.conf | awk -F '=' '{print $2}').local
 - 
 -     mkdir -p "/var/www/${local_hostname}/htdocs"
 -     { echo '<html>';
 -       echo '  <body>';
 -       echo "  This is a test on $local_hostname";
 -       echo '  </body>';
 -       echo '</html>'; } > "/var/www/${local_hostname}/htdocs/index.html"
 -     chown -R www-data:www-data "/var/www/${local_hostname}/htdocs"
 - 
 -     nginx_file=/etc/nginx/sites-available/$local_hostname
 -     { echo 'server {';
 -       echo '  listen 80;';
 -       echo '  listen [::]:80;';
 -       echo "  server_name ${local_hostname};";
 -       echo "  root /var/www/${local_hostname}/htdocs;";
 -       echo '  index index.html;';
 -       echo '}'; } > "$nginx_file"
 -     nginx_ensite "$local_hostname"
 - }
 - 
 - # NOTE: deliberately no exit 0
 
 
  |