#!/bin/bash # # .---. . . # | | | # |--- .--. .-. .-. .-.| .-. .--.--. |.-. .-. .--. .-. # | | (.-' (.-' ( | ( )| | | | )( )| | (.-' # ' ' --' --' -' - -' ' ' -' -' -' ' - --' # # Freedom in the Cloud # # Setup functions # # License # ======= # # Copyright (C) 2014-2016 Bob Mottram # # 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 . # Different system variants which may be specified within # the SYSTEM_TYPE option VARIANT_FULL="full" VARIANT_WRITER="writer" VARIANT_CLOUD="cloud" VARIANT_CHAT="chat" VARIANT_MAILBOX="mailbox" VARIANT_NONMAILBOX="nonmailbox" VARIANT_SOCIAL="social" VARIANT_MEDIA="media" VARIANT_DEVELOPER="developer" VARIANT_MESH="mesh" DEFAULT_DOMAIN_NAME= DEFAULT_DOMAIN_CODE= MY_USERNAME= SYSTEM_TYPE=$VARIANT_FULL # An optional configuration file which overrides some of these variables CONFIGURATION_FILE="${PROJECT_NAME}.cfg" # Directory where source code is downloaded and compiled INSTALL_DIR=$HOME/build # device name for an attached usb drive USB_DRIVE=/dev/sda1 # Location where the USB drive is mounted to USB_MOUNT=/mnt/usb # Number of days to keep backups for BACKUP_MAX_DAYS=30 # file containing a list of remote locations to backup to # Format: [username@friendsdomain//home/username] [ssh_password] # With the only space character being between the server and the password FRIENDS_SERVERS_LIST=/home/$MY_USERNAME/backup.list export DEBIAN_FRONTEND=noninteractive # used to limit CPU usage CPULIMIT='/usr/bin/cpulimit -l 20 -e' # command to create a git repository CREATE_GIT_PROJECT_COMMAND='create-project' # File which keeps track of what has already been installed COMPLETION_FILE=$HOME/${PROJECT_NAME}-completed.txt # log file where details of remote backups are stored REMOTE_BACKUPS_LOG=/var/log/remotebackups.log # message if something fails to install CHECK_MESSAGE="Check your internet connection, /etc/network/interfaces and /etc/resolv.conf, then delete $COMPLETION_FILE, run 'rm -fR /var/lib/apt/lists/* && apt-get update --fix-missing' and run this script again. If hash sum mismatches persist then try setting $DEBIAN_REPO to a different mirror and also change /etc/apt/sources.list." # Default diffie-hellman key length in bits DH_KEYLENGTH=2048 function initial_setup { if grep -Fxq "initial_setup" $COMPLETION_FILE; then return fi apt-get -y remove --purge apache* apt-get -y dist-upgrade apt-get -y install ca-certificates emacs24 cpulimit apt-get -y install cryptsetup libgfshare-bin obnam sshpass wget apt-get -y install avahi-daemon avahi-utils avahi-discover apt-get -y install connect-proxy if [ ! -d $INSTALL_DIR ]; then mkdir -p $INSTALL_DIR fi echo 'initial_setup' >> $COMPLETION_FILE } function search_for_attached_usb_drive { # If a USB drive is attached then search for email, # gpg, ssh keys and emacs configuration if grep -Fxq "search_for_attached_usb_drive" $COMPLETION_FILE; then return fi if [ -b $USB_DRIVE ]; then if [ ! -d $USB_MOUNT ]; then echo $'Mounting USB drive' mkdir $USB_MOUNT mount $USB_DRIVE $USB_MOUNT fi if ! [[ $SYSTEM_TYPE == "$VARIANT_WRITER" || $SYSTEM_TYPE == "$VARIANT_CLOUD" || $SYSTEM_TYPE == "$VARIANT_CHAT" || $SYSTEM_TYPE == "$VARIANT_SOCIAL" || $SYSTEM_TYPE == "$VARIANT_MEDIA" || $SYSTEM_TYPE == "$VARIANT_DEVELOPER" || $SYSTEM_TYPE == "$VARIANT_MESH" || $SYSTEM_TYPE == "$VARIANT_NONMAILBOX" ]]; then if [ -d $USB_MOUNT/Maildir ]; then echo $'Maildir found on USB drive' IMPORT_MAILDIR=$USB_MOUNT/Maildir fi if [ -d $USB_MOUNT/.gnupg ]; then echo $'Importing GPG keyring' cp -r $USB_MOUNT/.gnupg /home/$MY_USERNAME chown -R $MY_USERNAME:$MY_USERNAME /home/$MY_USERNAME/.gnupg GPG_KEYS_IMPORTED="yes" if [ ! -f /home/$MY_USERNAME/.gnupg/secring.gpg ]; then echo $'GPG files did not copy' exit 73529 fi fi if [ -f $USB_MOUNT/.procmailrc ]; then echo $'Importing procmail settings' cp $USB_MOUNT/.procmailrc /home/$MY_USERNAME chown -R $MY_USERNAME:$MY_USERNAME /home/$MY_USERNAME/.procmailrc fi if [ -f $USB_MOUNT/private_key.gpg ]; then echo $'GPG private key found on USB drive' MY_GPG_PRIVATE_KEY=$USB_MOUNT/private_key.gpg fi if [ -f $USB_MOUNT/public_key.gpg ]; then echo $'GPG public key found on USB drive' MY_GPG_PUBLIC_KEY=$USB_MOUNT/public_key.gpg fi fi if [ -d $USB_MOUNT/prosody ]; then if [ ! -d $XMPP_DIRECTORY ]; then mkdir $XMPP_DIRECTORY fi cp -r $USB_MOUNT/prosody/* $XMPP_DIRECTORY chown -R prosody:prosody $XMPP_DIRECTORY fi if [ -d $USB_MOUNT/.ssh ]; then echo $'Importing ssh keys' cp -r $USB_MOUNT/.ssh /home/$MY_USERNAME chown -R $MY_USERNAME:$MY_USERNAME /home/$MY_USERNAME/.ssh # for security delete the ssh keys from the usb drive if [ ! -f /home/$MY_USERNAME/.ssh/id_rsa ]; then echo $'ssh files did not copy' exit 8 fi fi if [ -f $USB_MOUNT/.emacs ]; then echo $'Importing .emacs file' cp -f $USB_MOUNT/.emacs /home/$MY_USERNAME/.emacs chown $MY_USERNAME:$MY_USERNAME /home/$MY_USERNAME/.emacs fi if [ -d $USB_MOUNT/.emacs.d ]; then echo $'Importing .emacs.d directory' cp -r $USB_MOUNT/.emacs.d /home/$MY_USERNAME chown -R $MY_USERNAME:$MY_USERNAME /home/$MY_USERNAME/.emacs.d fi if [ -d $USB_MOUNT/ssl ]; then echo $'Importing SSL certificates' cp -r $USB_MOUNT/ssl/* /etc/ssl chmod 640 /etc/ssl/certs/* chmod 400 /etc/ssl/private/* # change ownership of some certificates if [ -d /etc/prosody ]; then chown prosody:prosody /etc/ssl/private/xmpp.* chown prosody:prosody /etc/ssl/certs/xmpp.* fi if [ -d /etc/dovecot ]; then chown root:dovecot /etc/ssl/certs/dovecot.* chown root:dovecot /etc/ssl/private/dovecot.* fi if [ -f /etc/ssl/private/exim.key ]; then cp /etc/ssl/private/exim.key /etc/exim4 cp /etc/ssl/certs/exim.crt /etc/exim4 cp /etc/ssl/certs/exim.dhparam /etc/exim4 chown root:Debian-exim /etc/exim4/exim.key /etc/exim4/exim.crt /etc/exim4/exim.dhparam chmod 640 /etc/exim4/exim.key /etc/exim4/exim.crt /etc/exim4/exim.dhparam fi fi if [ -d $USB_MOUNT/personal ]; then echo $'Importing personal directory' cp -r $USB_MOUNT/personal /home/$MY_USERNAME chown -R $MY_USERNAME:$MY_USERNAME /home/$MY_USERNAME/personal fi else if [ -d $USB_MOUNT ]; then umount $USB_MOUNT rm -rf $USB_MOUNT fi echo $'No USB drive attached' fi echo 'search_for_attached_usb_drive' >> $COMPLETION_FILE } function mark_admin_user_account { if ! grep -q "Admin user:" $COMPLETION_FILE; then echo "Admin user:$MY_USERNAME" >> $COMPLETION_FILE fi } function remove_instructions_from_motd { sed -i '/## /d' /etc/motd } function remove_default_user { # make sure you don't use the default user account if [[ $MY_USERNAME == "debian" ]]; then echo 'Do not use the default debian user account. Create a different user with: adduser [username]' exit 68 fi # remove the default debian user to prevent it from becoming an attack vector if [ -d /home/debian ]; then userdel -r debian echo 'Default debian user account removed' fi } function create_completion_file { if [ ! -f $COMPLETION_FILE ]; then touch $COMPLETION_FILE fi } function upgrade_installation { # TODO echo '' } function setup_firewall { function_check create_completion_file create_completion_file function_check configure_firewall configure_firewall function_check configure_firewall_ping configure_firewall_ping function_check configure_firewall_for_dns configure_firewall_for_dns function_check configure_firewall_for_avahi configure_firewall_for_avahi } function setup_utils { function_check create_completion_file create_completion_file function_check read_configuration read_configuration function_check upgrade_installation upgrade_installation function_check set_default_onion_domains set_default_onion_domains function_check locale_setup locale_setup function_check parse_args parse_args function_check check_domains check_domains function_check install_static_network install_static_network function_check remove_default_user remove_default_user function_check setup_firewall setup_firewall function_check create_repo_sources create_repo_sources function_check configure_dns configure_dns function_check initial_setup initial_setup function_check install_tor install_tor #function_check resolve_dns_via_tor #resolve_dns_via_tor function_check install_command_line_browser install_command_line_browser function_check enable_ssh_via_onion enable_ssh_via_onion function_check check_date check_date function_check install_dynamicdns install_dynamicdns function_check randomize_cron randomize_cron function_check create_freedns_updater create_freedns_updater function_check mark_admin_user_account mark_admin_user_account function_check enforce_good_passwords enforce_good_passwords function_check install_editor install_editor function_check change_login_message change_login_message function_check enable_zram enable_zram function_check random_number_generator random_number_generator function_check set_your_domain_name set_your_domain_name function_check time_synchronisation_tlsdate time_synchronisation_tlsdate function_check configure_internet_protocol configure_internet_protocol function_check create_git_project create_git_project function_check setup_wifi setup_wifi function_check configure_ssh configure_ssh function_check configure_ssh_onion configure_ssh_onion function_check allow_ssh_to_onion_address allow_ssh_to_onion_address function_check remove_instructions_from_motd remove_instructions_from_motd function_check check_hwrng check_hwrng function_check search_for_attached_usb_drive search_for_attached_usb_drive function_check regenerate_ssh_keys regenerate_ssh_keys function_check create_mirrors create_mirrors function_check create_upgrade_script create_upgrade_script function_check letsencrypt_renewals letsencrypt_renewals function_check install_watchdog_script install_watchdog_script function_check install_avahi install_avahi function_check create_avahi_onion_domains create_avahi_onion_domains #function_check install_atheros_wifi #install_atheros_wifi function_check route_outgoing_traffic_through_tor route_outgoing_traffic_through_tor function_check upgrade_golang upgrade_golang } function setup_email { function_check create_completion_file create_completion_file function_check install_email install_email function_check create_procmail create_procmail function_check handle_admin_emails handle_admin_emails function_check spam_filtering spam_filtering function_check configure_imap configure_imap #function_check configure_imap_client_certs #configure_imap_client_certs function_check configure_gpg configure_gpg function_check refresh_gpg_keys refresh_gpg_keys function_check configure_backup_key configure_backup_key function_check install_monkeysphere install_monkeysphere function_check encrypt_incoming_email encrypt_incoming_email function_check encrypt_outgoing_email encrypt_outgoing_email function_check email_client email_client function_check email_archiving email_archiving function_check email_from_address email_from_address function_check create_public_mailing_list create_public_mailing_list #function check create_private_mailing_list #create_private_mailing_list function_check encrypt_all_email encrypt_all_email function_check import_email import_email } function setup_web { function_check create_completion_file create_completion_file function_check install_web_server install_web_server function_check install_web_server_access_control install_web_server_access_control } function upgrade_apps { function_check create_completion_file create_completion_file APPS_COMPLETED=() FILES=/usr/share/${PROJECT_NAME}/apps/${PROJECT_NAME}-app-* # for all the app scripts for filename in $FILES do app_name=$(echo "${filename}" | awk -F '-app-' '{print $2}') if [[ $(item_in_array ${app_name} ${APPS_COMPLETED[@]}) != 0 ]]; then function_check app_is_installed if [[ "$(app_is_installed $a)" == "1" ]]; then APPS_COMPLETED+=("${app_name}") function_check upgrade_${app_name} upgrade_${app_name} fi fi done } function setup_apps { function_check create_completion_file create_completion_file function_check choose_apps_for_variant choose_apps_for_variant "$SYSTEM_TYPE" echo $"System variant: $SYSTEM_TYPE" echo $'The following apps have been selected' echo '' function_check list_chosen_apps list_chosen_apps echo '' function_check upgrade_apps upgrade_apps function_check install_apps install_apps } function combine_all_scripts { combined_filename=$1 # initial variables cp $PROJECT_INSTALL_DIR/${PROJECT_NAME}-vars $combined_filename # utilities UTILS_FILES=/usr/share/${PROJECT_NAME}/utils/${PROJECT_NAME}-utils-* for f in $UTILS_FILES do # this removes the first line, which is #!/bin/bash tail -n +2 "$f" >> $combined_filename done # base system BASE_SYSTEM_FILES=/usr/share/${PROJECT_NAME}/base/${PROJECT_NAME}-base-* for f in $BASE_SYSTEM_FILES do tail -n +2 "$f" >> $combined_filename done # apps APP_FILES=/usr/share/${PROJECT_NAME}/apps/${PROJECT_NAME}-app-* for f in $APP_FILES do tail -n +2 "$f" >> $combined_filename done } # NOTE: deliberately no exit 0