Сетевая архитектура
Дата: 2026-01-23
1. Схема сети
┌─────────────────────────────────────────────────────────────────┐
│ INTERNET │
│ │
│ SIP Clients ◄───────────────────────────► Web Browsers │
│ (IP-phones) (Users) │
└───────────────────────────┬─────────────────────────────────────┘
│
┌─────────────────────────────────┼─────────────────────────────────┐
│ │ │
┌─────────▼─────────┐ ┌─────────▼─────────┐
│ lb-1 │ │ lb-2 │
│ 188.130.238.189 │ │ 92.47.181.152 │
│ (Primary LB) │ │ (Secondary LB) │
│ │ │ │
│ nginx + SIP NAT │ │ nginx + SIP NAT │
└─────────┬─────────┘ └─────────┬─────────┘
│ 10.10.19.10 │ 10.10.19.11
│ │
══════════════════════════════╪═════════════════════════════════╪══════════════════════════════════════
│ INTERNAL NETWORK: 10.10.19.0/24
══════════════════════════════╪═════════════════════════════════╪══════════════════════════════════════
│ │
┌────────────────────┴─────────────────────────────────┴────────────────────┐
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ web-1 │ │ web-2 │ │ voip-1 │ │ voip-2 │ │
│ │ 10.10.19.21 │ │ 10.10.19.22 │ │ 10.10.19.51 │ │ 10.10.19.52 │ │
│ │ Docker │ │ Docker │ │ Asterisk │ │ Asterisk │ │
│ │ :8000 API │ │ :8000 API │ │ :5060 SIP │ │ :5060 SIP │ │
│ │ :3000 Web │ │ :3000 Web │ │ :5038 AMI │ │ :5038 AMI │ │
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │
│ │ │ │ │ │
│ └────────┬───────┘ └────────┬───────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌─────────────────────────────┐ ┌─────────────────────────────┐ │
│ │ DATABASE │ │ CACHE │ │
│ │ ┌───────┐ ┌───────┐ │ │ ┌───────┐ │ │
│ │ │ db-1 │◄──►│ db-2 │ │ │ │redis-1│ │ │
│ │ │ .31 │ │ .32 │ │ │ │ .40 │ │ │
│ │ │Primary│ │Replica│ │ │ │Master │ │ │
│ │ │ :5432│ │ :5432 │ │ │ │ :6379 │ │ │
│ │ └───────┘ └───────┘ │ │ └───────┘ │ │
│ └─────────────────────────────┘ └─────────────────────────────┘ │
│ │
│ ┌─────────────────┐ │
│ │ mon-1 │ │
│ │ 10.10.19.60 │ │
│ │ Prometheus │◄──── node_exporter (все серверы)│
│ │ Grafana │ │
│ │ :9090 │ │
│ │ :3000 │ │
│ └─────────────────┘ │
│ │
└───────────────────────────────────────────────────────────────────────────┘
2. Подсети
| Сеть | CIDR | Назначение | Gateway |
|---|---|---|---|
| External (lb-1) | 188.130.238.0/24 | Публичный доступ | ISP |
| External (lb-2) | 92.47.181.0/27 | Публичный доступ (backup) | ISP |
| Internal | 10.10.19.0/24 | Внутренняя сеть серверов | 10.10.19.1 |
| Docker (web-1) | 172.17.0.0/16, 172.18.0.0/16 | Docker networks | — |
| Docker (web-2) | 172.17.0.0/16, 172.18.0.0/16 | Docker networks | — |
| Docker (mon-1) | 172.17.0.0/16, 172.18.0.0/16 | Docker networks | — |
3. IP адресация
3.1 Внешние IP
| Сервер | IP | Назначение |
|---|---|---|
| lb-1 | 188.130.238.189 | Primary public endpoint |
| lb-2 | 92.47.181.152 | Secondary public endpoint |
3.2 Внутренние IP
| Сервер | IP | Роль |
|---|---|---|
| lb-1 | 10.10.19.10 | Load Balancer Primary |
| lb-1 (VIP) | 10.10.19.100 | Virtual IP (для HA) |
| lb-2 | 10.10.19.11 | Load Balancer Secondary |
| web-1 | 10.10.19.21 | Application Server 1 |
| web-2 | 10.10.19.22 | Application Server 2 |
| db-1 | 10.10.19.31 | PostgreSQL Primary |
| db-2 | 10.10.19.32 | PostgreSQL Replica |
| redis-1 | 10.10.19.40 | Redis Master |
| voip-1 | 10.10.19.51 | Asterisk Primary |
| voip-2 | 10.10.19.52 | Asterisk Secondary |
| mon-1 | 10.10.19.60 | Monitoring |
4. Открытые порты по серверам
4.1 lb-1 / lb-2 (Load Balancers)
| Порт | Протокол | Сервис | Источник |
|---|---|---|---|
| 22 | TCP | SSH | Admin IPs |
| 80 | TCP | HTTP | Any (redirect) |
| 443 | TCP | HTTPS | Any |
| 5060 | UDP | SIP (NAT) | Any → voip-1 |
| 10000-20000 | UDP | RTP (NAT) | Any → voip-1 |
| 9100 | TCP | node_exporter | mon-1 |
4.2 web-1 / web-2 (Application Servers)
| Порт | Протокол | Сервис | Источник |
|---|---|---|---|
| 22 | TCP | SSH | lb-1, Admin |
| 3000 | TCP | Frontend (nginx) | lb-1, lb-2 |
| 8000 | TCP | Backend API | lb-1, lb-2 |
| 26379 | TCP | Redis Sentinel | Internal |
| 9100 | TCP | node_exporter | mon-1 |
4.3 db-1 / db-2 (Database Servers)
| Порт | Протокол | Сервис | Источник |
|---|---|---|---|
| 22 | TCP | SSH | lb-1, Admin |
| 5432 | TCP | PostgreSQL | web-1, web-2, voip-1, voip-2 |
| 8008 | TCP | Patroni REST | Internal |
| 2379 | TCP | etcd client | db-1, db-2, mon-1 |
| 2380 | TCP | etcd peer | db-1, db-2, mon-1 |
| 9100 | TCP | node_exporter | mon-1 |
4.4 redis-1 (Redis)
| Порт | Протокол | Сервис | Источник |
|---|---|---|---|
| 22 | TCP | SSH | lb-1, Admin |
| 6379 | TCP | Redis | web-1, web-2 |
| 26379 | TCP | Sentinel | web-1, web-2 |
| 9100 | TCP | node_exporter | mon-1 |
4.5 voip-1 / voip-2 (Asterisk)
| Порт | Протокол | Сервис | Источник |
|---|---|---|---|
| 22 | TCP | SSH | lb-1, Admin |
| 5060 | UDP | SIP | lb-1, lb-2 (NAT) |
| 5038 | TCP | AMI | web-1, web-2 |
| 10000-20000 | UDP | RTP | lb-1, lb-2 (NAT) |
| 9100 | TCP | node_exporter | mon-1 |
4.6 mon-1 (Monitoring)
| Порт | Протокол | Сервис | Источник |
|---|---|---|---|
| 22 | TCP | SSH | lb-1, Admin |
| 3000 | TCP | Grafana | lb-1 (proxy) |
| 9090 | TCP | Prometheus | Internal |
| 2379 | TCP | etcd client | db-1, db-2 |
| 2380 | TCP | etcd peer | db-1, db-2 |
| 9100 | TCP | node_exporter | localhost |
5. Маршрутизация трафика
5.1 HTTP/HTTPS трафик
User Browser
│
▼
lb-1 (188.130.238.189:443) ─── или ─── lb-2 (92.47.181.152:443)
│ │
│ nginx reverse proxy │
│ least_conn balancing │
▼ ▼
┌─────────────────────────────────────────────────────────┐
│ Internal Network │
│ │
│ /api/* ──────► web-1:8000 or web-2:8000 (backend) │
│ /* ──────► web-1:3000 or web-2:3000 (frontend)│
│ │
└─────────────────────────────────────────────────────────┘
5.2 SIP/RTP трафик
SIP Phone (External)
│
│ UDP:5060 (SIP signaling)
│ UDP:10000-20000 (RTP media)
▼
lb-1 (188.130.238.189) ─── или ─── lb-2 (92.47.181.152)
│ │
│ iptables DNAT │
▼ ▼
voip-1 (10.10.19.51:5060)
│
│ Asterisk PJSIP
│
▼
Queue / Extension
5.3 Подключение к БД
web-1 / web-2 voip-1 / voip-2
│ │
│ PostgreSQL (psycopg2) │ ODBC Realtime
│ │
▼ ▼
db-1 (10.10.19.31:5432) ◄──────────────┘
│
│ Streaming Replication
▼
db-2 (10.10.19.32:5432)
6. Firewall правила (iptables)
6.1 SIP Geo-фильтрация (ipset)
Дата внедрения: 2026-01-31
На lb-1 и lb-2 настроена geo-фильтрация SIP-трафика: разрешены только казахстанские IP-адреса.
Компоненты:
- ipset kz-sip (hash:net) — 561 KZ-подсеть из country-ip-blocks
- Сохранение: /etc/ipset-kz-sip.save
- Автозагрузка: systemd unit ipset-restore.service (запускается до netfilter-persistent)
Обновление KZ-подсетей (при необходимости):
# На lb-1:
curl -sL 'https://raw.githubusercontent.com/herrbischoff/country-ip-blocks/master/ipv4/kz.cidr' | \
while read cidr; do sudo ipset add kz-sip "$cidr" -exist; done
sudo ipset save > /etc/ipset-kz-sip.save
# Скопировать на lb-2:
scp /etc/ipset-kz-sip.save sysadmin@10.10.19.11:/tmp/
ssh sysadmin@10.10.19.11 'sudo cp /tmp/ipset-kz-sip.save /etc/ && sudo ipset restore -f /etc/ipset-kz-sip.save'
6.2 lb-1 правила
# PREROUTING (DNAT) — без изменений
-A PREROUTING -i ens192 -p udp --dport 5060 -j DNAT --to-destination 10.10.19.51:5060
-A PREROUTING -i ens192 -p udp --dport 10000:20000 -j DNAT --to-destination 10.10.19.51
# FORWARD (policy DROP)
-A FORWARD -p udp -m set --match-set kz-sip src -d 10.10.19.51 --dport 5060 -j ACCEPT # SIP: только KZ
-A FORWARD -p udp -d 10.10.19.51 --dport 5060 -j DROP # SIP: блок не-KZ
-A FORWARD -p udp -d 10.10.19.51 --dport 10000:20000 -j ACCEPT # RTP
-A FORWARD -i ens224 -o ens192 -j ACCEPT # Internal → External
-A FORWARD -i ens192 -o ens224 -m state --state RELATED,ESTABLISHED -j ACCEPT # Established
# POSTROUTING (MASQUERADE)
-A POSTROUTING -s 10.10.19.0/24 -o ens192 -j MASQUERADE
6.3 lb-2 правила
# PREROUTING (DNAT)
-A PREROUTING -i ens224 -p udp --dport 5060 -j DNAT --to-destination 10.10.19.51:5060
-A PREROUTING -i ens224 -p udp --dport 10000:20000 -j DNAT --to-destination 10.10.19.51
# FORWARD (policy DROP)
-A FORWARD -p udp -m set --match-set kz-sip src -d 10.10.19.51 --dport 5060 -j ACCEPT # SIP: только KZ
-A FORWARD -p udp -d 10.10.19.51 --dport 5060 -j DROP # SIP: блок не-KZ
-A FORWARD -p udp -d 10.10.19.51 --dport 10000:20000 -j ACCEPT # RTP
6.4 Persistence
| Компонент | Файл | Сервис |
|---|---|---|
| iptables | /etc/iptables/rules.v4 |
netfilter-persistent |
| ipset | /etc/ipset-kz-sip.save |
ipset-restore.service |
Порядок загрузки при boot: ipset-restore → netfilter-persistent (зависимость через Before=).
7. Связи между серверами
7.1 Матрица связей
| От \ К | lb-1 | lb-2 | web-1 | web-2 | db-1 | db-2 | redis-1 | voip-1 | voip-2 | mon-1 |
|---|---|---|---|---|---|---|---|---|---|---|
| lb-1 | — | — | ✓ | ✓ | — | — | — | ✓ | — | ✓ |
| lb-2 | — | — | ✓ | ✓ | — | — | — | ✓ | — | — |
| web-1 | — | — | — | — | ✓ | — | ✓ | ✓ | — | — |
| web-2 | — | — | — | — | ✓ | — | ✓ | ✓ | — | — |
| db-1 | — | — | — | — | — | ✓ | — | — | — | ✓ |
| db-2 | — | — | — | — | ✓ | — | — | — | — | ✓ |
| redis-1 | — | — | — | — | — | — | — | — | — | — |
| voip-1 | — | — | — | — | ✓ | — | — | — | — | — |
| voip-2 | — | — | — | — | ✓ | — | — | — | — | — |
| mon-1 | — | — | — | — | ✓ | ✓ | — | — | — | — |
Легенда: - ✓ = активное соединение
7.2 Кластерные связи
etcd кластер: - db-1:2379 ↔ db-2:2379 ↔ mon-1:2379
PostgreSQL репликация: - db-1 (primary) → db-2 (replica)
Redis Sentinel: - redis-1:26379 ↔ web-1:26379 ↔ web-2:26379
8. DNS
Внешние записи
| Домен | Тип | Значение | Назначение |
|---|---|---|---|
| b2g.kz | A | 188.130.238.189 | Основной сайт |
| mon.b2g.kz | A | 188.130.238.189 | Мониторинг (Grafana) |
Внутренний DNS
Внутренний DNS не настроен. Используются IP адреса напрямую.
9. Безопасность
9.1 SIP-защита (внедрено 2026-01-31)
Уровень 1 — Geo-фильтрация (lb-1, lb-2):
- ipset kz-sip — 561 KZ-подсеть
- SIP (5060/UDP) разрешён только из Казахстана
- Все остальные SIP-пакеты DROP на уровне FORWARD
Уровень 2 — fail2ban (voip-1, voip-2):
- Jail: asterisk, фильтр: asterisk-security
- Лог: /var/log/asterisk/messages.log, backend: auto
- Параметры: maxretry=3, findtime=600 (10 мин), bantime=86400 (24 ч)
- Ban action: nftables (блокировка на INPUT voip-серверов)
- Конфиг: /etc/fail2ban/jail.d/asterisk.conf
Уровень 3 — PJSIP аутентификация (Asterisk):
- Все endpoint'ы требуют digest-auth (auth_type=userpass)
- Пароли: 20+ символов, случайная генерация
- Trunk M-Core: идентификация по IP (match=77.73.130.68)
Проверка статуса:
# fail2ban
ssh sysadmin@10.10.19.51 'sudo fail2ban-client status asterisk'
# ipset (с lb-1)
sudo ipset list kz-sip | head -8
# iptables счётчики (с lb-1)
sudo iptables -L FORWARD -n -v --line-numbers | head -5
9.2 Рекомендации по дальнейшему усилению
- SSH: Ограничить доступ только с lb-1 и admin IPs
- PostgreSQL: Разрешить только с web-1, web-2, voip-1, voip-2
- Redis: Включить аутентификацию (уже включена)
- Monitoring: Prometheus/Grafana только через lb-1 proxy
- SIP TLS: Добавить transport-tls в pjsip.conf (порт 5061)
- SBC: Рассмотреть Kamailio перед Asterisk для глубокой инспекции SIP
- Ротация логов: Настроить logrotate для
/var/log/asterisk/messages.log(сейчас 8.5 ГБ) - Cron обновления: Периодическое обновление KZ-подсетей в ipset
9.3 TLS/SSL
- b2g.kz: Let's Encrypt сертификат
- mon.b2g.kz: Let's Encrypt сертификат
- PostgreSQL: scram-sha-256 authentication
- Redis: AUTH required
- SIP: Без TLS (только UDP, планируется переход на TLS)