This commit is contained in:
Graham McIntire 2026-03-26 17:53:51 -05:00
parent fb6d00b84d
commit baa50efccf
No known key found for this signature in database
GPG key ID: F4ABF488E6029E59
11 changed files with 120 additions and 21 deletions

View file

@ -192,8 +192,8 @@ tofu plan
- **Talos Extensions** (workers only):
- `iscsi-tools` v0.2.0 — required by Longhorn
- `util-linux-tools` 2.41.2 — required by Longhorn
- Installer image: `factory.talos.dev/installer/613e1592b2da41ae5e265e8789429f22e121aab91cb4deb6bc3c0b6262961245:v1.12.4`
- Control plane nodes use the stock `ghcr.io/siderolabs/installer:v1.12.4`
- Installer image: `factory.talos.dev/installer/613e1592b2da41ae5e265e8789429f22e121aab91cb4deb6bc3c0b6262961245:v1.12.6`
- Control plane nodes use the stock `ghcr.io/siderolabs/installer:v1.12.6`
- **Deployment**: Managed via OpenTofu in `/tofu/`
- **Configuration**: `/talos/` directory
- `talosconfig` - Talosctl client config

View file

@ -5,3 +5,7 @@ ansible_ssh_private_key_file: /Users/graham/.ssh/id_ed25519
ansible_ssh_common_args: '-o StrictHostKeyChecking=accept-new'
firewall_enabled: false
# Proxmox requires hostname to resolve to actual IP, not loopback
network:
loopback_in_hosts: false

View file

@ -1,6 +1,6 @@
---
ansible_user: graham
ansible_host: 100.108.110.128
ansible_host: db-towerops
ansible_python_interpreter: /usr/bin/python3
ansible_ssh_private_key_file: /Users/graham/.ssh/id_ed25519
ansible_ssh_common_args: '-o StrictHostKeyChecking=accept-new'

View file

@ -1,6 +1,6 @@
---
ansible_user: ansible
ansible_host: 204.110.191.8
ansible_host: skippy
ansible_python_interpreter: /usr/bin/python3
ansible_ssh_private_key_file: /Users/graham/.ssh/ansible
ansible_ssh_common_args: '-o StrictHostKeyChecking=accept-new'

View file

@ -1,6 +1,6 @@
---
ansible_user: graham
ansible_host: 204.110.191.231
ansible_host: staging
ansible_python_interpreter: /usr/bin/python3
ansible_ssh_private_key_file: /Users/graham/.ssh/id_ed25519
ansible_ssh_common_args: '-o StrictHostKeyChecking=accept-new'

View file

@ -21,7 +21,7 @@ monitor.vntx.net
[home_servers]
skippy.w5isp.com
mail.mcintire.me ansible_host=107.174.178.20
mail.mcintire.me ansible_host=mail
dokku.w5isp.com
aprs.w5isp.com
staging.towerops.net
@ -37,7 +37,7 @@ skippy.w5isp.com
[bind9_servers]
ns1.as393837.net ansible_host=204.110.191.222
git.mcintire.me ansible_host=172.245.56.83
git.mcintire.me ansible_host=git
[dns_servers:children]
bind9_servers
@ -49,12 +49,14 @@ git.mcintire.me
uisp.vntx.net
[proxmox_servers]
node1 ansible_host=10.0.15.101
node2 ansible_host=10.0.15.102
node3 ansible_host=10.0.15.103
vm1-380 ansible_host=10.0.0.1
vm2-380 ansible_host=vm2-380
node1 ansible_host=node1
node2 ansible_host=node2
node3 ansible_host=node3
[postgresql_servers]
db.towerops.net ansible_host=100.108.110.128
db.towerops.net ansible_host=db-towerops
db.aprs.me ansible_host=10.0.15.22
[home_cluster:children]

View file

@ -10,6 +10,13 @@ firewall_trusted_subnets:
firewall_default_incoming: deny
firewall_default_outgoing: allow
# Additional IPs allowed to SSH (port 22) to all hosts
firewall_ssh_allow_from:
- ip: 172.245.56.83
comment: git.mcintire.me
- ip: 107.174.178.20
comment: mail.mcintire.me
# Per-host rules for publicly exposed services
# Override in host_vars or group_vars as needed
# Example:

View file

