aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEuAndreh <eu@euandre.org>2020-08-10 11:30:44 -0300
committerEuAndreh <eu@euandre.org>2020-08-10 11:30:44 -0300
commit18e1dc6cc114e8ea3eedf09e67cd576e879c6326 (patch)
treecf1b375db20ec6d339b641643d8eb376abb102c1
parentTODOs.org (diff)
downloadtoph-18e1dc6cc114e8ea3eedf09e67cd576e879c6326.tar.gz
toph-18e1dc6cc114e8ea3eedf09e67cd576e879c6326.tar.xz
WIP: Move to Vultr and NixOS
-rw-r--r--TODOs.org1
-rw-r--r--configuration.nix124
-rw-r--r--default.nix2
-rw-r--r--derived-configuration.env.nix4
-rw-r--r--nix/configuration.nix107
-rw-r--r--secrets/nix/private-configuration.nixbin0 -> 73 bytes
-rw-r--r--secrets/secret-envrc.shbin2539 -> 2683 bytes
-rw-r--r--secrets/terraform/terraform.tfstatebin0 -> 3055 bytes
-rw-r--r--secrets/terraform/terraform.tfstate.backupbin0 -> 3055 bytes
l---------terraform.tfstate2
l---------terraform.tfstate.backup2
-rw-r--r--vps.tf108
12 files changed, 171 insertions, 179 deletions
diff --git a/TODOs.org b/TODOs.org
index 678c1d0..22f762a 100644
--- a/TODOs.org
+++ b/TODOs.org
@@ -1,6 +1,7 @@
* Tasks - v4
** TODO How to handle IP changes in mail server?
** TODO Add borg backup to crontab
+** TODO Add 2FA to Vultr
** TODO Clean-up garbage backups from rsync.net
** TODO Harden the server
*** TODO [#C] [[https://www.reddit.com/r/selfhosted/comments/bw8hqq/top_3_measures_to_secure_your_virtual_private/][Top 3 measures to secure your Virtual Private Server? (VPS)]]
diff --git a/configuration.nix b/configuration.nix
new file mode 100644
index 0000000..fad5305
--- /dev/null
+++ b/configuration.nix
@@ -0,0 +1,124 @@
+{ config, pkgs, ... }:
+
+let
+ privateConfiguration = import ./private-configuration.nix;
+ derivedConfiguration = import ./derived-configuration.nix;
+in {
+ imports = [ ./hardware-configuration.nix];
+
+ boot.loader.grub = {
+ enable = true;
+ version = 2;
+ device = "/dev/vda";
+ };
+
+ networking = {
+ useDHCP = false;
+ interfaces.ens3.useDHCP = true;
+ };
+
+ environment.systemPackages = with pkgs; [
+ vim
+ ];
+
+ networking.firewall.allowedTCPPorts = [ 80 443 22 ];
+
+ security.acme = {
+ acceptTerms = true;
+ email = privateConfiguration.letsencryptEmail;
+ };
+
+ services = {
+ openssh = {
+ enable = true;
+ permitRootLogin = "no";
+ passwordAuthentication = false;
+ };
+
+ nginx = {
+ enable = true;
+ recommendedGzipSettings = true;
+ recommendedOptimisation = true;
+ recommendedProxySettings = true;
+ recommendedTlsSettings = true;
+ sslCiphers = "AES256+EECDH:AES256+EDH:!aNULL"; # FIXME: ?????
+ virtualHosts = let
+ customConfigTLDs = {};
+ defaultConfigTLDs = [
+ derivedConfiguration.nextcloudTLD
+ derivedConfiguration.gitTLD
+ ];
+ buildDefaultConfiguration = tld:
+ {
+ "${tld}" = {
+ forceSSL = true;
+ enableACME = true;
+ };
+ };
+ in
+ pkgs.lib.fold
+ (tldString: acc: acc // buildDefaultConfiguration tldString)
+ customConfigTLDs
+ defaultConfigTLDs;
+
+ gitweb = {
+ enable = true;
+ location = "/";
+ virtualHost = derivedConfiguration.gitTLD;
+ };
+ };
+
+ nextcloud = {
+ enable = true;
+ hostName = derivedConfiguration.nextcloudTLD;
+ nginx.enable = true;
+ https = true;
+ autoUpdateApps.enable = true;
+ autoUpdateApps.startAt = "05:00:00";
+ config = {
+ overwriteProtocol = "https";
+
+ dbtype = "pgsql";
+ dbuser = "nextcloud";
+ dbhost = "/run/postgresql"; # nextcloud will add /.s.PGSQL.5432 by itself
+ dbname = "nextcloud";
+ dbpassFile = "/var/nextcloud-db-pass";
+
+ adminpassFile = "/var/nextcloud-admin-pass";
+ adminuser = "admin";
+ };
+ };
+
+ postgresql = {
+ enable = true;
+ ensureDatabases = [ "nextcloud" ];
+ ensureUsers = [
+ {
+ name = "nextcloud";
+ ensurePermissions."DATABASE nextcloud" = "ALL PRIVILEGES";
+ }
+ ];
+ };
+
+ gitweb = {
+ gitwebTheme = true;
+ projectroot = "/srv/git";
+ };
+ };
+
+ # FIXME: is this required?
+ systemd.services."nextcloud-setup" = {
+ requires = ["postgresql.service"];
+ after = ["postgresql.service"];
+ };
+
+ users.users.nixos = {
+ uid = 1000;
+ extraGroups = ["wheel"];
+ useDefaultShell = true;
+ # FIXME: password hash file?
+ openssh.authorizedKeys.keyFiles = [ "/etc/nixos/nixos-user-authorized-key"];
+ };
+
+ system.stateVersion = "19.09";
+}
diff --git a/default.nix b/default.nix
index 63bdfa1..171a3a9 100644
--- a/default.nix
+++ b/default.nix
@@ -37,7 +37,7 @@ in rec {
gitMinimal
git-crypt
gettext
- terraform-providers.digitalocean
+ terraform-providers.vultr
terraform
ansible
];
diff --git a/derived-configuration.env.nix b/derived-configuration.env.nix
new file mode 100644
index 0000000..b2bc8ea
--- /dev/null
+++ b/derived-configuration.env.nix
@@ -0,0 +1,4 @@
+{
+ nextcloudTLD = "$NEXTCLOUD_TLD";
+ gitTLD = "$GIT_TLD";
+}
diff --git a/nix/configuration.nix b/nix/configuration.nix
deleted file mode 100644
index e9f55ae..0000000
--- a/nix/configuration.nix
+++ /dev/null
@@ -1,107 +0,0 @@
-# Edit this configuration file to define what should be installed on
-# your system. Help is available in the configuration.nix(5) man page
-# and in the NixOS manual (accessible by running ‘nixos-help’).
-
-{ config, pkgs, ... }:
-
-{
- imports =
- [ # Include the results of the hardware scan.
- ./hardware-configuration.nix
- ];
-
- # Use the GRUB 2 boot loader.
- boot.loader.grub.enable = true;
- boot.loader.grub.version = 2;
- # boot.loader.grub.efiSupport = true;
- # boot.loader.grub.efiInstallAsRemovable = true;
- # boot.loader.efi.efiSysMountPoint = "/boot/efi";
- # Define on which hard drive you want to install Grub.
- boot.loader.grub.device = "/dev/vda"; # or "nodev" for efi only
-
- # networking.hostName = "nixos"; # Define your hostname.
- # networking.wireless.enable = true; # Enables wireless support via wpa_supplicant.
-
- # The global useDHCP flag is deprecated, therefore explicitly set to false here.
- # Per-interface useDHCP will be mandatory in the future, so this generated config
- # replicates the default behaviour.
- networking.useDHCP = false;
- networking.interfaces.ens3.useDHCP = true;
-
- # Configure network proxy if necessary
- # networking.proxy.default = "http://user:password@proxy:port/";
- # networking.proxy.noProxy = "127.0.0.1,localhost,internal.domain";
-
- # Select internationalisation properties.
- # i18n = {
- # consoleFont = "Lat2-Terminus16";
- # consoleKeyMap = "us";
- # defaultLocale = "en_US.UTF-8";
- # };
-
- # Set your time zone.
- # time.timeZone = "Europe/Amsterdam";
-
- # List packages installed in system profile. To search, run:
- # $ nix search wget
- # environment.systemPackages = with pkgs; [
- # wget vim
- # ];
-
- # Some programs need SUID wrappers, can be configured further or are
- # started in user sessions.
- # programs.mtr.enable = true;
- # programs.gnupg.agent = { enable = true; enableSSHSupport = true; };
-
- # List services that you want to enable:
-
- # Enable the OpenSSH daemon.
- services.openssh.enable = true;
- services.openssh.permitRootLogin = "no";
-
- # Open ports in the firewall.
- # networking.firewall.allowedTCPPorts = [ ... ];
- # networking.firewall.allowedUDPPorts = [ ... ];
- # Or disable the firewall altogether.
- # networking.firewall.enable = false;
-
- # Enable CUPS to print documents.
- # services.printing.enable = true;
-
- # Enable sound.
- # sound.enable = true;
- # hardware.pulseaudio.enable = true;
-
- # Enable the X11 windowing system.
- # services.xserver.enable = true;
- # services.xserver.layout = "us";
- # services.xserver.xkbOptions = "eurosign:e";
-
- # Enable touchpad support.
- # services.xserver.libinput.enable = true;
-
- # Enable the KDE Desktop Environment.
- # services.xserver.displayManager.sddm.enable = true;
- # services.xserver.desktopManager.plasma5.enable = true;
-
- # Define a user account. Don't forget to set a password with ‘passwd’.
- # users.users.jane = {
- # isNormalUser = true;
- # extraGroups = [ "wheel" ]; # Enable ‘sudo’ for the user.
- # };
- users.users.nixos = {
- uid = 1000;
- extraGroups = ["wheel"];
- useDefaultShell = true;
- openssh.authorizedKeys.keys = [
- "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDVkFI2Tp3S94X6pb20pKZ0S8hN3nqJA6tyDnkEgyPEkKiEotgYFYnL1KNJpve5n9wp66co4T3s+V5jEGrGH6Corev4veraf9QZ8OJBy8vFtDZEy4g+duZ4BANnRAlwtlcL9ptmsuXeN5XaSFPEnEPTpf5agKQbFDTGTsRQ/DOizBT7gXZM3NZkZAfF9s4d9YLMpFwrQxr22xoxR4ZVtK3Fjddw8NAZHVs/3wwL8mwHLgopC3zCwInwRiQ/IulT2nwT2McS2U1bU8j3sf+B/RKk4F8f7F+vdt+U6ODfTF0zLIav8q0em4vYnE/DikUp3yTLbfZ4ksnJ/iwoTRvDDxFokILPVuhfghG4kU5kAzbptJxG0JnK3FLtRPTvCArCwqApONHtyuOU65mltD3k3Rvf4Bbrhyk90nH0aTeirWENntX2rEapbhF+sSxU448Af1d78vSdALSDwAkOGSXe3AWFba4yzDOOgi/oBmoPg34xoC0Yul4EkXU7Z3EVY5cdjAlBeLYypERxzxSzHg4YaXk+7e4+GvISX58P8gk57EPLKjFnycxWP4R6StJzklBzva78CC9v1rKk6Qe/WKaf1mm/j87tylvGlsvXQHnC8Ow3nB8IGE4ziVMxyTnSJhrFg2RTAnJYJArRQJMYgu7aTEH+Xtj7zbtuQmshnSxw4uTVQw== andreh@velhinho-nixos"
- ];
- };
-
- # This value determines the NixOS release with which your system is to be
- # compatible, in order to avoid breaking some software such as database
- # servers. You should change this only after NixOS release notes say you
- # should.
- system.stateVersion = "19.09"; # Did you read the comment?
-
-}
diff --git a/secrets/nix/private-configuration.nix b/secrets/nix/private-configuration.nix
new file mode 100644
index 0000000..9796247
--- /dev/null
+++ b/secrets/nix/private-configuration.nix
Binary files differ
diff --git a/secrets/secret-envrc.sh b/secrets/secret-envrc.sh
index 266e671..29469b3 100644
--- a/secrets/secret-envrc.sh
+++ b/secrets/secret-envrc.sh
Binary files differ
diff --git a/secrets/terraform/terraform.tfstate b/secrets/terraform/terraform.tfstate
new file mode 100644
index 0000000..5004374
--- /dev/null
+++ b/secrets/terraform/terraform.tfstate
Binary files differ
diff --git a/secrets/terraform/terraform.tfstate.backup b/secrets/terraform/terraform.tfstate.backup
new file mode 100644
index 0000000..293d803
--- /dev/null
+++ b/secrets/terraform/terraform.tfstate.backup
Binary files differ
diff --git a/terraform.tfstate b/terraform.tfstate
index 4fa5ae3..44969ac 120000
--- a/terraform.tfstate
+++ b/terraform.tfstate
@@ -1 +1 @@
-../vps-state/secrets/terraform.tfstate \ No newline at end of file
+secrets/terraform/terraform.tfstate \ No newline at end of file
diff --git a/terraform.tfstate.backup b/terraform.tfstate.backup
index 54845c8..244cafa 120000
--- a/terraform.tfstate.backup
+++ b/terraform.tfstate.backup
@@ -1 +1 @@
-../vps-state/secrets/terraform.tfstate.backup \ No newline at end of file
+secrets/terraform/terraform.tfstate.backup \ No newline at end of file
diff --git a/vps.tf b/vps.tf
index 8579e76..e0c3262 100644
--- a/vps.tf
+++ b/vps.tf
@@ -1,8 +1,8 @@
# Input variables
-variable "do_token" {
+variable "vultr_api_key" {
type = string
- description = "DigitalOcean API token."
+ description = "Vultr API key."
}
variable "tld" {
@@ -20,95 +20,65 @@ variable "hostname" {
description = "Human name of the host. This is a pet name, not cattle name :)"
}
-variable "volume_name" {
+variable "storage_name" {
type = string
- description = "Name of the volume, which will also be the name of it's mount point."
+ description = "Name of the block storage volume, which will also be the name of it's mount point."
}
-# DigitalOcean
-provider "digitalocean" {
- token = var.do_token
- version = "~> 1.1"
-}
+# Vultr
-resource "digitalocean_ssh_key" "client" {
- name = "terraform-vps-client"
- public_key = file("${path.module}/secrets/ssh/vps-box-client.pub")
+provider "vultr" {
+ api_key = var.vultr_api_key
+ version = "~> 1.3"
}
-## Droplet and volume
-
-resource "digitalocean_droplet" "vps" {
- image = "ubuntu-18-04-x64"
- name = var.hostname
- region = "nyc3"
- size = "s-1vcpu-1gb"
- backups = true
- ipv6 = true
- monitoring = true
-
- user_data = file("${path.module}/generated/user-data.sh")
-
- ssh_keys = [
- "${digitalocean_ssh_key.client.fingerprint}",
- ]
-
- connection {
- user = "root"
- type = "ssh"
- private_key = file("${path.module}/secrets/ssh/vps-box-client")
- timeout = "2m"
- host = digitalocean_droplet.vps.ipv6_address
- }
-
- provisioner "remote-exec" {
- inline = ["echo 'SSH is up! Noop remote-exec is done.'"]
- }
-}
-resource "digitalocean_volume" "vps_persistent_volume" {
- region = "nyc3"
- name = var.volume_name
- size = 10
- initial_filesystem_type = "ext4"
- description = "Persistent disk to store docker volumes contents across droplets being created and destroyed"
-}
+# Instance
-resource "digitalocean_volume_attachment" "foobar" {
- volume_id = digitalocean_volume.vps_persistent_volume.id
- droplet_id = digitalocean_droplet.vps.id
+resource "vultr_server" "vps_server" {
+ enable_ipv6 = true
+ notify_activate = true
+ hostname = var.hostname
+ label = var.hostname
+ # $ curl https://api.vultr.com/v1/regions/list | jq '.["9"]'
+ region_id = 9
+ # $ curl https://api.vultr.com/v1/plans/list?type=vc2 | jq '.["201"]'
+ plan_id = 201
+ # $ curl -H "API-Key: $TF_VAR_vultr_api_key" https://api.vultr.com/v1/snapshot/list | jq
+ snapshot_id = "7245f30a2f3b3"
}
-## DNS and IP configuration
-
-resource "digitalocean_floating_ip" "vps_public_ip" {
- region = digitalocean_droplet.vps.region
+resource "vultr_block_storage" "vps_storage" {
+ size_gb = 10
+ region_id = 9
+ attached_id = vultr_server.vps_server.id
+ label = var.storage_name
+ live = "yes"
}
-resource "digitalocean_floating_ip_assignment" "vps_public_ip_assignment" {
- ip_address = digitalocean_floating_ip.vps_public_ip.id
- droplet_id = digitalocean_droplet.vps.id
-}
-output "public_floating_ip" {
- value = digitalocean_floating_ip.vps_public_ip.ip_address
+# DNS and IP configuration
+
+output "public_ip" {
+ value = vultr_server.vps_server.main_ip
}
-resource "digitalocean_domain" "vps_tld" {
- name = var.tld
+resource "vultr_dns_domain" "vps_tld" {
+ domain = var.tld
+ server_ip = vultr_server.vps_server.main_ip
}
-resource "digitalocean_record" "at_sign" {
- domain = digitalocean_domain.vps_tld.name
+resource "vultr_dns_record" "at_sign" {
+ domain = var.tld
type = "A"
name = "@"
- value = digitalocean_floating_ip.vps_public_ip.ip_address
+ data = vultr_server.vps_server.main_ip
}
-resource "digitalocean_record" "nextcloud" {
- domain = digitalocean_domain.vps_tld.name
+resource "vultr_dns_record" "nextcloud" {
+ domain = var.tld
type = "CNAME"
name = var.nextcloud_tld_prefix
- value = "${digitalocean_domain.vps_tld.name}."
+ data = vultr_server.vps_server.main_ip
}