Murat ÖZDEMİR 2198f932cd Implement: Gitea Actions runner, automated DB stack, and Turkish localization
*   Introduces an Ansible role for installing and registering `act_runner` for Gitea Actions.
*   Automates PostgreSQL and MongoDB deployment on Docker Swarm in the test environment, leveraging Docker named volumes for data persistence.
*   Translates core documentation, including `README.md` and `setup/04-test-db-docker-kurulum.md`, to Turkish.
*   Adds comprehensive documentation for firewall architecture (`facts/firewall.md`) and Docker Swarm node recovery (`facts/swarm-node-recovery.md`).
*   Enhances security hardening by ensuring `fail2ban` is enabled and streamlining admin SSH key management via Ansible.
*   Updates Ansible vault structure to support new secret variables and adds `.vault_pass` to `.gitignore`.
2026-05-12 18:34:24 +03:00

132 lines
4.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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 |
| 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 |
| 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 |
| 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`) — test'ten farklı kurallar
| Port | Protokol | Kaynak | Açıklama |
|------|----------|--------|----------|
| 5432 | TCP | 10.20.20.0/24 | PostgreSQL replikasyon (DB subnet içi) |
| 27017 | TCP | 10.20.20.0/24 | MongoDB replica set internal |
| 2379 | TCP | 10.20.20.0/24 | etcd client |
| 2380 | TCP | 10.20.20.0/24 | etcd peer |
| 8008 | TCP | 10.20.20.0/24 | Patroni REST API |
---
## 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
```
### 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.