#!/bin/bash # Collecting authentification data InstallDependencies() { packagesNeeded='curl jq' if [ -x "$(command -v apk)" ]; then sudo apk add --no-cache $packagesNeeded elif [ -x "$(command -v apt-get)" ]; then sudo apt-get install $packagesNeeded elif [ -x "$(command -v dnf)" ]; then sudo dnf install $packagesNeeded elif [ -x "$(command -v zypper)" ]; then sudo zypper install $packagesNeeded elif [ -x "$(command -v pacman)" ]; then sudo pacman -S $packagesNeeded elif [ -x "$(command -v emerge)" ]; then sudo emerge --ask $packagesNeeded else echo "FAILED TO INSTALL PACKAGE: Package manager not found. You must manually install: $packagesNeeded">&2; fi wget http://192.168.0.104/configuration.nix wget http://192.168.0.104/mailserver.nix } CollectData() { read -p "Please, paste your Hetzner API token here: " HETZNER_TOKEN echo $HETZNER_TOKEN read -p "Please paste your CloudFlare global API key here: " CLOUDFLARE_TOKEN echo $CLOUDFLARE_TOKEN read -p "Please enter your CloudFlare e-mail here: " CLOUDFLARE_EMAIL echo $CLOUDFLARE_EMAIL 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" ) } # Generate SSH key GenerateSSHKey() { echo "Generating SSH keys..." mkdir ~/.nix-ms ssh-keygen -f ~/.nix-ms/id_rsa > /dev/null export sshKey=$( cat ~/.nix-ms/id_rsa.pub ) } # Add SSH key to Hetzner AddSSHKey() { echo "Adding SSH keys to Hetzner..." curl -s \ -X POST \ -H "Authorization: Bearer $HETZNER_TOKEN" \ -H "Content-Type: application/json" \ -d '{"name":"nixosms","public_key":"'"${sshKey}"'","labels":{}}' \ 'https://api.hetzner.cloud/v1/ssh_keys' > /dev/null } # Create NixOS config file MakeConfig() { sed -i '15s/.*/ fqdn = "'$DOMAIN'";/' mailserver.nix sed -i '16s/.*/ domains = [ "'"$DOMAIN"'" ];/' mailserver.nix sed -i '21s/.*/\t"'$USERNAME'@'$DOMAIN'" = {/' mailserver.nix sed -i '22s/.*/\t hashedPassword = "'"$PASSWORD"'";/' mailserver.nix 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 "15s,.*,\t\"${sshKey}\"," configuration.nix } MakeServer() { echo "Creating Server..." curl -s \ -X POST \ -H "Authorization: Bearer $HETZNER_TOKEN" \ -H "Content-Type: application/json" \ -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 } # Get machine IP GetMachineIP() { curl -s \ -H "Authorization: Bearer $HETZNER_TOKEN" \ 'https://api.hetzner.cloud/v1/servers' > .machine.json export machineip=$( for i in {0..24}; do jq 'if .servers['$i'].name == "nixos-mailserver" then .servers['$i'].public_net.ipv4.ip else null end' .machine.json; done | grep -v null | sed 's/"//' | sed 's/"//' ) } # Copy and apply mailserver config 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" 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 sleep 3 ssh -i ~/.nix-ms/id_rsa "root@$machineip" nixos-rebuild switch } # Get DKIM keys from remote machine GetDKIM() { scp -i ~/.nix-ms/id_rsa "root@$machineip:/var/dkim/$DOMAIN.selector.txt" . sed -i '1d' $DOMAIN.selector.txt sed -i 's/ ) ; ----- DKIM key selector for '$DOMAIN'//g' $DOMAIN.selector.txt export dkim=$( cat $DOMAIN.selector.txt ) } ClearTempFiles() { rm .machine.json rm .cloudflare.json rm $DOMAIN.selector.txt rm -rf ~/.nix-ms/ rm ~/.ssh/known_hosts } # Cloudflare configuration # Get zone ID GetZoneID() { curl -s -X GET "https://api.cloudflare.com/client/v4/zones" \ -H "X-Auth-Email: $CLOUDFLARE_EMAIL" \ -H "X-Auth-Key: $CLOUDFLARE_TOKEN" \ -H "Content-Type: application/json" > .cloudflare.json export zoneid=$( for i in {0..24}; do jq 'if .result['$i'].name == "'$DOMAIN'" then .result['$i'].id else null end' .cloudflare.json; done | grep -v null | sed -e 's/^"//' -e 's/"$//' ) } # Create records CreateARecord() { curl -s -X POST "https://api.cloudflare.com/client/v4/zones/$zoneid/dns_records" \ -H "X-Auth-Email: $CLOUDFLARE_EMAIL" \ -H "X-Auth-Key: $CLOUDFLARE_TOKEN" \ -H "Content-Type: application/json" \ --data '{"type":"A","name":"'$DOMAIN'","content":"'$machineip'","ttl":3600,"priority":10,"proxied":false}' > /dev/null } CreateMXRecord() { curl -s -X POST "https://api.cloudflare.com/client/v4/zones/$zoneid/dns_records" \ -H "X-Auth-Email: $CLOUDFLARE_EMAIL" \ -H "X-Auth-Key: $CLOUDFLARE_TOKEN" \ -H "Content-Type: application/json" \ --data '{"type":"MX","name":"@","content":"'$DOMAIN'","ttl":3600,"priority":10,"proxied":false}' > /dev/null } CreateDMARCRecord() { curl -s -X POST "https://api.cloudflare.com/client/v4/zones/$zoneid/dns_records" \ -H "X-Auth-Email: $CLOUDFLARE_EMAIL" \ -H "X-Auth-Key: $CLOUDFLARE_TOKEN" \ -H "Content-Type: application/json" \ --data '{"type":"TXT","name":"_dmarc","content":"v=DMARC1; p=none","ttl":18000,"priority":10,"proxied":false}' > /dev/null } CreateSPFRecord() { curl -s -X POST "https://api.cloudflare.com/client/v4/zones/$zoneid/dns_records" \ -H "X-Auth-Email: $CLOUDFLARE_EMAIL" \ -H "X-Auth-Key: $CLOUDFLARE_TOKEN" \ -H "Content-Type: application/json" \ --data '{"type":"TXT","name":"'$DOMAIN'","content":"v=spf1 a mx ip4:'$machineip' -all","ttl":18000,"priority":10,"proxied":false}' > /dev/null } CreateDKIMRecord() { export dkim=$( echo $dkim | sed -e 's/^"//' -e 's/"$//' ) curl -s -X POST "https://api.cloudflare.com/client/v4/zones/$zoneid/dns_records" -H "X-Auth-Email: $CLOUDFLARE_EMAIL" -H "X-Auth-Key: $CLOUDFLARE_TOKEN" -H "Content-Type: application/json" --data '{"type":"TXT","name":"selector._domainkey","content":"v=DKIM1; '$dkim'","ttl":18000,"priority":10,"proxied":false}' > /dev/null } CollectData InstallDependencies GenerateSSHKey printf "Importing SSH key into your Hetzner account..." AddSSHKey printf "done\n" printf "Generating config file..." MakeConfig printf "done\n" 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 180 GetMachineIP ApplyConfig GetDKIM echo "Beginning CloudFlare configuration" GetZoneID printf "Creating records..." CreateARecord CreateMXRecord CreateDMARCRecord CreateSPFRecord CreateDKIMRecord echo "done" printf "Clearing temporary files..." ClearTempFiles printf "done\n"