diff --git a/content/_index.md b/content/_index.md index f447155..81a27b4 100644 --- a/content/_index.md +++ b/content/_index.md @@ -14,6 +14,6 @@ ## Установка сервера -:black_large_square: `curl https://selfprivacy.org/server.sh | sh` +:black_large_square: `bash <(curl -s https://selfprivacy.org/server.sh)` > Скрипт потребует ключи: Hetzner, CloudFlare, ssh diff --git a/content/posts/install.md b/content/posts/install.md index 1577739..faabed0 100644 --- a/content/posts/install.md +++ b/content/posts/install.md @@ -1,7 +1,7 @@ --- -title: "Install SelfPrivacy Server" -date: 2020-08-21T13:23:47+03:00 -draft: true +title: "Install" +date: 2020-08-21T17:09:10+03:00 +draft: false categories: - HowTo @@ -55,59 +55,59 @@ If your system and network setup meets all of the requirements, we can start set 1. In your Hetzner account, go to **Security** tab -![dashboard](resources/hetzner/1.png) +![dashboard](/img/hetzner/1.png) 2. Go to API Tokens -![security](resources/hetzner/2.png) +![security](/img/hetzner/2.png) 3. Click "**Generate API Token**" -![tokens](resources/hetzner/3.png) +![tokens](/img/hetzner/3.png) 4. Give your token a name(aka Token Description) -![generateTokens](resources/hetzner/4.png) +![generateTokens](/img/hetzner/4.png) 5. Copy your newly generated token | WARNING: You won't be able to see this token again, so please save it somewhere else, in the safe place | | --- | -![copyToken](resources/hetzner/5.png) +![copyToken](/img/hetzner/5.png) ### **Getting CloudFlare public API key** 1. In your CloudFlare account, click onto account icon at the upper right corner -![dashboard](resources/cloudflare/1.png) +![dashboard](/img/cloudflare/1.png) 2. At the newly appeared dropdown menu, click **My Profile** -![dropdown](resources/cloudflare/2.png) +![dropdown](/img/cloudflare/2.png) 3. In your account settings, open **API Tokens** tab -![myAccount](resources/cloudflare/3.png) +![myAccount](/img/cloudflare/3.png) 4. At the tokens tab, click **View** button, opposite of "Global API key" row -![globalAPIKey](resources/cloudflare/4.png) +![globalAPIKey](/img/cloudflare/4.png) 5. Enter your pasword, complete capcha and click **View** -![securityCheck](resources/cloudflare/5.png) +![securityCheck](/img/cloudflare/5.png) 6. Your key will be shown. Click **Copy** button to store it in the clipboard -![key](resources/cloudflare/6.png) +![key](/img/cloudflare/6.png) ## Running a script From now, you`re ready to start setting up a mailbox. To run a script, type: ``` -./install.sh +bash <(curl -s https://selfprivacy.org/server.sh) ``` ## Manual Installation diff --git a/static/img/cloudflare/1.png b/static/img/cloudflare/1.png new file mode 100644 index 0000000..8c4e9ee Binary files /dev/null and b/static/img/cloudflare/1.png differ diff --git a/static/img/cloudflare/2.png b/static/img/cloudflare/2.png new file mode 100644 index 0000000..da33387 Binary files /dev/null and b/static/img/cloudflare/2.png differ diff --git a/static/img/cloudflare/3.png b/static/img/cloudflare/3.png new file mode 100644 index 0000000..eb410a6 Binary files /dev/null and b/static/img/cloudflare/3.png differ diff --git a/static/img/cloudflare/4.png b/static/img/cloudflare/4.png new file mode 100644 index 0000000..d28f7d2 Binary files /dev/null and b/static/img/cloudflare/4.png differ diff --git a/static/img/cloudflare/5.png b/static/img/cloudflare/5.png new file mode 100644 index 0000000..bd968a7 Binary files /dev/null and b/static/img/cloudflare/5.png differ diff --git a/static/img/cloudflare/6.png b/static/img/cloudflare/6.png new file mode 100644 index 0000000..78747bc Binary files /dev/null and b/static/img/cloudflare/6.png differ diff --git a/static/img/hetzner/1.png b/static/img/hetzner/1.png new file mode 100644 index 0000000..80e8271 Binary files /dev/null and b/static/img/hetzner/1.png differ diff --git a/static/img/hetzner/2.png b/static/img/hetzner/2.png new file mode 100644 index 0000000..627139d Binary files /dev/null and b/static/img/hetzner/2.png differ diff --git a/static/img/hetzner/3.png b/static/img/hetzner/3.png new file mode 100644 index 0000000..61019b5 Binary files /dev/null and b/static/img/hetzner/3.png differ diff --git a/static/img/hetzner/4.png b/static/img/hetzner/4.png new file mode 100644 index 0000000..c25050a Binary files /dev/null and b/static/img/hetzner/4.png differ diff --git a/static/img/hetzner/5.png b/static/img/hetzner/5.png new file mode 100644 index 0000000..68062de Binary files /dev/null and b/static/img/hetzner/5.png differ diff --git a/static/server.sh b/static/server.sh new file mode 100755 index 0000000..e530048 --- /dev/null +++ b/static/server.sh @@ -0,0 +1,200 @@ +#!/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"