From f1791359419072e51d356116a06432c9b504d678 Mon Sep 17 00:00:00 2001 From: myve Date: Fri, 22 Mar 2024 13:22:19 -0600 Subject: [PATCH] Update mail-root.sh --- mail-root.sh | 231 +++++++++++ mail.sh | 1112 -------------------------------------------------- 2 files changed, 231 insertions(+), 1112 deletions(-) create mode 100644 mail-root.sh delete mode 100644 mail.sh diff --git a/mail-root.sh b/mail-root.sh new file mode 100644 index 0000000..dfee12c --- /dev/null +++ b/mail-root.sh @@ -0,0 +1,231 @@ +#!/usr/bin/env bash +set -a +set -e + +# Script is meant for Debian +hostnamectl | grep -q 'Debian' || exit 1 + +# Insert SSH keys here +sshkeys='' + +# Backup mailservers +backup_mailserver='' + +# Exit function +function die +{ + read -n 1 -s -p $'\n\e[1;33mError encountered, exiting...\e[0m\n' + exit 1 +} + +# Grab options +while [ ${1} != "" ] +do + case ${1} in + -u | --user ) + if [ ${2} != "" ] + then + username=${2} + shift + fi + ;; + -p | --port ) + if [ ${2} != "" ] + then + ssh_port=${2} + shift + fi + ;; + -d | --domain ) + if [ ${2} != "" ] + then + domain=${2} + shift + fi + ;; + -? | -h | --help ) + cat <&2 + exit 1 + ;; + esac + shift +done + +clear + +# Assign random alternate SSH port +if [ -z ${ssh_port} ] +then + ssh_port=$(shuf -i 10027-65000 -n 1) +fi + +# Random username +if [ -z ${username} ] +then + username=$(cat /dev/urandom | tr -d -c 'a-z' | fold -w 8 | head -n 1) +fi + +# Domain +if [ -z ${domain} ] +then + echo -e '\e[1;34mType in your full mail domain name (eg. mael.elgoog.com)\e[0m' + until [ "${domain}" ] + do + read -r -p 'Domain name: ' domain + [ "${domain}" ] || echo -e '\n\e[1;31mDomain name cannot be empty, try again\e[0m' + done + echo +fi + +# Superuser password +echo -e '\e[1;34mCreate a root superuser password\e[0m' +until [ "${rootpass}" = "${rootpass2}" -a "${rootpass}" ] +do + read -s -r -p 'Superuser password: ' rootpass + read -s -r -p $'\nVerify superuser password: ' rootpass2 + if [ -z "${rootpass}" ] + then + echo -e '\n\n\e[1;31mPassword field cannot be empty, try again\e[0m' + elif [ "${rootpass}" != "${rootpass2}" ] + then + echo -e '\n\n\e[1;31mPasswords did not match, try again\e[0m' + fi +done +printf '%s\n' "${rootpass}" "${rootpass}" | passwd &>/dev/null +echo -e '\n\n\e[1;32mRoot superuser password has been saved\e[0m\n' +unset rootpass rootpass2 + +# User password +echo -e '\e[1;34mSet a password for '"${username}"'\e[0m' +until [ "${userpass}" = "${userpass2}" -a "${userpass}" ] +do + read -s -r -p 'User password: ' userpass + read -s -r -p $'\nVerify user password: ' userpass2 + if [ -z "${userpass}" ] + then + echo -e '\n\n\e[1;31mPassword field cannot be empty, try again\e[0m' + elif [ "${userpass}" != "${userpass2}" ] + then + echo -e '\n\n\e[1;31mPasswords did not match, try again\e[0m' + fi +done +printf '%s\n' "${userpass}" "${userpass}" "" "" "" "" "" | adduser ${username} &>/dev/null +echo -e '\n\n\e[1;32mPassword for '${username}'@'${domain}' -p' ${ssh_port}' has been saved\e[0m\n' +unset userpass userpass2 + +echo -e '\e[1;34mUpgrading system...\e[0m' +apt remove -y nano exim* &>/dev/null +apt update -y || die +apt upgrade -y || die +apt dist-upgrade -y || die + +apt install -y sudo ufw vim fail2ban wget telnet dnsutils rsyslog zram-tools \ + || die 'Apt failed' + +# cron rsyslog +sed -i 's/#cron/cron/' /etc/rsyslog.conf + +# ufw firewall +ufw allow ${ssh_port}/tcp >/dev/null +yes | ufw enable >/dev/null +systemctl -q enable --now ufw fail2ban + +# fail2ban +tee /etc/fail2ban/jail.d/sshd.conf >/dev/null <<'SSHD' +[sshd] +enabled = true +filter = sshd +backend = systemd +maxretry = 5 +findtime = 1d +bantime = 4w +ignoreip = 127.0.0.1/8 +SSHD +install /dev/stdin /usr/local/bin/fail2ban-jails <<'ALL-JAILS' +#!/bin/bash +JAILS=$(sudo fail2ban-client status | grep "Jail list" | sed -E 's/^[^:]+:[ \t]+//' | sed 's/,//g') +for JAIL in $JAILS +do + sudo fail2ban-client status $JAIL +done +ALL-JAILS + +# zram swap +echo -e "ALGO=zstd\nPERCENT=60" >>/etc/default/zramswap + +# Shut up fstrim +rm -f /etc/cron.weekly/fstrim &>/dev/null + +# Hostname and unix users +hostnamectl set-hostname ${domain} +sed -i '/127.0.0.1/ s/$/ '${domain}'/' /etc/hosts +adduser ${username} sudo &>/dev/null + +# SSH settings +echo "Port ${ssh_port} +PermitRootLogin no +PasswordAuthentication no +Protocol 2" >/etc/ssh/sshd_config.d/zz-ssh.conf + +# Disable history saving +cat >>~/.bashrc <>/usr/local/bin/mail-server + + su ${username} <<"CHANGEUSER" + # SSH + yes | ssh-keygen -t ed25519 -q -f ~/.ssh/id_ed25519 -P "" + echo "${sshkeys}" >~/.ssh/authorized_keys +CHANGEUSER + + echo -e '\n\e[1m\t## Run "mail-server" immediately\n\e[0m' + su ${username} + + clear + echo -e "### +### Login ssh as new user +### +while : +do + clear + if ssh ${username}@${domain} -p ${ssh_port} exit + then + echo -e '\e[1m## Run "~/dhparam" upon logging in\n\e[0m' + ssh ${username}@${domain} -p ${ssh_port} + break + else + sleep 1 + fi +done\n" + + . ~/.bashrc + reboot +fi \ No newline at end of file diff --git a/mail.sh b/mail.sh deleted file mode 100644 index 835081f..0000000 --- a/mail.sh +++ /dev/null @@ -1,1112 +0,0 @@ -#!/usr/bin/env bash -set -a - -# Script is meant for Debian -hostnamectl | grep -q 'Debian' || exit 1 - -# Insert SSH keys here -sshkeys='' - -# Backup mailservers -backup_mailserver='' - -# Exit function -function die -{ - read -n 1 -s -p $'\n\e[1;33mError encountered, exiting...\e[0m\n' - exit 1 -} - -# Grab options -while [ ${1} != "" ] -do - case ${1} in - -u | --user ) - if [ ${2} != "" ] - then - username=${2} - shift - fi - ;; - -p | --port ) - if [ ${2} != "" ] - then - ssh_port=${2} - shift - fi - ;; - -d | --domain ) - if [ ${2} != "" ] - then - domain=${2} - shift - fi - ;; - -? | -h | --help ) - cat <&2 - exit 1 - ;; - esac - shift -done - -clear - -# Assign random alternate SSH port -if [ -z ${ssh_port} ] -then - ssh_port=$(shuf -i 10027-65000 -n 1) -fi - -# Random username -if [ -z ${username} ] -then - username=$(cat /dev/urandom | tr -d -c 'a-z' | fold -w 8 | head -n 1) -fi - -# Domain -if [ -z ${domain} ] -then - echo -e '\e[1;34mType in your full mail domain name (eg. mael.elgoog.com)\e[0m' - until [ "${domain}" ] - do - read -r -p 'Domain name: ' domain - [ "${domain}" ] || echo -e '\n\e[1;31mDomain name cannot be empty, try again\e[0m' - done - echo -fi - -# Superuser password -echo -e '\e[1;34mCreate a root superuser password\e[0m' -until [ "${rootpass}" = "${rootpass2}" -a "${rootpass}" ] -do - read -s -r -p 'Superuser password: ' rootpass - read -s -r -p $'\nVerify superuser password: ' rootpass2 - if [ -z "${rootpass}" ] - then - echo -e '\n\n\e[1;31mPassword field cannot be empty, try again\e[0m' - elif [ "${rootpass}" != "${rootpass2}" ] - then - echo -e '\n\n\e[1;31mPasswords did not match, try again\e[0m' - fi -done -printf '%s\n' "${rootpass}" "${rootpass}" | passwd &>/dev/null -echo -e '\n\n\e[1;32mRoot superuser password has been saved\e[0m\n' -unset rootpass rootpass2 - -# User password -echo -e '\e[1;34mSet a password for '"${username}"'\e[0m' -until [ "${userpass}" = "${userpass2}" -a "${userpass}" ] -do - read -s -r -p 'User password: ' userpass - read -s -r -p $'\nVerify user password: ' userpass2 - if [ -z "${userpass}" ] - then - echo -e '\n\n\e[1;31mPassword field cannot be empty, try again\e[0m' - elif [ "${userpass}" != "${userpass2}" ] - then - echo -e '\n\n\e[1;31mPasswords did not match, try again\e[0m' - fi -done -printf '%s\n' "${userpass}" "${userpass}" "" "" "" "" "" | adduser ${username} &>/dev/null -echo -e '\n\n\e[1;32mPassword for '${username}'@'${domain}' -p' ${ssh_port}' has been saved\e[0m\n' -unset userpass userpass2 - -echo -e '\e[1;34mUpgrading system...\e[0m' -apt remove -y nano exim* &>/dev/null -apt update -y || die -apt upgrade -y || die -apt dist-upgrade -y || die - -debconf-set-selections <<< "postfix postfix/mailname string $(echo ${domain} | awk -F . '{print $2}').$(echo ${domain} | awk -F . '{print $3}')" -debconf-set-selections <<< "postfix postfix/main_mailer_type string 'Internet Site'" -apt install -y sudo ufw vim fail2ban wget telnet dnsutils rsyslog zram-tools \ - composer git acl dbconfig-no-thanks \ - nginx certbot python3-certbot-nginx \ - mariadb-server mariadb-client postfix-mysql dovecot-mysql \ - php php-fpm php-imap php-mbstring php-mysql php-json php-curl php-zip php-xml php-bz2 php-intl php-gmp php-net-ldap3 php-imagick php-common php-gd php-sqlite3 php-cli \ - postfix postfix-pcre \ - dovecot-core dovecot-imapd dovecot-lmtpd \ - postfix-policyd-spf-python opendkim opendkim-tools \ - opendmarc || die 'Apt failed' - -# cron rsyslog -sed -i 's/#cron/cron/' /etc/rsyslog.conf - -# ufw firewall -ufw allow ${ssh_port}/tcp >/dev/null -yes | ufw enable >/dev/null -systemctl -q enable --now ufw fail2ban - -# fail2ban -tee /etc/fail2ban/jail.d/sshd.conf >/dev/null <<'SSHD' -[sshd] -enabled = true -filter = sshd -backend = systemd -maxretry = 5 -findtime = 1d -bantime = 4w -ignoreip = 127.0.0.1/8 -SSHD -install /dev/stdin /usr/local/bin/fail2ban-jails <<'ALL-JAILS' -#!/bin/bash -JAILS=$(sudo fail2ban-client status | grep "Jail list" | sed -E 's/^[^:]+:[ \t]+//' | sed 's/,//g') -for JAIL in $JAILS -do - sudo fail2ban-client status $JAIL -done -ALL-JAILS - -# zram swap -echo -e "ALGO=zstd\nPERCENT=60" >>/etc/default/zramswap - -# Shut up fstrim -rm -f /etc/cron.weekly/fstrim &>/dev/null - -# Hostname and unix users -hostnamectl set-hostname ${domain} -sed -i '/127.0.0.1/ s/$/ '${domain}'/' /etc/hosts -adduser ${username} sudo &>/dev/null - -# SSH settings -echo "Port ${ssh_port} -PermitRootLogin no -PasswordAuthentication no -Protocol 2" >/etc/ssh/sshd_config.d/zz-ssh.conf - -# Disable history saving -cat >>~/.bashrc </dev/null <<'MAILSERVER' - -# UFW -sudo ufw allow 25/tcp &>/dev/null -sudo ufw allow 80,443/tcp >/dev/null -sudo ufw allow 587/tcp >/dev/null -sudo ufw allow 143,993/tcp >/dev/null - -# Check port 25 -echo -if ! grep -q 'Connected to' <<< $(printf 'quit' | telnet -4 gmail-smtp-in.l.google.com 25) -then - echo -e '\n\e[1;31mPort 25 needs to be open for mail server installation to continue, exiting...\e[0m\n' - exit -fi - -# Exit function -function die -{ - read -n 1 -s -p $'\n\e[1;33mError encountered, exiting...\e[0m\n' - exit 1 -} - -# Static variables -ip_addr=$(wget -q4O- ipv4.icanhazip.com) -subdomain=$(hostname | awk -F . '{print $1}') -domain="$(hostname | awk -F . '{print $2}').$(hostname | awk -F . '{print $3}')" -eff_email='eff@'${domain} -roundcubedbpass=$(cat /dev/urandom | tr -d -c 'a-zA-Z0-9' | fold -w 128 | head -n 1) -postfixadmindbpass=$(cat /dev/urandom | tr -d -c 'a-zA-Z0-9' | fold -w 128 | head -n 1) -roundcubepass_strength_drive=$(cat /dev/urandom | tr -d -c 'a-z' | fold -w 8 | head -n 1) - -# Exit if static variable is null -if [ -z ${ip_addr} ] || [ -z ${subdomain} ] || [ -z ${domain} ] || [ -z ${eff_email} ] -then - die 'A static variable is nonexistent' -fi - -clear - -# Activate sudo -if sudo -v -then - until [[ ${proceed} = [yY] ]] - do - unset proceed - echo -e '\e[1;34mHit "y" to proceed with installation\e[0m' - read -n 1 -s -p $'\e[3m# If transferring mail servers to another provider, backup mail through Thunderbird or other IMAP clients before pressing any key to proceed\e[0m\n' proceed - echo - done -else - echo -e '\e[1;31mActivate sudo before running script\e[0m\n' - exit -fi - -# Dovecot -cd ~ -sudo mkdir -p /usr/share/dovecot /usr/share/webapps -sudo touch /usr/share/dovecot/dh.pem - -# Mail username -echo -e '\e[1;34mType in your email username\e[0m' -until [ ${mailuser} ] -do - read -r -p 'Username: ' mailuser - [ ${mailuser} ] || echo -e '\n\e[1;31mUsername cannot be empty, try again\e[0m' -done -echo -e '\n\e[1;32mMail user '${mailuser}'@'${domain}' has been saved\e[0m' - -# Postfixadmin password -echo -e '\n\e[1;34mCreate a postfixadmin setup password\e[0m' -until [ "${postfixadminpass}" = "${postfixadminpass2}" -a "${postfixadminpass}" ] -do - read -s -r -p 'Postfixadmin password: ' postfixadminpass - read -s -r -p $'\nVerify Postfixadmin password: ' postfixadminpass2 - if [ -z "${postfixadminpass}" ] - then - echo -e '\n\n\e[1;31mPassword field cannot be empty, try again\e[0m' - elif [ "${postfixadminpass}" != "${postfixadminpass2}" ] - then - echo -e '\n\n\e[1;31mPasswords did not match, try again\e[0m' - fi -done -echo -e '\n\n\e[1;32mPostfixadmin password has been saved\e[0m' - -# Mail account password -echo -e '\n\e[1;34mCreate a password for your mail account\e[0m' -until [ "${mailpass}" = "${mailpass2}" -a "${mailpass}" ] -do - read -s -r -p 'Mail password: ' mailpass - read -s -r -p $'\nVerify mail password: ' mailpass2 - if [ -z "${mailpass}" ] - then - echo -e '\n\n\e[1;31mPassword field cannot be empty, try again\e[0m' - elif [ "${mailpass}" != "${mailpass2}" ] - then - echo -e '\n\n\e[1;31mPasswords did not match, try again\e[0m' - fi -done -echo -e '\n\n\e[1;32mMail password has been saved\e[0m\n' - -# fail2ban -sudo tee /etc/fail2ban/jail.d/postfix.local >/dev/null <<'POSTFIX-FLOOD-ATTACK' -[postfix-flood-attack] -enabled = true -bantime = 12h -filter = postfix-flood-attack -action = iptables-multiport[name=postfix, port="http,https,smtp,submission,pop3,pop3s,imap,imaps,sieve", protocol=tcp] -logpath = /var/log/mail.log - -[postfix] -enabled = true -maxretry = 3 -bantime = 12h -filter = postfix -logpath = /var/log/mail.log -POSTFIX-FLOOD-ATTACK - -sudo tee /etc/fail2ban/filter.d/postfix-flood-attack.conf >/dev/null <<'POSTFIX-FLOOD-ATTACK' -[Definition] -failregex = lost connection after AUTH from (.*)\[\] -ignoreregex = -POSTFIX-FLOOD-ATTACK -sudo systemctl -q restart fail2ban.service - -# One last update before installing packages -echo -e '\e[1;34mInstalling required packages\e[5m...\e[0m' -sudo apt update -y && -sudo apt upgrade -y - -# PHP -sudo sed -i -e 's/^upload_max_filesize =.*/upload_max_filesize = 0/g' -e 's/^post_max_size =.*/post_max_size = 0/g' -e 's/^memory_limit =.*/memory_limit = 4096M/g' $(find /etc/php -name 'php.ini' | grep fpm) - -# Download Postfixadmin and Roundcube -sudo mkdir -p /usr/share/webapps/{roundcube,postfixadmin} -wget -q4 https://github.com/postfixadmin/postfixadmin/archive/refs/tags/$(wget -q4O- https://api.github.com/repos/postfixadmin/postfixadmin/releases/latest | grep tag_name | awk '{print $2}' | tr -d '"|,').tar.gz -O postfixadmin.tar.gz || die -wget -q4 $(wget -q4O- https://api.github.com/repos/roundcube/roundcubemail/releases/latest | grep 'complete.tar.gz"$' | awk '{print $2}' | tr -d '"|,') -O roundcubemail.tar.gz || die -sudo tar zxf roundcubemail.tar.gz -C /usr/share/webapps/roundcube --strip-components 1 -sudo tar zxf postfixadmin.tar.gz -C /usr/share/webapps/postfixadmin --strip-components 1 -rm *.tar.gz - -# Postfixadmin -echo -e '\n\e[1;34mInstalling Postfixadmin\e[0m' -cd /usr/share/webapps/postfixadmin -# Postfixadmin composer -wget -q4O- https://raw.githubusercontent.com/postfixadmin/postfixadmin/master/install.sh | sudo COMPOSER_ALLOW_SUPERUSER=1 bash - -sudo setfacl -R -m u:www-data:rwx templates_c/ - -# Roundcube -echo -e '\e[1;34mInstalling Roundcube\e[0m' -# Roundcube composer -cd /usr/share/webapps/roundcube -sudo COMPOSER_ALLOW_SUPERUSER=1 composer -n update --no-dev -sudo COMPOSER_ALLOW_SUPERUSER=1 composer -n install --no-dev -sudo chown www-data:www-data temp/ logs/ -R - -# Postwhite -cd /usr/local/bin -sudo git clone --quiet https://github.com/spf-tools/spf-tools.git -sudo git clone --quiet https://github.com/stevejenkins/postwhite.git -sudo cp /usr/local/bin/postwhite/postwhite.conf /etc -cd - -# Install MariaDB -echo -e '\n\e[1;34mInstalling MariaDB\e[0m' -printf '%s\n' "" "n" "y" "${postfixadminpass}" "${postfixadminpass}" "" "" "" "" | sudo mysql_secure_installation &>/dev/null - -# Roundcube database -sudo mysql -u root </dev/null - -# Roundcube password plugin -sudo cp /usr/share/webapps/roundcube/plugins/password/config.inc.php.dist /usr/share/webapps/roundcube/plugins/password/config.inc.php - -sudo sed -i "/^\$config\['password_db_dsn'\]/ s|=.*|= 'mysql://postfixadmin:${postfixadmindbpass}@localhost/postfixadmin';|" /usr/share/webapps/roundcube/plugins/password/config.inc.php -sudo sed -i "/^\$config\['password_query'\]/ s/=.*/= 'UPDATE mailbox SET password=%P,modified=NOW() WHERE username=%u';/" /usr/share/webapps/roundcube/plugins/password/config.inc.php -sudo sed -i "/^\$config\['password_strength_driver'\]/ s/=.*/= '${roundcubepass_strength_drive}';\\ -\$config['password_"${roundcubepass_strength_drive}"_min_score'] = 5;/" /usr/share/webapps/roundcube/plugins/password/config.inc.php -sudo sed -i "/^\$config\['password_algorithm'\]/ s/=.*/= 'dovecot';/" /usr/share/webapps/roundcube/plugins/password/config.inc.php -sudo sed -i "/^\$config\['password_dovecotpw'\]/ s|=.*|= '/usr/bin/doveadm pw -r 5';|" /usr/share/webapps/roundcube/plugins/password/config.inc.php -sudo sed -i "/^\$config\['password_dovecotpw_method'\]/ s/=.*/= 'ARGON2I';/" /usr/share/webapps/roundcube/plugins/password/config.inc.php -sudo sed -i "/^\$config\['password_dovecotpw_with_method'\]/ s/=.*/= true;/" /usr/share/webapps/roundcube/plugins/password/config.inc.php - -sudo rm /usr/share/webapps/roundcube/installer/ -r -sudo chown www-data:www-data /usr/share/webapps/roundcube/plugins/password/config.inc.php -sudo chmod 600 /usr/share/webapps/roundcube/plugins/password/config.inc.php - -# Postfixadmin config setup -# https://git.banananet.work/banananetwork/postfixadmin/raw/commit/864065cd37ef34b6dab915206eea4bd2ac4ebaed/config.inc.php -echo -e '\e[1;34mCreating mail users\e[0m' -echo -e ' '\''postmaster@'${domain}''\'', - '\''eff'\'' => '\''postmaster@'${domain}''\'', - '\''dmarc'\'' => '\''postmaster@'${domain}''\'', -); - -$CONF['\''password_validation'\''] = array( -# # '\''/regular expression/'\'' => '\''$PALANG key (optional: + parameter)'\'', -# '\''/.{5}/'\'' => '\''password_too_short 5'\'', # minimum length 5 characters -# '\''/([a-zA-Z].*){3}/'\'' => '\''password_no_characters 3'\'', # must contain at least 3 characters -# '\''/([0-9].*){2}/'\'' => '\''password_no_digits 2'\'', # must contain at least 2 digits -); - -$CONF['\''fetchmail'\''] = '\''NO'\''; -$CONF['\''show_footer_text'\''] = '\''NO'\''; - -$CONF['\''quota'\''] = '\''YES'\''; -$CONF['\''domain_quota'\''] = '\''YES'\''; -$CONF['\''quota_multiplier'\''] = '\''1024000'\''; -$CONF['\''used_quotas'\''] = '\''YES'\''; -$CONF['\''new_quota_table'\''] = '\''YES'\''; - -$CONF['\''aliases'\''] = '\''0'\''; -$CONF['\''mailboxes'\''] = '\''0'\''; -$CONF['\''maxquota'\''] = '\''0'\''; -$CONF['\''domain_quota_default'\''] = '\''0'\''; -$CONF['\''password_expiration'\''] = '\''NO'\''; - -# Postfixadmin hash -$CONF['\''setup_password'\''] = '\'$(sudo php -r "echo password_hash('${postfixadminpass}', PASSWORD_DEFAULT);")\'';' | sudo tee /usr/share/webapps/postfixadmin/config.local.php >/dev/null - -# Update Postfixadmin databases -# https://git.banananet.work/banananetwork/postfixadmin/raw/commit/864065cd37ef34b6dab915206eea4bd2ac4ebaed/config.inc.php -sudo -u www-data php /usr/share/webapps/postfixadmin/public/upgrade.php - -# Create Postfixadmin domain -sudo bash /usr/share/webapps/postfixadmin/scripts/postfixadmin-cli domain add "${domain}" --aliases 0 --mailboxes 0 --maxquota 0 --quota 0 --active --default-aliases -q - -# Create Postfixadmin admin -sudo bash /usr/share/webapps/postfixadmin/scripts/postfixadmin-cli admin add "postmaster@${domain}" --superadmin --active --domains "${domain}" --password "${postfixadminpass}" --password2 "${postfixadminpass}" -q - -# Create Postfixadmin mail users -sudo bash /usr/share/webapps/postfixadmin/scripts/postfixadmin-cli mailbox add "postmaster@${domain}" --active --password "${postfixadminpass}" --password2 "${postfixadminpass}" -q -sudo bash /usr/share/webapps/postfixadmin/scripts/postfixadmin-cli mailbox add "${mailuser}@${domain}" --active --password "${mailpass}" --password2 "${mailpass}" -q - -# Create Postfixadmin mail catch-all alias -sudo bash /usr/share/webapps/postfixadmin/scripts/postfixadmin-cli alias add "*@${domain}" --goto "${mailuser}@${domain}" --active -q - -unset mailuser postfixadminpass postfixadminpass2 mailpass mailpass2 roundcubedbpass roundcubepass_strength_drive -echo - -# Autorestart services -sudo mkdir -p /etc/systemd/system/{dovecot,postfix}.service.d -sudo tee /etc/systemd/system/dovecot.service.d/restart.conf >/dev/null <<'RESTART' -[Service] -Restart=always -RestartSec=5s -RESTART -sudo tee /etc/systemd/system/postfix.service.d/restart.conf >/dev/null <<'RESTART' -[Service] -Restart=on-failure -RestartSec=5s -RESTART -sudo systemctl -q daemon-reload - -# Postfix -# sudo postconf myhostname alias_maps alias_database myorigin mydestination relayhost mynetworks mailbox_size_limit recipient_delimiter inet_interfaces inet_protocols -# cat /etc/mailname -echo -e '\e[1;34mConfiguring Postfix\e[0m' -echo ${domain} | sudo tee /etc/mailname >/dev/null -sudo postconf -e "myhostname = ${subdomain}.${domain}" -sudo postconf -e 'relay_domains = $mydestination' -sudo postconf -e 'smtp_tls_security_level = may' -sudo postconf -e 'smtp_tls_loglevel = 1' -sudo postconf -e 'smtpd_tls_security_level = may' -sudo postconf -e 'smtpd_tls_loglevel = 1' -sudo postconf -e 'mailbox_size_limit = 0' -sudo postconf -e 'message_size_limit = 0' -sudo postconf -e "authorized_submit_users = root,www-data,${USER}" - -sudo postconf -e 'smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache' -sudo postconf -e 'smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache' - -sudo postconf -e 'smtp_tls_note_starttls_offer = yes' -sudo postconf -e 'smtpd_tls_received_header = yes' - -sudo postconf -e 'inet_interfaces = all' -# sudo postconf -e ' inet_interfaces = 127.0.0.1' -sudo postconf -e 'inet_protocols = ipv4' -sudo postconf -e 'smtp_address_preference = ipv4' -sudo postconf -e "mydomain = ${domain}" -sudo postconf -e 'myorigin = $mydomain' -sudo postconf -e 'mydestination = $myhostname, localhost.$mydomain, localhost' - -if [ ${backup_mailserver} ] -then - sudo postconf -e "$(sudo postconf mynetworks)$(printf ' %s/32' ${backup_mailserver[@]})" - sudo postconf -e "smtp_fallback_relay =$(printf ' [%s]:25' ${backup_mailserver[@]})" -fi - -# main.cf -echo -e '\n# Enforce TLSv1.3 or TLSv1.2 -smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1 -smtpd_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1 -smtp_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1 -smtp_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1 - -# Virtual mailboxes -mailbox_transport = lmtp:unix:private/dovecot-lmtp -smtputf8_enable = no - -virtual_mailbox_domains = proxy:mysql:/etc/postfix/sql/mysql_virtual_domains_maps.cf -virtual_mailbox_maps = - proxy:mysql:/etc/postfix/sql/mysql_virtual_mailbox_maps.cf, - proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_domain_mailbox_maps.cf -virtual_alias_maps = - proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_maps.cf, - proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_domain_maps.cf, - proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_domain_catchall_maps.cf - -virtual_transport = lmtp:unix:private/dovecot-lmtp - -virtual_mailbox_base = /var/vmail -virtual_minimum_uid = 600 -virtual_uid_maps = static:600 -virtual_gid_maps = static:600 -virtual_mailbox_limit = 0 - -smtp_header_checks = pcre:/etc/postfix/smtp_header_checks - -# SPF and DKIM checks -policyd-spf_time_limit = 3600 -smtpd_recipient_restrictions = - permit_mynetworks, - permit_sasl_authenticated, - reject_unauth_destination, - check_policy_service unix:private/policyd-spf, - check_client_access hash:/etc/postfix/rbl_override, - reject_rhsbl_helo dbl.spamhaus.org, - reject_rhsbl_reverse_client dbl.spamhaus.org, - reject_rhsbl_sender dbl.spamhaus.org - -# Milter configuration -milter_default_action = accept -milter_protocol = 6 -smtpd_milters = local:opendkim/opendkim.sock -non_smtpd_milters = $smtpd_milters - -# Blocking spam -smtpd_sender_restrictions = - permit_mynetworks - permit_sasl_authenticated - reject_unknown_sender_domain - reject_unknown_reverse_client_hostname - reject_unknown_client_hostname -smtpd_helo_required = yes -smtpd_helo_restrictions = - permit_mynetworks - permit_sasl_authenticated - check_helo_access hash:/etc/postfix/helo_access - reject_invalid_helo_hostname - reject_non_fqdn_helo_hostname - reject_unknown_helo_hostname - -# Postscreen spambots -postscreen_access_list = permit_mynetworks cidr:/etc/postfix/postscreen_access.cidr cidr:/etc/postfix/postscreen_spf_whitelist.cidr -postscreen_blacklist_action = drop - -postscreen_greet_action = enforce - -postscreen_dnsbl_threshold = 3 -postscreen_dnsbl_action = enforce -postscreen_dnsbl_sites = - zen.spamhaus.org*3 - bl.spameatingmonkey.net*2 - bl.spamcop.net - dnsbl.sorbs.net - -postscreen_dnsbl_whitelist_threshold = -2 - -header_checks = pcre:/etc/postfix/header_checks -body_checks = pcre:/etc/postfix/body_checks' | sudo tee -a /etc/postfix/main.cf >/dev/null - -# master.cf -sudo sed -i 's/smtp .*smtpd/# &/' /etc/postfix/master.cf -sudo sed -i '/#smtp\|#smtpd\|#dnsblog\|#tlsproxy/ s/^#//' /etc/postfix/master.cf - -echo -e '\n# Enable submission -submission inet n - y - - smtpd - -o syslog_name=postfix/submission - -o smtpd_tls_security_level=encrypt - -o smtpd_tls_wrappermode=no - -o smtpd_sasl_auth_enable=yes - -o smtpd_relay_restrictions=permit_sasl_authenticated,reject - -o smtpd_recipient_restrictions=permit_mynetworks,permit_sasl_authenticated,reject - -o smtpd_sasl_type=dovecot - -o smtpd_sasl_path=private/auth - -# SPF Policy -policyd-spf unix - n n - 0 spawn - user=policyd-spf argv=/usr/bin/policyd-spf' | sudo tee -a /etc/postfix/master.cf >/dev/null - -# Deleting Email Headers For Outgoing Emails -echo -e '/^X-Spam-Status:/ IGNORE -/^X-Spam-Checker-Version:/ IGNORE -/^Received:.*/ IGNORE -/^User-Agent:.*/ IGNORE' | sudo tee /etc/postfix/smtp_header_checks >/dev/null - -# Header checks -echo "/free mortgage quote/ DISCARD -/repair your credit/ DISCARD -/lose weight/ DISCARD -/To:.*(gmail.com|yahoo.com|outlook|hotmail.com).*${mailuser}@${domain}/ DISCARD -/To:.*${mailuser}@${domain}.*(gmail.com|yahoo.com|outlook|hotmail.com)/ DISCARD -/Cc:.*(gmail.com|yahoo.com|outlook|hotmail.com).*${mailuser}@${domain}/ DISCARD -/Cc:.*${mailuser}@${domain}.*(gmail.com|yahoo.com|outlook|hotmail.com)/ DISCARD -/To:.*<>/ DISCARD -/From:.*<>/ DISCARD" | sudo tee -a /etc/postfix/header_checks >/dev/null - -# Body checks -echo "/free mortgage quote/ DISCARD -/repair your credit/ DISCARD -/lose weight/ DISCARD" | sudo tee -a /etc/postfix/body_checks >/dev/null - -echo -e "# Permit my own IP addresses -${ip_addr}/32\tpermit" | sudo tee /etc/postfix/postscreen_access.cidr >/dev/null - -# Blocking Email Spam with Postfix -echo -e "${domain} OK" | sudo tee /etc/postfix/{helo_access,rbl_override} >/dev/null - -# Virtual mailboxes -sudo mkdir -p /etc/postfix/sql - -sudo tee /etc/postfix/sql/mysql_virtual_domains_maps.cf >/dev/null </dev/null </dev/null </dev/null </dev/null </dev/null </dev/null -sudo mkdir -p /var/vmail -sudo chown vmail:vmail /var/vmail/ -R - -sudo sed -i 's/#!include auth-sql.conf.ext/!include auth-sql.conf.ext/' /etc/dovecot/conf.d/10-auth.conf -sudo sed -i 's/!include auth-system.conf.ext/#&/' /etc/dovecot/conf.d/10-auth.conf -echo -e '\nauth_debug = yes -auth_debug_passwords = yes' | sudo tee -a /etc/dovecot/conf.d/10-auth.conf >/dev/null - -sudo tee -a /etc/dovecot/dovecot-sql.conf.ext >/dev/null </dev/null - -sudo sed -i 's|^mail_location =.*|mail_location = maildir:~/Maildir\ -'"$(if ! grep -q '^mail_home = /var/vmail/%d/%n/' /etc/dovecot/conf.d/10-mail.conf -then - echo 'mail_home = /var/vmail/%d/%n/' -fi)"'|g' /etc/dovecot/conf.d/10-mail.conf - -sudo sed -i 's|unix_listener lmtp {|unix_listener /var/spool/postfix/private/dovecot-lmtp {\ - mode = 0600\ - user = postfix\ - group = postfix|' /etc/dovecot/conf.d/10-master.conf -sudo sed -i 's|unix_listener auth-userdb {|unix_listener /var/spool/postfix/private/auth {\ - mode = 0660\ - user = postfix\ - group = postfix|' /etc/dovecot/conf.d/10-master.conf -sudo sed -i '/#disable_plaintext_auth/ s/^#//' /etc/dovecot/conf.d/10-auth.conf -sudo sed -i 's/#auth_username_format = %Lu/auth_username_format = %u/' /etc/dovecot/conf.d/10-auth.conf - -sudo sed -i 's/#auth_default_realm.*/auth_default_realm = '${domain}'/' /etc/dovecot/conf.d/10-auth.conf - -sudo sed -i 's/auth_mechanisms = plain/& login/' /etc/dovecot/conf.d/10-auth.conf -sudo sed -i 's/ssl = yes/ssl = required/' /etc/dovecot/conf.d/10-ssl.conf -sudo sed -i 's/#ssl_prefer_server_ciphers = no/ssl_prefer_server_ciphers = yes/' /etc/dovecot/conf.d/10-ssl.conf -sudo sed -i 's/#ssl_min_protocol =.*/ssl_min_protocol = TLSv1.2/' /etc/dovecot/conf.d/10-ssl.conf -echo -e '\nservice stats { - unix_listener stats-reader { - user = www-data - group = www-data - mode = 0660 -} - -unix_listener stats-writer { - user = www-data - group = www-data - mode = 0660 - } -}' | sudo tee -a /etc/dovecot/conf.d/10-master.conf >/dev/null -sudo gpasswd -a www-data dovecot >/dev/null - -# Mailboxes -sudo sed -i 's/namespace inbox {/&\ - # Archive folder\ - mailbox Archive {\ - special_use = \\Archive\ - }/' /etc/dovecot/conf.d/15-mailboxes.conf -sudo sed -i '/Sent Messages/! s/^ mailbox.*{/&\ - auto = subscribe/' /etc/dovecot/conf.d/15-mailboxes.conf -sudo adduser dovecot mail >/dev/null - -sudo systemctl restart dovecot postfix - -# SPF and DKIM -echo -e '\e[1;34mConfiguring SPF and DKIM policies\e[0m' -sudo gpasswd -a postfix opendkim >/dev/null - -grep -q '^Canonicalization.*relaxed/simple$' /etc/opendkim.conf || sudo sed -i 's|.*Canonicalization.*|Canonicalization relaxed/simple|' /etc/opendkim.conf -sudo sed -i '/^#Mode.*sv\|^#SubDomains.*no/ s/^#//' /etc/opendkim.conf -echo -e '\n# Map domains in "from" addresses to keys used to sign messages -KeyTable refile:/etc/opendkim/KeyTable -SigningTable refile:/etc/opendkim/SigningTable - -# Hosts to ignore when verifying signatures -ExternalIgnoreList /etc/opendkim/trusted.hosts - -# A set of internal hosts whose mail should be signed -InternalHosts /etc/opendkim/trusted.hosts' | sudo tee -a /etc/opendkim.conf >/dev/null - -sudo mkdir -p /etc/opendkim/keys -sudo chown -R opendkim:opendkim /etc/opendkim -sudo chmod go-rw /etc/opendkim/keys - -echo "*@${domain} default._domainkey.${domain}" | sudo tee -a /etc/opendkim/SigningTable >/dev/null -echo "default._domainkey.${domain} ${domain}:default:/etc/opendkim/keys/${domain}/default.private" | sudo tee -a /etc/opendkim/KeyTable >/dev/null -echo "127.0.0.1 -localhost - -*.${domain}" | sudo tee -a /etc/opendkim/trusted.hosts >/dev/null - -sudo mkdir -p /etc/opendkim/keys/${domain} -sudo opendkim-genkey -b 2048 -d ${domain} -D /etc/opendkim/keys/${domain} -s default -sudo chown opendkim:opendkim /etc/opendkim/keys/${domain}/default.private -sudo chmod 600 /etc/opendkim/keys/${domain}/default.private - -sudo mkdir -p /var/spool/postfix/opendkim -sudo chown opendkim:postfix /var/spool/postfix/opendkim -sudo sed -i '/^#Socket.*local:\/var\/spool\/postfix\/opendkim\/opendkim.sock/ s/^#//' /etc/opendkim.conf || sudo sed -i 's\^Socket.*local:/run/opendkim/opendkim.sock\Socket local:/var/spool/postfix/opendkim/opendkim.sock\' /etc/opendkim.conf -sudo sed -i 's\^SOCKET=local:$RUNDIR/opendkim.sock\SOCKET="local:/var/spool/postfix/opendkim/opendkim.sock"\' /etc/default/opendkim - -# DMARC -echo -e '\e[1;34mConfiguring DMARC\e[0m' -sudo sed -i 's/# AuthservID name/AuthservID OpenDMARC/' /etc/opendmarc.conf -sudo sed -i 's/# TrustedAuthservIDs HOSTNAME/TrustedAuthservIDs '${subdomain}'.'${domain}'/' /etc/opendmarc.conf -sudo sed -i 's/# RejectFailures false/RejectFailures true\ -IgnoreAuthenticatedClients true\ -RequiredHeaders true\ -SPFSelfValidate true/' /etc/opendmarc.conf -sudo sed -i 's|Socket local:/run/opendmarc/opendmarc.sock|Socket local:/var/spool/postfix/opendmarc/opendmarc.sock|' /etc/opendmarc.conf -sudo mkdir -p /var/spool/postfix/opendmarc -sudo chown opendmarc:opendmarc /var/spool/postfix/opendmarc -R -sudo chmod 750 /var/spool/postfix/opendmarc/ -R -sudo adduser postfix opendmarc >/dev/null -echo -e '\nIgnoreHosts /etc/opendmarc/ignore.hosts' | sudo tee -a /etc/opendmarc.conf >/dev/null -sudo mkdir -p /etc/opendmarc -echo '127.0.0.1' | sudo tee -a /etc/opendmarc/ignore.hosts >/dev/null - -# OpenDKIM and OpenDMARC headers -echo -e '\nSoftwareHeader yes' | sudo tee -a /etc/{opendkim,opendmarc}.conf >/dev/null - -sudo systemctl -q restart opendkim postfix opendmarc - -# Roundcube/Nginx -echo -e '\e[1;34mConfiguring Nginx\e[0m' -sudo tee $(find /etc/php/ -type d -name "pool.d")/zz-php-handler.conf >/dev/null </dev/null <<'PROXY' -proxy_set_header Host $http_host; -proxy_set_header X-Real-IP $remote_addr; -proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; -proxy_set_header X-Forwarded-Proto $scheme; -PROXY - -echo -e ' -upstream php-handler { - server unix:/run/php/php-fpm.sock; -} - -server { - server_name '${subdomain}'.'${domain}'; - - index index.php index.html; - - error_log /var/log/nginx/roundcube_error.log; - access_log /var/log/nginx/roundcube_access.log; - - root /usr/share/webapps/roundcube; - - # Postfixadmin - location ^~ /admin/ { - proxy_pass http://127.0.0.1:12000/; - include proxy_params; - } - - # Roundcube - location ~ \.php$ { - try_files $uri =404; - fastcgi_split_path_info ^(.+\.php)(/.+)$; - fastcgi_pass php-handler; - fastcgi_index index.php; - include fastcgi_params; - fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; - fastcgi_param PATH_INFO $fastcgi_path_info; - } -} - -server { - listen 12000; - root /usr/share/webapps/postfixadmin/public/; - index index.php index.html; - client_max_body_size 0; - - error_log /var/log/nginx/postfixadmin_error.log; - access_log /var/log/nginx/postfixadmin_access.log; - - location / { - try_files $uri $uri/ /index.php; - } - - location ~ ^/(.+\.php)$ { - try_files $uri =404; - fastcgi_pass php-handler; - fastcgi_index index.php; - fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; - include /etc/nginx/fastcgi_params; - } -}' | sudo tee /etc/nginx/sites-available/mail.conf >/dev/null -sudo ln -s /etc/nginx/sites-available/mail.conf /etc/nginx/sites-enabled/ - -# Certbot -sudo systemctl -q disable --now apache2.service -sudo systemctl -q reload nginx.service -sudo /etc/init.d/php*-fpm reload - -until sudo certbot --nginx --agree-tos --redirect --hsts --no-eff-email --staple-ocsp -m ${eff_email} -d ${subdomain}.${domain} -do - sleep 10 -done -sudo setfacl -R -m u:www-data:rx /etc/letsencrypt/live/ /etc/letsencrypt/archive/ - -# Postfix -sudo postconf -e "smtpd_tls_key_file = /etc/letsencrypt/live/${subdomain}.${domain}/privkey.pem" -sudo postconf -e "smtpd_tls_cert_file = /etc/letsencrypt/live/${subdomain}.${domain}/fullchain.pem" - -# Dovecot -# sudo sed -i 's|ssl_cert = /dev/null -sudo chmod 600 /etc/dovecot/ssl-keys.conf -echo -e '!include_try ssl-keys.conf' | sudo tee -a /etc/dovecot/dovecot.conf >/dev/null - -# Home directory mods -echo -e " -if [ -f ~/.bash_history ] -then - rm -f ~/.bash_history -fi - -unset HISTFILE -history -c - -# Mail logs -function mail-watch -{ - sudo tail -f /var/log/mail.log -} - -function mail-log -{ - sudo cat /var/log/mail.log -} - -function mail-troubleshoot -{ - systemctl status postfix.service dovecot.service opendkim.service opendmarc.service nginx.service mariadb.service - /etc/init.d/php*-fpm status -} - -function mail-reboot -{ - sudo systemctl -q restart postfix.service dovecot.service opendkim.service opendmarc.service nginx.service mariadb.service - sudo /etc/init.d/php*-fpm restart -} - -function mail-check -{ - if systemctl list-units --state failed | grep -q 'postfix\|dovecot\|opendkim\|opendmarc\|nginx\|mariadb\|php.*-fpm' - then - echo -e '\nErrors found...\n' - systemctl list-units --state failed - else - echo -e '\nAll good!\n' - fi -} - -function mail-test -{ - sudo systemctl stop postfix dovecot - read -n 1 -s -p $'\nPress any key to continue...\n' - sudo systemctl start postfix dovecot && - mail-watch -} - -# SSH pubkey access -function ssh-on -{ - sudo sed -i 's/^PasswordAuthentication no/PasswordAuthentication yes/' /etc/ssh/sshd_config.d/10-personal-sshd.conf - sudo systemctl -q restart sshd -} - -function ssh-off -{ - sudo sed -i 's/^PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config.d/10-personal-sshd.conf - sudo systemctl -q restart sshd -}" >> ~/.bashrc - -# Cron tasks -echo '#!/bin/sh -certbot renew --quiet && systemctl -q reload postfix dovecot nginx -/usr/local/bin/postwhite/postwhite &>/dev/null # Update Postscreen Whitelists' | sudo install /dev/stdin /etc/cron.daily/mailserver -echo '#!/bin/sh -/usr/local/bin/postwhite/scrape_yahoo &>/dev/null # Update Yahoo! IPs for Postscreen Whitelists' | sudo install /dev/stdin /etc/cron.weekly/mailserver -sudo ln -s /usr/share/webapps/roundcube/bin/cleandb.sh /etc/cron.daily/roundcube-cleandb - -# In your DNS manager, create a TXT record, enter default._domainkey in the name field -echo -e '\n\e[1;34mUpdate DKIM TXT on DNS registrar and press any key to continue\e[5m...\e[0m' -echo -e '\e[3m# Use default._domainkey in the host field' -echo -e '# Visit https://www.dmarcanalyzer.com/dkim/dkim-checker/ to check manually\e[0m' -sudo cat /etc/opendkim/keys/${domain}/default.txt | sed 's/.*( //' | sed 's/ ).*//' | sed 's/"//g' | sed 's/^[ \t]*//g' | sed ':a;N;$!ba;s/\n//g' - -# Run postwhite installer -echo -e '\e[1;34mInstalling Postwhite\e[0m' -sudo /usr/local/bin/postwhite/postwhite - -echo -e '\n\e[1;34mRestarting system services...\e[0m\n' -sudo systemctl -q restart postfix.service dovecot.service opendkim.service opendmarc.service nginx.service mariadb.service fail2ban.service -sudo /etc/init.d/php*-fpm restart - -# # Check DKIM key -# while : -# do -# if sudo opendkim-testkey -d ${domain} -s default -# then -# echo -e '\n\e[1;32mDKIM key has been verified!\e[0m' -# break -# fi -# sleep 5 -# done & -# disown - -sudo apt autoremove -y &>/dev/null - -install /dev/stdin ~/dhparam >/dev/null <<'dhparam' -#!/bin/sh -echo - -# Create certificates -echo -e '\e[1;34mGenerating DH parameters with openssl\e[0m' -echo -e '\e[3m# a notification will pop up once completed\e[0m' - -sudo openssl dhparam -out /usr/share/dovecot/dh.pem 4096 && -echo -e '\n\n\e[1;32mOpenssl certificates have successfully been generated!\e[0m' - -rm ${0} -dhparam - -echo -e "\e[1;32mInstaller has completed, login at https://${subdomain}.${domain} to access your new email." -echo -e "Reboot is recommended...\e[0m\n" -sudo rm ${0} -history -c -MAILSERVER - - su ${username} <<"CHANGEUSER" - # SSH - yes | ssh-keygen -t ed25519 -q -f ~/.ssh/id_ed25519 -P "" - echo "${sshkeys}" >~/.ssh/authorized_keys -CHANGEUSER - echo -e '\n\e[1m\t## Run "mail-server" immediately\n\e[0m' - su ${username} - - clear - echo -e "### -### Login ssh as new user -### -while : -do - clear - if ssh ${username}@${domain} -p ${ssh_port} exit - then - echo -e '\e[1m## Run "~/dhparam" upon logging in\n\e[0m' - ssh ${username}@${domain} -p ${ssh_port} - break - else - sleep 1 - fi -done\n" - - . ~/.bashrc - reboot -fi \ No newline at end of file