feat: tailscale + dns

This commit is contained in:
Tine 2024-08-23 22:03:47 +02:00
parent b1b8633945
commit 2a2b98f3fe
Signed by: mentos1386
SSH key fingerprint: SHA256:MNtTsLbihYaWF8j1fkOHfkKNlnN1JQfxEU/rBU8nCGw
8 changed files with 110 additions and 74 deletions

View file

@ -6,7 +6,7 @@
...
}:
let
ngx_http_geoip2_module = pkgs.stdenv.mkDerivation rec {
ngx_http_geoip2_module = pkgs.stdenv.mkDerivation {
name = "ngx_http_geoip2_module-a28ceff";
src = pkgs.fetchgit {
url = "https://github.com/leev/ngx_http_geoip2_module";
@ -28,23 +28,45 @@ in
# PROXMOX
services.qemuGuest.enable = true;
services.cloud-init = {
enable = true;
};
# USER MANAGEMENT
# TODO: Should this be in cloud-init?
nix.settings.trusted-users = [ "nixos" ];
users.users.nixos = {
isNormalUser = true;
password = "nixos";
extraGroups = [ "wheel" ];
openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICXAlzwziqfUUb2qmFwNF/nrBYc5MNT1MMOx81ohBmB+ tine@little.sys.tjo.space"
];
};
security.sudo.wheelNeedsPassword = false;
# SSH
services.openssh = {
enable = true;
settings.PasswordAuthentication = false;
settings.KbdInteractiveAuthentication = false;
settings.PermitRootLogin = "no";
};
security.sudo.wheelNeedsPassword = false;
# TAILSCALE
services.tailscale = {
enable = true;
};
# FIREWALL
networking.firewall = {
enable = true;
trustedInterfaces = [ "tailscale0" ];
allowedUDPPorts = [ config.services.tailscale.port ];
allowedTCPPorts = [ 22 ];
};
# NGINX
services.nginx = {

View file

@ -28,11 +28,13 @@ push:
--upload-file $NIXOS_IMAGE \
https://code.tjo.space/api/packages/tjo-cloud/generic/ingress/${VERSION}/nixos.qcow2
deploy:
deploy: build
#!/usr/bin/env sh
export NIXOS_IMAGE=$(nix path-info --quiet .#vm)/nixos.qcow2
export TF_VAR_image_path=$NIXOS_IMAGE
echo "Deploying $NIXOS_IMAGE"
cd {{justfile_directory()}}/terraform
tofu init
tofu apply

53
terraform/dns.tf Normal file
View file

@ -0,0 +1,53 @@
data "digitalocean_domain" "ingress" {
name = "ingress.tjo.cloud"
}
resource "digitalocean_record" "public" {
for_each = merge(
{
for key, node in local.nodes_with_address : key => {
node = node.name,
ip = node.public_ipv4,
type = "A",
}
},
{
for key, node in local.nodes_with_address : key => {
node = node.name,
ip = node.public_ipv6,
type = "AAAA",
}
}
)
domain = data.digitalocean_domain.ingress.id
type = each.value.type
name = lower(each.value.node)
value = each.value.ip
ttl = 60
}
resource "digitalocean_record" "internal" {
for_each = merge(
{
for key, node in local.nodes_with_address : key => {
node = node.name,
ip = node.internal_ipv4,
type = "A",
}
},
{
for key, node in local.nodes_with_address : key => {
node = node.name,
ip = node.internal_ipv6,
type = "AAAA",
}
}
)
domain = data.digitalocean_domain.ingress.id
type = each.value.type
name = lower(each.value.node)
value = each.value.ip
ttl = 60
}

View file

@ -1,9 +1,9 @@
locals {
nodes_with_names = {
for k, v in var.nodes : k => merge(v, {
id = 700 + index(keys(var.nodes), k)
name = "${v.name}.ingress.tjo.cloud"
hash = sha1(v.name)
id = 700 + index(keys(var.nodes), k)
hostname = "${v.name}.ingress.tjo.cloud"
hash = sha1(v.name)
})
}
nodes = {
@ -28,12 +28,22 @@ locals {
nodes_with_address = {
for k, v in local.nodes :
k => merge(v, {
ipv4 = local.ipv4_addresses[k]["eth0"][0]
ipv6 = local.ipv6_addresses[k]["eth0"][0]
public_ipv4 = local.ipv4_addresses[k]["eth0"][0]
public_ipv6 = local.ipv6_addresses[k]["eth0"][0]
internal_ipv4 = local.ipv4_addresses[k]["tailscale0"][0]
internal_ipv6 = local.ipv6_addresses[k]["tailscale0"][0]
})
}
}
resource "tailscale_tailnet_key" "ingress" {
reusable = true
ephemeral = true
preauthorized = true
tags = ["tag:ingress-tjo-cloud"]
description = "tailscale key for ingress-tjo-cloud nodes"
}
resource "proxmox_virtual_environment_file" "ingress" {
content_type = "iso"
datastore_id = var.common_storage
@ -54,9 +64,14 @@ resource "proxmox_virtual_environment_file" "cloudinit" {
source_raw {
data = <<-EOF
#cloud-config
bootcmd:
- [ 'tailscale', 'up', '--authkey', '${tailscale_tailnet_key.ingress.key}',
'--hostname', '${each.value.name}',
'--accept-routes', 'true',
'--ssh' ]
EOF
file_name = "${each.value.name}.cloudinit.yaml"
file_name = "${each.value.hostname}.cloudinit.yaml"
}
}
@ -64,7 +79,7 @@ resource "proxmox_virtual_environment_vm" "nodes" {
for_each = local.nodes
vm_id = each.value.id
name = each.value.name
name = each.value.hostname
node_name = each.value.host
description = "Node ${each.value.name} for ingress.tjo.cloud."

View file

@ -1,28 +0,0 @@
locals {
locations = {
DE = ["46.4.88.62", "2a01:4f8:202:2395::"]
SI = ["93.103.125.118", "2a01:261:455:6c00:21e:6ff:fe45:c34"]
}
}
data "digitalocean_domain" "ingress" {
name = "ingress.tjo.cloud"
}
resource "digitalocean_record" "locations" {
for_each = merge([
for location, ips in local.locations : {
for ip in ips : "${location} at ${ip}" => {
location = location,
ip = ip,
}
}
]...)
domain = data.digitalocean_domain.ingress.id
type = strcontains(each.value.ip, ":") ? "AAAA" : "A"
name = lower(each.value.location)
value = each.value.ip
ttl = 60
}

View file

@ -1,35 +0,0 @@
locals {
listeners = [
{
domain = "k8s.tjo.cloud"
name = "api"
locations = ["SI", "DE"]
},
{
domain = "k8s.tjo.cloud"
name = "dashboard"
locations = ["SI", "DE"]
}
]
}
resource "digitalocean_record" "listeners" {
for_each = merge(flatten([
for listener in local.listeners :
[
for location in listener.locations : {
for ip in local.locations[location] : "${ip} for ${listener.name}.${listener.domain} at ${location}" => {
ip = ip
domain = listener.domain
name = listener.name
}
}
]
])...)
domain = each.value.domain
type = strcontains(each.value.ip, ":") ? "AAAA" : "A"
name = each.value.name
value = each.value.ip
ttl = 60
}

View file

@ -25,6 +25,9 @@ provider "digitalocean" {
token = var.digitalocean_token
}
provider "tailscale" {
api_key = var.tailscale_apikey
}
provider "proxmox" {
# FIXME: Traefik/NGINX breaks this! 500 ERROR

View file

@ -27,6 +27,10 @@ variable "proxmox_token" {
type = string
}
variable "tailscale_apikey" {
type = string
}
variable "image_path" {
type = string
}