Короткий ответ
GeoIP — грубый рычаг: база стран ошибается, облака anycast, пользователи в роуминге. Если модель угроз «RDP/SSH с WAN не нужны никому» — закройте порт, не «весь Китай». Если публичный сайт для клиентов из многих стран — не drop стран на 443. Сузьте GeoIP до конкретной цели (например, admin VPN только из списка, или SMTP с репутацией), обновляйте базу с подписанного источника. Не flush filter, не отключайте nft «чтобы директор зашёл из отпуска».
WAN 203.0.113.10, клиенты LAN 10.0.10.0/24 GeoIP обычно не касается (исходящий NAT и так один белый).
Симптомы и как отличить
Пользователь VPN из командировки: handshake нет, в логе drop по address-list geo-xx. Сайт открывается из офиса, с LTE зарубежного оператора — нет. Обратное: вы «закрыли страны», а brute на 22 жив — GeoIP не покрыл ASN хостинга.
| Намерение | GeoIP уместен? | Лучше |
|---|---|---|
| Запрет 3389/22 с WAN | нет как основа | не публиковать |
| Сайт для РФ+клиенты EU | осторожно | WAF/rate, не drop EU |
| SMTP inbound | иногда | SPF/reputation, не только страна |
| Admin GUI | нет | только mgmt/VPN |
Возможные причины
- Скрипт выгрузки «block all except RU» на input WAN включая 443/VPN.
- Устаревшая база, IP уехал в другой CC.
- IPv6 не в list, IPv4 режется — хаос.
- List на 500k префиксов, RouterOS задыхается, ложные match из‑за ошибок импорта.
- GeoIP как замена any-any снятия.
- Пользователь на корпоративном VPN в облаке с зарубежным egress.
Диагностика
Воспроизведите с согласия пострадавшего: его публичный IP (то, что видит 203.0.113.10).
# на шлюзе: есть ли адрес в множестве
sudo nft list set inet filter geo_block | head/ip firewall address-list print where address=<публичный_IP_клиента>
/ip firewall filter print stats where src-address-list~"geo"Если IP в list и правило drop выше VPN accept — вот причина. Counters растут в момент подключения.
Проверьте порядок: Geo drop выше allow WG — типичный self-goal. См. shadowing.
Откуда list: cron wget без HTTPS/подписи? Риск отравленного list.
Не сканируйте иностранные сети «проверить, открыто ли у них».
Концепция pfBlockerNG-подобных пакетов: категория стран на WAN inbound. Смотрите hit на IP клиента. Не выдумывайте CLI.
Решение
Сценарий A. VPN/сайт сломаны командировкой
- Временный точечный accept 5-tuple (UDP VPN или 443) для IP клиента на 48 часов, выше geo-drop.
- Постоянно: geo-drop не должен стоять на портах публикации, которые по бизнесу глобальны.
- Перенесите geo на то, что всё равно закрыто: 22/8291/3389 с WAN (как второй слой после drop all unused).
RouterOS:
/ip firewall address-list add list=allow-travel address=<IP> timeout=2d comment="ticket-123"
/ip firewall filter add chain=input src-address-list=allow-travel protocol=udp dst-port=51820 action=accept place-before=0 comment="travel VPN"Не disable всего geo-list в панике без заявки.
Сценарий B. Модель угроз «админка не с мира»
Удалите geo с 443 сайта. Оставьте:
- порты админки закрыты всем WAN;
- geo как optional на остаточный шум, не как доступ.
Сценарий C. nftables множества
Не держите 300k элементов, если CPU шлюза мал. Сузьте до ASN/хостингов, с которых идёт brute (из ваших логов), или уберите geo, усилив brute-protection.
Обновление базы: HTTPS, проверка контрольной суммы по документации провайдера базы. Cron с логом.
Сценарий D. Исходящий GeoIP
Резать LAN→WAN по странам ломает CDN, обновления, SaaS. Обычно не нужно. Исключение: регуляторный запрет — allow-list dst, не «весь CC drop» без юридического владельца.
Сценарий E. Ложные облака
Azure/AWS регион «не та страна». Exception на prefix облака, которым вы пользуетесь, или отказ от geo на 443.
Откат: disable одного geo-правила (не всего firewall), backup list.
Куда GeoIP имеет право стоять, а куда нет
Разрешённая позиция: второй слой на портах, которые уже закрыты матрицей (22/8291/3389 с WAN) — чтобы уменьшить шум brute, не чтобы «открыть порт своей стране». Запрещённая: geo-drop выше allow WireGuard 51820 и выше 443 публичного сайта, если бизнес обслуживает командировки и иностранных клиентов.
Практический тест: возьмите публичный IP пострадавшего, address-list print where address=, handle правила drop, counter в момент handshake. Переставьте allow VPN выше geo или уберите порт VPN из match geo. Travel-exception с timeout=2d и номером тикета; без timeout список превратится в кладбище IP домашних провайдеров.
Обновление list — HTTPS и контрольная сумма по доке провайдера базы. Cron wget с http без проверки — риск отравленного drop вашего SaaS. CPU RouterOS: если list сотни тысяч и interrupt растёт, сузьте до ASN из ваших BRUTE логов, не «весь CC».
Как проверить, что проблема устранена
- Пострадавший подключается с того же IP (или нового, если LTE сменился — тогда VPN с allow timeout).
- Скан своего WAN: админ-порты по-прежнему не open.
- Counters geo-drop не режут UDP 51820 / tcp 443, если их убрали из match.
- CPU RouterOS не 100% на address-list.
- Документ: какие цепи/порты покрывает geo и почему.
Если не помогло
- DNS имени сайта режется другим слоем.
- IPsec NAT-T 4500 не в allow.
- Клиент на IPv6.
- Другой WAN/балансир без тех же правил.
- IPS параллельно — IPS.
Профилактика
- Политика: GeoIP не на пользовательский HTTPS без решения бизнеса.
- Timeout на travel-exception.
- Мониторинг ложных: тикеты «не заходит из страны».
- Обновление базы по расписанию + проверка подписи.
- Сначала закрыть порты, потом geo как приправа.
FAQ
Запретить весь мир кроме одной страны для VPN?
Работает, пока все админы в ней. Командировка, облачный провайдер, мобильный оператор с зарубежным NAT — сломается. MFA+закрытый WAN-admin надёжнее.
GeoIP вместо fail2ban?
Нет. Brute с «своей» страны пройдёт. Нужен rate/fail2ban.
Где брать списки?
Только контракт/документированный провайдер. Не «csv с github неизвестного пользователя».
RouterOS 7 встроенный GeoIP?
Базово — address-list, которые вы загружаете. Не выдумывайте меню, которого нет на вашей лицензии. Смотрите /ip firewall address-list.
Нужно ли логировать geo-drop?
Sample да, иначе не отличите от матричного drop. Limit обязателен.