freedombone/src/freedombone-utils-web

876 lines
36 KiB
Plaintext
Raw Normal View History

2016-07-03 17:13:34 +02:00
#!/bin/bash
#
# .---. . .
# | | |
# |--- .--. .-. .-. .-.| .-. .--.--. |.-. .-. .--. .-.
# | | (.-' (.-' ( | ( )| | | | )( )| | (.-'
# ' ' --' --' -' - -' ' ' -' -' -' ' - --'
#
# Freedom in the Cloud
#
# Web related functions
#
# License
# =======
#
2016-10-31 17:24:49 +01:00
# Copyright (C) 2014-2016 Bob Mottram <bob@freedombone.net>
2016-07-03 17:13:34 +02:00
#
# 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'
2017-01-01 21:40:08 +01:00
# onion port for the default domain
DEFAULT_DOMAIN_ONION_PORT=8099
2016-07-03 17:13:34 +02:00
# Whether Let's Encrypt is enabled for all sites
LETSENCRYPT_ENABLED="no"
LETSENCRYPT_SERVER='https://acme-v01.api.letsencrypt.org/directory'
# list of encryption protocols
SSL_PROTOCOLS="TLSv1 TLSv1.1 TLSv1.2"
# list of ciphers to use. See bettercrypto.org recommendations
SSL_CIPHERS="EDH+CAMELLIA:EDH+aRSA:EECDH+aRSA+AESGCM:EECDH+aRSA+SHA256:EECDH:+CAMELLIA128:+AES128:+SSLv3:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!DSS:!RC4:!SEED:!IDEA:!ECDSA:kEDH:CAMELLIA128-SHA: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 {
2016-08-08 14:49:19 +02:00
# 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
2016-07-03 17:13:34 +02:00
}
function nginx_disable_sniffing {
2016-08-08 14:49:19 +02:00
domain_name=$1
filename=/etc/nginx/sites-available/$domain_name
echo ' add_header X-Frame-Options DENY;' >> $filename
echo ' add_header X-Content-Type-Options nosniff;' >> $filename
echo '' >> $filename
2016-07-03 17:13:34 +02:00
}
function nginx_limits {
2016-08-08 14:49:19 +02:00
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};" >> $filename
echo ' client_body_buffer_size 128k;' >> $filename
echo '' >> $filename
echo ' limit_conn conn_limit_per_ip 10;' >> $filename
echo ' limit_req zone=req_limit_per_ip burst=10 nodelay;' >> $filename
echo '' >> $filename
}
function nginx_stapling {
domain_name=$1
filename=/etc/nginx/sites-available/$domain_name
echo " ssl_stapling on;" >> $filename
echo ' ssl_stapling_verify on;' >> $filename
echo ' ssl_trusted_certificate /etc/ssl/certs/${domain_name}.pem;' >> $filename
echo '' >> $filename
2016-07-03 17:13:34 +02:00
}
function nginx_http_redirect {
2016-08-08 14:49:19 +02:00
# redirect port 80 to https
domain_name=$1
filename=/etc/nginx/sites-available/$domain_name
echo 'server {' > $filename
echo ' listen 80;' >> $filename
echo ' listen [::]:80;' >> $filename
echo " server_name ${domain_name};" >> $filename
echo " root /var/www/${domain_name}/htdocs;" >> $filename
2016-11-10 14:26:31 +01:00
echo ' access_log /dev/null;' >> $filename
2016-11-18 19:33:08 +01:00
echo " error_log /dev/null;" >> $filename
2016-08-08 14:49:19 +02:00
function_check nginx_limits
nginx_limits $domain_name
2017-04-03 21:24:25 +02:00
if [ ${#2} -gt 0 ]; then
echo " $2;" >> $filename
fi
2016-08-08 14:49:19 +02:00
echo ' rewrite ^ https://$server_name$request_uri? permanent;' >> $filename
echo '}' >> $filename
echo '' >> $filename
2016-07-03 17:13:34 +02:00
}
function nginx_ssl {
2016-08-08 14:49:19 +02:00
# creates the SSL/TLS section for a website
domain_name=$1
filename=/etc/nginx/sites-available/$domain_name
2016-10-12 18:56:58 +02:00
echo ' ssl_stapling off;' >> $filename
echo ' ssl_stapling_verify off;' >> $filename
2016-08-08 14:49:19 +02:00
echo ' ssl on;' >> $filename
2017-03-14 23:26:35 +01:00
echo " ssl_certificate /etc/letsencrypt/live/${domain_name}/fullchain.pem;" >> $filename
echo " ssl_certificate_key /etc/letsencrypt/live/${domain_name}/privkey.pem;" >> $filename
2016-08-08 14:49:19 +02:00
echo " ssl_dhparam /etc/ssl/certs/${domain_name}.dhparam;" >> $filename
echo '' >> $filename
2016-10-12 19:06:33 +02:00
echo ' ssl_session_cache builtin:1000 shared:SSL:10m;' >> $filename
2016-08-08 14:49:19 +02:00
echo ' ssl_session_timeout 60m;' >> $filename
echo ' ssl_prefer_server_ciphers on;' >> $filename
echo " ssl_protocols $SSL_PROTOCOLS;" >> $filename
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
2016-10-17 18:57:16 +02:00
#nginx_stapling $1
2016-07-03 17:13:34 +02:00
}
2016-11-11 18:36:30 +01:00
function nginx_keybase {
# creates files suitable for keybase.io verification
domain_name=$1
filename=/etc/nginx/sites-available/$domain_name
2016-11-11 19:18:50 +01:00
echo '' >> $filename
echo " # make sure webfinger and other well known services aren't blocked" >> $filename
echo ' # by denying dot files and rewrite request to the front controller' >> $filename
echo ' location ^~ /.well-known/ {' >> $filename
echo ' allow all;' >> $filename
echo ' }' >> $filename
2016-11-11 18:36:30 +01:00
if [ ! -d /var/www/${domain_name}/htdocs/.well-known ]; then
mkdir -p /var/www/${domain_name}/htdocs/.well-known
fi
if [ ! -f /var/www/${domain_name}/htdocs/keybase.txt ]; then
touch /var/www/${domain_name}/htdocs/keybase.txt
fi
if [ ! -f /var/www/${domain_name}/htdocs/.well-known/keybase.txt ]; then
touch /var/www/${domain_name}/htdocs/.well-known/keybase.txt
fi
}
2016-07-03 17:13:34 +02:00
# check an individual domain name
function test_domain_name {
2016-08-08 14:49:19 +02:00
if [ $1 ]; then
TEST_DOMAIN_NAME=$1
2016-12-21 22:55:50 +01:00
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
2016-08-08 14:49:19 +02:00
fi
fi
2016-07-03 17:13:34 +02:00
}
# Checks whether certificates were generated for the given hostname
function check_certificates {
2016-08-08 14:49:19 +02:00
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"
2016-08-08 14:49:19 +02:00
exit 63959
fi
if [ ! -f /etc/ssl/certs/${1}.crt ]; then
echo $"Public certificate for ${CHECK_HOSTNAME} was not created"
2016-08-08 14:49:19 +02:00
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
2016-08-08 14:49:19 +02:00
else
if [ ! -f /etc/letsencrypt/live/${1}/privkey.pem ]; then
echo $"Private certificate for ${CHECK_HOSTNAME} was not created"
2016-08-08 14:49:19 +02:00
exit 6282
fi
if [ ! -f /etc/letsencrypt/live/${1}/fullchain.pem ]; then
echo $"Public certificate for ${CHECK_HOSTNAME} was not created"
2016-08-08 14:49:19 +02:00
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
2016-08-08 14:49:19 +02:00
fi
if [ ! -f /etc/ssl/certs/${1}.dhparam ]; then
echo $"DiffieHellman parameters for ${CHECK_HOSTNAME} were not created"
2016-08-08 14:49:19 +02:00
exit 5989
fi
2016-07-03 17:13:34 +02:00
}
2016-10-26 17:10:46 +02:00
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
2016-10-30 20:50:02 +01:00
if [ -f /etc/letsencrypt/live/${1}/fullchain.${cert_type} ]; then
echo "1"
else
echo "0"
fi
2016-10-26 17:10:46 +02:00
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 {
${PROJECT_NAME}-addcert -e ${SITE_DOMAIN_NAME} -s ${LETSENCRYPT_SERVER} --dhkey ${DH_KEYLENGTH} --email ${MY_EMAIL_ADDRESS}
if [ ! "$?" = "0" ]; 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"
exit 682529
fi
return
fi
function_check check_certificates
check_certificates ${SITE_DOMAIN_NAME} 'yes'
}
2016-07-03 17:13:34 +02:00
function create_site_certificate {
2016-08-08 14:49:19 +02:00
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
2016-10-30 20:59:40 +01:00
if [[ "$(cert_exists ${SITE_DOMAIN_NAME})" == "0" ]]; then
2016-08-08 14:49:19 +02:00
if [[ $LETSENCRYPT_ENABLED != "yes" ]]; then
2016-10-26 17:10:46 +02:00
create_self_signed_cert
2016-08-08 14:49:19 +02:00
else
2016-10-26 17:10:46 +02:00
create_letsencrypt_cert
fi
else
if [[ $LETSENCRYPT_ENABLED == "yes" ]]; then
2016-10-30 20:59:40 +01:00
if [[ "$(cert_exists ${SITE_DOMAIN_NAME} pem)" == "0" ]]; then
2016-10-26 17:10:46 +02:00
create_letsencrypt_cert
2016-08-08 14:49:19 +02:00
fi
fi
fi
fi
2016-07-03 17:13:34 +02:00
}
# script to automatically renew any Let's Encrypt certificates
function letsencrypt_renewals {
2016-08-08 14:49:19 +02:00
if [[ $ONION_ONLY != "no" ]]; then
return
fi
renewals_script=/etc/cron.monthly/letsencrypt
renewals_retry_script=/etc/cron.daily/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' > $renewals_script
echo '' >> $renewals_script
echo "PROJECT_NAME='${PROJECT_NAME}'" >> $renewals_script
echo 'COMPLETION_FILE=$HOME/${PROJECT_NAME}-completed.txt' >> $renewals_script
echo '' >> $renewals_script
echo 'if [ -d /etc/letsencrypt ]; then' >> $renewals_script
echo ' if [ -f ~/letsencrypt_failed ]; then' >> $renewals_script
echo ' rm ~/letsencrypt_failed' >> $renewals_script
echo ' fi' >> $renewals_script
echo -n ' ADMIN_USERNAME=$(cat $COMPLETION_FILE | grep "Admin user" | ' >> $renewals_script
echo -n "awk -F ':' '{print " >> $renewals_script
echo -n '$2' >> $renewals_script
echo "}')" >> $renewals_script
echo ' ADMIN_EMAIL_ADDRESS=$ADMIN_USERNAME@$HOSTNAME' >> $renewals_script
echo ' for d in /etc/letsencrypt/live/*/ ; do' >> $renewals_script
echo -n ' LETSENCRYPT_DOMAIN=$(echo "$d" | ' >> $renewals_script
echo -n "awk -F '/' '{print " >> $renewals_script
echo -n '$5' >> $renewals_script
echo "}')" >> $renewals_script
echo ' if [ -f /etc/nginx/sites-available/$LETSENCRYPT_DOMAIN ]; then' >> $renewals_script
echo ' ${PROJECT_NAME}-renew-cert -h $LETSENCRYPT_DOMAIN -p letsencrypt' >> $renewals_script
echo ' if [ ! "$?" = "0" ]; then' >> $renewals_script
echo " echo \"${renewal_failure_msg}\" > ~/temp_renewletsencrypt.txt" >> $renewals_script
echo ' echo "" >> ~/temp_renewletsencrypt.txt' >> $renewals_script
echo ' ${PROJECT_NAME}-renew-cert -h $LETSENCRYPT_DOMAIN -p letsencrypt 2>> ~/temp_renewletsencrypt.txt' >> $renewals_script
echo -n " cat ~/temp_renewletsencrypt.txt | mail -s \"${renewal_email_title}\" " >> $renewals_script
echo '$ADMIN_EMAIL_ADDRESS' >> $renewals_script
echo ' rm ~/temp_renewletsencrypt.txt' >> $renewals_script
echo ' if [ ! -f ~/letsencrypt_failed ]; then' >> $renewals_script
echo ' touch ~/letsencrypt_failed' >> $renewals_script
echo ' fi' >> $renewals_script
echo ' fi' >> $renewals_script
echo ' fi' >> $renewals_script
echo ' done' >> $renewals_script
echo 'fi' >> $renewals_script
chmod +x $renewals_script
# a secondary script keeps trying to renew after a failure
echo '#!/bin/bash' > $renewals_retry_script
echo '' >> $renewals_retry_script
echo "PROJECT_NAME='${PROJECT_NAME}'" >> $renewals_retry_script
echo 'COMPLETION_FILE=$HOME/${PROJECT_NAME}-completed.txt' >> $renewals_retry_script
echo '' >> $renewals_retry_script
echo 'if [ -d /etc/letsencrypt ]; then' >> $renewals_retry_script
echo ' if [ -f ~/letsencrypt_failed ]; then' >> $renewals_retry_script
echo ' rm ~/letsencrypt_failed' >> $renewals_retry_script
echo -n ' ADMIN_USERNAME=$(cat $COMPLETION_FILE | grep "Admin user" | ' >> $renewals_retry_script
echo -n "awk -F ':' '{print " >> $renewals_retry_script
echo -n '$2' >> $renewals_retry_script
echo "}')" >> $renewals_retry_script
echo ' ADMIN_EMAIL_ADDRESS=$ADMIN_USERNAME@$HOSTNAME' >> $renewals_retry_script
echo ' for d in /etc/letsencrypt/live/*/ ; do' >> $renewals_retry_script
echo -n ' LETSENCRYPT_DOMAIN=$(echo "$d" | ' >> $renewals_retry_script
echo -n "awk -F '/' '{print " >> $renewals_retry_script
echo -n '$5' >> $renewals_retry_script
echo "}')" >> $renewals_retry_script
echo ' if [ -f /etc/nginx/sites-available/$LETSENCRYPT_DOMAIN ]; then' >> $renewals_retry_script
echo ' ${PROJECT_NAME}-renew-cert -h $LETSENCRYPT_DOMAIN -p letsencrypt' >> $renewals_retry_script
echo ' if [ ! "$?" = "0" ]; then' >> $renewals_retry_script
echo " echo \"${renewal_failure_msg}\" > ~/temp_renewletsencrypt.txt" >> $renewals_retry_script
echo ' echo "" >> ~/temp_renewletsencrypt.txt' >> $renewals_retry_script
echo ' ${PROJECT_NAME}-renew-cert -h $LETSENCRYPT_DOMAIN -p letsencrypt 2>> ~/temp_renewletsencrypt.txt' >> $renewals_retry_script
echo -n " cat ~/temp_renewletsencrypt.txt | mail -s \"${renewal_email_title}\" " >> $renewals_retry_script
echo '$ADMIN_EMAIL_ADDRESS' >> $renewals_retry_script
echo ' rm ~/temp_renewletsencrypt.txt' >> $renewals_retry_script
echo ' if [ ! -f ~/letsencrypt_failed ]; then' >> $renewals_retry_script
echo ' touch ~/letsencrypt_failed' >> $renewals_retry_script
echo ' fi' >> $renewals_retry_script
echo ' fi' >> $renewals_retry_script
echo ' fi' >> $renewals_retry_script
echo ' done' >> $renewals_retry_script
echo ' fi' >> $renewals_retry_script
echo 'fi' >> $renewals_retry_script
chmod +x $renewals_retry_script
2016-07-03 17:13:34 +02:00
}
function configure_php {
2016-08-08 14:49:19 +02:00
sed -i "s/memory_limit = 128M/memory_limit = ${MAX_PHP_MEMORY}M/g" /etc/php5/fpm/php.ini
sed -i 's/;cgi.fix_pathinfo=1/cgi.fix_pathinfo=0/g' /etc/php5/fpm/php.ini
sed -i "s/memory_limit = -1/memory_limit = ${MAX_PHP_MEMORY}M/g" /etc/php5/cli/php.ini
sed -i "s/upload_max_filesize = 2M/upload_max_filesize = 50M/g" /etc/php5/fpm/php.ini
sed -i "s/post_max_size = 8M/post_max_size = 50M/g" /etc/php5/fpm/php.ini
2016-07-03 17:13:34 +02:00
}
function install_web_server_access_control {
2016-08-08 14:49:19 +02:00
if [ ! -f /etc/pam.d/nginx ]; then
echo '#%PAM-1.0' > /etc/pam.d/nginx
echo '@include common-auth' >> /etc/pam.d/nginx
echo '@include common-account' >> /etc/pam.d/nginx
echo '@include common-session' >> /etc/pam.d/nginx
fi
2016-07-03 17:13:34 +02:00
}
function install_dynamicdns {
2016-10-08 20:32:04 +02:00
if [[ $SYSTEM_TYPE == "mesh"* ]]; then
2016-08-08 14:49:19 +02:00
return
fi
if [[ $ONION_ONLY != "no" ]]; 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
2016-10-16 20:50:56 +02:00
if [[ $(is_completed $FUNCNAME) == "1" ]]; then
2016-08-08 14:49:19 +02:00
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
2016-10-23 20:38:14 +02:00
apt-get -yq install build-essential curl libgnutls28-dev automake1.11
2016-08-08 14:49:19 +02:00
if [ ! -d $INSTALL_DIR/inadyn ]; then
git_clone $INADYN_REPO $INSTALL_DIR/inadyn
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
git checkout $INADYN_COMMIT -b $INADYN_COMMIT
2016-10-16 20:50:56 +02:00
set_completion_param "inadyn commit" "$INADYN_COMMIT"
2016-08-08 14:49:19 +02:00
./configure
if [ ! "$?" = "0" ]; then
exit 74890
fi
USE_OPENSSL=1 make
if [ ! "$?" = "0" ]; then
exit 74858
fi
make install
if [ ! "$?" = "0" ]; then
exit 3785
fi
# create an unprivileged user
#chmod 600 /etc/shadow
#chmod 600 /etc/gshadow
2016-08-08 14:49:19 +02:00
#useradd -r -s /bin/false debian-inadyn
#chmod 0000 /etc/shadow
#chmod 0000 /etc/gshadow
2016-08-08 14:49:19 +02:00
# create a configuration file
echo 'background' > /etc/inadyn.conf
echo 'verbose 1' >> /etc/inadyn.conf
echo 'period 300' >> /etc/inadyn.conf
echo 'startup-delay 60' >> /etc/inadyn.conf
echo 'cache-dir /run/inadyn' >> /etc/inadyn.conf
echo 'logfile /dev/null' >> /etc/inadyn.conf
chmod 600 /etc/inadyn.conf
echo '[Unit]' > /etc/systemd/system/inadyn.service
echo 'Description=inadyn (DynDNS updater)' >> /etc/systemd/system/inadyn.service
echo 'After=network.target' >> /etc/systemd/system/inadyn.service
echo '' >> /etc/systemd/system/inadyn.service
echo '[Service]' >> /etc/systemd/system/inadyn.service
echo 'ExecStart=/usr/local/sbin/inadyn --config /etc/inadyn.conf' >> /etc/systemd/system/inadyn.service
echo 'Restart=always' >> /etc/systemd/system/inadyn.service
echo 'Type=forking' >> /etc/systemd/system/inadyn.service
echo '' >> /etc/systemd/system/inadyn.service
echo '[Install]' >> /etc/systemd/system/inadyn.service
echo 'WantedBy=multi-user.target' >> /etc/systemd/system/inadyn.service
systemctl enable inadyn
systemctl start inadyn
systemctl daemon-reload
2016-10-16 20:50:56 +02:00
mark_completed $FUNCNAME
2016-07-03 17:13:34 +02:00
}
2016-07-12 11:55:18 +02:00
function install_command_line_browser {
2016-10-16 20:50:56 +02:00
if [[ $(is_completed $FUNCNAME) == "1" ]]; then
2016-08-08 14:49:19 +02:00
return
fi
2016-10-23 20:38:14 +02:00
apt-get -yq install elinks
2016-08-08 14:49:19 +02:00
# set the home page
if ! grep -q "WWW_HOME" /home/$MY_USERNAME/.bashrc; then
if ! grep -q 'control' /home/$MY_USERNAME/.bashrc; then
echo "export WWW_HOME=$DEFAULT_SEARCH" >> /home/$MY_USERNAME/.bashrc
else
sed -i "/control/i export WWW_HOME=$DEFAULT_SEARCH" /home/$MY_USERNAME/.bashrc
fi
fi
2016-10-16 20:50:56 +02:00
mark_completed $FUNCNAME
2016-07-12 11:55:18 +02:00
}
function mesh_web_server {
2016-08-08 14:49:19 +02:00
if [ -d /etc/apache2 ]; then
2016-10-23 20:38:14 +02:00
chroot "$rootdir" apt-get -yq remove --purge apache2
2016-08-08 14:49:19 +02:00
chroot "$rootdir" rm -rf /etc/apache2
fi
2016-07-12 11:55:18 +02:00
2016-10-23 20:38:14 +02:00
chroot "$rootdir" apt-get -yq install nginx
2016-07-12 11:55:18 +02:00
2016-08-08 14:49:19 +02:00
if [ ! -d $rootdir/etc/nginx ]; then
echo $'Unable to install web server'
exit 346825
fi
2016-07-12 11:55:18 +02:00
}
2016-07-03 17:13:34 +02:00
function install_web_server {
2016-08-08 14:49:19 +02:00
if [ $INSTALLING_MESH ]; then
mesh_web_server
return
fi
# update to the next commit
function_check set_repo_commit
2016-10-02 21:41:56 +02:00
set_repo_commit $INSTALL_DIR/nginx_ensite "nginx-ensite commit" "$NGINX_ENSITE_COMMIT" $NGINX_ENSITE_REPO
2016-08-08 14:49:19 +02:00
2016-10-16 20:50:56 +02:00
if [[ $(is_completed $FUNCNAME) == "1" ]]; then
2016-08-08 14:49:19 +02:00
return
fi
# remove apache
2016-10-23 20:38:14 +02:00
apt-get -yq remove --purge apache2
2016-08-08 14:49:19 +02:00
if [ -d /etc/apache2 ]; then
rm -rf /etc/apache2
fi
# install nginx
2017-04-13 21:49:58 +02:00
apt-get -yq install nginx
apt-get -yq install php5-fpm git
2016-08-08 14:49:19 +02:00
2016-11-18 16:06:14 +01:00
# 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
2016-08-08 14:49:19 +02:00
# limit the number of php processes
sed -i 's/; process.max =.*/process.max = 32/g' /etc/php5/fpm/php-fpm.conf
#sed -i 's/;process_control_timeout =.*/process_control_timeout = 300/g' /etc/php5/fpm/php-fpm.conf
if ! grep -q "pm.max_children" /etc/php5/fpm/php-fpm.conf; then
echo 'pm.max_children = 10' >> /etc/php5/fpm/php-fpm.conf
echo 'pm.start_servers = 2' >> /etc/php5/fpm/php-fpm.conf
echo 'pm.min_spare_servers = 2' >> /etc/php5/fpm/php-fpm.conf
echo 'pm.max_spare_servers = 5' >> /etc/php5/fpm/php-fpm.conf
echo 'pm.max_requests = 50' >> /etc/php5/fpm/php-fpm.conf
fi
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;' > /etc/nginx/nginx.conf
#echo "worker_processes; $CPU_CORES" >> /etc/nginx/nginx.conf
echo 'pid /run/nginx.pid;' >> /etc/nginx/nginx.conf
echo '' >> /etc/nginx/nginx.conf
echo 'events {' >> /etc/nginx/nginx.conf
echo ' worker_connections 50;' >> /etc/nginx/nginx.conf
echo ' # multi_accept on;' >> /etc/nginx/nginx.conf
echo '}' >> /etc/nginx/nginx.conf
echo '' >> /etc/nginx/nginx.conf
echo 'http {' >> /etc/nginx/nginx.conf
echo ' # limit the number of connections per single IP' >> /etc/nginx/nginx.conf
echo ' limit_conn_zone $binary_remote_addr zone=conn_limit_per_ip:10m;' >> /etc/nginx/nginx.conf
echo '' >> /etc/nginx/nginx.conf
echo ' # limit the number of requests for a given session' >> /etc/nginx/nginx.conf
echo ' limit_req_zone $binary_remote_addr zone=req_limit_per_ip:10m rate=140r/s;' >> /etc/nginx/nginx.conf
echo '' >> /etc/nginx/nginx.conf
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' >> /etc/nginx/nginx.conf
echo ' client_body_buffer_size 128k;' >> /etc/nginx/nginx.conf
echo '' >> /etc/nginx/nginx.conf
echo ' # headerbuffer size for the request header from client, its set for testing purpose' >> /etc/nginx/nginx.conf
echo ' client_header_buffer_size 3m;' >> /etc/nginx/nginx.conf
echo '' >> /etc/nginx/nginx.conf
echo ' # maximum number and size of buffers for large headers to read from client request' >> /etc/nginx/nginx.conf
echo ' large_client_header_buffers 4 256k;' >> /etc/nginx/nginx.conf
echo '' >> /etc/nginx/nginx.conf
echo ' # read timeout for the request body from client, its set for testing purpose' >> /etc/nginx/nginx.conf
echo ' client_body_timeout 3m;' >> /etc/nginx/nginx.conf
echo '' >> /etc/nginx/nginx.conf
echo ' # how long to wait for the client to send a request header, its set for testing purpose' >> /etc/nginx/nginx.conf
echo ' client_header_timeout 3m;' >> /etc/nginx/nginx.conf
echo '' >> /etc/nginx/nginx.conf
echo ' ##' >> /etc/nginx/nginx.conf
echo ' # Basic Settings' >> /etc/nginx/nginx.conf
echo ' ##' >> /etc/nginx/nginx.conf
echo '' >> /etc/nginx/nginx.conf
echo ' sendfile on;' >> /etc/nginx/nginx.conf
echo ' tcp_nopush on;' >> /etc/nginx/nginx.conf
echo ' tcp_nodelay on;' >> /etc/nginx/nginx.conf
echo ' keepalive_timeout 65;' >> /etc/nginx/nginx.conf
echo ' types_hash_max_size 2048;' >> /etc/nginx/nginx.conf
echo ' server_tokens off;' >> /etc/nginx/nginx.conf
echo '' >> /etc/nginx/nginx.conf
echo ' # server_names_hash_bucket_size 64;' >> /etc/nginx/nginx.conf
echo ' # server_name_in_redirect off;' >> /etc/nginx/nginx.conf
echo '' >> /etc/nginx/nginx.conf
echo ' include /etc/nginx/mime.types;' >> /etc/nginx/nginx.conf
echo ' default_type application/octet-stream;' >> /etc/nginx/nginx.conf
echo '' >> /etc/nginx/nginx.conf
echo ' ##' >> /etc/nginx/nginx.conf
echo ' # Logging Settings' >> /etc/nginx/nginx.conf
echo ' ##' >> /etc/nginx/nginx.conf
echo '' >> /etc/nginx/nginx.conf
2016-11-18 19:33:08 +01:00
echo ' access_log /dev/null;' >> /etc/nginx/nginx.conf
echo ' error_log /dev/null;' >> /etc/nginx/nginx.conf
2016-08-08 14:49:19 +02:00
echo '' >> /etc/nginx/nginx.conf
echo ' ###' >> /etc/nginx/nginx.conf
echo ' # Gzip Settings' >> /etc/nginx/nginx.conf
echo ' ##' >> /etc/nginx/nginx.conf
echo ' gzip on;' >> /etc/nginx/nginx.conf
echo ' gzip_disable "msie6";' >> /etc/nginx/nginx.conf
echo '' >> /etc/nginx/nginx.conf
echo ' # gzip_vary on;' >> /etc/nginx/nginx.conf
echo ' # gzip_proxied any;' >> /etc/nginx/nginx.conf
echo ' # gzip_comp_level 6;' >> /etc/nginx/nginx.conf
echo ' # gzip_buffers 16 8k;' >> /etc/nginx/nginx.conf
echo ' # gzip_http_version 1.1;' >> /etc/nginx/nginx.conf
echo ' # gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;' >> /etc/nginx/nginx.conf
echo '' >> /etc/nginx/nginx.conf
echo ' ##' >> /etc/nginx/nginx.conf
echo ' # Virtual Host Configs' >> /etc/nginx/nginx.conf
echo ' ##' >> /etc/nginx/nginx.conf
echo '' >> /etc/nginx/nginx.conf
echo ' include /etc/nginx/conf.d/*.conf;' >> /etc/nginx/nginx.conf
echo ' include /etc/nginx/sites-enabled/*;' >> /etc/nginx/nginx.conf
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
function_check git_clone
git_clone $NGINX_ENSITE_REPO $INSTALL_DIR/nginx_ensite
cd $INSTALL_DIR/nginx_ensite
git checkout $NGINX_ENSITE_COMMIT -b $NGINX_ENSITE_COMMIT
2016-10-16 20:50:56 +02:00
set_completion_param "nginx-ensite commit" "$NGINX_ENSITE_COMMIT"
2016-08-08 14:49:19 +02:00
make install
nginx_dissite default
function_check configure_firewall_for_web_access
configure_firewall_for_web_access
2016-10-16 20:50:56 +02:00
mark_completed $FUNCNAME
2016-07-03 17:13:34 +02:00
}
2016-10-20 23:02:16 +02:00
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) == "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
}
2016-10-27 23:51:21 +02:00
function update_default_domain {
2016-10-30 20:42:39 +01:00
echo $'Updating default domain'
if [[ $ONION_ONLY == 'no' ]]; then
if [ -d /etc/prosody ]; then
2016-11-11 10:09:34 +01:00
if [ -d /etc/jitsi ]; then
read_config_param "JITSI_DOMAIN_NAME"
if [ ${#JITSI_DOMAIN_NAME} -gt 0 ]; then
if [ -f /etc/ssl/private/${JITSI_DOMAIN_NAME}.key ]; then
cp /etc/ssl/private/${JITSI_DOMAIN_NAME}.key /etc/prosody/certs/${JITSI_DOMAIN_NAME}.key
fi
if [ -f /etc/ssl/certs/${JITSI_DOMAIN_NAME}.crt ]; then
cp /etc/ssl/certs/${JITSI_DOMAIN_NAME}.crt /etc/prosody/certs/${JITSI_DOMAIN_NAME}.pem
fi
if [ -f /etc/ssl/certs/${JITSI_DOMAIN_NAME}.pem ]; then
cp /etc/ssl/certs/${JITSI_DOMAIN_NAME}.pem /etc/prosody/certs/${JITSI_DOMAIN_NAME}.pem
fi
2016-11-05 16:42:19 +01:00
fi
fi
if [ ! -d /etc/prosody/certs ]; then
mkdir /etc/prosody/certs
fi
2016-10-30 20:42:39 +01:00
cp /etc/ssl/private/xmpp* /etc/prosody/certs
cp /etc/ssl/private/${DEFAULT_DOMAIN_NAME}* /etc/prosody/certs
cp /etc/ssl/certs/xmpp* /etc/prosody/certs
cp /etc/ssl/certs/${DEFAULT_DOMAIN_NAME}* /etc/prosody/certs
2016-11-22 12:02:50 +01:00
if [ ! -f /etc/prosody/certs/${DEFAULT_DOMAIN_NAME}.dhparam ]; then
if [ -f /etc/ssl/certs/${DEFAULT_DOMAIN_NAME}.dhparam ]; then
cp /etc/ssl/certs/${DEFAULT_DOMAIN_NAME}.dhparam /etc/prosody/certs/${DEFAULT_DOMAIN_NAME}.dhparam
fi
fi
if [ ! /etc/prosody/certs/${DEFAULT_DOMAIN_NAME}.pem ]; then
if [ ! /etc/prosody/certs/${DEFAULT_DOMAIN_NAME}.crt ]; then
mv /etc/prosody/certs/${DEFAULT_DOMAIN_NAME}.crt /etc/prosody/certs/${DEFAULT_DOMAIN_NAME}.pem
fi
else
sed -i "s|/etc/prosody/certs/xmpp.key|/etc/prosody/certs/${DEFAULT_DOMAIN_NAME}.key|g" /etc/prosody/conf.avail/xmpp.cfg.lua
sed -i "s|/etc/prosody/certs/xmpp.crt|/etc/prosody/certs/${DEFAULT_DOMAIN_NAME}.pem|g" /etc/prosody/conf.avail/xmpp.cfg.lua
2016-10-27 23:55:49 +02:00
sed -i "s|/etc/prosody/certs/xmpp.key|/etc/prosody/certs/${DEFAULT_DOMAIN_NAME}.key|g" /etc/prosody/prosody.cfg.lua
sed -i "s|/etc/prosody/certs/xmpp.crt|/etc/prosody/certs/${DEFAULT_DOMAIN_NAME}.pem|g" /etc/prosody/prosody.cfg.lua
2016-10-27 23:51:21 +02:00
fi
2016-11-22 12:02:50 +01:00
chown -R prosody:default /etc/prosody
chmod -R 700 /etc/prosody/certs/*
2016-11-22 12:02:50 +01:00
chmod 600 /etc/prosody/prosody.cfg.lua
systemctl reload prosody
2016-10-28 14:19:08 +02:00
fi
2016-10-30 20:34:28 +01:00
if [ -d /var/lib/mumble-server ]; then
if [[ "$(cert_exists ${DEFAULT_DOMAIN_NAME} pem)" == "1" ]]; then
cp /etc/ssl/certs/${DEFAULT_DOMAIN_NAME}.pem /var/lib/mumble-server/mumble.pem
cp /etc/ssl/certs/${DEFAULT_DOMAIN_NAME}.dhparam /var/lib/mumble-server/mumble.dhparam
cp /etc/ssl/private/${DEFAULT_DOMAIN_NAME}.key /var/lib/mumble-server/mumble.key
chown -R mumble-server:mumble-server /var/lib/mumble-server
2016-12-30 19:32:06 +01:00
chmod -R 700 /var/lib/mumble-server/*.pem
chmod -R 700 /var/lib/mumble-server/*.key
chmod -R 700 /var/lib/mumble-server/*.dhparam
2016-12-30 19:42:59 +01:00
systemctl restart mumble-server
fi
fi
2016-10-30 20:34:28 +01:00
if [ -d /home/znc/.znc ]; then
echo $'znc found'
if [[ "$(cert_exists ${DEFAULT_DOMAIN_NAME} pem)" == "1" ]]; 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/ssl/certs/${DEFAULT_DOMAIN_NAME}.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/ssl/private/${DEFAULT_DOMAIN_NAME}.key" /etc/ngircd/ngircd.conf
echo $'irc certificates updated'
systemctl restart ngircd
su -c 'znc' - znc
fi
2016-10-28 17:00:22 +02:00
fi
2016-10-31 19:39:35 +01:00
if [ -d /etc/dovecot ]; then
if [ ${#DEFAULT_DOMAIN_NAME} -gt 0 ]; then
if ! grep -q "ssl_cert = </etc/ssl/certs/${DEFAULT_DOMAIN_NAME}.pem" /etc/dovecot/conf.d/10-ssl.conf; then
sed -i "s|#ssl_cert =.*|ssl_cert = </etc/ssl/certs/${DEFAULT_DOMAIN_NAME}.pem|g" /etc/dovecot/conf.d/10-ssl.conf
sed -i "s|ssl_cert =.*|ssl_cert = </etc/ssl/certs/${DEFAULT_DOMAIN_NAME}.pem|g" /etc/dovecot/conf.d/10-ssl.conf
systemctl restart dovecot
fi
fi
2016-10-31 19:39:35 +01:00
fi
fi
2016-10-27 23:51:21 +02:00
}
2017-01-01 21:40:08 +01:00
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
./deploy.sh EN /var/www/${DEFAULT_DOMAIN_NAME}/htdocs
else
if [ -d /home/${MY_USERNAME}/${PROJECT_NAME} ]; then
cd /home/${MY_USERNAME}/${PROJECT_NAME}
./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 {' >> $nginx_site
echo ' listen 443 ssl;' >> $nginx_site
echo ' listen [::]:443 ssl;' >> $nginx_site
echo " server_name $DEFAULT_DOMAIN_NAME;" >> $nginx_site
echo '' >> $nginx_site
echo ' # Security' >> $nginx_site
function_check nginx_ssl
nginx_ssl $DEFAULT_DOMAIN_NAME
function_check nginx_disable_sniffing
nginx_disable_sniffing $DEFAULT_DOMAIN_NAME
echo ' add_header Strict-Transport-Security max-age=15768000;' >> $nginx_site
echo '' >> $nginx_site
echo ' # Logs' >> $nginx_site
echo ' access_log /dev/null;' >> $nginx_site
echo ' error_log /dev/null;' >> $nginx_site
echo '' >> $nginx_site
echo ' # Root' >> $nginx_site
echo " root /var/www/$DEFAULT_DOMAIN_NAME/htdocs;" >> $nginx_site
echo '' >> $nginx_site
echo ' # Index' >> $nginx_site
echo ' index index.html;' >> $nginx_site
echo '' >> $nginx_site
echo ' # Location' >> $nginx_site
echo ' location / {' >> $nginx_site
function_check nginx_limits
nginx_limits $DEFAULT_DOMAIN_NAME '15m'
echo ' }' >> $nginx_site
echo '' >> $nginx_site
echo ' # Restrict access that is unnecessary anyway' >> $nginx_site
echo ' location ~ /\.(ht|git) {' >> $nginx_site
echo ' deny all;' >> $nginx_site
echo ' }' >> $nginx_site
echo '}' >> $nginx_site
else
echo -n '' > $nginx_site
fi
echo 'server {' >> $nginx_site
echo " listen 127.0.0.1:$DEFAULT_DOMAIN_ONION_PORT default_server;" >> $nginx_site
echo " server_name $DEFAULT_DOMAIN_NAME;" >> $nginx_site
echo '' >> $nginx_site
function_check nginx_disable_sniffing
nginx_disable_sniffing $DEFAULT_DOMAIN_NAME
echo '' >> $nginx_site
echo ' # Logs' >> $nginx_site
echo ' access_log /dev/null;' >> $nginx_site
echo ' error_log /dev/null;' >> $nginx_site
echo '' >> $nginx_site
echo ' # Root' >> $nginx_site
echo " root /var/www/$DEFAULT_DOMAIN_NAME/htdocs;" >> $nginx_site
echo '' >> $nginx_site
echo ' # Location' >> $nginx_site
echo ' location / {' >> $nginx_site
function_check nginx_limits
nginx_limits $DEFAULT_DOMAIN_NAME '15m'
echo ' }' >> $nginx_site
echo '' >> $nginx_site
echo ' # Restrict access that is unnecessary anyway' >> $nginx_site
echo ' location ~ /\.(ht|git) {' >> $nginx_site
echo ' deny all;' >> $nginx_site
echo ' }' >> $nginx_site
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
}
2016-07-03 17:13:34 +02:00
# NOTE: deliberately no exit 0