aboutsummaryrefslogtreecommitdiff
path: root/servers/guixvps
diff options
context:
space:
mode:
Diffstat (limited to 'servers/guixvps')
-rw-r--r--servers/guixvps/hostname.txt1
-rw-r--r--servers/guixvps/infrastructure.tf139
-rw-r--r--servers/guixvps/machines.scm129
-rw-r--r--servers/guixvps/tld.txt1
4 files changed, 270 insertions, 0 deletions
diff --git a/servers/guixvps/hostname.txt b/servers/guixvps/hostname.txt
new file mode 100644
index 0000000..c84cac8
--- /dev/null
+++ b/servers/guixvps/hostname.txt
@@ -0,0 +1 @@
+toph
diff --git a/servers/guixvps/infrastructure.tf b/servers/guixvps/infrastructure.tf
new file mode 100644
index 0000000..2721c56
--- /dev/null
+++ b/servers/guixvps/infrastructure.tf
@@ -0,0 +1,139 @@
+terraform {
+ required_providers {
+ vultr = {
+ source = "vultr/vultr"
+ version = "~> 2.1.2"
+ }
+ }
+ required_version = ">= 0.13"
+}
+
+# Input variables
+
+variable "vultr_api_key" {
+ type = string
+ description = "Vultr API key."
+}
+
+variable "vps_tld" {
+ type = string
+ description = "Root Top-Level Domain. Subdomains will be derived from it."
+}
+
+variable "vps_hostname" {
+ type = string
+ description = "Human name of the host. This is a pet name, not cattle name :)"
+}
+
+variable "vps_dkim_public_key" {
+ type = string
+ description = "Public key for the DNS TXT DKIM record."
+}
+
+variable "vps_dkim_selector" {
+ type = string
+ description = "The DKIM selector that prefixes the domain in the TXT record."
+}
+
+# Vultr
+
+provider "vultr" {
+ api_key = var.vultr_api_key
+}
+
+# Instance
+
+resource "vultr_instance" "vps_server" {
+ enable_ipv6 = true
+ backups = "enabled"
+ hostname = var.vps_hostname
+ activation_email = true
+ label = var.vps_hostname
+ region = "cdg"
+ plan = "vc2-1c-1gb"
+ # $ curl -H "Authorization: Bearer $TF_VAR_vultr_api_key" https://api.vultr.com/v2/snapshots | jq
+ snapshot_id = "8e6aaab6-7973-48a0-aeb5-cb99ab1ff43d"
+}
+
+output "vps_public_ipv4" {
+ value = vultr_instance.vps_server.main_ip
+}
+
+output "vps_public_ipv6" {
+ value = vultr_instance.vps_server.v6_main_ip
+}
+
+# DNS and IP configuration
+
+locals {
+ mail_domain = "mail.${var.vps_tld}"
+}
+
+resource "vultr_dns_domain" "vps_tld" {
+ # The CNAME record is already generated by Vultr
+ domain = var.vps_tld
+ ip = vultr_instance.vps_server.main_ip
+}
+
+resource "vultr_dns_record" "vps_mail_a_record" {
+ domain = vultr_dns_domain.vps_tld.id
+ name = "mail"
+ data = vultr_instance.vps_server.main_ip
+ type = "A"
+}
+
+resource "vultr_reverse_ipv4" "vps_mail_reverse_ipv4" {
+ instance_id = vultr_instance.vps_server.id
+ ip = vultr_instance.vps_server.main_ip
+ reverse = local.mail_domain
+}
+
+resource "vultr_dns_record" "vps_mail_aaaa_record" {
+ domain = vultr_dns_domain.vps_tld.id
+ name = "mail"
+ data = vultr_instance.vps_server.v6_main_ip
+ type = "AAAA"
+}
+
+resource "vultr_reverse_ipv6" "vps_mail_reverse_ipv6" {
+ instance_id = vultr_instance.vps_server.id
+ ip = vultr_instance.vps_server.v6_main_ip
+ reverse = local.mail_domain
+}
+
+resource "vultr_dns_record" "vps_mx_record" {
+ domain = vultr_dns_domain.vps_tld.id
+ name = ""
+ data = local.mail_domain
+ type = "MX"
+}
+
+resource "vultr_dns_record" "vps_spf_txt" {
+ domain = vultr_dns_domain.vps_tld.id
+ name = ""
+ data = "\"v=spf1 mx -all\""
+ type = "TXT"
+}
+
+resource "vultr_dns_record" "vps_dkim_txt" {
+ domain = vultr_dns_domain.vps_tld.id
+ name = "${var.vps_dkim_selector}._domainkey"
+ data = "\"v=DKIM1;k=rsa;p=${var.vps_dkim_public_key}\""
+ type = "TXT"
+}
+
+resource "vultr_dns_record" "vps_dmarc_txt" {
+ domain = vultr_dns_domain.vps_tld.id
+ name = "_dmarc"
+ data = "\"v=DMARC1;p=none;pct=100;rua=mailto:postmaster@${var.vps_tld};\""
+ type = "TXT"
+}
+
+# I think this DNS is configured by default
+
+# resource "vultr_dns_record" "vps_cname_start_alias" {
+# domain = vultr_dns_domain.vps_tld.id
+# name = "*"
+# data = var.vps_tld
+# type = "CNAME"
+# }
diff --git a/servers/guixvps/machines.scm b/servers/guixvps/machines.scm
new file mode 100644
index 0000000..8933709
--- /dev/null
+++ b/servers/guixvps/machines.scm
@@ -0,0 +1,129 @@
+(use-modules (guix gexp)
+ (gnu)
+ (guix)
+ ((guix build utils) #:prefix utils:)
+ ((guix modules) #:prefix modules:)
+ ((srfi srfi-1) #:prefix srfi-1:)
+ (srfi srfi-26) ; cut utility
+ ((ice-9 textual-ports) #:prefix textual-ports:)
+ ((ice-9 ftw) #:prefix ftw:)
+ ((ice-9 popen) #:prefix popen:)
+ ((ice-9 rdelim) #:prefix rdelim:)
+ ((ice-9 string-fun) #:prefix string-fun:))
+
+(use-package-modules ssh
+ backup
+ version-control)
+(use-service-modules networking
+ ssh
+ mcron
+ admin
+ mail
+ web
+ certbot
+ cgit)
+
+(define user "andreh")
+(define tld (slurp "servers/vps/tld.txt"))
+
+;; permit nopass :wheel
+(define sudoers "\
+root ALL=(ALL) ALL
+%wheel ALL=NOPASSWD: ALL\n")
+
+(define letsencrypt-prefix
+ "/etc/letsencrypt/live/")
+
+(define (tls-pub-for domain)
+ (string-append letsencrypt-prefix domain "/fullchain.pem"))
+
+(define (tls-priv-for domain)
+ (string-append letsencrypt-prefix domain "/privkey.pem"))
+
+(define tls-domains
+ (list tld))
+
+(define my-system
+ (operating-system
+ (host-name (slurp "servers/vps/hostname.txt"))
+ (users (cons* (user-account
+ (name user)
+ (group "users")
+ (home-directory (string-append "/home/" user))
+ (supplementary-groups '("wheel")))
+ %base-user-accounts))
+ (sudoers-file (plain-file "sudoers" sudoers))
+ (packages
+ (append (map (compose list specification->package+output symbol->string)
+ ;; required for guix pull
+ '(nss-certs))
+ %base-packages))
+ (services
+ (append
+ (list (service dhcp-client-service-type)
+ (service openssh-service-type
+ (openssh-configuration
+ (openssh openssh-sans-x)
+ (password-authentication? #f)
+ (permit-root-login #f)
+ (authorized-keys
+ `((,user ,(local-file (string-append (getenv "HOME") "/.ssh/id_rsa.pub")))))))
+ (service git-daemon-service
+ (git-daemon-configuration
+ (export-all? #t)))
+ (service unattended-upgrade-service-type
+ (unattended-upgrade-configuration
+ (schedule "30 3 * * *")))
+ (service mcron-service-type
+ (mcron-configuration
+ (jobs
+ (list #~(job "30 1 * * 1" "/opt/bin/gc.sh")
+ #~(job "30 0 * * *" "/opt/bin/backup.sh")))))
+ (service nginx-service-type
+ (nginx-configuration
+ (server-blocks
+ (list (nginx-server-configuration
+ (server-name tls-domains))
+ (ssl-certificate (tls-pub-for tld))
+ (ssl-certificate-key (tls-priv-for tld)))))))
+ (service certbot-service-type
+ (certbot-configuration
+ (email (string-append "certbot@" tld))
+ (certificates
+ (list
+ (certificate-configuration
+ (domains tls-domains)))))))
+ (modify-services
+ %base-services
+ (guix-service-type
+ config => (guix-configuration
+ (inherit config)
+ (authorized-keys
+ (append
+ (list (local-file "/etc/guix/signing-key.pub"))
+ %default-authorized-guix-keys)))))))
+ (bootloader
+ (bootloader-configuration
+ (bootloader grub-bootloader)
+ (target "/dev/vda")
+ (terminal-outputs '(console))))
+ (swap-devices
+ (list (uuid "79a91c82-f3e1-4ed7-8c4e-23569f1ae0ca")))
+ (file-systems
+ (cons* (file-system
+ (mount-point "/")
+ (device
+ (uuid "fddb6a4c-8b8c-4f57-b274-5d6d33200f28"
+ 'ext4))
+ (type "ext4"))
+ %base-file-systems))))
+
+(list
+ (machine
+ (operating-system my-system)
+ (environment managed-host-environment-type)
+ (configuration (machine-ssh-configuration
+ (host-name tld)
+ (system "x86_64-linux")
+ (user user)
+ (host-key "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOwnnw/u8ub+kcQhnVSyNWarYGH8aesUwIy4SIprufKf")))))
diff --git a/servers/guixvps/tld.txt b/servers/guixvps/tld.txt
new file mode 100644
index 0000000..1aaed8d
--- /dev/null
+++ b/servers/guixvps/tld.txt
@@ -0,0 +1 @@
+arrobaponto.org