CMMC Level 2 · NIST 800-171 · Homelab Portfolio

Homelab K8s Infrastructure

AWS us-west-2 ● Live RKE2 Kubernetes Rocky Linux 9.7 5 EC2 Nodes Phase 10 Complete
Account: 355564824199
Region: us-west-2
github.com/jslocomb/homelab-k8s
GovCloud Transferable (IL2/IL4)
EC2 Node Topology — AWS us-west-2
AWS VPC — 10.0.0.0/16 — us-west-2 Public Subnet · 10.0.1.0/24 Private Subnet · 10.0.2.0/24 BASTION bastion 10.0.1.x (public EIP) ● SSH gateway (:22) ● Jump host only ● SG: 22/tcp cidr-restricted ● No inbound beyond SSH ROCKY LINUX 9.7 t3.micro · 1 vCPU · 1GB IDENTITY ipa01 10.0.2.x ● FreeIPA 4.12.2 ● DNS (lab.internal) ● LDAP / LDAPS :636 ● Kerberos KDC :88 ● Internal CA / HBAC ● IPA Web UI :443 ● Splunk UF → k8s-w02 ● AIDE baseline (cron 02:00) t3.medium · 2 vCPU · 4GB · 50GB ROCKY LINUX 9.7 CONTROL PLANE k8s-cp01 10.0.2.x ● RKE2 Server ● kube-apiserver :6443 ● etcd :2379-2380 ● RKE2 supervisor :9345 ● kube-scheduler ● controller-manager ● CoreDNS :53 ● CIS Hardening Profile ● AIDE baseline (cron 02:00) ● Falco DaemonSet (eBPF) ● Splunk UF → k8s-w02 t3.medium · 2 vCPU · 4GB · 100GB ROCKY LINUX 9.7 WORKER 1 k8s-w01 10.0.2.x ● RKE2 Agent ● GitLab CE 18.10.1 (native) port :8929 (web) :2222 (SSH) ● AWX (K8s operator) ● NetBox v4.5.5 (Helm) ● kube-prom-stack (Grafana) ● Falco 0.43.0 DaemonSet ● AIDE baseline (cron 02:00) ● Splunk UF → k8s-w02 t3.large · 2 vCPU · 8GB · 100GB ROCKY LINUX 9.7 WORKER 2 — k8s-w02 ● RKE2 Agent ● Splunk Enterprise 10.2.1 (native) :8000 web · :8089 mgmt · :9997 fwd · :8088 HEC ● Receives UF from: bastion · ipa01 · k8s-cp01 · k8s-w01 · k8s-w02 (self) ● Indexes: os_logs · k8s_audit · secure · syslog · aide_alerts ● AIDE baseline (cron 02:00) · Falco DaemonSet t3.large · 2 vCPU · 8GB · 150GB (upsized from t3.medium — Splunk RAM requirement) ROCKY LINUX 9.7 SSH jump Private subnet internal network · RKE2 Canal CNI VXLAN :8472/udp · Pod CIDR 10.42.0.0/16 · Svc CIDR 10.43.0.0/16
Public Subnet (bastion)
Identity Layer (FreeIPA)
K8s Control Plane
K8s Worker Nodes
SIEM (Splunk Enterprise)
AWS Network Topology & Traffic Flows
INTERNET External / Admin workstation AWS SECURITY GROUPS SG-bastion · SG-ipa · SG-k8s SSH :22 (key-only, cidr-restricted) BASTION Public EIP · 10.0.1.x SSH jump host only SG: port 22 inbound only SSH ProxyJump FREEIPA ipa01 · 10.0.2.x DNS / LDAP / CA / HBAC zone: lab.internal NAT GATEWAY Public subnet → Internet Outbound only from private nodes pkg updates / GitHub mirror *.lab.internal DNS K8S INGRESS-NGINX RKE2 reuseport :443 / NodePort SNI routing · cert-manager (FreeIPA CA) SSH tunnel / kubectl proxy AWX K8s operator ns: awx GitLab CE native :8929 k8s-w01 host Grafana kube-prom :3000 ns: monitoring Splunk native :8000 k8s-w02 host NetBox Helm ns:netbox AWX dyn inventory Falco 0.43.0 DaemonSet legacy eBPF driver LDAPS :636 Pod Network: 10.42.0.0/16 (Canal/Flannel VXLAN :8472/udp) Service CIDR: 10.43.0.0/16 · CoreDNS: 10.43.0.10 · K8s API: cp01:6443 AWS Infrastructure: VPC 10.0.0.0/16 · Public Subnet 10.0.1.0/24 · Private Subnet 10.0.2.0/24 Security Groups: SG-bastion (22/tcp ext) · SG-private (all internal) · NAT Gateway (private→internet outbound) Splunk Universal Forwarder → k8s-w02:9997 Sources: audit.log · secure · syslog · messages · k8s-audit.log · aide-check output (all 5 nodes) RKE2 API :6443 · Supervisor :9345 · etcd :2379-2380 · kubelet :10250 · AWS SGs replace all firewall rules
AWS / SSH access paths
K8s ingress / service routing
LDAP auth (LDAPS :636)
Splunk UF telemetry
Kubernetes Cluster Architecture — RKE2
CONTROL PLANE — k8s-cp01 (t3.medium) kube-apiserver :6443 (TLS) etcd :2379-2380 kube-scheduler + controller-mgr CoreDNS 10.43.0.10 :53 Canal CNI :8472/udp VXLAN CIS Profile Audit → Splunk UF WORKER 1 · k8s-w01 (t3.large) ns: awx AWX Web operator 3.2.1 Helm AWX Task + EE runner PVC 20GB AWX PostgreSQL PVC 10GB · ClusterIP LDAP: FreeIPA · K8s RBAC host: gitlab CE (native) GitLab CE 18.10.1 :8929 web · :2222 SSH mirrored → github.com/jslocomb NetBox v4.5.5 Helm ns:netbox AWX dyn inventory src DAEMONSET PODS Falco 0.43.0 (legacy eBPF) · node-exporter :9100 · Splunk UF → w02:9997 kubelet :10250 · containerd runtime · AIDE cron 02:00 UTC WORKER 2 · k8s-w02 (t3.large) ns: monitoring Prometheus kube-prom PVC 30GB Grafana :3000 PVC 5GB Alertmanager kube-prom-stack · ClusterIP ServiceMonitor scrape all ns host: splunk (native) SPLUNK 10.2.1 :8000 Web · :8089 Mgmt :9997 UF recv · :8088 HEC idx: os_logs · k8s_audit idx: secure · syslog idx: aide_alerts · 90d ret. 5 UF sources all nodes DAEMONSET PODS Falco 0.43.0 (legacy eBPF) · node-exporter :9100 · Splunk UF (self) kubelet :10250 · containerd runtime · AIDE cron 02:00 UTC :9345 :9345 CLUSTER SERVICES: cert-manager (cert-manager ns) · ingress-nginx (ingress-nginx) · AWX operator (awx) · CoreDNS (kube-system) · Canal CNI (kube-system)
GitOps & Automation Data Flow
GITOPS PIPELINE — COMMIT TO EXECUTION ENGINEER ① commit git push GITLAB CE k8s-w01:8929 (native) ● Playbook / manifest repo ● MR review + CI validate ● Webhook → AWX trigger ● Mirror → github/jslocomb ② store + CI webhook AWX operator 3.2.1 · ns:awx ● SCM sync (GitLab CE) ● LDAP auth (FreeIPA) ● NetBox dyn inventory ● Job scheduling + creds ③ sync + run SSH ansible kubectl :6443 EC2 NODES Rocky Linux 9.7 (AWS) ipa01 · cp01 · w01 · w02 via bastion SSH ProxyJump K8S API k8s-cp01:6443 · Helm deploys kubectl apply manifests OBSERVABILITY PIPELINE — TELEMETRY COLLECTION ALL EC2 NODES auditd · syslog · K8s audit AIDE output · Falco events metrics :9100 (node-exporter) Splunk UF :9997 SPLUNK k8s-w02 native :8000 · :8088 HEC 5 indexes · 90d ret. /metrics :15s PROMETHEUS kube-prom-stack 30d retention · 30GB ServiceMonitors Falco runtime alerts FALCO 0.43.0 DaemonSet legacy eBPF driver syscall monitoring GRAFANA kube-prom-stack :3000 ● datasource: Prometheus ● LDAP auth: FreeIPA ● Alertmanager integration ALERTMANAGER kube-prom-stack route by ns / severity webhook → Splunk HEC FREEIPA Central LDAP / DNS / CA AWX · GitLab · Grafana NetBox · K8s RBAC Every execution logged in AWX · All config changes in GitLab · Full telemetry in Splunk / Prometheus · Runtime in Falco
Authentication & Identity Flow
FREEIPA ipa01 · 10.0.2.x (AWS private) LDAP :389/636 · Kerberos :88 DNS · Internal CA · HBAC dc=lab,dc=internal cn=users · cn=groups · FreeIPA 4.12.2 K8s RBAC integration (verified) AWX operator 3.2.1 · ns:awx bind: uid=awx-bind group: cn=awx-users admin: cn=awx-admins ✓ verified test login GITLAB CE k8s-w01:8929 (native) bind: uid=gitlab-bind group: cn=gitlab-users admin: cn=gitlab-admins attr: uid / mail / displayName GRAFANA kube-prom-stack :3000 bind: uid=grafana-bind Admin: cn=grafana-admins Viewer: all auth users ldap.toml mounted secret NETBOX ns:netbox (Helm) bind: uid=netbox-bind django-auth-ldap is_staff: cn=netbox-admins allowed_host: svc.cluster.local K8S RBAC FreeIPA LDAP integration Groups map → ClusterRoles cn=k8s-admins → cluster-admin OIDCConfig in kube-apiserver ✓ verified mapping SSH ACCESS Bastion → private nodes HBAC rules (FreeIPA) group: cn=infra-admins key-only auth (SSSD) SG-bastion :22 cidr-restricted LDAPS :636 LDAPS :636 LDAPS :636 LDAPS :636 LDAPS :636 Kerberos+HBAC All bind accounts are read-only service accounts · No shared passwords · Separate bind DN per application FreeIPA 4.12.2 · HBAC controls SSH access by group · K8s RBAC groups mapped from LDAP cn=
Service Map & Deployment Boundaries
Identity Layer — ipa01 (EC2 private)
FreeIPA 4.12.2ipa01.lab.internal
DNS (lab.internal zone):53
LDAP / LDAPS:389 / :636
Kerberos KDC:88
Internal CA / cert-manager:443
HBAC · sudo rules · OTPIPA UI
ns: awx — Automation
AWX Web (operator 3.2.1)ClusterIP
AWX Task RunnerClusterIP
AWX PostgreSQLPVC 10GB
GitLab CE 18.10.1 (native):8929 / :2222
GitLab Gitalyrepos on disk
Mirror → GitHubjslocomb/homelab-k8s
ns: monitoring — Observability
Prometheus (kube-prom-stack):9090
Grafana:3000
Alertmanager:9093
node-exporter DaemonSet:9100 all nodes
ServiceMonitor CRDsall ns
SIEM — k8s-w02 (native)
Splunk Enterprise 10.2.1:8000 web
Splunk HEC:8088 events
Splunk Mgmt API:8089
UF Receiver:9997 all nodes
idx: os_logs · k8s_audit90d ret.
idx: secure · aide_alerts90d ret.
ns: netbox — CMDB
NetBox v4.5.5Helm ns:netbox
NetBox PostgreSQLPVC 10GB
NetBox Rediscache layer
LDAP: django-auth-ldapFreeIPA
AWX dynamic inventory srccustom py script
Security — Runtime & Integrity
Falco 0.43.0 DaemonSetlegacy eBPF
AIDE baselinesall 5 nodes
AIDE cron check02:00 UTC daily
auditd → Splunk UFall nodes
K8s audit log → Splunk UFcp01
Cluster Infrastructure Services
ingress-nginxRKE2 reuseport :443
cert-managerFreeIPA CA issuer
CoreDNS10.43.0.10
Canal CNIVXLAN :8472/udp
AWS SGs replace firewallno MetalLB needed
IaC & GitOps
TerraformAWS VPC / EC2 / SGs
AnsibleOS hardening / config
HelmAWX · NetBox · kube-prom
GitHub mirrorjslocomb/homelab-k8s
GovCloud transferableIL2/IL4 compatible
Port Reference — AWS Security Group Rules
RKE2 / K8s Control Plane
6443TCPK8s API server (TLS)
9345TCPRKE2 supervisor API
2379TCPetcd client
2380TCPetcd peer
10250TCPkubelet API
8472UDPVXLAN (Canal/Flannel)
FreeIPA / Identity (ipa01)
53TCP/UDPDNS (lab.internal)
88TCP/UDPKerberos KDC
389TCPLDAP (StartTLS)
636TCPLDAPS (SSL)
443TCPIPA Web UI / CA
464TCP/UDPKerberos kpasswd
Native Services (non-K8s)
8929TCPGitLab CE web (k8s-w01)
2222TCPGitLab CE SSH (k8s-w01)
8000TCPSplunk web UI (k8s-w02)
8088TCPSplunk HEC ingest
8089TCPSplunk mgmt API
9997TCPSplunk UF receiver
Monitoring / Telemetry
9090TCPPrometheus
9093TCPAlertmanager
3000TCPGrafana (ClusterIP)
9100TCPnode-exporter /metrics
AWS Security Group Rules
22TCPSSH bastion → all (key-only)
ALLALLSG-private internal traffic
OUTBOUNDALLVia NAT Gateway (private)
443TCPIngress-nginx (K8s NodePort)
Security / Integrity
Falco: eBPF syscall (in-kernel)
AIDE: file integrity cron 02:00
auditd → Splunk UF :9997
K8s audit log → UF (cp01)