Added restic backup support

master
Illia Chub 2020-09-01 19:33:37 +03:00
parent d6f8207f8a
commit cf99a37afe
6 changed files with 171 additions and 19 deletions

View File

@ -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;

76
static/goss.yaml Normal file
View File

@ -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

View File

@ -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;

23
static/restic.nix Normal file
View File

@ -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;
};
}

BIN
static/s3cli Executable file

Binary file not shown.

View File

@ -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