diff --git a/static/configuration.nix b/static/configuration.nix index 691538b..18aa4a5 100644 --- a/static/configuration.nix +++ b/static/configuration.nix @@ -2,8 +2,8 @@ imports = [ ./hardware-configuration.nix ./mailserver.nix - ./goss.nix - + #./goss.nix + ./restic.nix ]; boot.cleanTmpDir = true; @@ -12,14 +12,15 @@ networking.firewall.allowedTCPPorts = [ 22 443 80 143 993 587 25 465 ]; networking.firewall.allowedUDPPorts = [ 443 80 143 993 587 25 465 ]; services.openssh.enable = true; - users.users.root.openssh.authorizedKeys.keys = [ - "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDBfUx8fxgBgp40J6Tt1JJYX0BqQdLYtvtkKTG4ec/puxfFf7mZ0LUwvfY0uGPmE3qfV1RLgwgDFNwQe4g8pm8gYriptPPN7FjjcvsWy4UF0Knm9hfZ4HXToWDVgROPsivEwgZIs85Dffz28mTTDT3J+4NHS1yC0QHe0b6g9H4zMbJpTFVOhGgyLpOq6gP4dln4dAYhRf59WHf8pR15OItdf/lbhgV+genpC3FHyggun5rauXGdsrJtJR2uQlm9VxjmPQZeD4MBGf5F1ouie8us/gUoxD9QSuJL8vOYqyBgONoFwekI1gzCFbE8BmBCDBd1FPBFedFEDMLexIc4x4CXdgCbJEnnACNpMlYoDDgVEaGj3oszVYabKdN7PmfM1T8fjw1DW0Ia+4RwipjJVyv0v7zefEP0/S4T3uF0oScQfImBRDfMxBEqPIneiGP47Lopa1qaZ/95YRrCLpOscJXCpOKSchhgHmhpVZv0zf63C2GipCkYHqy5NvfMyaF1yoE= dragonhaze@ilchub-net" + "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC5Si4/wpG3QaMPYWJ0WOnb9nvi+glahYEqewbPPiq64H2JjlDz3Sz6Kph5vnKX+c7ULuXI/vchiGy6l5UQZnX2bVw3g4loiGMGhe78FZlKFVJShEPqsJuXfRMz1FUtp9J/LZOfzsXQp8xIhiXL8ymim+Zvd8nvCN+iHY5yMNQxCXUx6NZ5FYbk2eaO0fcJnXiSv+/MZzIXZGZuxCLog2QWHOx4R6L8dSw4pxCFNlDsrX8GikkKL58nIb4xGe6+odZH0XUSKU4Emw/j7FXIzVuljy7Vji1O6LDnFf65EJTSOwV26uJi+cHCfM/f3smq6fdnWbUdLrlpG9ztZzVHSyC4pHX3xeTiXo2EduITjJfgq4E5az83BayUQeRD6jD2wxAdWj4/fvTa0t58x35xwJ9G/FrNSH93tDhI5aKjbbrkgwcPuNls174lslXK5w6vkRAXQudcV85MXTFsJekC3NhUgtwFIlEPEuS/CqVst5yUZBpMqVsJoSCMiaaWvXDud8M= dragonhaze@ilchub.net" + ]; environment.systemPackages = with pkgs; [ htop vim letsencrypt opendkim + restic ]; system.autoUpgrade.enable = true; system.autoUpgrade.allowReboot = false; diff --git a/static/goss.yaml b/static/goss.yaml new file mode 100644 index 0000000..cee205c --- /dev/null +++ b/static/goss.yaml @@ -0,0 +1,76 @@ +port: + tcp:22: + listening: true + ip: + - 0.0.0.0 + tcp:143: + listening: true + ip: + - 0.0.0.0 + tcp:993: + listening: true + ip: + - 0.0.0.0 + tcp:4190: + listening: true + ip: + - 0.0.0.0 + tcp:12340: + listening: true + ip: + - 0.0.0.0 + tcp6:22: + listening: true + ip: + - '::' + tcp6:143: + listening: true + ip: + - '::' + tcp6:993: + listening: true + ip: + - '::' + tcp6:4190: + listening: true + ip: + - '::' + tcp6:12340: + listening: true + ip: + - '::' +service: + postfix: + enabled: true + running: true + sshd: + enabled: true + running: true +user: + postfix: + exists: true + uid: 13 + gid: 13 + groups: + - opendkim + - postfix + - rspamd + home: /var/empty + shell: /run/current-system/sw/bin/nologin + sshd: + exists: true + uid: 999 + gid: 65534 + groups: + - nogroup + home: /var/empty + shell: /run/current-system/sw/bin/nologin +group: + postfix: + exists: true + gid: 13 +process: + dovecot: + running: true + sshd: + running: true diff --git a/static/mailserver.nix b/static/mailserver.nix index 061bf77..a6ec161 100644 --- a/static/mailserver.nix +++ b/static/mailserver.nix @@ -19,7 +19,7 @@ # mkpasswd -m sha-512 "super secret password" loginAccounts = { "test@ilchub.net" = { - hashedPassword = "$6$RRdwLtjNCzd.JnNF$xT2J.g2umZtVEPTpHhamTJygBW5mheKcngiePKRbqgj7N13zu.tz3mFBr7OmQVdaO98W.wlE9KRURtWylBeET0"; + hashedPassword = ""; #aliases = [ # "mail@example.com" @@ -46,7 +46,7 @@ certificateScheme = 3; # Enable IMAP and POP3 - enableImap = false; + enableImap = true; enablePop3 = false; enableImapSsl = true; enablePop3Ssl = false; diff --git a/static/restic.nix b/static/restic.nix new file mode 100644 index 0000000..e150436 --- /dev/null +++ b/static/restic.nix @@ -0,0 +1,23 @@ +{ pkgs, ... }: + +{ + systemd = { + timers.restic = { + wantedBy = [ "timers.target" ]; + partOf = [ "restic.service" ]; + timerConfig.OnCalendar = [ "hourly" "daily" ]; + }; + services.restic = { + serviceConfig = { + Type = "oneshot"; + User = "restic"; + }; + script = '' + restic -r s3:s3.amazonaws.com/ backup /var/vmail /var/vmail + ''; + }; + }; + users.users.restic = { + isNormalUser = false; + }; +} diff --git a/static/s3cli b/static/s3cli new file mode 100755 index 0000000..4dd936f Binary files /dev/null and b/static/s3cli differ diff --git a/static/server.sh b/static/server.sh index 1f24357..cd3b6d0 100755 --- a/static/server.sh +++ b/static/server.sh @@ -4,7 +4,7 @@ InstallDependencies() { - packagesNeeded='curl jq' + packagesNeeded='curl jq expect pwgen' if [ -x "$(command -v apk)" ]; then sudo apk add --no-cache $packagesNeeded # Alpine Linux elif [ -x "$(command -v apt-get)" ]; then sudo apt-get install $packagesNeeded # Debian/Ubuntu Linux elif [ -x "$(command -v dnf)" ]; then sudo dnf install $packagesNeeded # Fedora Linux @@ -17,18 +17,19 @@ InstallDependencies() wget https://selfprivacy.org/configuration.nix wget https://selfprivacy.org/mailserver.nix wget https://selfprivacy.org/goss.nix + wget https://selfprivacy.org/restic.nix + wget https://selfprivacy.org/restic.yaml + wget https://selfprivacy.org/s3cli } CollectData() { read -p "Please, paste your Hetzner API token here: " HETZNER_TOKEN - echo $HETZNER_TOKEN - read -p "Please paste your CloudFlare Token: " CLOUDFLARE_TOKEN - echo $CLOUDFLARE_TOKEN - read -p "Please define your domain there: " DOMAIN - echo $DOMAIN - read -p "Please define your mail username: " USERNAME - echo $USERNAME - read -p "Please define your password: " PASSWORD && PASSWORD=$( mkpasswd -m sha-512 "$PASSWORD" ) + read -p "Please, paste your CloudFlare Token: " CLOUDFLARE_TOKEN + read -p "Please, paste your AWS Secret Access Key: " AWS_TOKEN + read -p "Please, paste your AWS Access Key ID: " AWS_TOKEN_ID + read -p "Please, define your domain there: " DOMAIN + read -p "Please, define your mail username: " USERNAME + read -p "Please, define your password: " PASSWORD && PASSWORD=$( mkpasswd -m sha-512 "$PASSWORD" ) } # Generate SSH key @@ -55,6 +56,7 @@ AddSSHKey() # Create NixOS config file MakeConfig() { + # Mailserver sed -i '15s/.*/ fqdn = "'$DOMAIN'";/' mailserver.nix sed -i '16s/.*/ domains = [ "'"$DOMAIN"'" ];/' mailserver.nix sed -i '21s/.*/\t"'$USERNAME'@'$DOMAIN'" = {/' mailserver.nix @@ -62,7 +64,10 @@ MakeConfig() sed -i '31s/.*/\t\t"'"$DOMAIN"'"/' mailserver.nix sed -i '41s/.*/\t "admin@'"$DOMAIN"'" = "'"$USERNAME"'@'"$DOMAIN"'";/' mailserver.nix sed -i '63s/.*/ email = "'"$USERNAME"'@'"$DOMAIN"'";/' mailserver.nix - sed -i "16s,.*,\t\"${sshKey}\"," configuration.nix + + # System Configuration + sed -i "15s,.*,\t\"${sshKey}\"," configuration.nix + sed -i "16s,.*,\t restic -r s3:s3.amazonaws.com/${AWS_BUCKET_NAME} backup /var/vmail /var/vmail ," restic.nix } MakeServer() @@ -75,6 +80,37 @@ MakeServer() -d '{"name":"nixos-mailserver","server_type":"cx11","start_after_create":true,"image":"ubuntu-20.04","ssh_keys":["nixosms"],"volumes":[],"networks":[],"user_data":"#cloud-config\nruncmd:\n- curl https://raw.githubusercontent.com/elitak/nixos-infect/master/nixos-infect | PROVIDER=hetzner NIX_CHANNEL=nixos-20.03 bash 2>&1 | tee /tmp/infect.log","labels":{},"automount":false}' \ 'https://api.hetzner.cloud/v1/servers' > /dev/null } + +CreateS3BucketRaw() +{ + local date="$(date -u '+%a, %e %b %Y %H:%M:%S +0000')" + local string_to_sign + local MD5="" + printf -v string_to_sign "%s\n%s\n\n%s\n%s" "PUT" "$MD5" "$date" "$path" + signature=$(echo -n "$string_to_sign" | openssl sha1 -binary -hmac "${AWS_SECRET_ACCESS_KEY}" | openssl base64) + curl -s \ + -X PUT \ + -H "Host: $AWS_TOKEN_ID.s3-control.us-east-2.amazonaws.com" \ + -H "Content-Length: 0" \ + -H "Date: $(date +'%a, %d %b %Y %H:%M:%S %Z')" \ + -H "Authorization: AWS $AWS_TOKEN_ID:$signature" +} + +CreateS3Bucket() +{ + mkdir ~/.aws + touch ~/.aws/credentials + echo "[default]" >> ~/.aws/credentials + echo "aws_access_key_id=$AWS_TOKEN_ID" >> ~/.aws/credentials + echo "aws_secret_access_key=$AWS_TOKEN" >> ~/.aws/credentials + if [[ -z "$(./s3cli -e http://s3.us-east-2.amazonaws.com --ak "$AWS_TOKEN_ID" --sk "$AWS_TOKEN" --region us-east-2 bucket ls | grep backup)" ]]; then + read "AWS S3 bucket found in your account. Do you want to restore backup from there? (y/n) " RESTORE_MAILBACKUP + else + export AWS_BUCKET_NAME=$(pwgen -1 --no-capitalize 6)-backup + ./s3cli -e http://s3.us-east-2.amazonaws.com --ak "$AWS_TOKEN_ID" --sk "$AWS_TOKEN" --region us-east-2 bucket create $AWS_BUCKET_NAME + fi +} + # Get machine IP GetMachineIP() { @@ -90,12 +126,20 @@ ApplyConfig() ssh -i ~/.nix-ms/id_rsa "root@$machineip" echo "Authentificated" scp -i ~/.nix-ms/id_rsa mailserver.nix "root@$machineip:/root" scp -i ~/.nix-ms/id_rsa configuration.nix "root@$machineip:/root" + scp -i ~/.nix-ms/id_rsa goss.nix "root@$machineip:/root" scp -i ~/.nix-ms/id_rsa goss.yaml "root@$machineip:/root" ssh -i ~/.nix-ms/id_rsa "root@$machineip" cp /root/mailserver.nix /etc/nixos/mailserver.nix ssh -i ~/.nix-ms/id_rsa "root@$machineip" cp /root/configuration.nix /etc/nixos/configuration.nix ssh -i ~/.nix-ms/id_rsa "root@$machineip" cp /root/goss.nix /etc/nixos/goss.nix sleep 3 ssh -i ~/.nix-ms/id_rsa "root@$machineip" nixos-rebuild switch + ssh -i ~/.nix-ms/id_rsa "root@$machineip" export AWS_ACCESS_KEY_ID=$AWS_TOKEN_ID + ssh -i ~/.nix-ms/id_rsa "root@$machineip" export AWS_SECRET_ACCESS_KEY=$AWS_TOKEN +} + +RestoreBackup() +{ + ssh -i ~/.nix-ms/id_rsa "root@$machineip" restic -r s3:s3.amazonaws/$AWS_BUCKET_NAME restore latest --target /var/vmail /var/dkim } # Get DKIM keys from remote machine @@ -114,6 +158,8 @@ ClearTempFiles() rm $DOMAIN.selector.txt rm -rf ~/.nix-ms/ rm ~/.ssh/known_hosts + rm .healthz.json + rm .hetzner_machines.json } # Cloudflare configuration @@ -168,6 +214,8 @@ CreateDKIMRecord() PostInstallation() { + ssh -i ~/.nix-ms/id_rsa "root@$machineip" restic -r s3:s3.amazonaws.com/$AWS_BUCKET_NAME init + ssh -i ~/.nix-ms/id_rsa "root@$machineip" restic -r s3:s3.amazonaws.com/$AWS_BUCKET_NAME forget --prune --keep-hourly 2 --keep-daily 7 --keep-weekly 4 ssh -i ~/.nix-ms/id_rsa "root@$machineip" cp /root/result/bin/goss /root/ ssh -i ~/.nix-ms/id_rsa "root@$machineip" /root/goss serve --format json & } @@ -206,7 +254,7 @@ then exit -1 fi fi -RunPreFlightChecks +#RunPreFlightChecks InstallDependencies GenerateSSHKey printf "Importing SSH key into your Hetzner account..." @@ -219,9 +267,13 @@ printf "Waiting for the server to create...\n" MakeServer sleep 30 printf "Waiting for nixos-infect to replace system files(this may take some time)...\n" -sleep 200 +sleep 240 +CreateS3Bucket GetMachineIP ApplyConfig +if [$RESTORE_MAILBACKUP == "y"]; then +RestoreBackup +fi GetDKIM echo "Beginning CloudFlare configuration" @@ -234,7 +286,7 @@ CreateSPFRecord CreateDKIMRecord printf "done\n" PostInstallation -PerformTests +#PerformTests #while ! ping -c1 192.168.0.107 &>/dev/null # do echo "Ping Fail - `date`" #done