Allow only exposing services over Tailscale
/ terraform (push) Failing after 41s Details
/ ansible (push) Successful in 1m41s Details

This works using public DNS, so doesn't need Tailscale's magic DNS to override my local.
This commit is contained in:
Jake Howard 2024-03-07 22:30:10 +00:00
parent 451a114262
commit f88d224168
Signed by: jake
GPG Key ID: 57AFB45680EDD477
10 changed files with 56 additions and 0 deletions

View File

@ -2,5 +2,6 @@
tailscale_up_skip: true tailscale_up_skip: true
tailscale_cidr: 100.64.0.0/24 # It's really /10, but I don't use that many IPs tailscale_cidr: 100.64.0.0/24 # It's really /10, but I don't use that many IPs
tailscale_cidr_ipv6: fd7a:115c:a1e0::/120 # It's really /48, but I don't use that many IPs
tailscale_port: 41641 tailscale_port: 41641

View File

@ -1,3 +1,5 @@
"vps_hosts": "vps_hosts":
"casey_ip": "213.219.38.11" "casey_ip": "213.219.38.11"
"private_ipv6_marker": "2a01:7e00:e000:7f7::1"
"private_ipv6_range": "2a01:7e00:e000:7f7::1/128"
"walker_ip": "192.248.168.230" "walker_ip": "192.248.168.230"

View File

@ -21,6 +21,20 @@ map $ssl_preread_server_name $gateway_destination {
server { server {
listen 443; listen 443;
listen 8448; listen 8448;
listen [::]:443;
listen [::]:8448;
proxy_pass $gateway_destination; proxy_pass $gateway_destination;
proxy_protocol on; proxy_protocol on;
} }
server {
listen [{{ vps_hosts.private_ipv6_marker }}]:443;
listen [{{ vps_hosts.private_ipv6_marker }}]:8448;
access_log off;
deny all;
# This is never used, but need to keep nginx happy
proxy_pass 127.0.0.1:80;
}

View File

@ -9,6 +9,8 @@ access_log /var/log/nginx/access.log access;
server { server {
listen 443; listen 443;
listen 8448; listen 8448;
listen [::]:443;
listen [::]:8448;
proxy_pass {{ pve_hosts.docker.ip }}:443; proxy_pass {{ pve_hosts.docker.ip }}:443;
proxy_protocol on; proxy_protocol on;
proxy_socket_keepalive on; proxy_socket_keepalive on;

View File

@ -7,6 +7,9 @@ services:
labels: labels:
- traefik.enable=true - traefik.enable=true
- traefik.http.routers.whoami.rule=Host(`whoami.theorangeone.net`) || Host(`whoami-cdn.theorangeone.net`) - traefik.http.routers.whoami.rule=Host(`whoami.theorangeone.net`) || Host(`whoami-cdn.theorangeone.net`)
- traefik.http.routers.whoami-private.rule=Host(`whoami-private.theorangeone.net`)
- traefik.http.routers.whoami-private.middlewares=tailscale-only@file
networks: networks:
- default - default
- traefik - traefik

View File

@ -8,3 +8,9 @@ http:
headers: headers:
customResponseHeaders: customResponseHeaders:
Permissions-Policy: interest-cohort=() Permissions-Policy: interest-cohort=()
tailscale-only:
ipAllowList:
sourceRange:
- "{{ tailscale_cidr }}"
- "{{ tailscale_cidr_ipv6 }}"

View File

@ -6,6 +6,16 @@ resource "linode_instance" "casey" {
private_ip = true private_ip = true
} }
resource "linode_ipv6_range" "casey_extra" {
linode_id = linode_instance.casey.id
prefix_length = 64
}
locals {
private_ipv6_marker = cidrhost(linode_ipv6_range.casey_extra.id, 1)
private_ipv6_range = cidrsubnet(linode_ipv6_range.casey_extra.id, 64, 1)
}
resource "linode_firewall" "casey" { resource "linode_firewall" "casey" {
label = "casey" label = "casey"
linodes = [linode_instance.casey.id] linodes = [linode_instance.casey.id]

View File

@ -2,6 +2,8 @@ resource "local_file" "hosts" {
content = yamlencode({ content = yamlencode({
vps_hosts : { vps_hosts : {
casey_ip : linode_instance.casey.ip_address, casey_ip : linode_instance.casey.ip_address,
private_ipv6_marker : local.private_ipv6_marker,
private_ipv6_range : local.private_ipv6_range,
walker_ip : vultr_instance.walker.main_ip, walker_ip : vultr_instance.walker.main_ip,
} }
}) })

View File

@ -37,3 +37,11 @@ resource "cloudflare_record" "sys_domain_pve" {
type = "A" type = "A"
ttl = 1 ttl = 1
} }
resource "cloudflare_record" "sys_domain_private" {
zone_id = cloudflare_zone.theorangeonenet.id
name = "private.sys"
value = local.private_ipv6_marker
type = "AAAA"
ttl = 1
}

View File

@ -26,6 +26,14 @@ resource "cloudflare_record" "theorangeonenet_whoami_cdn" {
ttl = 1 ttl = 1
} }
resource "cloudflare_record" "theorangeonenet_whoami_private" {
zone_id = cloudflare_zone.theorangeonenet.id
name = "whoami-private"
value = cloudflare_record.sys_domain_private.hostname
type = "CNAME"
ttl = 1
}
resource "cloudflare_record" "theorangeonenet_mx1" { resource "cloudflare_record" "theorangeonenet_mx1" {
zone_id = cloudflare_zone.theorangeonenet.id zone_id = cloudflare_zone.theorangeonenet.id
name = "@" name = "@"