Фаервол VPS: адкрыйце толькі порт VPN і давядзіце гэта
Адзін порт павінен заставацца публічным, інакш ніводзін кліент не падключыцца. Адхіліце астатнія, трымайце перанакіраванне асобна ад уваходу і пакіньце шлях аднаўлення, які вы праверылі загадзя.
Фаервол, які прапускае толькі порт VPN, — гэта не адно правіла. Гэта тры асобныя рашэнні, якія проста датычаць аднаго нумара порта: ланцуг уваходу вырашае, што можа дайсці да лакальнага працэсу, ланцуг перанакіравання вырашае, што можа прайсці праз хост ад імя кліентаў тунеля, а табліца NAT перапісвае адрас крыніцы на выхадзе. Памыліцеся ў адным — і вынікам рэдка бывае чыстае адключэнне. Вы атрымаеце хост, які прымае кліентаў, але нічога не загружае, або хост, які выглядае закрытым, пакуль хтосьці не прачытае парадак ланцугоў.
Адзіны порт, які нельга зачыніць
Слухач VPN павінен прымаць злучэнні з адрасоў, якія вы не можаце прадказаць, таму ён публічная служба па вызначэнні. Гэта адзінае выключэнне, вакол якога пабудаваны дызайн: адзін порт UDP для OpenVPN, адзін порт UDP для WireGuard, адзін порт TCP для SSL VPN. Усё астатняе належыць за тунелем, а значыць, службы праграм павінны прывязвацца да адраса тунеля або да loopback, а не да ўсіх інтэрфейсаў.
Але прывязка — гэта не прымус. Працэс, прывязаны да 0.0.0.0, дасяжны толькі калі правіла гэта дазваляе, а прадвызначаная палітыка — гэта запасны варыянт для трафіку, які не супаў ні з адным правілам, а не правіла, што кіруе портам. Дазвол, пастаўлены вышэй за ваш забарон, застаецца дазволам, і перанос службы з публічнага адраса — незалежнае паляпшэнне, а не замена ланцуга.
Уваход, перанакіраванне і NAT адказваюць на розныя пытанні
Трафік уваходу прызначаны самому хосту, таму менавіта там жывуць слухач VPN і адміністрацыйны шлях. Трафік перанакіравання праходзіць праз хост, і кліентам тунеля патрэбна гэта плюс net.ipv4.ip_forward=1. Класічная напалову працоўная канфігурацыя дазваляе выходны паток і забываецца пра зваротны кірунак, таму кліент завяршае рукапацісканне, а затым нічога не загружаецца; правіла conntrack для ўсталяванага і звязанага трафіку закрывае гэты кірунак.
NAT — трэцяе пытанне. Без перапісвання postrouting перанакіраваныя пакеты сыходзяць з прыватнай крыніцай тунеля і скідваюцца вышэй па сетцы, бо ніводная сетка за межамі хоста не ведае, як маршрутызаваць пул назад. Прэфікс крыніцы ў гэтым правіле павінен адпавядаць пулу VPN, а не ўласнаму адрасу хоста, і тое ж самае тычыцца правіла перанакіравання, якое называе падсетку кліентаў.
IPv6 — гэта другая палітыка, а не думка ўслед. Хост з строгім ланцугом IPv4 і адкрытай палітыкай ip6tables нічога не закрыў; службы ўсё яшчэ дасяжныя праз іншае сямейства. Або люстэркуйце набор правіл праз ip6tables, або свядома адключыце IPv6 на публічным інтэрфейсе, і запішыце, які варыянт вы выбралі.
Базавая лінія, якую можна прачытаць за адзін праход
Пачніце з забароны, затым дадайце толькі тое, што патрэбна хосту. Спачатку loopback і адказы, затым адміністрацыйны шлях, затым слухач тунеля, затым палітыка перанакіравання для кліентаў:
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT
iptables -A INPUT -p udp --dport 1194 -m conntrack --ctstate NEW -j ACCEPT
sysctl -w net.ipv4.ip_forward=1
iptables -A FORWARD -i tun0 -o eth0 -s 10.8.0.0/24 -j ACCEPT
iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADEНазвы інтэрфейсаў, порт і пул — гэта запаўняльнікі; чытайце іх з сервера, а не капіруйце. Захаваць вынік так жа важна, як напісаць яго, бо набор правіл, які жыве толькі ў памяці, знікае пры наступнай перазагрузцы і ціха адкрывае хост зноў. Замацуйце яго механізмам дыстрыбутыва і трымайце копію па-за машынай на той дзень, калі машына не загрузіцца.
Закрыць апошні порт, не страціўшы хост
У дызайне ёсць падвох. Калі SSH існуе толькі праз тунель, збой службы VPN забірае SSH з сабой, і адзіным шляхам назад можа быць кансоль, якую вы ніколі не адкрывалі. Перш чым зачыніць апошні публічны порт, пераканайцеся, што гэтая кансоль існуе і што вы сапраўды можаце ёю карыстацца, або пакіньце адзін вузкі адміністрацыйны шлях, які не залежыць ад тунеля: SSH з фіксаванага адраса, толькі ключы, аўтэнтыфікацыя па паролі выключана.
Ужывайце змену з ужо ўсталяванай сесіі, а не праз злучэнне, якое вы збіраецеся фільтраваць. Заплануйце адкат, каб памылка скончылася, а не стала пастаяннай, напрыклад заданне systemd-run --on-active=10min, якое аднаўляе папярэдні набор правіл, і трымайце другую сесію SSH адкрытай, пакуль тэстуеце першую. Затым праверце, што заданне адкату сапраўды запускаецца, бо неправеранае аднаўленне — гэта тое ж самае, што яго адсутнасць.
Правярайце шлях, а не скрыпт
Чытайце загружаныя правілы, а не файл, які павінен быў іх загрузіць. З дазволенага знешняга хоста пераканайцеся, што адказваюць толькі патрэбныя парты; знутры тунеля пераканайцеся, што службы, якія вы хацелі апублікаваць, дасяжныя. Палітыка забароны па змаўчанні, якая блакуе і трафік тунеля, выглядае гэтак жа, як працоўнае закрыццё, пакуль хтосьці не паспрабуе ёю скарыстацца.
iptables -S
iptables -t nat -S
ss -lntup
ip -4 addr showЗапішыце дазволены порт, пул кліентаў, інтэрфейс тунеля, адміністрацыйную крыніцу і працэдуру кансолі побач з канфігурацыяй. Наступная змена пула або назвы інтэрфейса павінна быць узгоднена і ў фільтры, і ў правіле NAT, інакш хост вернецца ў напалову адкрыты стан, і ніхто гэтага не заўважыць.
Адна звычка каштоўнейшая за набор правіл: пасля кожнай змены давядзіце шлях перанакіравання запытам кліента, а шлях аднаўлення — другой сесіяй. Закрыццё, якім вы не карысталіся, — гэта гіпотэза.