Skip to content
Snippets Groups Projects
freedombone-utils-setup 37.7 KiB
Newer Older
Bob Mottram's avatar
Bob Mottram committed
#!/bin/bash
Bob Mottram's avatar
Bob Mottram committed
#  _____               _           _
# |   __|___ ___ ___ _| |___ _____| |_ ___ ___ ___
# |   __|  _| -_| -_| . | . |     | . | . |   | -_|
# |__|  |_| |___|___|___|___|_|_|_|___|___|_|_|___|
Bob Mottram's avatar
Bob Mottram committed
#
Bob Mottram's avatar
Bob Mottram committed
#                              Freedom in the Cloud
Bob Mottram's avatar
Bob Mottram committed
#
# Setup functions
#
# License
# =======
#
Bob Mottram's avatar
Bob Mottram committed
# Copyright (C) 2014-2018 Bob Mottram <bob@freedombone.net>
Bob Mottram's avatar
Bob Mottram committed
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

if [ ! "$PROJECT_NAME" ]; then
Bob Mottram's avatar
Bob Mottram committed
    PROJECT_NAME='freedombone'
fi

if [ ! "$LOCAL_NAME" ]; then
    LOCAL_NAME=${PROJECT_NAME}
fi

Bob Mottram's avatar
Bob Mottram committed
DEFAULT_DOMAIN_NAME=
DEFAULT_DOMAIN_CODE=
MY_USERNAME=
if [ ! "$SYSTEM_TYPE" ]; then
Bob Mottram's avatar
Bob Mottram committed
    SYSTEM_TYPE="full"
fi
Bob Mottram's avatar
Bob Mottram committed

# An optional configuration file which overrides some of these variables
if [ ! "$CONFIGURATION_FILE" ]; then
Bob Mottram's avatar
Bob Mottram committed
    CONFIGURATION_FILE="$HOME/${PROJECT_NAME}.cfg"
fi
Bob Mottram's avatar
Bob Mottram committed

# 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
Bob Mottram's avatar
Bob Mottram committed
FRIENDS_SERVERS_LIST="/home/$MY_USERNAME/backup.list"
Bob Mottram's avatar
Bob Mottram committed

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
Bob Mottram's avatar
Bob Mottram committed
CHECK_MESSAGE="Check your internet connection, /etc/network/interfaces and /etc/resolvconf/resolv.conf.d/head, then delete $COMPLETION_FILE, run 'rm -fR /var/lib/apt/lists/* && $UPDATE_PACKAGES --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."
Bob Mottram's avatar
Bob Mottram committed

# Default diffie-hellman key length in bits
DH_KEYLENGTH=2048

function configure_cpu_monitor {
    if [ -f /etc/systemd/system/cpumonitor.service ]; then
        return
    fi

    { echo '[Unit]';
      echo 'Description=Monitor CPU usage and produce warnings';
      echo 'After=network.target';
      echo '';
      echo '[Service]';
      echo 'User=root';
      echo "ExecStart=/usr/local/bin/${PROJECT_NAME}-cpu-monitor";
      echo "ExecReload=/bin/kill \$MAINPID";
      echo 'KillMode=process';
      echo 'Restart=always';
      echo '';
      echo '[Install]';
      echo 'WantedBy=multi-user.target'; } > /etc/systemd/system/cpumonitor.service

    systemctl enable cpumonitor
    systemctl daemon-reload
    systemctl start cpumonitor
}

