forked from clan/clan-infra
Merge pull request 'dns' (#7) from dns into main
Reviewed-on: clan/clan-infra#7
This commit is contained in:
commit
4821acf1c8
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,6 +1,7 @@
|
||||
# secrets
|
||||
.envrc.private
|
||||
.terraform.lock.hcl
|
||||
secrets.auto.tfvars.sops.json
|
||||
|
||||
# git is our backup
|
||||
*.tfstate.backup
|
||||
|
@ -10,7 +10,7 @@ keys:
|
||||
# Downloaded like this: nix-shell -p ssh-to-age --run 'ssh-keyscan clan.lol | ssh-to-age'
|
||||
- &web01 age17xuvz0fqtynzdmf8rfh4g3e46tx8w3mc6zgytrmuj5v9dhnldgxs7ue7ct
|
||||
creation_rules:
|
||||
- path_regex: targets/.*/terraform.tfstate$
|
||||
- path_regex: targets/.*/(terraform.tfstate|secrets.auto.tfvars.sops.json)$
|
||||
key_groups:
|
||||
- age:
|
||||
- *joerg
|
||||
|
@ -60,7 +60,8 @@
|
||||
pkgs.bashInteractive
|
||||
pkgs.sops
|
||||
(pkgs.terraform.withPlugins (p: [
|
||||
p.namecheap
|
||||
p.hetznerdns
|
||||
# TODO: drop netlify
|
||||
p.netlify
|
||||
p.hcloud
|
||||
p.null
|
||||
|
@ -4,6 +4,7 @@
|
||||
./gitea
|
||||
./postfix.nix
|
||||
./harmonia.nix
|
||||
./dendrite.nix
|
||||
../zerotier
|
||||
../zerotier/ctrl.nix
|
||||
];
|
||||
|
147
modules/web01/dendrite.nix
Normal file
147
modules/web01/dendrite.nix
Normal file
@ -0,0 +1,147 @@
|
||||
{ config
|
||||
, pkgs
|
||||
, ...
|
||||
}:
|
||||
let
|
||||
database = {
|
||||
connection_string = "postgres:///dendrite?host=/run/postgresql";
|
||||
max_open_conns = 100;
|
||||
max_idle_conns = 5;
|
||||
conn_max_lifetime = -1;
|
||||
};
|
||||
inherit (config.services.dendrite.settings.global) server_name;
|
||||
domain = "clan.lol";
|
||||
nginx-vhost = "matrix.${domain}";
|
||||
element-web =
|
||||
pkgs.runCommand "element-web-with-config"
|
||||
{
|
||||
nativeBuildInputs = [ pkgs.buildPackages.jq ];
|
||||
} ''
|
||||
cp -r ${pkgs.element-web} $out
|
||||
chmod -R u+w $out
|
||||
jq '."default_server_config"."m.homeserver" = { "base_url": "https://${nginx-vhost}:443", "server_name": "${server_name}" }' \
|
||||
> $out/config.json < ${pkgs.element-web}/config.json
|
||||
ln -s $out/config.json $out/config.${nginx-vhost}.json
|
||||
'';
|
||||
in
|
||||
{
|
||||
# $ nix-shell -p dendrite --run 'generate-keys --private-key /tmp/key'
|
||||
sops.secrets.matrix-server-key = { };
|
||||
# $ echo "REGISTRATION_SHARED_SECRET=$(openssl rand -base64 32)"
|
||||
sops.secrets.registration-secret = { };
|
||||
|
||||
services.dendrite = {
|
||||
enable = true;
|
||||
httpPort = 8043;
|
||||
environmentFile = config.sops.secrets.registration-secret.path;
|
||||
|
||||
settings = {
|
||||
sync_api.search = {
|
||||
enabled = true;
|
||||
index_path = "/var/lib/dendrite/searchindex";
|
||||
};
|
||||
global = {
|
||||
server_name = domain;
|
||||
# `private_key` has the type `path`
|
||||
# prefix a `/` to make `path` happy
|
||||
private_key = "/$CREDENTIALS_DIRECTORY/matrix-server-key";
|
||||
trusted_third_party_id_servers = [
|
||||
"matrix.org"
|
||||
"vector.im"
|
||||
];
|
||||
metrics.enabled = true;
|
||||
};
|
||||
logging = [
|
||||
{
|
||||
type = "std";
|
||||
level = "warn";
|
||||
}
|
||||
];
|
||||
app_service_api = {
|
||||
inherit database;
|
||||
config_files = [ ];
|
||||
};
|
||||
client_api = {
|
||||
registration_disabled = true;
|
||||
rate_limiting.enabled = false;
|
||||
registration_shared_secret = ''''${REGISTRATION_SHARED_SECRET}'';
|
||||
};
|
||||
media_api = {
|
||||
inherit database;
|
||||
dynamic_thumbnails = true;
|
||||
};
|
||||
room_server = {
|
||||
inherit database;
|
||||
};
|
||||
push_server = {
|
||||
inherit database;
|
||||
};
|
||||
relay_api = {
|
||||
inherit database;
|
||||
};
|
||||
mscs = {
|
||||
inherit database;
|
||||
mscs = [ "msc2836" "msc2946" ];
|
||||
};
|
||||
sync_api = {
|
||||
inherit database;
|
||||
real_ip_header = "X-Real-IP";
|
||||
};
|
||||
key_server = {
|
||||
inherit database;
|
||||
};
|
||||
federation_api = {
|
||||
inherit database;
|
||||
key_perspectives = [
|
||||
{
|
||||
server_name = "matrix.org";
|
||||
keys = [
|
||||
{
|
||||
key_id = "ed25519:auto";
|
||||
public_key = "Noi6WqcDj0QmPxCNQqgezwTlBKrfqehY1u2FyWP9uYw";
|
||||
}
|
||||
{
|
||||
key_id = "ed25519:a_RXGa";
|
||||
public_key = "l8Hft5qXKn1vfHrg3p4+W8gELQVo8N13JkluMfmn2sQ";
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
prefer_direct_fetch = false;
|
||||
};
|
||||
user_api = {
|
||||
account_database = database;
|
||||
device_database = database;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services.dendrite.serviceConfig.LoadCredential = [
|
||||
"matrix-server-key:${config.sops.secrets.matrix-server-key.path}"
|
||||
];
|
||||
|
||||
systemd.services.dendrite.after = [ "postgresql.service" ];
|
||||
services.postgresql = {
|
||||
ensureDatabases = [ "dendrite" ];
|
||||
ensureUsers = [
|
||||
{
|
||||
name = "dendrite";
|
||||
ensurePermissions."DATABASE dendrite" = "ALL PRIVILEGES";
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
services.nginx.virtualHosts.${nginx-vhost} = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
extraConfig = ''
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_read_timeout 600;
|
||||
'';
|
||||
locations."/_matrix".proxyPass = "http://127.0.0.1:${toString config.services.dendrite.httpPort}";
|
||||
# for remote admin access
|
||||
locations."/_synapse".proxyPass = "http://127.0.0.1:${toString config.services.dendrite.httpPort}";
|
||||
locations."/".root = element-web;
|
||||
};
|
||||
}
|
@ -4,10 +4,15 @@ set -euo pipefail
|
||||
rm -f .terraform.lock.hcl
|
||||
if grep -q .sops terraform.tfstate; then
|
||||
sops -i -d terraform.tfstate
|
||||
if [[ -f secrets.auto.tfvars.sops.json ]]; then
|
||||
sops -d secrets.auto.tfvars.sops.json > secrets.auto.tfvars.json
|
||||
fi
|
||||
fi
|
||||
cleanup() {
|
||||
rm -f secrets.auto.tfvars.json
|
||||
sops -i -e terraform.tfstate
|
||||
}
|
||||
|
||||
trap "cleanup" EXIT
|
||||
terraform init
|
||||
terraform "$@"
|
||||
|
@ -1,5 +1,7 @@
|
||||
ssh_host_ed25519_key: ENC[AES256_GCM,data:68nXUeyy7xh/KKdd4ajdrkuzc54ZpnXhMpPjaDYtwMLlHja/O/t7g4IlVgLTKWwgMbr5/lAj04cEI99dAuoARaE+p4ldQeQNzPb7ZOPyRmSnBgO/qgtZoKNLaIX7q+Mwl+vsa2d2ZSHG8Fu7hzNIELWHQoaIFi782U+yKt2LHhahdVyY/FUPcymi0EtrwCqBHKSlEu+SXiwDXT4f+PCBtyaCJT4T4Mo2+TbERur9r9YOnKG2GEg46lDwTrr6FMya5K2WBks7AQwQ+rpoHCEy05tTg3GTJd8DypLhemrHMD7HeYzRf+HnVCyTngxmoquCD5/g9OM+fu63GIsnbGItWxREfjfzvODKuPaVCOat4mWQr1pLch1lcIkxQhU4EXg4LgHUMXFnQFrR8rvRT++YK1nRLB3w/lyvU4PAoocYlNR3G9JEClRnu4GH615ILEjXhyUZyAHIGx1+W7M6j4aGFhm3NOJWCTctaFd5r6uUeTqDpV757UzgHIR5lhtlfjeL41r3mmN09os/HpKt9EZ0,iv:+T4xz2xvyerO/ffW/YAKUkf5B/UVL8cUOl/ifWKIIx4=,tag:NTJklV5yqMT7uq0TvclhIA==,type:str]
|
||||
harmonia-key: ENC[AES256_GCM,data:pZObqfbLogp0DYs47Tg2STKT9HptPSiP4sgcf31FD68PKSWhkgJbdY3gO/pfa0zsnvZTrAiljR8Ugh/x9z70T/XhjgZ/dIKqtcrGw0or9WPDmVzD4UHYm6iWR30MZLa9EBK0GFInlcSa/g==,iv:9HRnOaqP1iKMyyRX7evl6woZgfw9h4t7mBD98v/iBng=,tag:MQDio//aEOAOTVWlgADYDQ==,type:str]
|
||||
matrix-server-key: ENC[AES256_GCM,data:0148ezOFk8jX5KPQPCG0jQK9ajSfe/iOdUqlvys5/M8DrIwPXH9GzrkknwH+l8kF9ViTRDC/q5md8J2bj3/FBR/RW4rwjDrYx9cBEFm8wjHrywUlwON8kNKtj9ycJmXgtRyCrVGv7sBmODy0ZC5ZfWbhIQh6xWBkX2/rsSh4zwi/1PoHLpOO3u4=,iv:IwHPDi1E3R9LAY/seGpvx1U+N8mB9NMrUjLg4KMA1UA=,tag:pwRJ/CqkFN2eedrnMAaj2w==,type:str]
|
||||
registration-secret: ENC[AES256_GCM,data:EvPearZAxxb2irZFYgvy/tFA72h+IABuzwCbvy94IYR0eoHjuYw6GBde8CNUWG4SUiwyXJr4v438o/YThDhehsZ/cZFjg2o=,iv:ogN4/Iia5Zl95a3HP1KZoy86K8LyBFYw50cZUpkDNQo=,tag:5wU2OrNi7b5gWPfFZcGLjg==,type:str]
|
||||
gitea-actions-runner: ENC[AES256_GCM,data:JKXAa7J1V3GH8lp3UtHTBmiezJlqxX1ItHLE7UcaIeNFQH8We2imaOMVftMpVCeXTpRX,iv:W9+4wH4asw3+w28i5om0OcJFHrABC85bhjhbgGWEs8E=,tag:Rf9XBeiEoJ1Pt8Z1TDIyJA==,type:str]
|
||||
sops:
|
||||
kms: []
|
||||
@ -34,8 +36,8 @@ sops:
|
||||
Q2J3VHNZZm13RlFwekJ6MHpPTmpZek0KiOqGozDqC5QQop5y+Scq+QHhVSXX43Ix
|
||||
KS496VWzRCdXYdgMk9gleA0AjaOGdAZOzdxsMQrWo+XfHrCy/1fU/w==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
lastmodified: "2023-07-12T14:19:37Z"
|
||||
mac: ENC[AES256_GCM,data:qnO1VyiPUK0uoAQux/3tRs2uE8e5aJVNL6SuR7lTNSJkfdV42H0w1AzFwyrAfnTzOkGGqJ9/gESH5/WyDuLSwYmRDUFH4E9CQI5RtjEfiiGDd9ah58kDDhy8UhhH1U1lfzUQMLSq7WJOFLF6tMVYZz+cSMCbrMHdcilzXFBwoEA=,iv:YTrQItix0HLekjGCa7apf73cQ+Zg57czvwtuFrSgUZ4=,tag:3uyWTBjFdHDa2dMerVqjrQ==,type:str]
|
||||
lastmodified: "2023-07-13T14:38:59Z"
|
||||
mac: ENC[AES256_GCM,data:jUKdCKb0Lw2+C+P5GfTt8zBw/LcAsBiyw/ShsJcpBmuokYgnkREJVokbeiVCql06a5IGnV3GBEzZvd+SnhRzKD9cgsu+ekwSzLGdVSv2j8B7il2M+L7IpBbUe/SnBKkQezKHaQ+mN2nJiCNtyjvPJKX16jmHVUx9yGee8tTi2sg=,iv:DwrfwR8BZDfBnG8CVPXZPSCMlBJbT1WFslGm6MM/j5E=,tag:Hqjp+qdhxXfM7O+ASQAcOw==,type:str]
|
||||
pgp: []
|
||||
unencrypted_suffix: _unencrypted
|
||||
version: 3.7.3
|
||||
|
@ -2,12 +2,15 @@ terraform {
|
||||
backend "local" {}
|
||||
}
|
||||
|
||||
variable "hetznerdns_token" {}
|
||||
|
||||
module "web01" {
|
||||
source = "../../terraform/web01"
|
||||
domain = "clan.lol"
|
||||
netlify_dns_zone = "clan.lol"
|
||||
nixos_flake_attr = "web01"
|
||||
nixos_vars_file = "${path.module}/nixos-vars.json"
|
||||
hetznerdns_token = var.hetznerdns_token
|
||||
tags = {
|
||||
Terraform = "true"
|
||||
Target = "web01"
|
||||
|
File diff suppressed because one or more lines are too long
@ -3,77 +3,70 @@ resource "netlify_dns_zone" "server" {
|
||||
name = var.netlify_dns_zone
|
||||
}
|
||||
|
||||
locals {
|
||||
subdomains = [
|
||||
"@",
|
||||
"git",
|
||||
"mail",
|
||||
"cache",
|
||||
"matrix",
|
||||
"www"
|
||||
]
|
||||
domains = [
|
||||
var.domain,
|
||||
"www.${var.domain}",
|
||||
"git.${var.domain}",
|
||||
"mail.${var.domain}",
|
||||
"cache.${var.domain}",
|
||||
"matrix.${var.domain}",
|
||||
]
|
||||
}
|
||||
|
||||
resource "hetznerdns_zone" "server" {
|
||||
name = var.domain
|
||||
ttl = 3600
|
||||
}
|
||||
|
||||
resource "hetznerdns_record" "server_a" {
|
||||
for_each = toset(local.subdomains)
|
||||
zone_id = hetznerdns_zone.server.id
|
||||
name = each.value
|
||||
type = "A"
|
||||
value = hcloud_server.server.ipv4_address
|
||||
}
|
||||
|
||||
resource "hetznerdns_record" "server_aaaa" {
|
||||
for_each = toset(local.subdomains)
|
||||
zone_id = hetznerdns_zone.server.id
|
||||
name = each.value
|
||||
type = "AAAA"
|
||||
value = hcloud_server.server.ipv6_address
|
||||
}
|
||||
|
||||
resource "netlify_dns_record" "server_a" {
|
||||
for_each = toset(local.domains)
|
||||
zone_id = netlify_dns_zone.server.id
|
||||
hostname = var.domain
|
||||
hostname = each.value
|
||||
type = "A"
|
||||
value = hcloud_server.server.ipv4_address
|
||||
}
|
||||
|
||||
resource "netlify_dns_record" "server_aaaa" {
|
||||
for_each = toset(local.domains)
|
||||
zone_id = netlify_dns_zone.server.id
|
||||
hostname = var.domain
|
||||
type = "AAAA"
|
||||
value = hcloud_server.server.ipv6_address
|
||||
}
|
||||
|
||||
resource "netlify_dns_record" "www_a" {
|
||||
zone_id = netlify_dns_zone.server.id
|
||||
hostname = "www.${var.domain}"
|
||||
type = "A"
|
||||
value = hcloud_server.server.ipv4_address
|
||||
}
|
||||
|
||||
resource "netlify_dns_record" "www_aaaa" {
|
||||
zone_id = netlify_dns_zone.server.id
|
||||
hostname = "www.${var.domain}"
|
||||
type = "AAAA"
|
||||
value = hcloud_server.server.ipv6_address
|
||||
}
|
||||
|
||||
resource "netlify_dns_record" "git_a" {
|
||||
zone_id = netlify_dns_zone.server.id
|
||||
hostname = "git.${var.domain}"
|
||||
type = "A"
|
||||
value = hcloud_server.server.ipv4_address
|
||||
}
|
||||
|
||||
resource "netlify_dns_record" "git_aaaa" {
|
||||
zone_id = netlify_dns_zone.server.id
|
||||
hostname = "git.${var.domain}"
|
||||
type = "AAAA"
|
||||
value = hcloud_server.server.ipv6_address
|
||||
}
|
||||
|
||||
resource "netlify_dns_record" "mail_a" {
|
||||
zone_id = netlify_dns_zone.server.id
|
||||
hostname = "mail.${var.domain}"
|
||||
type = "A"
|
||||
value = hcloud_server.server.ipv4_address
|
||||
}
|
||||
|
||||
resource "netlify_dns_record" "mail_aaaa" {
|
||||
zone_id = netlify_dns_zone.server.id
|
||||
hostname = "mail.${var.domain}"
|
||||
type = "AAAA"
|
||||
value = hcloud_server.server.ipv6_address
|
||||
}
|
||||
|
||||
resource "netlify_dns_record" "cache_a" {
|
||||
zone_id = netlify_dns_zone.server.id
|
||||
hostname = "cache.${var.domain}"
|
||||
type = "A"
|
||||
value = hcloud_server.server.ipv4_address
|
||||
}
|
||||
|
||||
resource "netlify_dns_record" "cache_aaaa" {
|
||||
zone_id = netlify_dns_zone.server.id
|
||||
hostname = "cache.${var.domain}"
|
||||
hostname = each.value
|
||||
type = "AAAA"
|
||||
value = hcloud_server.server.ipv6_address
|
||||
}
|
||||
|
||||
# for sending emails
|
||||
resource "hetznerdns_record" "spf" {
|
||||
zone_id = hetznerdns_zone.server.id
|
||||
name = "@"
|
||||
type = "TXT"
|
||||
value = "\"v=spf1 ip4:${hcloud_server.server.ipv4_address} ip6:${hcloud_server.server.ipv6_address} ~all\""
|
||||
}
|
||||
|
||||
resource "netlify_dns_record" "spf" {
|
||||
zone_id = netlify_dns_zone.server.id
|
||||
hostname = var.domain
|
||||
@ -81,6 +74,14 @@ resource "netlify_dns_record" "spf" {
|
||||
value = "v=spf1 ip4:${hcloud_server.server.ipv4_address} ip6:${hcloud_server.server.ipv6_address} ~all"
|
||||
}
|
||||
|
||||
resource "hetznerdns_record" "dkim" {
|
||||
zone_id = hetznerdns_zone.server.id
|
||||
name = "v1._domainkey"
|
||||
type = "TXT"
|
||||
# take from `systemctl status opendkim`
|
||||
value = "\"v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDTFSkQcM0v6mC4kiWEoF/EgK/hPVgOBJlHesLVIe+8BmidylaUowKlyC2gECipXhoVX9++OfMFAKNtGrIJcCTVNH/DRGkhbHLSxzzXijCbJ7G/fjpHRifpxMydEmybQDKdidR44YMR74Aj0OwUEgu+N/yJZ2+ubOlstW0fZJaJwQIDAQAB\""
|
||||
}
|
||||
|
||||
resource "netlify_dns_record" "dkim" {
|
||||
zone_id = netlify_dns_zone.server.id
|
||||
hostname = "v1._domainkey.${var.domain}"
|
||||
@ -89,6 +90,13 @@ resource "netlify_dns_record" "dkim" {
|
||||
value = "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDTFSkQcM0v6mC4kiWEoF/EgK/hPVgOBJlHesLVIe+8BmidylaUowKlyC2gECipXhoVX9++OfMFAKNtGrIJcCTVNH/DRGkhbHLSxzzXijCbJ7G/fjpHRifpxMydEmybQDKdidR44YMR74Aj0OwUEgu+N/yJZ2+ubOlstW0fZJaJwQIDAQAB"
|
||||
}
|
||||
|
||||
resource "hetznerdns_record" "adsp" {
|
||||
zone_id = hetznerdns_zone.server.id
|
||||
name = "_adsp._domainkey"
|
||||
type = "TXT"
|
||||
value = "\"dkim=all;\""
|
||||
}
|
||||
|
||||
resource "netlify_dns_record" "adsp" {
|
||||
zone_id = netlify_dns_zone.server.id
|
||||
hostname = "_adsp._domainkey.${var.domain}"
|
||||
@ -96,6 +104,13 @@ resource "netlify_dns_record" "adsp" {
|
||||
value = "dkim=all;"
|
||||
}
|
||||
|
||||
resource "hetznerdns_record" "dmarc" {
|
||||
zone_id = hetznerdns_zone.server.id
|
||||
name = "_dmarc"
|
||||
type = "TXT"
|
||||
value = "\"v=DMARC1; p=none; adkim=r; aspf=r; rua=mailto:joerc.dmarc@thalheim.io; ruf=mailto:joerg.dmarc@thalheim.io; pct=100\""
|
||||
}
|
||||
|
||||
resource "netlify_dns_record" "dmarc" {
|
||||
zone_id = netlify_dns_zone.server.id
|
||||
hostname = "_dmarc.${var.domain}"
|
||||
@ -103,7 +118,6 @@ resource "netlify_dns_record" "dmarc" {
|
||||
value = "v=DMARC1; p=none; adkim=r; aspf=r; rua=mailto:joerc.dmarc@thalheim.io; ruf=mailto:joerg.dmarc@thalheim.io; pct=100"
|
||||
}
|
||||
|
||||
|
||||
resource "hcloud_rdns" "master_a" {
|
||||
server_id = hcloud_server.server.id
|
||||
ip_address = hcloud_server.server.ipv4_address
|
||||
@ -115,6 +129,3 @@ resource "hcloud_rdns" "master_aaaa" {
|
||||
ip_address = hcloud_server.server.ipv6_address
|
||||
dns_ptr = "mail.${var.domain}"
|
||||
}
|
||||
|
||||
#v1._domainkey IN TXT ( "" ) ;
|
||||
|
||||
|
@ -1,7 +1,13 @@
|
||||
terraform {
|
||||
required_providers {
|
||||
netlify = { source = "AegirHealth/netlify" }
|
||||
hcloud = { source = "hetznercloud/hcloud" }
|
||||
local = { source = "hashicorp/local" }
|
||||
netlify = { source = "AegirHealth/netlify" }
|
||||
hcloud = { source = "hetznercloud/hcloud" }
|
||||
local = { source = "hashicorp/local" }
|
||||
hetznerdns = { source = "timohirt/hetznerdns" }
|
||||
}
|
||||
}
|
||||
|
||||
variable "hetznerdns_token" {}
|
||||
provider "hetznerdns" {
|
||||
apitoken = var.hetznerdns_token
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user