Здається, усе зачинено. Ваш скан IPv4 чистий. У зміні вказано «файрвол увімкнено». А потім клієнт надсилає знімок екрана із запитом на вхід — через IPv6. Це не теоретична прогалина; це реальна, і вона проявиться саме тоді, коли найменше хочеться: під час аудитів, інцидентів або в недільне технічне вікно.
Ubuntu 24.04 полегшує опинитися напівзахищеним. Не тому, що щось зламалося, а тому, що значення за замовчуванням, шари інструментів і реалії хмари створюють ідеальну пастку «клянуся, ми це заблокували». Це практичний посібник, як закрити діру правильно — nftables, UFW, сервіси й мережевий край — щоб «двостеково» означало «захищено в обох стеках», а не «ой, ми лишили бокові двері відкритими».
Що насправді йде не так: шаблон «тіньового» відкриття IPv6
Режим відмови нудний і стабільний:
- Ви розгортаєте правила файрвола, які явно блокують вхідний трафік IPv4.
- На хості є глобальна маршрутизована IPv6‑адреса (або /64 на інтерфейсі).
- Ваші інструменти файрвола або не застосовуються до IPv6, застосовуються інакше, або їх обходить інший рівень.
- Сервіс прив’язаний до
::(усі IPv6‑інтерфейси), що часто також означає прийняття IPv4 через v6‑mapped поведінку залежно від налаштувань. - Ви тестуєте лише з IPv4‑точки зору й оголошуєте перемогу.
Ubuntu 24.04 — це «сучасний Linux». Це добре. Але це також означає, що netfilter орієнтований на nftables, UFW — суміжний шар, iptables може працювати як nft‑підкапотний інтерфейс, а метадані хмари й автоконфігурація можуть додавати адреси, яких ви не очікували. Якщо ви думаєте лише «iptables rules = firewall», ви вже запізнилися.
Короткий жарт для розвантаження: Файрвол, що блокує IPv4, але не IPv6 — як зачиняти вхідні двері й лишати гараж відкритим — тільки в гаражі ще й неоновий напис «new protocol, who dis».
Також: «відключити IPv6» — не стратегія. Це крайній тимчасовий захід, який ламає реальні речі (дзеркала пакетів, сучасні CDN, деякі корпоративні мережі) і часто повертається пізніше з ще дивнішими помилками. Вам потрібна політика: за замовчуванням заборонити вхідні з’єднання в обох стеках, явно дозволяти потрібне, перевіряти з обох стеків і примусово виконувати на більше ніж одному рівні.
Цікаві факти та контекст (бо історія повторюється)
- IPv6 стандартизований із кінця 1990‑х. Протокол не новий; оперативні звички відстають.
- Ранні Linux‑файрволи були здебільшого орієнтовані на iptables. Багато команд виробили м’язову пам’ять навколо IPv4‑таблиць і ставилися до IPv6 як «пізніше».
- IPv6 усуває NAT як типовий костиль. З глобальним адресуванням «за NAT‑ом, отже в порядку» перестає працювати як аргумент.
- UFW історично опирався на iptables/ip6tables. У еру nftables перекладні шари можуть здивувати, якщо ви припускаєте «однакові правила, однакова поведінка».
- Деякі сканери й перевірки відповідності досі за замовчуванням використовують IPv4. Ви можете пройти звіт, будучи все ще повністю відкритими на IPv6.
- IPv6 neighbor discovery замінює ARP. Інший контроль‑плейн означає інші режими відмов, коли люди надто агресивно блокують «дивний ICMP».
- ICMPv6 не є опціональним. Блокуйте його бездумно — і ви зламаєте PMTUD і базову мережеву взаємодію малоприємними інтермітентними способами.
- Двостековість часто «увімкнена випадково». Образи хмари, оголошення маршрутизатора або DHCPv6 можуть надати глобальну адресу без відповідного тикету.
- «Слухати на ::» — поширений за замовчуванням варіант. Багато демонів прив’язуються до IPv6‑вілдкард і стають доступними по v6, навіть якщо ви тестували лише v4.
Правильна ментальна модель: пакети, гачки й хто вирішує «заборонити»
На Ubuntu 24.04 «файрвол» — не єдина річ. Це конвеєр:
- Мережевий край (security groups хмари, ACL роутера, корпоративний файрвол, слухачі балансувальника навантаження).
- Пакетний фільтр ядра хоста (ruleset nftables, потенційно керований UFW, firewalld або кастомною автоматизацією).
- Локальний дозвіл (сервіс, що слухає сокет, активація через systemd і ACL на рівні додатка).
nftables — це двигун. UFW — менеджер. Команди iptables можуть бути сумісним фронтендом, що пише правила в nft. Можна мати кілька менеджерів, і вони можуть наступати один одному на ноги. Якщо вам не пощастило, у вас є правила для IPv4, політика за замовчуванням для IPv6 пуста, і сервіс на ::. Ось і весь фільм.
Люди з надійності часто цитують фразу. Ось парафраз однієї з таких ідей, бо точна формулювання варіюється: парафразована ідея — «надія — не стратегія»
— часто приписується колам інженерного та операційного керівництва.
Перекладіть це на роботу з файрволом: не надійтеся, що «UFW увімкнено» означає «IPv6 заблоковано». Перевірте ruleset ядра і перевірте зовнішнім IPv6‑сканом.
Швидкий план діагностики
Якщо підозрюєте експозицію IPv6 на Ubuntu 24.04, робіть це в такому порядку. Він призначений знайти вузьке місце (або відсутній контроль) швидко, а не задовольнити цікавість.
1) Підтвердіть, що хост реально досяжний по IPv6
Перше питання: чи є у вас глобальна IPv6‑адреса? Якщо так — вважайте, що ви досяжні, поки не доведете інше. Якщо ні — ризик може бути нижчим, але не розслабляйтеся: інтерфейси та маршрути змінюються.
2) Визначте, що слухає на IPv6
Знайдіть сервіси, прив’язані до :: або конкретних v6‑адрес. Слухачі — це «чому». Правила файрвола — це «як».
3) Перегляньте реальний ruleset (nftables), а не лише стан інструменту
Статус UFW — підказка. Ruleset nftables — правда. Шукайте ланцюги ip6 і політики.
4) Перевірте примус виконання: лічильники, логування й реальна IPv6‑перевірка
Лічильники покажуть, чи збігаються правила. Проба з іншого хоста скаже, чи вірна ваша модель. «Локальний curl» — не тест безпеки.
5) Перевірте крайові контролі (cloud SG / router ACL)
Якщо край дозволяє IPv6 широко, хост‑файрвол — ваша остання лінія. Якщо край блокує, хост‑файрвол все одно потрібен (для латерального руху й помилково маршрутизованого трафіку), але ваша експозиція може бути обмежена.
Практичні завдання (команди, виводи, рішення)
Це не «запустіть їх заради забави». Кожне завдання має: команду, реалістичний фрагмент виводу, що це означає і яке рішення ви приймаєте. Виконуйте в терміналі. Зберігайте виводи в тікеті інциденту. Майбутнє ви подякує.
Завдання 1 — Перевірити, чи IPv6 увімкнено і які адреси є
cr0x@server:~$ ip -6 addr show
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 state UP qlen 1000
inet6 2001:db8:10:20::123/64 scope global dynamic
valid_lft 86390sec preferred_lft 14390sec
inet6 fe80::a00:27ff:fe4e:66a1/64 scope link
valid_lft forever preferred_lft forever
Що це означає: У вас є глобальна IPv6‑адреса (2001:db8:...). Цей хост потенційно досяжний з інтернету (залежно від маршрутизації та крайових правил).
Рішення: Ставтеся до експозиції IPv6 серйозно. Продовжуйте перевірки слухачів і файрвола.
Завдання 2 — Перевірити, чи IPv6 відключено через sysctl (не припускайтесь)
cr0x@server:~$ sysctl net.ipv6.conf.all.disable_ipv6 net.ipv6.conf.default.disable_ipv6
net.ipv6.conf.all.disable_ipv6 = 0
net.ipv6.conf.default.disable_ipv6 = 0
Що це означає: IPv6 увімкнено на рівні ядра.
Рішення: Тримайте IPv6 увімкненим; виправляйте файрвол і сервіси замість спроб «вимкнути інтернет».
Завдання 3 — Перелічити сокети, що слухають, включно з IPv6
cr0x@server:~$ ss -lntup
Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
tcp LISTEN 0 4096 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=1123,fd=3))
tcp LISTEN 0 4096 [::]:22 [::]:* users:(("sshd",pid=1123,fd=4))
tcp LISTEN 0 4096 [::]:8080 [::]:* users:(("java",pid=2210,fd=99))
Що це означає: SSH і Java‑сервіс слухають на IPv6‑вілдкард. Навіть якщо ваш IPv4‑файрвол жорсткий, IPv6 все ще може дістатися до цих портів.
Рішення: Потрібно або (a) заблокувати вхідні IPv6 для цих портів в nftables/UFW, або (б) прив’язати сервіси до конкретних інтерфейсів, або й те, й інше.
Завдання 4 — Перевірити налаштування IPv6 в UFW (саме тут люди обманюються)
cr0x@server:~$ sudo grep -n '^IPV6=' /etc/default/ufw
13:IPV6=no
Що це означає: UFW не керуватиме правилами IPv6. Ваш «UFW увімкнено» стосується тільки IPv4.
Рішення: Якщо використовуєте UFW — встановіть IPV6=yes і перезавантажте, потім перевірте nftables. Якщо не використовуєте UFW — упевніться, що nftables має явну ip6‑фільтрацію.
Завдання 5 — Подивитися статус UFW, але ставитись до нього як до індикатора
cr0x@server:~$ sudo ufw status verbose
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), disabled (routed)
New profiles: skip
To Action From
22/tcp ALLOW IN 10.0.0.0/8
Що це означає: UFW активний для того, що він керує. Зауважте, що тут нічого не каже про охоплення IPv6.
Рішення: Перевірте nftables для ip6. Якщо IPv6 у UFW відключено, цей вивід може небезпечно заспокоювати.
Завдання 6 — Переглянути реальний ruleset nftables
cr0x@server:~$ sudo nft list ruleset
table inet ufw {
chain input {
type filter hook input priority filter; policy drop;
ct state established,related accept
iif "lo" accept
ip protocol icmp accept
tcp dport 22 ip saddr 10.0.0.0/8 accept
counter packets 1840 bytes 220800 drop
}
}
Що це означає: Цей ruleset знаходиться в таблиці inet, що може співставляти й IPv4, і IPv6. Але зверніть увагу: тут приймається ip protocol icmp (IPv4 ICMP), і SSH дозволено лише з ip saddr (IPv4‑джерело). Тут немає явного дозволу ICMPv6 і немає явного дозволу SSH для IPv6. З політикою «drop» за замовчуванням IPv6 може бути заблокований — або ж оброблятися в іншому місці, якщо існують інші таблиці/ланцюги, яких ви не бачили у фрагменті.
Рішення: Підтвердіть, що є єдиний авторитетний input‑ланцюг, прикріплений для inet, і що він включає необхідні для IPv6 правила (neighbor discovery ICMPv6) та явні дозволи.
Завдання 7 — Підтвердити, які гачки існують (чи фільтруєте ви взагалі IPv6 input?)
cr0x@server:~$ sudo nft list chains
table inet ufw
chain input
chain forward
chain output
Що це означає: У вас є ланцюги, але все одно потрібно підтвердити, що вони дійсно прикріплені з type filter hook input для правильної родини.
Рішення: Якщо ви не бачите прикріпленого input‑ланцюга в таблиці inet або ip6, можна працювати «без IPv6‑файрвола», незважаючи на заяви інструменту.
Завдання 8 — Перевірити, чи neighbor discovery IPv6 не вбивають
cr0x@server:~$ ip -6 neigh show dev enp0s3
fe80::1 lladdr 52:54:00:12:34:56 router REACHABLE
Що це означає: Neighbor discovery працює, принаймні до маршрутизатора. Якщо ND зламається, ви можете одночасно мати «файрвол безпечний» і «мережа дивно нестабільна».
Рішення: Коли загострюєте IPv6‑правила, явно дозволяйте потрібні типи ICMPv6 (або дозволяйте ICMPv6 широко, якщо немає вагомих причин цього не робити).
Завдання 9 — Перевірити плутанину legacy iptables (nft backend vs legacy)
cr0x@server:~$ sudo update-alternatives --display iptables | sed -n '1,12p'
iptables - auto mode
link best version is /usr/sbin/iptables-nft
link currently points to /usr/sbin/iptables-nft
link iptables is /usr/sbin/iptables
Що це означає: Команди iptables використовують nft‑бекенд. Це нормально, але означає, що вивід «iptables-save» може не відповідати вашим старим playbook‑ам.
Рішення: Визначте єдиний підхід: керуйте правилами безпосередньо через nftables або одним інструментом (UFW) і припиніть змішувати iptables‑скрипти з nft‑правилами, якщо не любите налагоджувати о 2‑й ночі.
Завдання 10 — Переконатися, що немає другого менеджера файрвола (firewalld)
cr0x@server:~$ systemctl is-active firewalld; systemctl is-active ufw
inactive
active
Що це означає: Добре. Один менеджер активний.
Рішення: Якщо обидва активні — оберіть один. Вимкніть інший. Змішане володіння створює прогалини і «випадкову» втрату правил.
Завдання 11 — Визначити, чи systemd socket activation відкрив щось, що ви забули
cr0x@server:~$ systemctl list-sockets --all | sed -n '1,12p'
LISTEN UNIT ACTIVATES DESCRIPTION
[::]:22 ssh.socket ssh.service OpenSSH Server Socket
[::]:631 cups.socket cups.service CUPS Scheduler
Що це означає: systemd слухає IPv6‑адреси для сервісів. Навіть якщо ви «зупинили сервіс», сокет все ще може приймати з’єднання й запускати його.
Рішення: Вимкніть сокети, які не потрібні (systemctl disable --now cups.socket) і переконайтесь, що файрвол покриває порт.
Завдання 12 — Перевірити поведінку демона SSH щодо прив’язки
cr0x@server:~$ sudo sshd -T | egrep '^(addressfamily|listenaddress|port)'
addressfamily any
port 22
Що це означає: SSH слухає і на IPv4, і на IPv6 («any»), якщо не обмежено.
Рішення: Якщо плануєте SSH лише з мережі управління, забезпечте це в правилах файрвола для обох стеків і розгляньте прив’язку SSH до конкретного інтерфейсу/адреси.
Завдання 13 — Підтвердити вхідний шлях, пробуючи з іншої машини (IPv6)
cr0x@server:~$ nc -6vz 2001:db8:10:20::123 22
Connection to 2001:db8:10:20::123 22 port [tcp/ssh] succeeded!
Що це означає: Порт досяжний по IPv6. Це «реальна діра» відкритим текстом.
Рішення: Блокуйте його на краї й на хості, або обмежте до потрібних джерел, потім повторно перевіряйте, поки з неавторизованих джерел не перестане проходити.
Завдання 14 — Спостерігати лічильники nft під час тестування (доказ, яке правило спрацювало)
cr0x@server:~$ sudo nft -a list chain inet ufw input
table inet ufw {
chain input { # handle 3
type filter hook input priority filter; policy drop;
ct state established,related accept # handle 10
iif "lo" accept # handle 11
ip protocol icmp accept # handle 12
tcp dport 22 ip saddr 10.0.0.0/8 accept # handle 13
counter packets 1901 bytes 228120 drop # handle 14
}
}
Що це означає: Ви бачите, як лічильники змінюються, коли трафік потрапляє. Якщо ваш IPv6‑пробник проходить, але тут лічильники не змінюються, значить IPv6‑трафік не фільтрується цим ланцюгом. Це димний слід.
Рішення: Знайдіть ланцюг, який насправді прикріплений до IPv6‑input, або створіть правильний inet фільтр‑ланцюг, що охоплює обидва стеки.
UFW в Ubuntu 24.04: що насправді робить для IPv6
UFW популярний через читабельність. Це не те саме, що «повнота». Найбільша оперативна пастка — що підтримка IPv6 вмикається перемикачем у /etc/default/ufw. Якщо він вимкнений, ви можете мати чисту, застосовану політику IPv4 і недоторканий IPv6‑світ.
Правильне увімкнення IPv6 в UFW (якщо ви використовуєте UFW)
Відредагуйте /etc/default/ufw і встановіть IPV6=yes. Потім перезавантажте.
cr0x@server:~$ sudo sed -i 's/^IPV6=.*/IPV6=yes/' /etc/default/ufw
cr0x@server:~$ sudo ufw reload
Firewall reloaded
Що це означає: UFW тепер генеруватиме й застосовуватиме правила IPv6 також.
Рішення: Невідкладно перевірте за допомогою sudo nft list ruleset і зовнішньої IPv6‑проби. Не довіряйте лише повідомленню про перезавантаження.
Встановіть розумні значення за замовчуванням для двостеку
cr0x@server:~$ sudo ufw default deny incoming
Default incoming policy changed to 'deny'
(be sure to update your rules accordingly)
cr0x@server:~$ sudo ufw default allow outgoing
Default outgoing policy changed to 'allow'
(be sure to update your rules accordingly)
Що це означає: Ви забороняєте вхідні з’єднання за замовчуванням для обох стеків (після увімкнення IPv6) й дозволяєте вихідні. Це базова політика для серверів.
Рішення: Додайте явні дозволи для потрібних вхідних портів, обмежені за джерелом там, де можливо, як у IPv4, так і у IPv6 термінах.
Дозволити SSH із префіксу управління по IPv6 (приклад)
cr0x@server:~$ sudo ufw allow from 2001:db8:100::/56 to any port 22 proto tcp
Rule added
Rule added (v6)
Що це означає: Тепер у вас є v6‑специфічне правило дозволу поряд із v4‑правилами. Рядок «(v6)» — саме те, що потрібно бачити.
Рішення: Якщо не бачите «(v6)», ваш IPv6‑перемикач або синтаксис правила робить не те, що ви думаєте.
Дві поради, що збережуть вам час
- Не покладайтеся на «allow 22/tcp» без обмежень джерела для машин у відкритому інтернеті. На IPv6 простір адрес не зупиняє грубу силу. Атакувальникам байдуже, що сканування «складніше», коли вони вже мають вашу адресу з DNS чи логів.
- Не блокувати надмірно ICMPv6. Ви зламаєте IPv6 так, що це виглядатиме як випадкові втрати пакетів. Залишайте простим: дозволяйте необхідні ICMPv6 вхідні повідомлення, а потім звужуйте, якщо маєте докази та тести.
Перевірка реальності nftables: таблиці, ланцюги, пріоритети
Якщо хочете менше сюрпризів — керуйте nftables напряму й тримайте UFW осторонь — або віддайтеся UFW і перевіряйте згенеровані ним nft‑правила. Головне — не мати три системи «що допомагають». Саме так ви отримаєте сервер, що і відкритий, і час від часу ламаний.
Використовуйте таблицю inet для двостекового фільтру
Сімейство inet дозволяє одному ланцюгу співставляти й IPv4, й IPv6. Це зазвичай найпростіший спосіб уникнути «ми забули ip6». Мінімальний підхід:
- За замовчуванням drop на input
- Дозволяти established/related
- Дозволяти loopback
- Дозволяти ICMP + ICMPv6 (або принаймні потрібні типи ICMPv6)
- Дозволяти конкретні сервіси з конкретних джерел
Приклад: створити простий двостековий input‑ланцюг (ілюстративно — адаптуйте до вашого середовища, не копіюйте бездумно в прод):
cr0x@server:~$ sudo nft add table inet filter
cr0x@server:~$ sudo nft 'add chain inet filter input { type filter hook input priority 0; policy drop; }'
cr0x@server:~$ sudo nft add rule inet filter input ct state established,related accept
cr0x@server:~$ sudo nft add rule inet filter input iif "lo" accept
cr0x@server:~$ sudo nft add rule inet filter input ip protocol icmp accept
cr0x@server:~$ sudo nft add rule inet filter input ip6 nexthdr ipv6-icmp accept
cr0x@server:~$ sudo nft add rule inet filter input tcp dport 22 ip saddr 10.0.0.0/8 accept
cr0x@server:~$ sudo nft add rule inet filter input tcp dport 22 ip6 saddr 2001:db8:100::/56 accept
Що це означає: Один ланцюг покриває обидва стеки. Ви явно дозволяєте IPv4 ICMP і IPv6 ICMP, і скоповано SSH за джерелом для кожної родини.
Рішення: Вирішіть, чи керуєте правилами напряму через nft. Якщо так — вимкніть UFW, щоб уникнути дуелі ланцюгів, і збережіть правила через ваш CM‑підхід.
Збереження правил nftables: явно вказуйте власника
Системи Ubuntu різняться тим, як зберігається персистентність nftables у вашому середовищі. Ключ не в механізмі, а в тому, щоб механізм був єдиний та під аудиту. Якщо ви пишете правила інтерактивно і забуваєте їх зберегти, ви «виправите» проблему до наступного ребута — класичний паперовий щит.
Якщо використовуєте UFW: нехай UFW їх зберігає. Якщо використовуєте nftables напряму: зберігайте обраним методом і тестуйте на перезавантаження в рамках валідації змін.
Ще один короткий жарт і повертаємось до роботи: IPv6‑експозиція — це такий баг, що ховається настільки добре, що починає здаватися функцією — поки аудитор не знайде його і раптом це стане «legacy‑поведінкою».
Це не лише файрвол: сервіси, що слухають IPv6 за замовчуванням
Навіть за ідеального файрвола не дозволяйте сервісам слухати широко, якщо це не потрібно. Захист у глибину — це не слоган; це спосіб вижити при помилках конфігурації, майбутніх змінах і випадкових «тимчасових» правил, які забувають видалити.
Прив’язуйте до конкретних адрес, де це практично
Деякі сервіси можна налаштувати так, щоб вони прив’язувались лише до інтерфейсу управління або до localhost за зворотнім проксі. Приклади:
- Панелі адміністрування мають бути прив’язані до
127.0.0.1і::1, доступ через SSH‑тунель або VPN. - Внутрішні API мають слухати внутрішній VLAN‑інтерфейс, а не публічний інтерфейс.
- Усе «тимчасове» має за замовчуванням прив’язуватись до localhost.
Обережно з systemd sockets
systemd може тримати порти відкритими, навіть коли ви думаєте, що сервіс зупинений. Це не баг; це функція для on‑demand сервісів. Але це й підстава для промаху, якщо ви не перевіряєте сокети.
Якщо знайшли сокет, слухаючий на IPv6, якого не хочете — вимкніть його:
cr0x@server:~$ sudo systemctl disable --now cups.socket
Removed "/etc/systemd/system/sockets.target.wants/cups.socket".
Що це означає: Юніт сокета не буде слухати після цього і не стартуватиметься при завантаженні.
Рішення: Робіть це для будь‑якого небажаного socket‑activated слушача, а потім підтверджуйте через ss -lntup.
IPv6 і «localhost» — не те саме
Інженери іноді прив’язують додаток до «localhost» і думають, що він локальний. Але «localhost» може означати лише IPv4 (127.0.0.1), лише IPv6 (::1) або обидва залежно від конфігурації. Будьте явними у конфігураціях сервісів. Вкажіть обидві адреси, якщо маєте на увазі обидві. Тестуйте обидві.
Хмара та край: security groups, NACL, балансувальники та чому хост‑файрвол недостатній
У корпоративних системах найпоширеніша IPv6‑помилка — роздвоєна політика:
- Мережевий відділ ретельно блокує IPv4 security groups.
- IPv6 вмикають пізніше («потрібно для відповідності» / «модернізація» / «бо є чекбокс у провайдера»).
- Правила для IPv6 вхідних з’єднань лишаються дозволеними або за замовчуванням‑дозволити в місці, яке ніхто не перевіряє щодня.
- Хост‑файрвол вважають блокуючим, але UFW IPv6 вимкнено або nft‑правила не прикріплені.
Хост‑файрвол потрібен, але не достатній. Якщо можете блокувати вхідний IPv6 на краї — робіть це. Потім все одно запровадьте хост‑політику. Два рівні ловлять різні класи помилок:
- Крайові контролі захищають від прямого інтернет‑шуму і зменшують площу експозиції.
- Хост‑файрвол захищає від латерального руху, неправильно маршрутизованого трафіку, внутрішніх загроз і моментів, коли «хтось відкрив порт на інстансі».
Також пам’ятайте про балансувальники навантаження: у вас може бути IPv6‑слухач на LB, що форвардить на інстанси по IPv4. Або навпаки. Двостековість на краї не гарантує двостековості на хості. Саме на цій невідповідності спокійно живуть помилки моніторингу.
Три корпоративні міні‑історії з практики
1) Інцидент через неправильне припущення: «UFW увімкнено, отже ми в безпеці»
Середня компанія розгорнула Ubuntu 24.04 образи для внутрішніх інструментів. У них був акуратний скрипт затвердження: встановити UFW, встановити deny за замовчуванням для вхідних, дозволити SSH із корпоративних IPv4‑діапазонів, увімкнути логування. Воно пройшло їх стандартний «port scan», який, як і слід було очікувати, запускався з IPv4‑лише раннера всередині CI.
Через три місяці червона команда помітила кілька хостів з доступним SSH по IPv6. Першою реакцією команди була відмова, потім спантеличення, потім шквал скріншотів «UFW активний». Підказка була на видноті: IPV6=no у /etc/default/ufw. Це налаштування успадкували від старішої бази, коли у середовищі не було маршрутизації IPv6. Воно збереглось як скам’янілість.
Хости отримали глобальні IPv6‑адреси через зміну в мережі, яка не була представлена як «зміна експозиції». Router advertisements автоматично додали адреси. Ніхто не вважав це подією безпеки. Це неправильне припущення: «призначення адреси — мережеве питання». У двостеку це — подія політики.
Виправлення було не лише в перемиканні IPV6=yes. Потрібно було додати правильні дозволи ICMPv6, інакше з’єднання ламалися дивними способами. Також виявили деякі сервіси, що «тимчасово» були прив’язані до ::. Після примусової прив’язки сервісів і впровадження двостекових правил результати червоної команди стали нудними. Нудно — добре.
2) Оптимізація, що обернулась проти: «Drop all ICMP, щоб зменшити шум»
Інша організація керувала великовантажною API‑платформою і пишалася «мінімальною площею атаки». Інженер помітив багато ICMP в логах і вирішив, що це «непотрібно». Вони посилили правила, щоб скидати ICMP повністю, включно з ICMPv6, бо «у проді пінг не потрібен». Це було подано як оптимізація: менше пакетів, менше логів, менше відволікань.
За кілька днів платформа отримала інтермітентні таймаути. Не чистий outage — гірше. Деякі клієнти бачили провали великих запитів, інші — ні. Повторні спроби допомагали. Латентність виглядала нормально, поки раптом ні. На чергуванні почали збиратися забобони. Хтось звинувачував CDN. Хтось — TLS.
Справжня причина — зламане PMTUD по IPv6. ICMPv6 «Packet Too Big» повідомлення не повертались. З’єднання відкотились до фрагментації, що не відповідала очікуванням, й деякі шляхи чорніли пакети. Оптимізація обернулась на кошмар надійності і податкову плату за дебаг.
Вони виправили це, дозволивши необхідні ICMPv6 і налаштувавши логування так, щоб шум був контрольований. Урок закарбувався: ICMPv6 — це не «ping». Це мережеве сантехнічне забезпечення. Вимикати його через шум — як вирізати лампу олії, бо вона дратує.
3) Нудна, але правильна практика, що врятувала ситуацію: валідаційні ворота для двостеку
Компанія поруч із фінансовою сферою вже обпеклася на IPv6‑експозиції, тому інституціоналізувала практику, яку нікому не подобалось: кожен новий сервіс і кожен базовий образ мав проходити тести двостекової досяжності. Не «ми раз запустили nmap», а невеликий автоматизований набір: перевірити слухачі, перевірити прикріплення nft‑ланцюгів, пробити з IPv6‑раннера й запевнити, що «тільки ці порти досяжні».
Це було нудно. Інженери скаржились, що це уповільнює provisioning. Security тішилась. SRE терпіла. Винагорода прийшла тихо: під час міграції в хмару мережеві зміни додали IPv6 до сабнетів за замовчуванням. Багато команд навіть не помітили, бо нічого не ламалось. Але ворота в CI зафіксували проблему: збірки падали, бо тести IPv6 виявляли відкриті порти.
Замість інциденту проблему виявили в CI. Виправлення були невеликими і повторюваними: увімкнути UFW IPv6 (або поправити nftables inet правила), обмежити SSH за v6‑префіксом і відключити невикористовувані systemd сокети. Міграція пішла за планом. Ніхто не писав постмортем. Ось це ідеал.
Типові помилки: симптом → корінна причина → виправлення
1) «Скан IPv4 чистий, але аудитори кажуть, що порти відкриті»
Симптом: Зовнішній звіт показує SSH/HTTP досяжні; ваш внутрішній скан показує закрито.
Корінна причина: Аудитор сканував IPv6; ви перевіряли тільки IPv4.
Виправлення: Виконуйте двостекове сканування. Підтвердіть ip -6 addr, потім пробуйте nc -6vz або еквівалент із IPv6‑хоста. Увімкніть IPv6‑правила в UFW або nftables.
2) «UFW активний, але IPv6‑з’єднання все одно проходять»
Симптом: ufw status виглядає правильно; IPv6‑з’єднання все одно досягають сервісів.
Корінна причина: IPV6=no у /etc/default/ufw, або UFW‑правила не прикріплені в nftables для inet/ip6 шляхів.
Виправлення: Встановіть IPV6=yes, перезавантажте UFW, перевірте nft list ruleset і повторно протестуйте із зовнішнього IPv6‑джерела.
3) «IPv6 випадково вмирає після харднінгу»
Симптом: Деякі з’єднання зависають, великі передачі падають, дивні інтермітентні обриви.
Корінна причина: ICMPv6 заблоковано надто агресивно (PMTUD і neighbor discovery проблеми).
Виправлення: Дозвольте ICMPv6 (ip6 nexthdr ipv6-icmp accept) або принаймні потрібні типи. Тестуйте з реальними робочими навантаженнями, а не лише ping.
4) «Сервіс зупинено, але порт все ще відкритий»
Симптом: Ви зупиняєте демон; ss все ще показує прослуховування.
Корінна причина: systemd socket activation тримає порт відкритим через юніт .socket.
Виправлення: Вимкніть socket‑юніт (systemctl disable --now name.socket) і перевірте слухачі.
5) «Правила є, але IPv6‑трафік не потрапляє на лічильники»
Симптом: IPv6‑з’єднання проходять; очікувані лічильники ланцюга nft не зростають.
Корінна причина: Ваш ланцюг не прикріплений для input, або інша таблиця/ланцюг має пріоритет, або ви фільтруєте тільки ip‑сімейство.
Виправлення: Переконайтесь, що маєте inet або ip6 input‑ланцюг з гачком і правильним пріоритетом. Спроостіть володіння: один менеджер.
6) «Ми дозволили SSH з корпоративного IPv4, але IPv6 все одно дозволяє весь світ»
Симптом: SSH обмежений IPv4‑джерелами; IPv6 відкритий.
Корінна причина: Правило матчує лише ip saddr, а не ip6 saddr.
Виправлення: Додайте IPv6‑праваховорні правила (UFW allow from 2001:.../... або nft ip6 saddr).
7) «Ми відключили IPv6, але воно повертається / додатки ламаються»
Симптом: Хтось тумблює sysctl для відключення IPv6; пізніше воно знову з’являється або сервіси падають.
Корінна причина: Вимкнення IPv6 крихке в різних середовищах і може ламати залежності; або налаштування застосовано непослідовно по інтерфейсам.
Виправлення: Увімкніть IPv6 і впровадьте правильну політику файрвола й прив’язки. Якщо ви змушені відключати — робіть це послідовно й документуйте, а потім плануйте переробку.
Чеклісти / покроковий план
Покроково: закрийте реальну діру на одному Ubuntu 24.04 хості
- Знайдіть IPv6‑адреси та маршрути. Якщо є глобальна адреса — вважайте експозицію реальною і дійте.
- Перелічіть слухачів. Визначте, що прив’язане до
::і що не повинно. - Оберіть одного менеджера файрвола. UFW або nftables. Не обидва. Не «iptables‑скрипти плюс UFW».
- Забезпечте deny за замовчуванням для входу в обох стеках. В UFW встановіть
IPV6=yes. В nftables — використайтеinetinput‑ланцюг зpolicy drop. - Дозвольте необхідний ICMPv6. Зберігайте функціональність IPv6, закриваючи її одночасно.
- Додайте явні дозволи для потрібних сервісів. Віддавайте перевагу скопингу за джерелами: префікси управління для SSH, сабнети LB для портів додатків.
- Зменште кількість слушачів. Прив’язуйте внутрішні/адміністративні сервіси до localhost або внутрішніх інтерфейсів. Вимикайте невикористовувані systemd‑сокети.
- Перевірте зовні по IPv6. Якщо не можете тестувати зовні — ваша зміна неперевірена.
- Перевірте лічильники/логування. Підтвердіть, що правила справді застосовуються.
- Збережіть конфігурацію. Переконайтесь, що правила переживуть ребут і не дрейфлять через CM.
Чекліст для операцій: що додати в тікет (щоб аудити пройшли)
- Вивід
ip -6 addrіip -6 route(доказ адресації і дефолтного маршруту). - Вивід
ss -lntup(доказ можливих досяжностей). - Вивід
nft list ruleset(доказ реального виконання). - Статус UFW + перемикач IPv6 у
/etc/default/ufw(доказ області відповідальності менеджера). - Результати зовнішньої IPv6‑проби до/після (доказ закриття).
Питання й відповіді
1) Чому це виявилось саме в Ubuntu 24.04?
Ubuntu 24.04 твердо стоїть в епосі nftables, а двостекові мережі часто ввімкнені за замовчуванням у багатьох середовищах. «Підводний камінь» не унікальний для 24.04, але суміш шарів інструментів і сучасних налаштувань робить напівконфігурації більш ймовірними.
2) Якщо у сервера немає AAAA‑запису в DNS, чи я в безпеці від IPv6‑експозиції?
Ні. DNS — механізм виявлення, а не контроль доступу. IPv6‑адреси просочуються через логи, конфіги, сертифікати, телеметрію й інвентар хмари. Також внутрішньому атакувальникові DNS не потрібен.
3) Чи є «сканувати IPv6 важко» значущим захистом?
Не дуже. Атакувальникам не треба сканувати весь /64, якщо вони вже знають вашу адресу, а вони часто її знають. І багато сервісів мають передбачувані адреси в середовищах хмари.
4) Можна просто відключити IPv6, щоб це зникло?
Можна, але зазвичай це тимчасове патч‑рішення з побічними ефектами. Воно ламає деякі мережі, ускладнює налагодження й має тенденцію відкотитись пізніше. Правильне двостекове файрволювання — довготривале рішення.
5) Чи потрібні окремі правила для IPv4 і IPv6?
Потрібно охопити обидва стеки. З nftables таблиця inet дозволяє одному ланцюгу працювати для обох родин. В UFW потрібно увімкнути IPv6 і перевірити, що правила генеруються для v6.
6) Який ICMPv6 слід дозволити?
Як мінімум дозвольте ICMPv6 трафік, потрібний для neighbor discovery і PMTUD. Якщо немає часу вишукувати типи — дозволяйте ICMPv6 вхідний і потім звужуйте після реальних тестів і підстав.
7) Чому я бачу сервіси на [::]:port, коли конфігурацію робив лише для IPv4?
Багато демонів за замовчуванням прив’язуються до IPv6‑вілдкард, бо це покриває обидва стеки, або тому що дистрибутиви так налаштовані. Це нормально; просто означає, що треба забезпечити політику файрвола і для IPv6.
8) Як дізнатися, чи UFW справді застосовує IPv6?
Перевірте /etc/default/ufw на наявність IPV6=yes, потім інспектуйте nftables ruleset і тестуйте із зовнішнього IPv6‑хоста. Статус інструмента сам по собі не доказ.
9) Який найшвидший спосіб довести, що ми виправили проблему?
Ззовні, поза межами дозволених діапазонів, спробуйте підключитися по IPv6 до раніше відкритого порта (наприклад, nc -6vz). Він має бути недоступний. Потім підтвердіть, що лічильники nft показують дроп для цього трафіку.
10) Якщо в нас є cloud security groups, навіщо морочитися з хост‑файрволом?
Бо крайові політики змінюються, існує внутрішній трафік і трапляються неправильні маршрути. Хост‑файрвол захищає вас, коли периметр не ідеальний — а він ніколи не ідеальний.
Висновок: наступні кроки, які можна реально запланувати
Закрийте діру так, як закривають будь‑яку реальну операційну прогалину: доведіть її наявність, виправте в одному авторитетному місці, а потім додайте запобіжник, щоб вона не повернулася.
- Сьогодні: запустіть
ip -6 addr,ss -lntupіsudo nft list rulesetна одному репрезентативному хості. Якщо бачите глобальний IPv6 + відкриті слушачі + слабкі правила — проблема знайдена. - Цього тижня: оберіть модель володіння файрволом (UFW з увімкненим IPv6 або native nftables). Запровадьте deny за замовчуванням для входу в обох стеках. Дозвольте ICMPv6 правильно. Обмежте вхідні дозволи за джерелом.
- Цього місяця: додайте ворота валідації двостеку: зовнішня IPv6‑проба + інвентар слухачів + перевірка прикріплення nft‑ланцюгів. Зробіть це нудним. Зробіть автоматичним.
Двостековість уже не опціональна. Хороша новина: виправити це просто, коли перестати вдавати, що IPv6 — «пізніше».