function support_256_colours {
    if ! grep 'xterm-256color' /etc/skel/.profile; then
        echo '' >> /etc/skel/.profile
        echo 'export TERM=xterm-256color' >> /etc/skel/.profile
    fi

    if ! grep 'xterm-256color' /home/$MY_USERNAME/.profile; then
        echo '' >> /home/$MY_USERNAME/.profile
        echo 'export TERM=xterm-256color' >> /home/$MY_USERNAME/.profile
Bob Mottram's avatar
Bob Mottram committed
        chown $MY_USERNAME:$MY_USERNAME /home/$MY_USERNAME/.profile
Bob Mottram's avatar
Bob Mottram committed
function separate_tmp_filesystem {
    tmp_filesystem_size_mb=$1
    if [ ! -d /tmp ]; then
        mkdir -p /tmp
    fi
    if ! grep -q '/tmp' /etc/fstab; then
Bob Mottram's avatar
Bob Mottram committed
        mount -t tmpfs -o size="${tmp_filesystem_size_mb}m" tmpfs /tmp
Bob Mottram's avatar
Bob Mottram committed
        echo "tmpfs       /tmp tmpfs   nodev,nosuid,noexec,nodiratime,size=${tmp_filesystem_size_mb}M   0 0" >> /etc/fstab
    fi
}

Bob Mottram's avatar
Bob Mottram committed
function proc_filesystem_settings {
    if ! grep -q "proc proc defaults,nodev,nosuid " /etc/fstab; then
       sed -i 's|proc /proc proc defaults |proc /proc proc defaults,nodev,nosuid |g' /etc/fstab
    fi
Bob Mottram's avatar
Bob Mottram committed
}

Bob Mottram's avatar
Bob Mottram committed
function remove_bluetooth {
    bluetooth_changed=
    bnep_exists=$(lsmod | grep bnep)
    if [[ "$bnep_exists" == "bnep"* ]]; then
        rmmod -f bnep
        bluetooth_changed=1
    fi
    bluetooth_exists=$(lsmod | grep bluetooth)
    if [[ "$bluetooth_exists" == "bluetooth"* ]]; then
        rmmod -f bluetooth
        bluetooth_changed=1
    fi
Bob Mottram's avatar
Bob Mottram committed
    if [ -f /etc/default/bluetooth ]; then
Bob Mottram's avatar
Bob Mottram committed
        if grep -q "BLUETOOTH_ENABLED=" /etc/default/bluetooth; then
Bob Mottram's avatar
Bob Mottram committed
            sed -i 's|BLUETOOTH_ENABLED=.*|BLUETOOTH_ENABLED=0|g' /etc/default/bluetooth
        else
            echo "BLUETOOTH_ENABLED=0" >> /etc/default/bluetooth
        fi
        bluetooth_changed=1
Bob Mottram's avatar
Bob Mottram committed
    fi
Bob Mottram's avatar
Bob Mottram committed
    if ! grep -q 'blacklist bnep' /etc/modprobe.d/bluetooth.conf; then
Bob Mottram's avatar
Bob Mottram committed
        echo 'blacklist bnep' >> /etc/modprobe.d/bluetooth.conf
        bluetooth_changed=1
Bob Mottram's avatar
Bob Mottram committed
    fi
Bob Mottram's avatar
Bob Mottram committed
    if ! grep -q 'blacklist btusb' /etc/modprobe.d/bluetooth.conf; then
Bob Mottram's avatar
Bob Mottram committed
        echo 'blacklist btusb' >> /etc/modprobe.d/bluetooth.conf
        bluetooth_changed=1
Bob Mottram's avatar
Bob Mottram committed
    fi
Bob Mottram's avatar
Bob Mottram committed
    if ! grep -q 'blacklist bluetooth' /etc/modprobe.d/bluetooth.conf; then
Bob Mottram's avatar
Bob Mottram committed
        echo 'blacklist bluetooth' >> /etc/modprobe.d/bluetooth.conf
        bluetooth_changed=1
    fi
    if [ $bluetooth_changed ]; then
Bob Mottram's avatar
Bob Mottram committed
        update-initramfs -u -k "$(uname -r)" -v
        update-rc.d bluetooth remove
Bob Mottram's avatar
Bob Mottram committed
function running_as_root {
    if [[ $EUID != 0 ]] ; then
        echo "0"
    else
        echo "1"
    fi
}

Bob Mottram's avatar
Bob Mottram committed
function reset_usb_devices {
Bob Mottram's avatar
Bob Mottram committed
    for xhci in /sys/bus/pci/drivers/?hci-pci ; do
Bob Mottram's avatar
Bob Mottram committed

Bob Mottram's avatar
Bob Mottram committed
        if ! cd "$xhci" ; then
Bob Mottram's avatar
Bob Mottram committed
            return
        fi

Bob Mottram's avatar
Bob Mottram committed
        echo "Resetting devices from $xhci..."
Bob Mottram's avatar
Bob Mottram committed

        for i in ????:??:??.? ; do
            echo -n "$i" > unbind
            echo -n "$i" > bind
        done
    done
    udevadm control --reload-rules
}

function install_backports_kernel {
    # install backports kernel if possible
    architecture_type=$(uname -a)

    if [[ "$architecture_type" == *"amd64"* ]]; then
        package_installed=$(dpkg-query -W -f='${Package}\n' linux-image-amd64 2>/dev/null)
Bob Mottram's avatar
Bob Mottram committed
        if [ ! "$package_installed" ]; then
            $INSTALL_PACKAGES linux-image-amd64
Bob Mottram's avatar
Bob Mottram committed
function save_rsys_header {
    { echo "";
      echo "#################";
      echo "#### MODULES ####";
      echo "#################";
      echo '';
      echo 'module(load="imuxsock")';
      echo 'module(load="imklog")';
      echo '';
      echo '###########################';
      echo '#### GLOBAL DIRECTIVES ####';
      echo '###########################';
      echo '';
      echo "\$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat";
      echo '';
      echo "\$FileOwner root";
      echo "\$FileGroup adm";
      echo "\$FileCreateMode 0640";
      echo "\$DirCreateMode 0755";
      echo "\$Umask 0022";
      echo '';
      echo "\$WorkDirectory /var/spool/rsyslog";
      echo '';
      echo "\$IncludeConfig /etc/rsyslog.d/*.conf";
      echo '';
      echo '###############';
      echo '#### RULES ####';
      echo '###############';
      echo ''; } > /etc/rsyslog.conf
}

Bob Mottram's avatar
Bob Mottram committed
function turn_off_rsys_logging {
Bob Mottram's avatar
Bob Mottram committed
    save_rsys_header
    echo '*.*     ~' >> /etc/rsyslog.conf

    rm -rf /var/log/wtmp*
    rm -rf /var/log/debug*
    rm -rf /var/log/cron.*
    rm -rf /var/log/auth.*
    rm -rf /var/log/mail.*
    rm -rf /var/log/daemon.*
    rm -rf /var/log/user.*
    rm -rf /var/log/messages*
    rm -rf /var/log/syslog*
    rm -rf /var/log/alternatives*
    rm -rf /var/log/faillog
    rm -rf /var/log/kern.log*
Bob Mottram's avatar
Bob Mottram committed
}

function install_password_generator {
    if [[ $(is_completed "${FUNCNAME[0]}") == "1" ]]; then
        return
    fi
    $INSTALL_PACKAGES diceware
    mark_completed "${FUNCNAME[0]}"
}

Bob Mottram's avatar
Bob Mottram committed
function initial_setup {
Bob Mottram's avatar
Bob Mottram committed
    if [[ $(is_completed "${FUNCNAME[0]}") == "1" ]]; then
    $REMOVE_PACKAGES_PURGE apache2-bin*
Bob Mottram's avatar
Bob Mottram committed
    $UPGRADE_PACKAGES
    $INSTALL_PACKAGES ca-certificates
    $INSTALL_PACKAGES apt-utils
    $INSTALL_PACKAGES cryptsetup libgfshare-bin duplicity sshpass wget avahi-daemon
    $INSTALL_PACKAGES avahi-utils avahi-discover connect-proxy openssh-server
    $INSTALL_PACKAGES sudo git dialog build-essential avahi-daemon avahi-utils
    $INSTALL_PACKAGES avahi-discover iptables dnsutils net-tools
    $INSTALL_PACKAGES network-manager iputils-ping libnss-mdns libnss-myhostname
    $INSTALL_PACKAGES libnss-gw-name nano man ntp locales locales-all debconf
    $INSTALL_PACKAGES wireless-tools wpasupplicant usbutils zsh cpulimit screen
    $INSTALL_PACKAGES pinentry-curses eatmydata iotop bc hostapd

    # With some VMs, the hardware cycles counter is emulated and deterministic,
    # and thus predictible, so havege should not be used
    if [[ $ARCHITECTURE != 'qemu'* ]]; then
        $INSTALL_PACKAGES haveged
Bob Mottram's avatar
Bob Mottram committed
    if [[ $ARCHITECTURE == 'qemu'* || $ARCHITECTURE == 'amd64' || $ARCHITECTURE == 'x86_64' || $ARCHITECTURE == 'i686' || $ARCHITECTURE == 'i386' ]]; then
        $INSTALL_PACKAGES grub2 lvm2
Bob Mottram's avatar
Bob Mottram committed
    fi

Bob Mottram's avatar
Bob Mottram committed
    if [ ! -d "$INSTALL_DIR" ]; then
        mkdir -p "$INSTALL_DIR"
Bob Mottram's avatar
Bob Mottram committed
    mark_completed "${FUNCNAME[0]}"
Bob Mottram's avatar
Bob Mottram committed
function turn_off_magic_sysrq {
    if grep -q 'kernel.sysrq = 0' /etc/sysctl.conf; then
        return
    fi
    if grep -q 'kernel.sysrq' /etc/sysctl.conf; then
        sed -i 's|#kernel.sysrq.*|kernel.sysrq = 0|g' /etc/sysctl.conf
        sed -i 's|kernel.sysrq.*|kernel.sysrq = 0|g' /etc/sysctl.conf
    else
        echo 'kernel.sysrq = 0' >> /etc/sysctl.conf
    fi
}

Bob Mottram's avatar
Bob Mottram committed
function setup_grub {
    if [[ $ARCHITECTURE == 'qemu'* || $ARCHITECTURE == 'amd64' || $ARCHITECTURE == 'x86_64' || $ARCHITECTURE == 'i686' || $ARCHITECTURE == 'i386' ]]; then
Bob Mottram's avatar
Bob Mottram committed
        if ! grep -q 'ifnames=0' /etc/default/grub; then
Bob Mottram's avatar
Bob Mottram committed
            sed -i 's|GRUB_CMDLINE_LINUX_DEFAULT=.*|GRUB_CMDLINE_LINUX_DEFAULT="quiet ifnames=0 slub_debug=FZP slab_nomerge page_poison=1 panic=0"|g' /etc/default/grub
Bob Mottram's avatar
Bob Mottram committed
            update-grub
        fi
    fi
}

function admin_user_sudo {
Bob Mottram's avatar
Bob Mottram committed
    # shellcheck disable=SC2154
    if ! grep -q "$MY_USERNAME  ALL=(ALL) ALL" "$rootdir/etc/sudoers"; then
        echo "$MY_USERNAME  ALL=(ALL) ALL" >> "$rootdir/etc/sudoers"
Bob Mottram's avatar
Bob Mottram committed
function search_for_attached_usb_drive {
Bob Mottram's avatar
Bob Mottram committed
    # If a USB drive is attached then search for email,
    # gpg, ssh keys and emacs configuration
Bob Mottram's avatar
Bob Mottram committed
    if [[ $(is_completed "${FUNCNAME[0]}") == "1" ]]; then
Bob Mottram's avatar
Bob Mottram committed
        return
    fi
    USB_DRIVE=$(detect_connected_drives)
    # shellcheck disable=SC2086
Bob Mottram's avatar
Bob Mottram committed
    if [ -b $USB_DRIVE ]; then
        if [ ! -d $USB_MOUNT ]; then
            echo $'Mounting USB drive'
            mkdir $USB_MOUNT
            mount $USB_DRIVE $USB_MOUNT
        fi
Bob Mottram's avatar
Bob Mottram committed
        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
            if [ ! -f /home/$MY_USERNAME/.gnupg/secring.gpg ]; then
                echo $'GPG files did not copy'
                exit 73529
Bob Mottram's avatar
Bob Mottram committed
        if [ -f $USB_MOUNT/private_key.gpg ]; then
            echo $'GPG private key found on USB drive'
Bob Mottram's avatar
Bob Mottram committed
            MY_GPG_PRIVATE_KEY="$USB_MOUNT/private_key.gpg"
Bob Mottram's avatar
Bob Mottram committed
        if [ -f $USB_MOUNT/public_key.gpg ]; then
            echo $'GPG public key found on USB drive'
Bob Mottram's avatar
Bob Mottram committed
            MY_GPG_PUBLIC_KEY="$USB_MOUNT/public_key.gpg"
        if [ -f $USB_MOUNT/letsencrypt ]; then
            echo $'Copying letsencrypt keys"'
            cp -r $USB_MOUNT/letsencrypt /etc
        fi

Bob Mottram's avatar
Bob Mottram committed
        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
Bob Mottram's avatar
Bob Mottram committed
    mark_completed "${FUNCNAME[0]}"
Bob Mottram's avatar
Bob Mottram committed
}

function mark_admin_user_account {
Bob Mottram's avatar
Bob Mottram committed
    set_completion_param "Admin user" "$MY_USERNAME"
Bob Mottram's avatar
Bob Mottram committed
}

function remove_instructions_from_motd {
    if grep -q "## " /etc/motd; then
        sed -i '/## /d' /etc/motd
    fi
Bob Mottram's avatar
Bob Mottram committed
}

function remove_default_user {
Bob Mottram's avatar
Bob Mottram committed
    # 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
Bob Mottram's avatar
Bob Mottram committed
function create_completion_file {
Bob Mottram's avatar
Bob Mottram committed
    if [ ! -f "$COMPLETION_FILE" ]; then
        touch "$COMPLETION_FILE"
Bob Mottram's avatar
Bob Mottram committed
}

function remove_management_engine_interface {
    # see https://www.kernel.org/doc/Documentation/misc-devices/mei/mei.txt
    # Disabling this interface doesn't cure the problems of ME, but it
    # might stop an adversary in control of AMT from using the command
    # interface to control the operating system.
    if [ -f /dev/mei0 ]; then
        rmmod mei_me
        rmmod mei0
    fi

    blacklist_changed=
    if [ ! -f /etc/modprobe.d/blacklist.conf ]; then
        touch /etc/modprobe.d/blacklist.conf
        blacklist_changed=1
    fi
    if ! grep -q "blacklist mei" /etc/modprobe.d/blacklist.conf; then
        echo "blacklist mei" >> /etc/modprobe.d/blacklist.conf
        blacklist_changed=1
    fi
    if ! grep -q "blacklist mei_me" /etc/modprobe.d/blacklist.conf; then
        echo "blacklist mei_me" >> /etc/modprobe.d/blacklist.conf
        blacklist_changed=1
    fi

    if [ $blacklist_changed ]; then
        depmod -ae -E
        update-initramfs -u
Bob Mottram's avatar
Bob Mottram committed
function set_login_umask {
Bob Mottram's avatar
Bob Mottram committed
    logindefs_umask=$(grep UMASK /etc/login.defs | grep -v '#')
    if [[ "$logindefs_umask" != *'077' ]]; then
        sed -i 's|UMASK\t.*|UMASK\t\t077|g' /etc/login.defs
    fi
Bob Mottram's avatar
Bob Mottram committed
}

Bob Mottram's avatar
Bob Mottram committed
function disable_deferred_execution {
    systemctl stop atd
    systemctl disable atd
}

Bob Mottram's avatar
Bob Mottram committed
function set_shadow_permissions {
    chown root:root /etc/shadow
    chmod 0000 /etc/shadow
    chown root:root /etc/gshadow
    chmod 0000 /etc/gshadow
}

Bob Mottram's avatar
Bob Mottram committed
function set_max_login_tries {
    max_tries=$1

Bob Mottram's avatar
Bob Mottram committed
    if ! grep -q ' deny=' /etc/pam.d/common-auth; then
Bob Mottram's avatar
Bob Mottram committed
        sed -i "/pam_deny.so/a auth    required\\t\\t\\tpam_tally.so    onerr=fail no_lock_time per_user deny=$max_tries" /etc/pam.d/common-auth
Bob Mottram's avatar
Bob Mottram committed
    else
        if ! grep -q " deny=$max_tries" /etc/pam.d/common-auth; then
            sed -i "s| deny=.*| deny=$max_tries|g" /etc/pam.d/common-auth
        fi
Bob Mottram's avatar
Bob Mottram committed
    if ! grep -q 'pam_tally.so' /etc/pam.d/common-account; then
        sed -i '/pam_deny.so/a account required\t\t\tpam_tally.so' /etc/pam.d/common-account
function limit_user_logins {
    # overall max logins
Bob Mottram's avatar
Bob Mottram committed
    if ! grep -q '\* hard maxsyslogins' /etc/security/limits.conf; then
        echo '* hard maxsyslogins 10' >> /etc/security/limits.conf
    else
Bob Mottram's avatar
Bob Mottram committed
        if ! grep -q '\* hard maxsyslogins 10' /etc/security/limits.conf; then
            sed -i 's|hard maxsyslogins.*|hard maxsyslogins 10|g' /etc/security/limits.conf
        fi
    fi

    # Max logins for each user
Bob Mottram's avatar
Bob Mottram committed
    if ! grep -q '\* hard maxlogins' /etc/security/limits.conf; then
        echo '* hard maxlogins 2' >> /etc/security/limits.conf
    else
Bob Mottram's avatar
Bob Mottram committed
        if ! grep -q '\* hard maxlogins 2' /etc/security/limits.conf; then
            sed -i 's|hard maxlogins.*|hard maxlogins 2|g' /etc/security/limits.conf
        fi
function remove_serial_logins {
Bob Mottram's avatar
Bob Mottram committed
    if grep -q 'ttyS' /etc/securetty; then
        cp /etc/securetty /etc/securetty_old
        sed -i '/ttyS/d' /etc/securetty
    fi
}

Bob Mottram's avatar
Bob Mottram committed
function set_sticky_bits {
    world_writable=$(find / -xdev -type d -perm -002 \! -perm -1000)
    for w in $world_writable; do
        echo "Setting sticky bit on $w"
Bob Mottram's avatar
Bob Mottram committed
        chmod +t "$w"
Bob Mottram's avatar
Bob Mottram committed
    done
}

function disable_ctrl_alt_del {
    ctrl_alt_del=$(ls -l /etc/systemd/system/ctrl-alt-del.target)
    if [[ "$ctrl_alt_del" !=  *'/dev/null' ]]; then
        ln -sf /dev/null /etc/systemd/system/ctrl-alt-del.target
    fi
Bob Mottram's avatar
Bob Mottram committed
function lockdown_permissions {
Bob Mottram's avatar
Bob Mottram committed
    if [ -d /root/.npm ]; then
        chmod -R 700 /root/.npm
    # All commands owned by root
    if [ -d /root/.cache/yarn ]; then
        rm -rf /root/.cache/yarn
    fi
Bob Mottram's avatar
Bob Mottram committed
    if [ -d /usr/local/share/.cache/yarn ]; then
        rm -rf /usr/local/share/.cache/yarn
    fi
    if [ -f /usr/lib/ssl/certs/ssl-cert-snakeoil.pem ]; then
        chown root:root /usr/lib/ssl/certs/ssl-cert-snake*
    fi
    if [ -d /bin ]; then
        chown root:root /bin/*
    fi
    if [ -d /usr/bin ]; then
        chown root:root /usr/bin/*
    fi
    if [ -d /usr/local/bin ]; then
        chown root:root /usr/local/bin/*
    fi
    if [ -d /sbin ]; then
        chown root:root /sbin/*
    fi
    if [ -d /usr/sbin ]; then
        chown root:root /usr/sbin/*
    fi
    if [ -d /usr/local/sbin ]; then
        chown root:root /usr/local/sbin/*
    fi
    if [ -d /usr/share/${PROJECT_NAME} ]; then
        chown -R root:root /usr/share/${PROJECT_NAME}
        chmod -R +r /usr/share/${PROJECT_NAME}
    fi
Bob Mottram's avatar
Bob Mottram committed

    # All libraries owned by root
Bob Mottram's avatar
Bob Mottram committed
    if [ -d /lib ]; then
        chown -R root:root /lib/*
    fi
    if [ -d /lib64 ]; then
        chown -R root:root /lib64/*
    fi
    if [ -d /usr/lib ]; then
        chown -R root:root /usr/lib/*
Bob Mottram's avatar
Bob Mottram committed
        if [ -d /usr/lib/node_modules ]; then
            chmod -R 750 /usr/lib/node_modules/*
        fi
        if [ -d /usr/lib/prosody ]; then
            chown -R prosody:prosody /usr/lib/prosody
        fi
Bob Mottram's avatar
Bob Mottram committed
    fi
    if [ -d /usr/lib64 ]; then
        chown -R root:root /usr/lib64/*
    fi
    # sudo permissions
    chmod 4755 /usr/bin/sudo
    chmod 4755 /usr/lib/sudo/sudoers.so
    chown root:root /etc/sudoers
    # permissions on email commands
    if [ -f /usr/bin/procmail ]; then
        chmod 6755 /usr/bin/procmail
    fi
    if [ -f /usr/sbin/exim ]; then
        chmod u+s /usr/sbin/exim
    fi
    if [ -f /usr/sbin/exim4 ]; then
        chmod u+s /usr/sbin/exim4
    fi
Bob Mottram's avatar
Bob Mottram committed

    set_sticky_bits

    # Create some directories to correspond with users in passwords file
    if [ ! -d /var/spool/lpd ]; then
        mkdir /var/spool/lpd
    fi
    if [ ! -d /var/spool/news ]; then
        mkdir /var/spool/news
    fi
    if [ ! -d /var/spool/uucp ]; then
        mkdir /var/spool/uucp
    fi
    if [ ! -d /var/list ]; then
        mkdir /var/list
    fi
    if [ ! -d /var/lib/gnats ]; then
        mkdir /var/lib/gnats
    fi
    if [ ! -d /var/lib/saned ]; then
        mkdir /var/lib/saned
    fi
Bob Mottram's avatar
Bob Mottram committed
    if [ -d /etc/prosody ]; then
Bob Mottram's avatar
Bob Mottram committed
        chown -R prosody /etc/prosody
Bob Mottram's avatar
Bob Mottram committed
        chmod -R 700 /etc/prosody/conf.d
Bob Mottram's avatar
Bob Mottram committed
    if [ -d /var/lib/prosody ]; then
Bob Mottram's avatar
Bob Mottram committed
        chown -R prosody /var/lib/prosody
    fi
Bob Mottram's avatar
Bob Mottram committed
    if [ -d /etc/letsencrypt ]; then
        chmod -R 600 /etc/letsencrypt
        chmod -R g=rX /etc/letsencrypt
        chown -R root:ssl-cert /etc/letsencrypt
Bob Mottram's avatar
Bob Mottram committed
    fi
    chown -f root:root /etc/motd /etc/issue*
    chmod -f 0444 /etc/motd /etc/issue*
Bob Mottram's avatar
Bob Mottram committed
function disable_core_dumps {
Bob Mottram's avatar
Bob Mottram committed
    if ! grep -q '\* hard core' /etc/security/limits.conf; then
Bob Mottram's avatar
Bob Mottram committed
        echo '* hard core 0' >> /etc/security/limits.conf
    else
Bob Mottram's avatar
Bob Mottram committed
        if ! grep -q '\* hard core 0' /etc/security/limits.conf; then
            sed -i 's|hard core.*|hard core 0|g' /etc/security/limits.conf
        fi
Bob Mottram's avatar
Bob Mottram committed
function dummy_nologin_command {
    if [ ! -f /sbin/nologin ]; then
        echo '#!/bin/bash' > /sbin/nologin
        chmod +x /sbin/nologin
    fi
}

Bob Mottram's avatar
Bob Mottram committed
function disable_null_passwords {
    if grep -q ' nullok_secure' /etc/pam.d/common-auth; then
        sed -i 's| nullok_secure||g' /etc/pam.d/common-auth
    fi
Bob Mottram's avatar
Bob Mottram committed
function create_usb_canary {
    if [[ $SYSTEM_TYPE == "mesh"* ]]; then
        return
    fi
Bob Mottram's avatar
Bob Mottram committed
    if [[ $(is_completed "${FUNCNAME[0]}") == "1" ]]; then
Bob Mottram's avatar
Bob Mottram committed
    echo "ACTION==\"add\", KERNEL==\"sd*[!0-9]\", RUN+=\"/bin/bash /usr/local/bin/${PROJECT_NAME}-usb-canary\"" > /etc/udev/rules.d/00-usb-canary.rules
Bob Mottram's avatar
Bob Mottram committed
    udevadm control --reload-rules
Bob Mottram's avatar
Bob Mottram committed
    mark_completed "${FUNCNAME[0]}"
Bob Mottram's avatar
Bob Mottram committed
}

function install_vulnerability_checkers {
    if [[ $(is_completed "${FUNCNAME[0]}") == "1" ]]; then
        return
    fi
    $INSTALL_PACKAGES_BACKPORTS spectre-meltdown-checker
    mark_completed "${FUNCNAME[0]}"
}

Bob Mottram's avatar
Bob Mottram committed
function setup_firewall {
Bob Mottram's avatar
Bob Mottram committed
    function_check create_completion_file
    create_completion_file
Bob Mottram's avatar
Bob Mottram committed

Bob Mottram's avatar
Bob Mottram committed
    function_check configure_firewall
    configure_firewall
Bob Mottram's avatar
Bob Mottram committed

Bob Mottram's avatar
Bob Mottram committed
    function_check block_firefox_telemetry
    block_firefox_telemetry

Bob Mottram's avatar
Bob Mottram committed
    function_check configure_firewall_ping
    configure_firewall_ping
Bob Mottram's avatar
Bob Mottram committed

Bob Mottram's avatar
Bob Mottram committed
    function_check firewall_handle_port_scans
    firewall_handle_port_scans

    function_check firewall_drop_telnet
    firewall_drop_telnet

Bob Mottram's avatar
Bob Mottram committed
    function_check firewall_drop_spoofed_packets
    firewall_drop_spoofed_packets

    function_check firewall_rate_limits
    firewall_rate_limits

Bob Mottram's avatar
Bob Mottram committed
    function_check configure_firewall_for_dns
    configure_firewall_for_dns
Bob Mottram's avatar
Bob Mottram committed

Bob Mottram's avatar
Bob Mottram committed
    function_check configure_firewall_for_avahi
    configure_firewall_for_avahi

    function_check global_rate_limit
    global_rate_limit
Bob Mottram's avatar
Bob Mottram committed

    function_check firewall_block_bad_ip_ranges
    firewall_block_bad_ip_ranges
Bob Mottram's avatar
Bob Mottram committed
function setup_powerline {
Bob Mottram's avatar
Bob Mottram committed
    if [ -f ~/${PROJECT_NAME}/src/${PROJECT_NAME}-powerline ]; then
        if [ ! -f ~/.powerline.bash ]; then
            cp ~/${PROJECT_NAME}/src/${PROJECT_NAME}-powerline ~/.powerline.bash
        else
            HASH1=$(sha256sum ~/${PROJECT_NAME}/src/${PROJECT_NAME}-powerline | awk -F ' ' '{print $1}')
            HASH2=$(sha256sum ~/.powerline.bash | awk -F ' ' '{print $1}')
            if [[ "$HASH1" != "$HASH2" ]]; then
                cp ~/${PROJECT_NAME}/src/${PROJECT_NAME}-powerline ~/.powerline.bash
            fi
        fi
        if [ ! -f /etc/skel/.powerline.bash ]; then
            cp ~/${PROJECT_NAME}/src/${PROJECT_NAME}-powerline /etc/skel/.powerline.bash
        else
            HASH1=$(sha256sum ~/${PROJECT_NAME}/src/${PROJECT_NAME}-powerline | awk -F ' ' '{print $1}')
            HASH2=$(sha256sum /etc/skel/.powerline.bash | awk -F ' ' '{print $1}')
            if [[ "$HASH1" != "$HASH2" ]]; then
                cp ~/${PROJECT_NAME}/src/${PROJECT_NAME}-powerline /etc/skel/.powerline.bash
            fi
        fi
Bob Mottram's avatar
Bob Mottram committed
    else
Bob Mottram's avatar
Bob Mottram committed
        if [ -f /home/${MY_USERNAME}/${PROJECT_NAME}/src/${PROJECT_NAME}-powerline ]; then
            if [ ! -f ~/.powerline.bash ]; then
                cp /home/${MY_USERNAME}/${PROJECT_NAME}/src/${PROJECT_NAME}-powerline ~/.powerline.bash
            else
                HASH1=$(sha256sum /home/${MY_USERNAME}/${PROJECT_NAME}/src/${PROJECT_NAME}-powerline | awk -F ' ' '{print $1}')
                HASH2=$(sha256sum ~/.powerline.bash | awk -F ' ' '{print $1}')
                if [[ "$HASH1" != "$HASH2" ]]; then
                    cp /home/${MY_USERNAME}/${PROJECT_NAME}/src/${PROJECT_NAME}-powerline ~/.powerline.bash
                fi
            fi

            if [ ! -f /etc/skel/.powerline.bash ]; then
                cp /home/${MY_USERNAME}/${PROJECT_NAME}/src/${PROJECT_NAME}-powerline /etc/skel/.powerline.bash
            else
                HASH1=$(sha256sum /home/${MY_USERNAME}/${PROJECT_NAME}/src/${PROJECT_NAME}-powerline | awk -F ' ' '{print $1}')
                HASH2=$(sha256sum /etc/skel/.powerline.bash | awk -F ' ' '{print $1}')
                if [[ "$HASH1" != "$HASH2" ]]; then
                    cp /home/${MY_USERNAME}/${PROJECT_NAME}/src/${PROJECT_NAME}-powerline /etc/skel/.powerline.bash
                fi
            fi
Bob Mottram's avatar
Bob Mottram committed
        fi
    fi
    if ! grep -q "powerline" ~/.bashrc; then
        if [ -f ~/.powerline.bash ]; then
            echo 'source ~/.powerline.bash' >> ~/.bashrc
        fi
    fi
    if ! grep -q "powerline" /etc/skel/.bashrc; then
        if [ -f /etc/skel/.powerline.bash ]; then
            echo 'source ~/.powerline.bash' >> /etc/skel/.bashrc
        fi
    fi
}

function congestion_control {
    # see /proc/sys/net/ipv4/tcp_congestion_control
    if [ ! -f /etc/sysctl.d/10-custom-kernel-bbr.conf ]; then
        echo 'net.core.default_qdisc=fq' > /etc/sysctl.d/10-custom-kernel-bbr.conf
        echo 'net.ipv4.tcp_congestion_control=bbr' >> /etc/sysctl.d/10-custom-kernel-bbr.conf
        sysctl --system
    fi
function install_shellcheck {
    # Used by the tests command
    $INSTALL_PACKAGES shellcheck
function install_webcam {
    # Used by the USB canary
    $INSTALL_PACKAGES fswebcam
}

function microsd_card_optimisations {
    # These values can improve performance on microSD cards
    $INSTALL_PACKAGES hdparm
    printf '#!/bin/bash\n' > /usr/bin/enable_optimisations

    if [ -f /sys/devices/virtual/bdi/179:0/read_ahead_kb ]; then
        echo -n '4096' > /sys/devices/virtual/bdi/179:0/read_ahead_kb
        echo "echo -n '4096' > /sys/devices/virtual/bdi/179:0/read_ahead_kb" >> /usr/bin/enable_optimisations
    fi

    if [ -f /proc/sys/vm/dirty_expire_centisecs ]; then
        echo -n '100' > /proc/sys/vm/dirty_expire_centisecs
        echo "echo -n '100' > /proc/sys/vm/dirty_expire_centisecs" >> /usr/bin/enable_optimisations

    if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
        echo -n '100' > /proc/sys/vm/dirty_writeback_centisecs
        echo "echo -n '100' > /proc/sys/vm/dirty_writeback_centisecs" >> /usr/bin/enable_optimisations
    fi

    chmod +x /usr/bin/enable_optimisations

    { echo '[Unit]';
      echo "Description=${PROJECT_NAME} optimisations";
      echo 'After=syslog.target';
      echo 'After=network.target';
      echo 'After=remote-fs.target';
      echo '';
      echo '[Service]';
      echo 'Type=simple';
      echo 'User=root';
      echo 'Group=root';
      echo 'WorkingDirectory=/root';
      echo 'ExecStart=/usr/bin/enable_optimisations';
      echo '';
      echo '[Install]';
      echo 'WantedBy=multi-user.target'; } > /etc/systemd/system/optimisations.service
      systemctl enable optimisations
Bob Mottram's avatar
Bob Mottram committed
function install_myqr {
    ARCH=$(uname -m)
    if [[ "$ARCH" != 'x86'* && "$ARCH" != 'amd64' ]]; then
        return
    fi
Bob Mottram's avatar
Bob Mottram committed
    if [ -f /usr/local/bin/myqr ]; then
        return
    fi
    $INSTALL_PACKAGES python3-pip
    pip3 install myqr
    if [ ! -f /usr/local/bin/myqr ]; then
        echo $'Failed to install myqr'
        exit 3683653
    fi
}

function setup_utils {
Bob Mottram's avatar
Bob Mottram committed
    read_config_param "PROJECT_REPO"
    write_config_param "PROJECT_REPO" "$PROJECT_REPO"

    function_check remove_management_engine_interface
    remove_management_engine_interface
    function_check support_256_colours
    support_256_colours

    function_check congestion_control
    congestion_control

    function_check install_password_generator
    install_password_generator

Bob Mottram's avatar
Bob Mottram committed
    function_check enable_predictable_device_names
    enable_predictable_device_names

Bob Mottram's avatar
Bob Mottram committed
    function_check turn_off_magic_sysrq
    turn_off_magic_sysrq

Bob Mottram's avatar
Bob Mottram committed
    function_check separate_tmp_filesystem
    separate_tmp_filesystem 150
    function_check microsd_card_optimisations
    microsd_card_optimisations
Bob Mottram's avatar
Bob Mottram committed
    function_check proc_filesystem_settings
    proc_filesystem_settings

    function_check optimise_filesystem
    optimise_filesystem

Bob Mottram's avatar
Bob Mottram committed
    function_check disable_null_passwords
    disable_null_passwords

    function_check disable_ctrl_alt_del
    disable_ctrl_alt_del

Bob Mottram's avatar
Bob Mottram committed
    function_check dummy_nologin_command
    dummy_nologin_command

Bob Mottram's avatar
Bob Mottram committed
    function_check disable_core_dumps
    disable_core_dumps

    function_check remove_serial_logins
    remove_serial_logins

Bob Mottram's avatar
Bob Mottram committed
    function_check set_max_login_tries
    set_max_login_tries 10

Bob Mottram's avatar
Bob Mottram committed
    function_check set_shadow_permissions
    set_shadow_permissions

Bob Mottram's avatar
Bob Mottram committed
    function_check remove_bluetooth
    remove_bluetooth

Bob Mottram's avatar
Bob Mottram committed
    function_check set_login_umask
    set_login_umask

Bob Mottram's avatar
Bob Mottram committed
    function_check disable_deferred_execution
    disable_deferred_execution

Bob Mottram's avatar
Bob Mottram committed
    function_check turn_off_rsys_logging
    turn_off_rsys_logging

    function_check install_backports_kernel
    install_backports_kernel

Bob Mottram's avatar
Bob Mottram committed
    function_check create_completion_file
    create_completion_file
Bob Mottram's avatar
Bob Mottram committed

Bob Mottram's avatar
Bob Mottram committed
    function_check read_configuration
    read_configuration
Bob Mottram's avatar
Bob Mottram committed

Bob Mottram's avatar
Bob Mottram committed
    function_check check_system_type
    check_system_type

Bob Mottram's avatar
Bob Mottram committed
    function_check set_default_onion_domains
    set_default_onion_domains
Bob Mottram's avatar
Bob Mottram committed

Bob Mottram's avatar
Bob Mottram committed
    function_check locale_setup
    locale_setup
Bob Mottram's avatar
Bob Mottram committed

Bob Mottram's avatar
Bob Mottram committed
    function_check parse_args
    parse_args
Bob Mottram's avatar
Bob Mottram committed

Bob Mottram's avatar
Bob Mottram committed
    function_check check_domains
    check_domains
Bob Mottram's avatar
Bob Mottram committed

Bob Mottram's avatar
Bob Mottram committed
    function_check install_static_network
    install_static_network
Bob Mottram's avatar
Bob Mottram committed

Bob Mottram's avatar
Bob Mottram committed
    function_check remove_default_user
    remove_default_user
Bob Mottram's avatar
Bob Mottram committed

Bob Mottram's avatar
Bob Mottram committed
    function_check setup_firewall
    setup_firewall
Bob Mottram's avatar
Bob Mottram committed

Bob Mottram's avatar
Bob Mottram committed
    function_check create_repo_sources
    create_repo_sources
Bob Mottram's avatar
Bob Mottram committed

Bob Mottram's avatar
Bob Mottram committed
    function_check configure_dns
    configure_dns
Bob Mottram's avatar
Bob Mottram committed

Bob Mottram's avatar
Bob Mottram committed
    function_check initial_setup
    initial_setup
Bob Mottram's avatar
Bob Mottram committed