locals { # home gateway (prodnxsr0020) end of the mail DMZ tunnel hub_endpoint = "103.216.191.185" hub_port = 51821 hub_address = "10.10.13.1" wg_port = 51820 # only these destinations route over wg0; everything else (incl. SMTP) stays public wg_allowed_ips = [ "10.10.13.1/32", # prodnxsr0020 tunnel address "10.10.12.200/32", # management ssh client (wireguard workstation) "198.18.200.2/32", # puppetca.k8s.syd1.au.unkin.net "198.18.200.3/32", # puppet.k8s.syd1.au.unkin.net "198.18.200.4/32", # artifactapi.k8s.syd1.au.unkin.net (package repos) "198.18.200.7/32", # bind-internal resolvers "198.18.200.17/32", # rspamd milter :11332 "198.18.25.78/32", # vault.service.consul "198.18.26.197/32", # vault.service.consul "198.18.27.116/32", # vault.service.consul "198.18.28.248/32", # vault.service.consul "198.18.29.92/32", # vault.service.consul ] vpcs = { syd = "10.10.14.0/24" mel = "10.10.15.0/24" } gateways = { mta1 = { region = "syd", wg_address = "10.10.13.11" } mta2 = { region = "mel", wg_address = "10.10.13.12" } } } resource "binarylane_vpc" "dmz" { for_each = local.vpcs name = "dmz-${each.key}" ip_range = each.value } resource "wireguard_asymmetric_key" "hub" {} resource "wireguard_asymmetric_key" "gateway" { for_each = local.gateways } resource "vault_kv_secret_v2" "hub" { mount = "kv" name = "service/wireguard/binarylane/prodnxsr0020" data_json = jsonencode({ private_key = wireguard_asymmetric_key.hub.private_key public_key = wireguard_asymmetric_key.hub.public_key address = "${local.hub_address}/24" listen_port = local.hub_port }) } resource "vault_kv_secret_v2" "gateway" { for_each = local.gateways mount = "kv" name = "service/wireguard/binarylane/${each.key}" data_json = jsonencode({ private_key = wireguard_asymmetric_key.gateway[each.key].private_key public_key = wireguard_asymmetric_key.gateway[each.key].public_key address = "${each.value.wg_address}/24" listen_port = local.wg_port }) } resource "binarylane_server" "gateway" { for_each = local.gateways name = "${each.key}.edge.unkin.net" region = each.value.region image = "alma-9" size = "std-min" public_ipv4_count = 1 vpc_id = binarylane_vpc.dmz[each.value.region].id port_blocking = false backups = false ipv6 = false user_data = templatefile("${path.module}/cloud-init.yaml.tftpl", { hostname = each.key fqdn = "${each.key}.edge.unkin.net" wg_address = each.value.wg_address wg_port = local.wg_port wg_private_key = wireguard_asymmetric_key.gateway[each.key].private_key hub_public_key = wireguard_asymmetric_key.hub.public_key hub_endpoint = "${local.hub_endpoint}:${local.hub_port}" allowed_ips = join(", ", local.wg_allowed_ips) }) } resource "binarylane_server_reverse_name" "gateway" { for_each = local.gateways server_id = binarylane_server.gateway[each.key].id ipv4_address = binarylane_server.gateway[each.key].public_ipv4_addresses[0] reverse_name = "${each.key}.edge.unkin.net" } # SSH has no public rule: management reaches sshd through wg0, which this firewall never sees. resource "binarylane_server_firewall_rules" "gateway" { for_each = local.gateways server_id = binarylane_server.gateway[each.key].id firewall_rules = [ { description = "mail and https" protocol = "tcp" source_addresses = ["0.0.0.0/0"] destination_addresses = [binarylane_server.gateway[each.key].public_ipv4_addresses[0]] destination_ports = ["25", "465", "587", "993", "443"] action = "accept" }, { description = "wireguard from home gateway" protocol = "udp" source_addresses = ["${local.hub_endpoint}/32"] destination_addresses = [binarylane_server.gateway[each.key].public_ipv4_addresses[0]] destination_ports = [tostring(local.wg_port)] action = "accept" }, { description = "icmp" protocol = "icmp" source_addresses = ["0.0.0.0/0"] destination_addresses = [binarylane_server.gateway[each.key].public_ipv4_addresses[0]] action = "accept" }, { description = "default deny" protocol = "all" source_addresses = ["0.0.0.0/0"] destination_addresses = [binarylane_server.gateway[each.key].public_ipv4_addresses[0]] action = "drop" }, ] }