add source code and readme
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
# Harbor Registry Firewall Rules for Direct Access
|
||||
apiVersion: "cilium.io/v2"
|
||||
kind: CiliumClusterwideNetworkPolicy
|
||||
metadata:
|
||||
name: "harbor-registry-host-firewall"
|
||||
spec:
|
||||
description: "Allow external access to ports 80/443 only for NGINX Ingress serving Harbor"
|
||||
# Target NGINX Ingress Controller pods specifically (they use hostNetwork)
|
||||
endpointSelector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: "ingress-nginx"
|
||||
app.kubernetes.io/component: "controller"
|
||||
ingress:
|
||||
# Allow external traffic to NGINX Ingress on HTTP/HTTPS ports
|
||||
- fromEntities:
|
||||
- world
|
||||
- cluster
|
||||
toPorts:
|
||||
- ports:
|
||||
- port: "80"
|
||||
protocol: "TCP"
|
||||
- port: "443"
|
||||
protocol: "TCP"
|
||||
|
||||
# Allow cluster-internal traffic to NGINX Ingress
|
||||
- fromEntities:
|
||||
- cluster
|
||||
toPorts:
|
||||
- ports:
|
||||
- port: "80"
|
||||
protocol: "TCP"
|
||||
- port: "443"
|
||||
protocol: "TCP"
|
||||
- port: "10254" # NGINX metrics port
|
||||
protocol: "TCP"
|
||||
|
||||
---
|
||||
# Allow NGINX Ingress to reach Harbor services
|
||||
apiVersion: "cilium.io/v2"
|
||||
kind: CiliumNetworkPolicy
|
||||
metadata:
|
||||
name: "harbor-services-access"
|
||||
namespace: "harbor-registry"
|
||||
spec:
|
||||
description: "Allow NGINX Ingress Controller to reach Harbor services"
|
||||
endpointSelector:
|
||||
matchLabels:
|
||||
app: "harbor"
|
||||
ingress:
|
||||
# Allow traffic from NGINX Ingress Controller
|
||||
- fromEndpoints:
|
||||
- matchLabels:
|
||||
app.kubernetes.io/name: "ingress-nginx"
|
||||
app.kubernetes.io/component: "controller"
|
||||
|
||||
# Allow traffic between Harbor components
|
||||
- fromEndpoints:
|
||||
- matchLabels:
|
||||
app: "harbor"
|
||||
@@ -0,0 +1,262 @@
|
||||
# policies/host-fw-control-plane.yaml
|
||||
apiVersion: "cilium.io/v2"
|
||||
kind: CiliumClusterwideNetworkPolicy
|
||||
metadata:
|
||||
name: "host-fw-control-plane"
|
||||
spec:
|
||||
description: "control-plane specific access rules. Restricted to Tailscale network for security."
|
||||
nodeSelector:
|
||||
matchLabels:
|
||||
node-role.kubernetes.io/control-plane: ""
|
||||
ingress:
|
||||
# Allow access to kube api from Tailscale network, VLAN, VIP, and external IPs
|
||||
# VIP (<VIP_IP>) allows new nodes to bootstrap via VLAN without network changes
|
||||
- fromCIDR:
|
||||
- 100.64.0.0/10 # Tailscale CGNAT range
|
||||
- 10.132.0.0/24 # VLAN subnet (includes VIP <VIP_IP> and node IPs)
|
||||
- <VIP_IP>/32 # Explicit VIP for control plane (new node bootstrapping)
|
||||
- <NODE_1_EXTERNAL_IP>/32 # n1 external IP
|
||||
- <NODE_2_EXTERNAL_IP>/32 # n2 external IP
|
||||
- <NODE_3_EXTERNAL_IP>/32 # n3 external IP
|
||||
- fromEntities:
|
||||
- cluster # Allow cluster-internal access
|
||||
toPorts:
|
||||
- ports:
|
||||
- port: "6443"
|
||||
protocol: "TCP"
|
||||
|
||||
# Allow access to talos from Tailscale network, VLAN, VIP, external IPs, and cluster
|
||||
# Restricted access (not world) for security - authentication still required
|
||||
# https://www.talos.dev/v1.4/learn-more/talos-network-connectivity/
|
||||
- fromCIDR:
|
||||
- 100.64.0.0/10 # Tailscale CGNAT range
|
||||
- 10.132.0.0/24 # VLAN subnet for node bootstrapping
|
||||
- <VIP_IP>/32 # VIP for control plane access
|
||||
- <NODE_1_EXTERNAL_IP>/32 # n1 external IP
|
||||
- <NODE_2_EXTERNAL_IP>/32 # n2 external IP
|
||||
- <NODE_3_EXTERNAL_IP>/32 # n3 external IP
|
||||
- fromEntities:
|
||||
- cluster # Allow cluster-internal access
|
||||
toPorts:
|
||||
- ports:
|
||||
- port: "50000"
|
||||
protocol: "TCP"
|
||||
- port: "50001"
|
||||
protocol: "TCP"
|
||||
|
||||
# Allow worker nodes to access control plane Talos API
|
||||
- fromEntities:
|
||||
- remote-node
|
||||
toPorts:
|
||||
- ports:
|
||||
- port: "50000"
|
||||
protocol: "TCP"
|
||||
- port: "50001"
|
||||
protocol: "TCP"
|
||||
|
||||
# Allow kube-proxy-replacement from kube-apiserver
|
||||
- fromEntities:
|
||||
- kube-apiserver
|
||||
toPorts:
|
||||
- ports:
|
||||
- port: "10250"
|
||||
protocol: "TCP"
|
||||
- port: "4244"
|
||||
protocol: "TCP"
|
||||
|
||||
# Allow access from hubble-relay to hubble-peer (running on the node)
|
||||
- fromEndpoints:
|
||||
- matchLabels:
|
||||
k8s-app: hubble-relay
|
||||
toPorts:
|
||||
- ports:
|
||||
- port: "4244"
|
||||
protocol: "TCP"
|
||||
|
||||
# Allow metrics-server to scrape
|
||||
- fromEndpoints:
|
||||
- matchLabels:
|
||||
k8s-app: metrics-server
|
||||
toPorts:
|
||||
- ports:
|
||||
- port: "10250"
|
||||
protocol: "TCP"
|
||||
|
||||
# Allow ICMP Ping from/to anywhere.
|
||||
- icmps:
|
||||
- fields:
|
||||
- type: 8
|
||||
family: IPv4
|
||||
- type: 128
|
||||
family: IPv6
|
||||
|
||||
# Allow cilium tunnel/health checks from other nodes.
|
||||
- fromEntities:
|
||||
- remote-node
|
||||
toPorts:
|
||||
- ports:
|
||||
- port: "8472"
|
||||
protocol: "UDP"
|
||||
- port: "4240"
|
||||
protocol: "TCP"
|
||||
|
||||
# Allow etcd communication between control plane nodes
|
||||
# Required for etcd cluster formation and peer communication
|
||||
# Ports: 2379 (client API), 2380 (peer communication), 51871 (Talos etcd peer discovery)
|
||||
- fromCIDR:
|
||||
- 100.64.0.0/10 # Tailscale CGNAT range
|
||||
- 10.132.0.0/24 # VLAN subnet (includes VIP <VIP_IP> and node IPs)
|
||||
- <VIP_IP>/32 # Explicit VIP for control plane (new node bootstrapping)
|
||||
- <NODE_1_EXTERNAL_IP>/32 # n1 external IP
|
||||
- <NODE_2_EXTERNAL_IP>/32 # n2 external IP
|
||||
- <NODE_3_EXTERNAL_IP>/32 # n3 external IP
|
||||
- fromEntities:
|
||||
- remote-node # Allow from other nodes (including bootstrapping control planes)
|
||||
- cluster # Allow from cluster pods
|
||||
toPorts:
|
||||
- ports:
|
||||
- port: "2379"
|
||||
protocol: "TCP" # etcd client API
|
||||
- port: "2380"
|
||||
protocol: "TCP" # etcd peer communication
|
||||
- port: "51871"
|
||||
protocol: "UDP" # Talos etcd peer discovery
|
||||
|
||||
# HTTP and HTTPS access - allow external for Harbor direct access and Let's Encrypt challenges
|
||||
# everything else is secured and I really hate this
|
||||
- fromEntities:
|
||||
- cluster
|
||||
- world # Allow external access for Harbor and Let's Encrypt
|
||||
- fromCIDR:
|
||||
- 100.64.0.0/10 # Tailscale CGNAT range - allow Tailscale services (e.g., Kibana proxy)
|
||||
toPorts:
|
||||
- ports:
|
||||
- port: "80"
|
||||
protocol: "TCP"
|
||||
- port: "443"
|
||||
protocol: "TCP"
|
||||
|
||||
# Allow access from inside the cluster to the admission controller
|
||||
- fromEntities:
|
||||
- cluster
|
||||
toPorts:
|
||||
- ports:
|
||||
- port: "8443"
|
||||
protocol: "TCP"
|
||||
|
||||
# Allow PostgreSQL and Redis database connections from cluster
|
||||
- fromEntities:
|
||||
- cluster
|
||||
toPorts:
|
||||
- ports:
|
||||
- port: "5432"
|
||||
protocol: "TCP" # PostgreSQL
|
||||
- port: "6379"
|
||||
protocol: "TCP" # Redis
|
||||
|
||||
# Allow PostgreSQL monitoring/health checks and CloudNativePG coordination
|
||||
- fromEntities:
|
||||
- cluster
|
||||
toPorts:
|
||||
- ports:
|
||||
- port: "9187"
|
||||
protocol: "TCP" # PostgreSQL metrics port
|
||||
- port: "8000"
|
||||
protocol: "TCP" # CloudNativePG health endpoint
|
||||
- port: "9443"
|
||||
protocol: "TCP" # CloudNativePG operator webhook server
|
||||
|
||||
# Allow local kubelet health checks on control plane pods
|
||||
# (kubelet on control plane needs to check health endpoints of local pods)
|
||||
- fromEntities:
|
||||
- host
|
||||
toPorts:
|
||||
- ports:
|
||||
- port: "8000"
|
||||
protocol: "TCP" # CloudNativePG health endpoint for kubelet probes
|
||||
|
||||
# OpenObserve and metrics collection ports
|
||||
- fromEntities:
|
||||
- cluster
|
||||
toPorts:
|
||||
- ports:
|
||||
- port: "5080"
|
||||
protocol: "TCP" # OpenObserve
|
||||
- port: "10254"
|
||||
protocol: "TCP" # NGINX Ingress metrics
|
||||
|
||||
egress:
|
||||
# Allow all cluster communication (pods, services, nodes)
|
||||
- toEntities:
|
||||
- cluster
|
||||
- remote-node
|
||||
- host
|
||||
|
||||
# Allow etcd communication to other control plane nodes
|
||||
# Required for etcd cluster formation and peer communication
|
||||
- toCIDR:
|
||||
- 10.132.0.0/24 # VLAN subnet (all control plane nodes)
|
||||
- <VIP_IP>/32 # VIP
|
||||
- toEntities:
|
||||
- remote-node # Allow to other nodes
|
||||
toPorts:
|
||||
- ports:
|
||||
- port: "2379"
|
||||
protocol: "TCP" # etcd client API
|
||||
- port: "2380"
|
||||
protocol: "TCP" # etcd peer communication
|
||||
- port: "51871"
|
||||
protocol: "UDP" # Talos etcd peer discovery
|
||||
|
||||
|
||||
# Allow control plane to reach CloudNativePG health endpoints on all nodes
|
||||
- toEntities:
|
||||
- cluster
|
||||
- remote-node
|
||||
- host
|
||||
toPorts:
|
||||
- ports:
|
||||
- port: "8000"
|
||||
protocol: "TCP" # CloudNativePG health endpoint
|
||||
|
||||
# Allow control plane to reach PostgreSQL databases on worker nodes
|
||||
- toEntities:
|
||||
- cluster
|
||||
- remote-node
|
||||
toPorts:
|
||||
- ports:
|
||||
- port: "5432"
|
||||
protocol: "TCP" # PostgreSQL database
|
||||
- port: "9187"
|
||||
protocol: "TCP" # PostgreSQL metrics
|
||||
- port: "8000"
|
||||
protocol: "TCP" # CloudNativePG health endpoint (correct port)
|
||||
- port: "8080"
|
||||
protocol: "TCP" # Additional health/admin endpoints
|
||||
- port: "9443"
|
||||
protocol: "TCP" # CloudNativePG operator webhook server
|
||||
|
||||
# Allow DNS resolution
|
||||
- toEntities:
|
||||
- cluster
|
||||
- remote-node
|
||||
toPorts:
|
||||
- ports:
|
||||
- port: "53"
|
||||
protocol: "TCP"
|
||||
- port: "53"
|
||||
protocol: "UDP"
|
||||
|
||||
# Allow outbound internet access for backup operations, image pulls, etc.
|
||||
- toEntities:
|
||||
- world
|
||||
toPorts:
|
||||
- ports:
|
||||
- port: "443"
|
||||
protocol: "TCP" # HTTPS
|
||||
- port: "80"
|
||||
protocol: "TCP" # HTTP
|
||||
- port: "53"
|
||||
protocol: "UDP" # DNS
|
||||
- port: "123"
|
||||
protocol: "UDP" # NTP time synchronization
|
||||
@@ -0,0 +1,199 @@
|
||||
# policies/host-fw-worker-nodes.yaml
|
||||
apiVersion: "cilium.io/v2"
|
||||
kind: CiliumClusterwideNetworkPolicy
|
||||
metadata:
|
||||
name: "host-fw-worker-nodes"
|
||||
spec:
|
||||
description: "Worker node firewall rules - more permissive for database workloads"
|
||||
nodeSelector:
|
||||
matchExpressions:
|
||||
- key: node-role.kubernetes.io/control-plane
|
||||
operator: DoesNotExist
|
||||
ingress:
|
||||
# Allow all cluster communication for database operations
|
||||
- fromEntities:
|
||||
- cluster
|
||||
- remote-node
|
||||
- host
|
||||
|
||||
# Allow PostgreSQL and Redis connections from anywhere in cluster
|
||||
- fromEntities:
|
||||
- cluster
|
||||
toPorts:
|
||||
- ports:
|
||||
- port: "5432"
|
||||
protocol: "TCP" # PostgreSQL
|
||||
- port: "6379"
|
||||
protocol: "TCP" # Redis
|
||||
|
||||
# Allow health check and monitoring ports
|
||||
- fromEntities:
|
||||
- cluster
|
||||
toPorts:
|
||||
- ports:
|
||||
- port: "8000"
|
||||
protocol: "TCP" # CloudNativePG health endpoint
|
||||
- port: "8080"
|
||||
protocol: "TCP"
|
||||
- port: "9187"
|
||||
protocol: "TCP" # PostgreSQL metrics
|
||||
- port: "9443"
|
||||
protocol: "TCP" # CloudNativePG operator webhook server
|
||||
- port: "10250"
|
||||
protocol: "TCP" # kubelet
|
||||
|
||||
# Allow kubelet access from VLAN for cluster operations
|
||||
- fromCIDR:
|
||||
- 10.132.0.0/24 # VLAN subnet
|
||||
toPorts:
|
||||
- ports:
|
||||
- port: "10250"
|
||||
protocol: "TCP" # kubelet API
|
||||
|
||||
# HTTP and HTTPS access - allow from cluster and Tailscale network
|
||||
# Tailscale network needed for Tailscale operator proxy pods (e.g., Kibana via MagicDNS)
|
||||
- fromEntities:
|
||||
- cluster
|
||||
- fromCIDR:
|
||||
- 100.64.0.0/10 # Tailscale CGNAT range - allow Tailscale services
|
||||
toPorts:
|
||||
- ports:
|
||||
- port: "80"
|
||||
protocol: "TCP"
|
||||
- port: "443"
|
||||
protocol: "TCP"
|
||||
|
||||
# Allow access to Talos API from Tailscale network, VLAN, and external IPs
|
||||
# Restricted access (not world) for security - authentication still required
|
||||
- fromCIDR:
|
||||
- 100.64.0.0/10 # Tailscale CGNAT range
|
||||
- 10.132.0.0/24 # VLAN subnet for node bootstrapping
|
||||
- <NODE_1_EXTERNAL_IP>/32 # n1 external IP
|
||||
- <NODE_2_EXTERNAL_IP>/32 # n2 external IP
|
||||
- <NODE_3_EXTERNAL_IP>/32 # n3 external IP
|
||||
- fromEntities:
|
||||
- cluster # Allow cluster-internal access
|
||||
toPorts:
|
||||
- ports:
|
||||
- port: "50000"
|
||||
protocol: "TCP"
|
||||
- port: "50001"
|
||||
protocol: "TCP"
|
||||
|
||||
# Allow ICMP Ping
|
||||
- icmps:
|
||||
- fields:
|
||||
- type: 8
|
||||
family: IPv4
|
||||
- type: 128
|
||||
family: IPv6
|
||||
|
||||
# Allow cilium tunnel/health checks
|
||||
- fromEntities:
|
||||
- remote-node
|
||||
toPorts:
|
||||
- ports:
|
||||
- port: "8472"
|
||||
protocol: "UDP"
|
||||
- port: "4240"
|
||||
protocol: "TCP"
|
||||
|
||||
# Allow hubble communication
|
||||
- fromEndpoints:
|
||||
- matchLabels:
|
||||
k8s-app: hubble-relay
|
||||
toPorts:
|
||||
- ports:
|
||||
- port: "4244"
|
||||
protocol: "TCP"
|
||||
|
||||
# NGINX Ingress Controller metrics port
|
||||
- fromEntities:
|
||||
- cluster
|
||||
toPorts:
|
||||
- ports:
|
||||
- port: "10254"
|
||||
protocol: "TCP" # NGINX Ingress metrics
|
||||
|
||||
# OpenObserve metrics ingestion port
|
||||
- fromEntities:
|
||||
- cluster
|
||||
toPorts:
|
||||
- ports:
|
||||
- port: "5080"
|
||||
protocol: "TCP" # OpenObserve HTTP API
|
||||
|
||||
# Additional monitoring ports (removed unused Prometheus/Grafana ports)
|
||||
# Note: OpenObserve is used instead of Prometheus/Grafana stack
|
||||
|
||||
egress:
|
||||
# Allow all cluster communication (pods, services, nodes) - essential for CloudNativePG
|
||||
- toEntities:
|
||||
- cluster
|
||||
- remote-node
|
||||
- host
|
||||
|
||||
# Allow worker nodes to reach control plane services
|
||||
- toEntities:
|
||||
- cluster
|
||||
- remote-node
|
||||
toPorts:
|
||||
- ports:
|
||||
- port: "6443"
|
||||
protocol: "TCP" # Kubernetes API server
|
||||
- port: "8000"
|
||||
protocol: "TCP" # CloudNativePG health endpoints
|
||||
- port: "9443"
|
||||
protocol: "TCP" # CloudNativePG operator webhook
|
||||
- port: "5432"
|
||||
protocol: "TCP" # PostgreSQL replication
|
||||
- port: "9187"
|
||||
protocol: "TCP" # PostgreSQL metrics
|
||||
|
||||
# Allow access to control plane via VLAN for node bootstrapping
|
||||
# Explicit VIP access ensures new nodes can reach kubeapi without network changes
|
||||
- toCIDR:
|
||||
- 10.132.0.0/24 # VLAN subnet for cluster bootstrapping (includes VIP)
|
||||
- <VIP_IP>/32 # Explicit VIP for control plane kubeapi
|
||||
- <NODE_1_IP>/32 # n1 VLAN IP (fallback)
|
||||
toPorts:
|
||||
- ports:
|
||||
- port: "6443"
|
||||
protocol: "TCP" # Kubernetes API server
|
||||
- port: "50000"
|
||||
protocol: "TCP" # Talos API
|
||||
- port: "50001"
|
||||
protocol: "TCP" # Talos API trustd
|
||||
|
||||
# Allow DNS resolution
|
||||
- toEndpoints:
|
||||
- matchLabels:
|
||||
k8s-app: kube-dns
|
||||
toPorts:
|
||||
- ports:
|
||||
- port: "53"
|
||||
protocol: "UDP"
|
||||
- port: "53"
|
||||
protocol: "TCP"
|
||||
|
||||
# Allow worker nodes to reach external services (OpenObserve, monitoring)
|
||||
- toEntities:
|
||||
- cluster
|
||||
toPorts:
|
||||
- ports:
|
||||
- port: "5080"
|
||||
protocol: "TCP" # OpenObserve
|
||||
|
||||
# Allow outbound internet access for NTP, image pulls, etc.
|
||||
- toEntities:
|
||||
- world
|
||||
toPorts:
|
||||
- ports:
|
||||
- port: "443"
|
||||
protocol: "TCP" # HTTPS
|
||||
- port: "80"
|
||||
protocol: "TCP" # HTTP
|
||||
- port: "53"
|
||||
protocol: "UDP" # DNS
|
||||
- port: "123"
|
||||
protocol: "UDP" # NTP time synchronization
|
||||
@@ -0,0 +1,68 @@
|
||||
---
|
||||
# Fix for apiserver-kubelet-client RBAC permissions
|
||||
# Required when adding new control plane nodes to Talos clusters
|
||||
# This ensures the kubelet can access node/pods subresource for static pod management
|
||||
#
|
||||
# The system:kubelet-api-admin ClusterRole should already exist in Kubernetes,
|
||||
# but we ensure the ClusterRoleBinding exists and has the correct permissions.
|
||||
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: system:apiserver-kubelet-client
|
||||
annotations:
|
||||
description: "Grants apiserver-kubelet-client permission to access nodes and pods for kubelet operations"
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: system:kubelet-api-admin
|
||||
subjects:
|
||||
- apiGroup: rbac.authorization.k8s.io
|
||||
kind: User
|
||||
name: system:apiserver-kubelet-client
|
||||
---
|
||||
# Ensure the ClusterRole has nodes/pods subresource permission
|
||||
# This may need to be created if it doesn't exist or updated if missing nodes/pods
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: system:kubelet-api-admin
|
||||
labels:
|
||||
kubernetes.io/bootstrapping: rbac-defaults
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- nodes
|
||||
- nodes/proxy
|
||||
- nodes/stats
|
||||
- nodes/log
|
||||
- nodes/spec
|
||||
- nodes/metrics
|
||||
- nodes/pods # CRITICAL: Required for kubelet to get pod status on nodes
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- create
|
||||
- patch
|
||||
- update
|
||||
- delete
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- pods
|
||||
- pods/status
|
||||
- pods/log
|
||||
- pods/exec
|
||||
- pods/portforward
|
||||
- pods/proxy
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- create
|
||||
- patch
|
||||
- update
|
||||
- delete
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
|
||||
resources:
|
||||
- host-fw-control-plane.yaml
|
||||
- host-fw-worker-nodes.yaml
|
||||
- harbor-registry-firewall.yaml
|
||||
Reference in New Issue
Block a user