selfprivacy_fork/static/server.sh

297 lines
10 KiB
Bash
Raw Normal View History

#!/bin/bash
# Collecting authentification data
InstallDependencies()
{
2020-09-04 17:04:27 +03:00
packagesNeeded='curl jq mkpasswd pwgen'
2020-08-24 13:28:59 +03:00
if [ -x "$(command -v apk)" ]; then sudo apk add --no-cache $packagesNeeded # Alpine Linux
2020-09-04 17:04:27 +03:00
elif [ -x "$(command -v apt-get)" ]; then sudo apt-get install curl jq whois pwgen # Debian/Ubuntu Linux
2020-08-24 13:28:59 +03:00
elif [ -x "$(command -v dnf)" ]; then sudo dnf install $packagesNeeded # Fedora Linux
2020-08-26 16:31:08 +03:00
elif [ -x "$(command -v rpm-ostree)" ]; then sudo rpm-ostree install $packagesNeeded # Fedora Linux Silverblue
2020-08-24 13:28:59 +03:00
elif [ -x "$(command -v zypper)" ]; then sudo zypper install $packagesNeeded # openSUSE Linux
elif [ -x "$(command -v pacman)" ]; then sudo pacman -S $packagesNeeded # Arch/Manjaro Linux
elif [ -x "$(command -v emerge)" ]; then sudo emerge --ask $packagesNeeded # Gentoo Linux
elif [ -x "$(command -v nix-env)" ]; then nix-env -iA $packagesNeeded # NixOS
else echo "FAILED TO INSTALL PACKAGE: Package manager not found. You must manually install: $packagesNeeded">&2; fi
2020-08-24 13:28:59 +03:00
wget https://selfprivacy.org/configuration.nix
wget https://selfprivacy.org/mailserver.nix
2020-08-27 11:39:04 +03:00
wget https://selfprivacy.org/goss.nix
2020-09-03 17:54:31 +03:00
wget https://selfprivacy.org/goss.yaml
2020-09-01 19:33:37 +03:00
wget https://selfprivacy.org/restic.nix
wget https://selfprivacy.org/s3cli
2020-09-03 17:54:31 +03:00
chmod +x s3cli
}
CollectData()
{
read -p "Please, paste your Hetzner API token here: " HETZNER_TOKEN
2020-09-01 19:33:37 +03:00
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
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()
{
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()
{
2020-09-01 19:33:37 +03:00
# Mailserver
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
2020-09-04 16:48:52 +03:00
sed -i '48s/.*/\t "admin@'"$DOMAIN"'" = "'"$USERNAME"'@'"$DOMAIN"'";/' mailserver.nix
sed -i '70s/.*/ email = "'"$USERNAME"'@'"$DOMAIN"'";/' mailserver.nix
2020-09-01 19:33:37 +03:00
# System Configuration
2020-09-03 17:54:31 +03:00
sed -i "16s,.*,\t\"${sshKey}\"," configuration.nix
# Restic
sed -i '14s/.*/\t\tEnvironment = [ "AWS_ACCESS_KEY_ID='$AWS_TOKEN_ID'" "AWS_SECRET_ACCESS_KEY='$AWS_TOKEN'" ];/' restic.nix
sed -i "17s,.*,\t restic -r s3:s3.amazonaws.com/${AWS_BUCKET_NAME} backup /var/vmail /var/vmail ," restic.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
}
2020-09-01 19:33:37 +03:00
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()
{
2020-09-03 17:54:31 +03:00
if test -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
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
else
read -p "Restore from backup? y/n " RESTORE_MAILBACKUP
2020-09-01 19:33:37 +03:00
fi
}
# 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"
2020-09-01 19:33:37 +03:00
scp -i ~/.nix-ms/id_rsa goss.nix "root@$machineip:/root"
2020-09-03 17:54:31 +03:00
scp -i ~/.nix-ms/id_rsa restic.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
2020-08-27 11:39:04 +03:00
ssh -i ~/.nix-ms/id_rsa "root@$machineip" cp /root/goss.nix /etc/nixos/goss.nix
2020-09-03 17:54:31 +03:00
ssh -i ~/.nix-ms/id_rsa "root@$machineip" cp /root/restic.nix /etc/nixos/restic.nix
sleep 3
ssh -i ~/.nix-ms/id_rsa "root@$machineip" nixos-rebuild switch
2020-09-01 19:33:37 +03:00
}
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
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
2020-09-03 17:54:31 +03:00
rm configuration.nix
rm goss.nix
rm goss.yaml
rm mailserver.nix
rm restic.nix
rm s3cli
exit 0
}
# Cloudflare configuration
# Get zone ID
GetZoneID()
{
curl -s -X GET "https://api.cloudflare.com/client/v4/zones" \
2020-08-26 16:31:08 +03:00
-H "Authorization: Bearer $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" \
2020-08-26 16:31:08 +03:00
-H "Authorization: Bearer $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" \
2020-08-26 16:31:08 +03:00
-H "Authorization: Bearer $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" \
2020-08-26 16:31:08 +03:00
-H "Authorization: Bearer $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" \
2020-08-26 16:31:08 +03:00
-H "Authorization: Bearer $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/"$//' )
2020-08-26 16:31:08 +03:00
curl -s -X POST "https://api.cloudflare.com/client/v4/zones/$zoneid/dns_records" -H "Authorization: Bearer $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
}
PostInstallation()
{
2020-09-01 19:33:37 +03:00
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
2020-09-03 17:54:31 +03:00
#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 &
}
2020-08-26 16:31:08 +03:00
PerformTests()
{
curl $machineip:8080/healthz > .healthz.json
for i in {0..24}; do jq 'if .results['$i'].err != null then "FAIL" else "OK" end' .healthz.json;
done
}
RunPreFlightChecks()
{
curl -H "Authorization: Bearer $HETZNER_TOKEN" 'https://api.hetzner.cloud/v1/servers' > .hetzner_test.json
jq 'if .error != null then "Preflight checks failed" else "Success" end' .hetzner_test.json | if [ "Preflight checks failed" ]
then
echo "Hetzner Authorization failed"
exit -1
fi
}
2020-08-26 16:31:08 +03:00
if test -z "$HETZNER_TOKEN" || test -z "$CLOUDFLARE_TOKEN" || test -z "$PASSWORD"
then
CollectData
if [ ${#HETZNER_TOKEN} != 64 ]
then
echo "Hetzner Token is incorrect. Please double check your input"
exit -1
elif [ ${#CLOUDFLARE_TOKEN} != 40 ]
then
echo "Cloudflare Token is incorrect. Please double check your input"
exit -1
elif [[ ${DOMAIN} != *.* ]]
then
echo "Got unexpected domain. Possibly wrong input"
exit -1
fi
2020-08-26 16:31:08 +03:00
fi
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"
2020-09-03 17:54:31 +03:00
sleep 280
2020-09-01 19:33:37 +03:00
CreateS3Bucket
GetMachineIP
ApplyConfig
2020-09-03 17:54:31 +03:00
if [ $RESTORE_MAILBACKUP == "y" ]
then
2020-09-01 19:33:37 +03:00
RestoreBackup
fi
GetDKIM
echo "Beginning CloudFlare configuration"
GetZoneID
printf "Creating records..."
CreateARecord
CreateMXRecord
CreateDMARCRecord
CreateSPFRecord
CreateDKIMRecord
2020-08-24 13:28:59 +03:00
printf "done\n"
2020-08-26 16:31:08 +03:00
PostInstallation
printf "Clearing temporary files..."
ClearTempFiles
printf "done\n"