# Firewall Mimarisi ## Genel Bakış Trafik filtreleme iki katmanda uygulanıyor. Bir paket sunucuya ulaşmadan önce Hetzner Cloud Firewall'dan geçmek zorunda; geçse bile sunucu içinde firewalld tarafından tekrar denetleniyor. ``` İnternet → Hetzner Cloud Firewall (Terraform) → firewalld (Ansible) → Uygulama ``` | Katman | Araç | Yönetim | Kapsam | |--------|------|---------|--------| | 1. Hetzner Cloud Firewall | Terraform | `terraform/hetzner/{test,prod}/firewall.tf` | Ağ seviyesi, sunucuya ulaşmadan drop | | 2. firewalld | Ansible | `ansible/roles/hardening/tasks/main.yml` | İşletim sistemi seviyesi, default zone: drop | Admin IP'leri her iki katmanda da aynı değişkenden besleniyor: - **Terraform:** `var.admin_allowed_cidrs` → `terraform.tfvars` - **Ansible:** `admin_allowed_cidrs` → `group_vars/all/vars.yml` Mevcut admin CIDR'ları: `78.187.87.109/32`, `95.70.151.248/32` --- ## Katman 1 — Hetzner Cloud Firewall (Terraform) Her ortam için iki ayrı firewall tanımı var: `app` ve `db` node'larına uygulanıyor. ### Test Ortamı Subnet'ler: app `10.10.10.0/24`, db `10.10.20.0/24` #### App Firewall (`iklim-test-firewall-app`) | Port | Protokol | Kaynak | Açıklama | |------|----------|--------|----------| | 22 | TCP | admin CIDRs | SSH | | 80 | TCP | 0.0.0.0/0, ::/0 | HTTP public | | 443 | TCP | 0.0.0.0/0, ::/0 | HTTPS public | | 51820 | UDP | 0.0.0.0/0, ::/0 | WireGuard VPN (DB node management) | | 2377 | TCP | 10.10.10.0/24, 10.10.20.0/24 | Docker Swarm control plane | | 7946 | TCP/UDP | 10.10.10.0/24, 10.10.20.0/24 | Docker Swarm node discovery | | 4789 | UDP | 10.10.10.0/24, 10.10.20.0/24 | Docker Swarm VXLAN overlay | | 8200 | TCP | 10.10.10.0/24 | Vault API (Host port kapalı, sadece private/overlay) | | 6379 | TCP | 10.10.10.0/24 | Redis | | 5672 | TCP | 10.10.10.0/24 | RabbitMQ AMQP | | 61613 | TCP | 10.10.10.0/24 | RabbitMQ STOMP | | 15674 | TCP | 10.10.10.0/24 | RabbitMQ Web STOMP | | 15672 | TCP | 10.10.10.0/24 | RabbitMQ Management (SWAG üzerinden 443) | | 9000 | TCP | 10.10.10.0/24 | APISIX Dashboard (SWAG üzerinden 443, IP kısıtlı) | | 9180 | TCP | 10.10.10.0/24 | APISIX Admin API (sadece Docker overlay) | | 9090 | TCP | 10.10.10.0/24 | Prometheus (SWAG üzerinden 443) | | 3000 | TCP | 10.10.10.0/24 | Grafana (SWAG üzerinden 443, IP kısıtlı) | #### DB Firewall (`iklim-test-firewall-db`) | Port | Protokol | Kaynak | Açıklama | |------|----------|--------|----------| | 22 | TCP | admin CIDRs | SSH | | 51820 | UDP | 0.0.0.0/0, ::/0 | WireGuard VPN | | 5432 | TCP | 10.10.10.0/24 | PostgreSQL (app'ten) | | 27017 | TCP | 10.10.10.0/24 | MongoDB (app'ten) | | 2377 | TCP | 10.10.10.0/24 | Docker Swarm control plane | | 7946 | TCP/UDP | 10.10.10.0/24 | Docker Swarm node discovery | | 4789 | UDP | 10.10.10.0/24 | Docker Swarm VXLAN overlay | ### Prod Ortamı Subnet'ler: app `10.20.10.0/24`, db `10.20.20.0/24` App firewall test ile aynı kurallara sahip (kaynak IP'ler prod subnet'leri). #### DB Firewall (`iklim-prod-firewall-db`) | Port | Protokol | Kaynak | Açıklama | |------|----------|--------|----------| | 22 | TCP | admin CIDRs | SSH | | 51820 | UDP | 0.0.0.0/0, ::/0 | WireGuard VPN | | 2377 | TCP | 10.20.10.0/24 | Docker Swarm control plane (Manager IP'lerden) | | 7946 | TCP/UDP | 10.20.10.0/24, 10.20.20.0/24 | Docker Swarm node discovery | | 4789 | UDP | 10.20.10.0/24, 10.20.20.0/24 | Docker Swarm VXLAN overlay | | 5432 | TCP | 10.20.10.0/24, 10.20.20.0/24 | PostgreSQL (App erisimi + DB replikasyon) | | 27017 | TCP | 10.20.10.0/24, 10.20.20.0/24 | MongoDB (App erisimi + replica set internal) | | 2379 | TCP | 10.20.20.0/24 | etcd client (DB subnet içi) | | 2380 | TCP | 10.20.20.0/24 | etcd peer (DB subnet içi) | | 8008 | TCP | 10.20.20.0/24 | Patroni REST API (DB subnet içi) | > **Önemli:** Mikroservis ve altyapı servisleri (`docker-stack-infra.yml`) artık published port içermemektedir. SWAG dışındaki servislere erişim `iklimco-net` overlay üzerinden veya private IP (VPN) üzerinden sağlanır. --- ## Katman 2 — firewalld (Ansible) Tüm ortamlarda `hardening` role tarafından uygulanıyor. Default zone `drop` — listelenmeyen her trafik reddedilir. | Port | Protokol | Kaynak | Açıklama | |------|----------|--------|----------| | 22 | TCP | admin CIDRs | SSH (rich rule, zone: drop) | SSH rich rule örneği: ``` rule family="ipv4" source address="78.187.87.109/32" service name="ssh" accept ``` ### SSH Sertleştirme (sshd_config) | Parametre | Değer | Açıklama | |-----------|-------|----------| | PasswordAuthentication | no | Sadece key ile giriş | | PermitRootLogin | prohibit-password | Root key ile girebilir, şifre ile giremez | | PermitEmptyPasswords | no | Boş şifre yasak | | MaxAuthTries | 3 | 3 başarısız denemede bağlantı kesilir | > **Not:** `MaxAuthTries 3` ssh-agent'ta birden fazla key varken "Too many authentication failures" hatasına yol açar. `~/.ssh/config`'de `IdentitiesOnly yes` ile doğru key'i belirtmek gerekir. --- ## Kural Güncelleme Rehberi ### Admin IP değiştiğinde İki dosyayı güncelle: ``` terraform/hetzner/test/terraform.tfvars → admin_allowed_cidrs ansible/test/group_vars/all/vars.yml → admin_allowed_cidrs ``` Sonra uygula: ```bash # Terraform cd terraform/hetzner/test && terraform apply # Ansible cd ansible/test && ansible-playbook test-bootstrap.yml --tags hardening --vault-password-file=../.vault_pass ``` ### Yeni port açılacaksa Hetzner seviyesinde `firewall.tf`'e kural ekle, Terraform ile uygula. Sunucu içinde firewalld'da açmak gerekiyorsa hardening role'una da ekle.