@ -36,6 +36,18 @@
loop: "{{ firewall_trusted_subnets }}"
when: ansible_os_family == "RedHat"
- name: Allow SSH from specific IPs in firewalld
ansible.posix.firewalld:
zone: public
rich_rule: 'rule family="ipv4" source address="{{ item.ip }}" port port="22" protocol="tcp" accept'
permanent: true
immediate: true
state: enabled
loop: "{{ firewall_ssh_allow_from }}"
when:
- ansible_os_family == "RedHat"
- firewall_ssh_allow_from | length > 0
- name: Allow per-host public services in firewalld
ansible.posix.firewalld:
zone: public
@ -48,30 +60,47 @@
- ansible_os_family == "RedHat"
- firewall_allow_rules | length > 0
# --- UFW (Debian/Ubuntu) ---
# --- UFW (Debian/Ubuntu) - Disable when firewall not managed ---
- name: Disable ufw
ufw:
state: disabled
when:
- ansible_os_family == "Debian"
- not (firewall_enabled | default(true))
# --- UFW (Debian/Ubuntu) - Configure when firewall managed ---
- name: Reset ufw to defaults
ufw:
state: reset
when: ansible_os_family == "Debian"
when:
- ansible_os_family == "Debian"
- firewall_enabled | default(true)
- name: Set default incoming policy to deny
ufw:
direction: incoming
policy: "{{ firewall_default_incoming }}"
when: ansible_os_family == "Debian"
when:
- ansible_os_family == "Debian"
- firewall_enabled | default(true)
- name: Set default outgoing policy to allow
ufw:
direction: outgoing
policy: "{{ firewall_default_outgoing }}"
when: ansible_os_family == "Debian"
when:
- ansible_os_family == "Debian"
- firewall_enabled | default(true)
- name: Set default routed policy
ufw:
direction: routed
policy: "{{ firewall_default_routed }}"
when: ansible_os_family == "Debian"
when:
- ansible_os_family == "Debian"
- firewall_enabled | default(true)
- name: Allow all traffic from trusted subnets
ufw:
@ -79,7 +108,22 @@
from_ip: "{{ item.subnet }}"
comment: "{{ item.comment }}"
loop: "{{ firewall_trusted_subnets }}"
when: ansible_os_family == "Debian"
when:
- ansible_os_family == "Debian"
- firewall_enabled | default(true)
- name: Allow SSH from specific IPs
ufw:
rule: allow
port: "22"
proto: tcp
from_ip: "{{ item.ip }}"
comment: "SSH from {{ item.comment }}"
loop: "{{ firewall_ssh_allow_from }}"
when:
- ansible_os_family == "Debian"
- firewall_enabled | default(true)
- firewall_ssh_allow_from | length > 0
- name: Allow per-host public services
ufw:
@ -90,6 +134,7 @@
loop: "{{ firewall_allow_rules }}"
when:
- ansible_os_family == "Debian"
- firewall_enabled | default(true)
- firewall_allow_rules | length > 0
- name: Enable IP forwarding
@ -101,6 +146,7 @@
reload: true
when:
- ansible_os_family == "Debian"
- firewall_enabled | default(true)
- firewall_ip_forward
- name: Configure NAT masquerade rules in ufw before.rules
@ -116,10 +162,13 @@
loop: "{{ firewall_masquerade_rules }}"
when:
- ansible_os_family == "Debian"
- firewall_enabled | default(true)
- firewall_masquerade_rules | length > 0
notify: Reload ufw
- name: Enable ufw
ufw:
state: enabled
when: ansible_os_family == "Debian"
when:
- ansible_os_family == "Debian"
- firewall_enabled | default(true)

View file

@ -5,7 +5,7 @@ metadata:
name: cloudflared
namespace: cloudflared
spec:
replicas: 2
replicas: 3
selector:
matchLabels:
app: cloudflared
@ -14,6 +14,13 @@ spec:
labels:
app: cloudflared
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
app: cloudflared
topologyKey: kubernetes.io/hostname
containers:
- name: cloudflared
image: cloudflare/cloudflared:latest

View file

@ -239,6 +239,36 @@ resource "cloudflare_record" "aprs_me_tunnel" {
proxied = true
}
# aprs.me - Resend email (DKIM, SPF, DMARC, MX)
resource "cloudflare_record" "aprs_me_dkim_resend" {
zone_id = cloudflare_zone.zones["aprs.me"].id
type = "TXT"
name = "resend._domainkey"
content = "p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrIhTzL7qrNSdbVOWG2WVwXpKrRrkHY4w/giB7JGl9Hj23z1qIQNh8aNyvDaC0Eosf1013TSWvS+bFMETc5kQZ6lQDq6pvZxHeKbAGH1FvUDVQ2uhjV77Qopf95SdoDKsod3hRnfn4kNZBQ2GfrbJmqobIsQRT8IHFA3XOjOn/jwIDAQAB"
}
resource "cloudflare_record" "aprs_me_mx_send" {
zone_id = cloudflare_zone.zones["aprs.me"].id
type = "MX"
name = "send"
content = "feedback-smtp.us-east-1.amazonses.com"
priority = 10
}
resource "cloudflare_record" "aprs_me_spf_send" {
zone_id = cloudflare_zone.zones["aprs.me"].id
type = "TXT"
name = "send"
content = "v=spf1 include:amazonses.com ~all"
}
resource "cloudflare_record" "aprs_me_dmarc" {
zone_id = cloudflare_zone.zones["aprs.me"].id
type = "TXT"
name = "_dmarc"
content = "v=DMARC1; p=none;"
}
resource "cloudflare_record" "gridmap_org_tunnel" {
zone_id = cloudflare_zone.zones["gridmap.org"].id
type = "CNAME"
@ -399,7 +429,7 @@ resource "cloudflare_ruleset" "towerops_firewall" {
# Allow agent WebSocket connections (must come before block rules)
rules {
action = "skip"
action = "skip"
action_parameters {
ruleset = "current"
}

File diff suppressed because one or more lines are too long