Виртуальные сети и NSG
Разбираемся, как выглядит ваш собственный кусочек сети внутри дата-центра Microsoft: VNet, подсети, NSG-файрвол и схема, в которой база данных недоступна из интернета в принципе.
Virtual Network (VNet) — изолированная виртуальная сеть внутри Azure, где вы сами выбираете диапазон IP-адресов, режете его на подсети и решаете, кто с кем имеет право разговаривать.
Зачем это на практике
Пока вы поднимаете одну виртуалку «посмотреть», сеть кажется формальностью: Azure сам создаст VNet, сам выдаст адрес, всё заработает. Проблемы начинаются на втором ресурсе. Появляется база данных — и вопрос «а кто может к ней подключиться?» перестаёт быть теоретическим. По умолчанию сервис с публичным IP виден всему интернету, а интернет очень любознателен: боты находят открытый порт PostgreSQL за считанные минуты и начинают перебирать пароли.
Правильный ответ почти всегда один и тот же: наружу торчит только то, что обязано торчать наружу. Веб-приложение слушает 443-й порт — да, он открыт. База данных, кэш Redis, внутренний API, очередь — всё это живёт в приватной подсети и доступно только соседям по VNet. Такую границу в Azure рисуют двумя инструментами: VNet с подсетями (кто где физически находится) и NSG (кому что разрешено).
VNet и подсети: разметка адресов
VNet создаётся в одном регионе и в одной подписке. Вы задаёте адресное пространство в нотации CIDR — например, 10.20.0.0/16, это 65 536 адресов из приватного диапазона RFC 1918. Дальше этот кусок режется на подсети: 10.20.1.0/24 для веба, 10.20.2.0/24 для базы и так далее.
az group create --name rg-shop --location westeurope
# VNet сразу с первой подсетью
az network vnet create \
--resource-group rg-shop \
--name vnet-shop \
--address-prefix 10.20.0.0/16 \
--subnet-name snet-web \
--subnet-prefix 10.20.1.0/24
# вторая подсеть — под базу
az network vnet subnet create \
--resource-group rg-shop \
--vnet-name vnet-shop \
--name snet-db \
--address-prefix 10.20.2.0/24
Здесь важна одна неочевидная деталь: Azure забирает себе 5 адресов в каждой подсети — первый (адрес сети), следующие три (шлюз и два внутренних DNS) и последний (broadcast). Поэтому в подсети /24 у вас не 256 полезных адресов, а 251. А модная попытка сэкономить и взять /29 (8 адресов) оставит вам целых три — это ловушка, в которую регулярно попадают на первом же масштабировании.
Второй момент: адресные пространства разных VNet не должны пересекаться, если вы когда-нибудь захотите их соединить (peering, VPN, подключение к офису). Поднять две сети 10.0.0.0/16 легко — а вот связать их потом уже нельзя, и переделка означает пересоздание ресурсов. Заведите себе привычку сразу разводить сети по разным диапазонам: 10.10.0.0/16 — dev, 10.20.0.0/16 — prod, и так далее.
Публичные и приватные IP
Приватный IP выдаётся из диапазона подсети, живёт вместе с сетевым интерфейсом и виден только внутри VNet (и связанных с ней сетей). Публичный IP — это отдельный ресурс Azure, за который вам выставляют счёт, даже если он ни к чему не привязан.
| Свойство | Приватный IP | Публичный IP |
| Откуда берётся | из CIDR подсети | отдельный ресурс Microsoft.Network/publicIPAddresses |
| Кто видит | ресурсы VNet и связанных сетей | весь интернет |
| Стоимость | бесплатно | порядка 3–4 $ в месяц за адрес Standard |
| Типичное применение | база, кэш, внутренний API | балансировщик, Application Gateway, публичный веб |
Про исходящий трафик тоже стоит знать заранее: первые 100 ГБ в месяц наружу бесплатны, дальше идёт оплата за гигабайт. А «неявный» выход в интернет без публичного IP Microsoft сворачивает — для новых развёртываний правильный путь наружу это NAT Gateway (порядка 33 $ в месяц плюс плата за обработанные данные). Учтите это в смете, а не постфактум.
NSG: файрвол на входе
Network Security Group (NSG) — набор правил «разрешить/запретить», который вешается на подсеть, на сетевой интерфейс (NIC) или сразу на оба. Каждое правило описывает: направление (входящее/исходящее), источник, назначение, порт, протокол, действие и приоритет — число от 100 до 4096.
Логика простая и жёсткая: правила проверяются по возрастанию приоритета, и первое совпавшее выигрывает. Дальше проверка не идёт. Если правило Deny с приоритетом 200 совпало — правило Allow с приоритетом 300 уже никого не спасёт.
az network nsg create --resource-group rg-shop --name nsg-web
# пускаем HTTPS из интернета
az network nsg rule create \
--resource-group rg-shop \
--nsg-name nsg-web \
--name allow-https \
--priority 100 \
--direction Inbound \
--access Allow \
--protocol Tcp \
--source-address-prefixes Internet \
--destination-port-ranges 443
# привязываем NSG к подсети
az network vnet subnet update \
--resource-group rg-shop \
--vnet-name vnet-shop \
--name snet-web \
--network-security-group nsg-web
Обратите внимание на --source-address-prefixes Internet. Это не литерал, а service tag — символическое имя для набора адресов, который поддерживает сам Microsoft. Кроме Internet есть VirtualNetwork, AzureLoadBalancer, Storage, Sql и десятки других. Использовать теги вместо захардкоженных диапазонов — почти всегда правильное решение: адреса Azure меняются, а тег остаётся.
В каждом NSG уже есть правила по умолчанию с приоритетами в районе 65000, их нельзя удалить, но можно перебить своими:
| Правило | Приоритет | Что делает |
| AllowVnetInBound | 65000 | разрешает весь трафик внутри VNet |
| AllowAzureLoadBalancerInBound | 65001 | пускает health-пробы балансировщика |
| DenyAllInBound | 65500 | запрещает всё остальное на вход |
| AllowInternetOutBound | 65001 | разрешает выход в интернет |
Вывод из таблицы важный: снаружи по умолчанию не пускают никого, а изнутри наружу — пускают всех. Первое хорошо, второе — повод задуматься, если вы работаете с чувствительными данными.
Схема «веб снаружи, база внутри»
Соберём каноническую двухслойную топологию, которую вы будете повторять от проекта к проекту.
| Подсеть | CIDR | Что живёт | Вход разрешён |
| snet-web | 10.20.1.0/24 | веб-серверы, балансировщик | 443 из Internet |
| snet-db | 10.20.2.0/24 | PostgreSQL, Redis | 5432 только из 10.20.1.0/24 |
az network nsg create --resource-group rg-shop --name nsg-db
# база принимает подключения ТОЛЬКО из подсети веба
az network nsg rule create \
--resource-group rg-shop \
--nsg-name nsg-db \
--name allow-pg-from-web \
--priority 100 \
--direction Inbound \
--access Allow \
--protocol Tcp \
--source-address-prefixes 10.20.1.0/24 \
--destination-port-ranges 5432
# явный запрет всего остального (страховка и документация замысла)
az network nsg rule create \
--resource-group rg-shop \
--nsg-name nsg-db \
--name deny-all-inbound \
--priority 4000 \
--direction Inbound \
--access Deny \
--protocol '*' \
--source-address-prefixes '*' \
--destination-port-ranges '*'
az network vnet subnet update --resource-group rg-shop --vnet-name vnet-shop --name snet-db --network-security-group nsg-db
У базы нет публичного IP вообще. Даже если завтра кто-то угадает пароль, ему просто некуда его вводить: до порта 5432 из интернета не доехать. Если база — не виртуалка, а управляемый сервис (Azure Database for PostgreSQL, Storage, Key Vault), тот же эффект даёт Private Endpoint: сервису выдаётся приватный адрес внутри вашей подсети, а публичный доступ выключается. Стоит это порядка 7–8 $ в месяц за эндпоинт плюс копейки за трафик — дёшево за то, чтобы убрать сервис из интернета.
А как же администратору попасть на машину без открытого SSH? Правильные варианты: Azure Bastion (доступ через браузер, без публичных IP на виртуалках) или Just-in-Time access из Microsoft Defender for Cloud, который открывает 22-й порт вашему IP на 3 часа и сам его закрывает.
Как это работает
NSG — это не отдельная железка и не виртуалка с iptables, за которую вы платите. Это правила, которые применяет SDN-стек на хосте-гипервизоре, прямо на пути пакета к вашей виртуальной сетевой карте. Поэтому сам NSG бесплатен и не создаёт узкого места: фильтрация распределена по всем хостам.
Три механизма, которые надо держать в голове:
- NSG stateful. Разрешили входящий 443 — ответный трафик уйдёт автоматически, обратное исходящее правило писать не нужно. Соединение отслеживается целиком.
- Двойная проверка. Для входящего трафика сначала применяется NSG подсети, потом NSG сетевой карты. Для исходящего — наоборот. Пакет должен пройти обе проверки. Классический «мистический» баг: правило есть, а трафик не идёт, потому что второй NSG о нём не знает.
- Внутри подсети тоже фильтруется. Частое заблуждение — что NSG подсети работает только «на границе». Нет: трафик между двумя виртуалками одной подсети тоже проходит через правила.
Когда картина не сходится, не гадайте — спросите Azure, какие правила реально действуют на интерфейс:
az network nic list-effective-nsg --resource-group rg-shop --name nic-web-1 -o table
Частые ошибки
- Открытый 22/3389 для
0.0.0.0/0. Самая массовая дыра в облаке. Боты находят порт за минуты. Используйте Bastion или JIT. - Путаница с приоритетами. Добавили Allow с приоритетом 300, а Deny с приоритетом 200 уже совпал раньше — правило не работает. Всегда смотрите на порядок чисел, а не на порядок в списке.
- Пересекающиеся адресные пространства. Два
10.0.0.0/16невозможно объединить peering'ом. Планируйте адресацию до того, как что-то создано. - Слишком узкие подсети. Помните про 5 служебных адресов;
/29оставит вам три штуки. - Деньги на забытых ресурсах. Публичный IP Standard тарифицируется, даже когда ни к чему не привязан. Azure Bastion в базовом SKU — это порядка 140 $ в месяц: включили «на посмотреть», забыли выключить, получили счёт. NAT Gateway и peering тоже платные, причём за peering платят обе стороны трафика.
- Ожидать от NSG защиты уровня приложения. NSG работает с IP и портами, он не видит SQL-инъекцию в теле запроса. Для этого нужен Application Gateway с WAF или Azure Firewall.
Итоги
- VNet — ваша приватная сеть в регионе; подсети режут её адресное пространство, Azure забирает 5 адресов из каждой.
- Публичный IP — отдельный платный ресурс; всё, что не обязано смотреть в интернет, живёт без него.
- NSG — stateful-файрвол на подсети и/или NIC; правила от 100 до 4096, первое совпавшее выигрывает, дефолт запрещает вход и разрешает выход.
- Рабочая схема: веб в публичной подсети с 443, база — в приватной, доступна только из подсети веба; для PaaS-сервисов — Private Endpoint.
- Сами VNet и NSG бесплатны; деньги едят публичные IP, Bastion, NAT Gateway и трафик peering.