VoIP працює чудово — поки ви не пропустите його через VPN‑тунель, не поділите лінію з хмарним бекапом і дозволите комусь запустити «швидкий» демонстраційний показ екрану. Тоді це перетворюється на радіоп’єсу: паузи, переривання один одного, роботизовані склади й страшне «можете повторити?» від фінансового директора.
Більшість команд трактує це як містичну проблему: «VPN додає оверхед». Це правда, але не допомагає. Справжні причини, як правило, вимірювані й виправні: невідповідні MTU, bufferbloat, погане чергування, неправильно помічені пакети та тунелі, які ховають трафік від пристрою, що міг би його пріоритизувати.
Ментальна модель: що тунель VPN робить із голосовим трафіком
VoIP дуже чутливий до варіативності. Не лише до затримки — а до змінної затримки. Люди значно краще сприймають стабільні 80 мс, ніж сплески 30–200 мс. VPN‑тунелі зазвичай збільшують варіативність з трьох нудних причин:
- Додаткові заголовки та криптографія: більше байтів на пакет, більше CPU на пакет і іноді інша поведінка NIC‑офлоаду.
- Сховані потоки: після шифрування проміжні пристрої не бачать «це RTP», якщо ви не помітите його до шифрування та не збережете мітки.
- Черговість переміщується: ви можете думати, що вузьке місце — ваш фаєрвол; фактично пакетам може бути гірше на CPE провайдера або в апстрім‑шейпері.
Голос (SIP‑сигналізація + RTP‑медіа) зазвичай використовує маленькі пакети з постійною частотою. Тунелі також подобаються стабільні потоки — доки канцелярська лінія не насититься. Коли відбувається насичення, великі потоки (хмарні диски, оновлення, бекапи) створюють черги. Ці черги вкидають джиттер у RTP. Тоді jitter‑буфер намагається впоратися, додає затримку, а коли не може — ви отримуєте обрізане аудіо.
Є суворий закон офісних мереж: ви не «лікуєте джиттер» всередині тунелю; ви запобігаєте чергам перед вузьким місцем і пріоритизуєте голос при вході в тунель. Це означає shaping на виході реальної обмеженої лінії та вибір дисципліни чергування, яка не карає малі потоки реального часу.
Одна суха операційна жартівлива ремарка, як обіцяно: VPN‑тунелі як парасолі — їх згадують лише коли вже йде дощ і вони промокли.
Що припускає ця стаття (і чого ні)
Припущення:
- У вас є офісний роутер/фаєрвол під вашим контролем (Linux, pfSense/OPNsense, вендорський фаєрвол або router‑on‑a‑stick VM).
- VoIP‑пристрої — це стаціонарні телефони, софтфони або хмарний PBX/SBC, і офіс тунелює трафік кудись (у DC, у хмару, у шлюз безпеки).
- Ви можете запускати захоплення пакетів і базові CLI‑інструменти.
Не‑цілі:
- Ми не пропонуємо «купіть нову WAN‑лінію» як первинне рішення, хоча іноді це правильна доросла відповідь.
- Ми не махаємо рукою «про QoS» без доведення, де саме вузьке місце.
Цікаві факти та контекст (бо історія повторюється у пакетах)
- VoIP через IP став популярним задовго до появи «хорошого інтернету». Ранні впровадження покладалися на jitter‑буфери, оскільки канали доступу були нестабільні й перевантажені.
- RTP навмисно простий: він припускає, що мережа іноді буде поганою, і кінцеві точки згладжують це буферизацією та приховуванням втрат.
- DiffServ (DSCP) походить з кінця 1990‑х як заміна старшого IP Precedence. Це досі основна мова QoS, хоча багато мереж її ігнорують.
- IPsec ESP створювався для конфіденційності, а не для трафік‑інженерії. Те, що тепер ми очікуємо збереження QoS‑міток — це оперативна адаптація, а не початкова ідея.
- Bufferbloat був названий у 2009 році, але така поведінка існувала стільки, скільки побутова техніка постачалась з глибокими незрівноваженими буферами.
- FQ‑CoDel і CAKE з’явилися через біль реального часу: геймери та голосові користувачі привели до практичних поліпшень управління чергами.
- SRTP шифрує медіа від кінця до кінця. Коли ви додаєте VPN зверху, це подвійне шифрування. Це може бути норм, якщо крайовий CPU не тане від навантаження.
- Проблеми з MTU загострилися з VPN на широкосмугових лініях через PPPoE, VLAN‑теги та зверху‑додатковий оверхед тунелів.
Як виглядає «якісний голос»: затримка, джиттер, втрата та MOS
Щоб виправити VoIP через VPN, вам потрібні цілі. Ось практичні орієнтири, які використовуються в продуктивних середовищах:
- Односпрямована затримка: < 150 мс загалом «добре». 150–250 мс — терпимо, але помітно. Понад 250 мс — люди починають говорити одночасно.
- Джиттер: тримайте < 20–30 мс для комфортного досвіду. Ви можете пережити більше, але jitter‑буфер додасть затримку.
- Втрати пакетів: тримайте < 1% для пристойного звуку. Багато кодеків можуть приховати трохи втрат; вони цього не люблять.
- Перестановка пакетів: невеликі обсяги допустимі. Деякі VPN/ WAN‑акселяційні методи можуть її збільшувати, а RTP не любить сюрпризів.
Jitter‑буфер — не лікування, а позика
Кінцеві точки компенсують джиттер буферизацією. Цей буфер збільшує затримку. Якщо ви «вирішуєте» джиттер шляхом збільшення розміру буфера, ви просто пересуваєте біль від роботизованого звуку до відстрочки розмови. Іноді це правильний компроміс — кол‑центри часто віддають перевагу трохи більшій затримці над рваністістю — але це не безкоштовно.
MOS теж не магія
MOS (Mean Opinion Score) — це модель. Вона корисна, коли лінії трендів очевидні і ви їй не брешете. Якщо можливо, вимірюйте джиттер/втрати безпосередньо; сприймайте MOS як проксі для задоволеності користувачів, а не як фізичний двигун.
Один надійний оперативний вислів (парафраз), бо в операціях є пророки: Ідея, яка приписується Werner Vogels: усе ламатиметься постійно — проектуйте й експлуатуйте так, ніби відмови нормальні.
Швидка діагностика: перший/другий/третій
Перший: доведіть, де вузьке місце
Перш ніж крутити QoS‑ручки, з’ясуйте, що саме насичується:
- Перевірте завантаження і помилки каналу на реальному egress WAN (пристрій, який штовхає пакети до ISP). Якщо ви шейпите на внутрішньому інтерфейсі, ви, ймовірно, шейпите не там.
- Перевірте bufferbloat: затримка під навантаженням — це правда. Якщо пінг під час аплоаду стрибає у 10 разів, ви знайшли свою фабрику джиттера.
- Перевірте CPU на VPN‑кінці: шифрування пакетів часто обмежене одним ядром. Тунель може бути «готовий», поки коробка тихо плавиться.
Другий: перевірте MTU та фрагментацію end‑to‑end
Якщо є фрагментація, PMTUD‑чорні діри або проблеми з MSS, голос буде “провалюватися” так, ніби це випадковий джиттер. Це не випадково; пакети затримуються, фрагментуються або відкидаються.
Третій: упевніться, що голос класифіковано правильно до шифрування
Голос має бути ідентифікований та пріоритизований до того, як він зникне в тунелі. Далі вам потрібно або:
- Зберегти DSCP в зовнішньому заголовку тунелю, або
- Класифікувати всередині тунельного кінця і застосувати там shaping/чергування.
Четвертий: виправте чергування сучасними дисциплінами (FQ‑CoDel/CAKE)
Класичні пріоритетні черги можуть допомогти, але також можуть голодувати все інше і створювати дивну імпульсність. Для офісних ліній CAKE або FQ‑CoDel із розумним shaping зазвичай — це рішення, що «працює в понеділок вранці».
П’ятий: лише потім налаштовуйте кінцеві точки та PBX
Вибір кодека, packetization time (ptime), jitter‑буфер і таймери SIP важливі — але вони не виправлять насичений uplink із жахливими чергами.
Практичні завдання: команди, виводи та рішення (12+)
Ці завдання написані для Linux‑шлюзу VPN. Якщо у вас апаратний пристрій, ті самі концепції застосовні; команди просто стануть вендорно‑специфічними.
Завдання 1: Ідентифікуйте реальний WAN‑інтерфейс і тип лінії
cr0x@server:~$ ip -br link
lo UNKNOWN 00:00:00:00:00:00 <LOOPBACK,UP,LOWER_UP>
ens18 UP 52:54:00:aa:bb:cc <BROADCAST,MULTICAST,UP,LOWER_UP>
ppp0 UNKNOWN 00:11:22:33:44:55 <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP>
wg0 UNKNOWN 9a:bc:de:f0:12:34 <POINTOPOINT,NOARP,UP,LOWER_UP>
Що це означає: Ви можете бути на PPPoE (ppp0) і не підозрювати, що шейпите не той інтерфейс (ens18). PPP додає оверхед і має іншу поведінку MTU.
Рішення: Застосовуйте shaping/QoS на фактичному WAN‑egress (часто ppp0). Якщо ви шейпите на ens18, але реальне вузьке місце — ppp0 або модем ISP, ви просто танцюєте інтерпретативний танець.
Завдання 2: Перевірте статистику VPN‑інтерфейсу на помилки та дропи
cr0x@server:~$ ip -s link show dev wg0
4: wg0: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1420 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
RX: bytes packets errors dropped missed mcast
987654321 123456 0 12 0 0
TX: bytes packets errors dropped carrier collsns
876543210 120000 0 0 0 0
Що це означає: Відкиди RX можуть вказувати на переповнення черги на стороні прийому, конкуренцію за CPU або тиск на рівні ядра. Для WireGuard дропи часто пов’язані з апстрім‑перевантаженням або політикою QoS в іншому місці.
Рішення: Якщо дропи ростуть під час дзвінків, не чіпайте спочатку PBX. Виправте затори/чергування і перевірте CPU та шейпінг.
Завдання 3: Виміряйте затримку під навантаженням (тест bufferbloat, який можна запустити зараз)
cr0x@server:~$ ping -i 0.2 -c 30 1.1.1.1
PING 1.1.1.1 (1.1.1.1) 56(84) bytes of data.
64 bytes from 1.1.1.1: icmp_seq=1 ttl=56 time=12.3 ms
64 bytes from 1.1.1.1: icmp_seq=2 ttl=56 time=13.1 ms
...
--- 1.1.1.1 ping statistics ---
30 packets transmitted, 30 received, 0% packet loss, time 6008ms
rtt min/avg/max/mdev = 11.9/12.8/14.6/0.6 ms
Що це означає: Базовий рівень виглядає стабільним. Тепер повторіть, одночасно наситивши аплоад (наприклад, speedtest із клієнта або контрольований iperf). Якщо max підстрибує до 200–800 мс — у вас bufferbloat.
Рішення: Якщо затримка під навантаженням стрибає, ваше перше виправлення — shaping + сучасний AQM (CAKE/FQ‑CoDel), а не «змінити кодеки».
Завдання 4: Підтвердіть поточний qdisc на WAN‑egress
cr0x@server:~$ tc qdisc show dev ppp0
qdisc pfifo_fast 0: root refcnt 2 bands 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1
Що це означає: pfifo_fast — старомодний і зазвичай поганий під змішаним трафіком. Він не управляє затримкою активно.
Рішення: Замініть на CAKE або FQ‑CoDel + shaping. Якщо не можете — будете вічно боротися з симптомами.
Завдання 5: Встановіть shaping CAKE (приклад) і перевірте, що воно активно
cr0x@server:~$ sudo tc qdisc replace dev ppp0 root cake bandwidth 80Mbit diffserv4 nat nowash ack-filter
cr0x@server:~$ tc -s qdisc show dev ppp0
qdisc cake 8001: root refcnt 2 bandwidth 80Mbit diffserv4 nat nowash ack-filter
Sent 123456789 bytes 234567 pkt (dropped 123, overlimits 456 requeues 0)
backlog 0b 0p requeues 0
Що це означає: CAKE шейпить до 80 Mbit і застосовує DiffServ‑рівні. Деякі дропи нормальні; вони повинні відбуватися у вашому шейпері, а не в гігантському буфері ISP.
Рішення: Встановіть bandwidth трохи нижче реальної пропускної здатності (часто 85–95%). Потім повторно перевірте якість дзвінків під навантаженням. Якщо вона покращується суттєво — ви знайшли основну причину.
Завдання 6: Подивіться DSCP на вхідному RTP до шифрування
cr0x@server:~$ sudo tcpdump -ni ens18 -vv 'udp and (port 5060 or portrange 10000-20000)' -c 5
tcpdump: listening on ens18, link-type EN10MB (Ethernet), snapshot length 262144 bytes
IP (tos 0xb8, ttl 64, id 12345, offset 0, flags [DF], proto UDP (17), length 214)
10.10.20.50.40012 > 198.51.100.10.16432: UDP, length 172
IP (tos 0x00, ttl 64, id 12346, offset 0, flags [DF], proto UDP (17), length 498)
10.10.20.50.5060 > 198.51.100.10.5060: SIP, length 456
Що це означає: RTP із міткою DSCP EF (0xb8) — ідеал. SIP часто залишається best‑effort (0x00), що нормально; важливіше — медіа.
Рішення: Якщо RTP не помічено, вирішіть, маркувати на телефоні, на доступному комутаторі/AP або на шлюзі (mangle‑таблиця). Маркування на краю чистіше.
Завдання 7: Перевірте, чи DSCP виживає всередині тунелю (зовнішній заголовок)
cr0x@server:~$ sudo tcpdump -ni ppp0 -vv 'udp and host 203.0.113.20' -c 3
tcpdump: listening on ppp0, link-type LINUX_SLL2, snapshot length 262144 bytes
IP (tos 0x00, ttl 64, id 54321, offset 0, flags [DF], proto UDP (17), length 148)
192.0.2.10.51820 > 203.0.113.20.51820: UDP, length 96
Що це означає: Зовнішні пакети тунелю — best‑effort (tos 0x00). Це поширено: інкапсуляція не скопіювала внутрішній DSCP у зовнішній заголовок.
Рішення: Якщо ваша WAN‑QoS залежить від DSCP, доведеться копіювати DSCP (де підтримано) або класифікувати трафік на кінці тунелю і шейпити там. Інакше ваш ISP бачить один бляклий потік і ставиться до голосу як до котячих відео.
Завдання 8: Перевірте MTU на тунелі і виявте ризик фрагментації
cr0x@server:~$ ip link show dev wg0
4: wg0: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1420 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
Що це означає: 1420 — типовий WireGuard MTU. Якщо у вас LAN 1500 і ви не обмежуєте MSS для TCP, ви побачите фрагментацію для великих пакетів. RTP малі, але SIP/TLS і «інший трафік під час дзвінка» все ще можуть викликати черги та ретрансляції.
Рішення: Якщо є підозра на проблеми MTU, ставте MSS‑clamp для TCP і перевіряйте PMTUD. Не гадьте.
Завдання 9: Тест PMTU з пінгом із «не фрагментувати»
cr0x@server:~$ ping -M do -s 1372 -c 3 203.0.113.20
PING 203.0.113.20 (203.0.113.20) 1372(1400) bytes of data.
1400 bytes from 203.0.113.20: icmp_seq=1 ttl=57 time=23.1 ms
1400 bytes from 203.0.113.20: icmp_seq=2 ttl=57 time=23.4 ms
1400 bytes from 203.0.113.20: icmp_seq=3 ttl=57 time=23.0 ms
--- 203.0.113.20 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 23.0/23.1/23.4/0.2 ms
Що це означає: 1400‑байтові пакети з DF проходять. Збільшуйте розмір, поки не впаде, щоб знайти справжню PMTU‑відстань.
Рішення: Якщо навіть помірні DF‑пінги падають — ймовірно, у вас PMTUD‑чорна діра. Виправте MTU/MSS і переконайтесь, що ICMP «frag needed» не блокується.
Завдання 10: Clamp MSS для TCP, щоб уникнути фрагментації через тунель
cr0x@server:~$ sudo iptables -t mangle -A FORWARD -o wg0 -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
cr0x@server:~$ sudo iptables -t mangle -S FORWARD | grep TCPMSS
-A FORWARD -o wg0 -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
Що це означає: Це запобігає тому, щоб TCP‑сесії відправляли сегменти, що занадто великі для тунелю, зменшуючи фрагментацію та ретрансляції, які опосередковано погіршують джиттер під навантаженням.
Рішення: Тримайте це, якщо немає дуже специфічної причини не робити так. Це один із «нудних, але правильних» запобіжників.
Завдання 11: Перевірте завантаження CPU на VPN‑кінці під час дзвінків
cr0x@server:~$ mpstat -P ALL 1 5
Linux 6.8.0 (server) 12/28/2025 _x86_64_ (4 CPU)
12:10:01 AM CPU %usr %nice %sys %iowait %irq %soft %steal %idle
12:10:02 AM all 22.0 0.0 11.0 0.0 0.0 20.0 0.0 47.0
12:10:02 AM 0 18.0 0.0 9.0 0.0 0.0 42.0 0.0 31.0
12:10:02 AM 1 25.0 0.0 12.0 0.0 0.0 18.0 0.0 45.0
12:10:02 AM 2 23.0 0.0 11.0 0.0 0.0 15.0 0.0 51.0
12:10:02 AM 3 22.0 0.0 12.0 0.0 0.0 5.0 0.0 61.0
Що це означає: Високий %soft на одному ядрі може вказувати на вузьке місце обробки пакетів (softirq). Шифрування і інкапсуляція тунелів можуть прив’язувати навантаження до ядра залежно від драйвера/чергування.
Рішення: Якщо одне ядро постійно завантажене під час піку, потрібно оптимізувати CPU‑шлях (NIC RSS, афінність IRQ, швидший шифр, апаратне прискорення або зменшити кількість пакетів через більший ptime, де це прийнятно).
Завдання 12: Спостерігайте softirq‑тиск (обробка мережі) і дропи пакетів
cr0x@server:~$ cat /proc/softirqs | egrep 'NET_RX|NET_TX'
NET_TX: 1020304 993322 880011 770022
NET_RX: 9090909 8888888 7777777 6666666
Що це означає: Великий швидкозростаючий NET_RX на одному CPU може корелювати з джиттером, коли система перевантажена і пакети чекають своєї черги.
Рішення: Якщо це корелює з поганими дзвінками, зменшіть частоту пакетів (packetization), масштабуйте CPU або налаштуйте IRQ/RPS/RFS, щоб робота розподілялася.
Завдання 13: Перевірте втрачені RTP‑пакети та джиттер за допомогою захоплення на шлюзі
cr0x@server:~$ sudo tshark -ni ens18 -f "udp portrange 10000-20000" -c 50 -q -z rtp,streams
Running as user "root" and group "root". This could be dangerous.
========================= RTP Streams =========================
Start time End time Src IP Src port Dst IP Dst port SSRC Payload Packets Lost Max Jitter
0.000000 9.842000 10.10.20.50 40012 198.51.100.10 16432 0x1a2b3c4d 111 400 3 14.7 ms
===============================================================
Що це означає: Ви бачите фактичні втрати й джиттер RTP (зафіксовані в точці захоплення). Декілька втрачених пакетів можуть бути допустимі; стійкі втрати корелюють із чутними артефактами.
Рішення: Якщо втрата відбувається до інкапсуляції тунелю, виправляйте LAN/Wi‑Fi. Якщо після інкапсуляції (захоплення на WAN‑стороні), виправляйте WAN‑шейпінг/шлях ISP/тунельний кінець.
Завдання 14: Перевірте тиск conntrack (переповнення NAT‑таблиці може виглядати як «джиттер»)
cr0x@server:~$ sudo sysctl net.netfilter.nf_conntrack_count net.netfilter.nf_conntrack_max
net.netfilter.nf_conntrack_count = 24789
net.netfilter.nf_conntrack_max = 262144
Що це означає: Достатньо запасу. Якщо count близький до max, нові потоки відкидаються/евіктяться, що може ламати SIP/RTP дивними способами.
Рішення: Якщо під час робочих годин близько до max, збільшіть conntrack_max і/або зменшіть непотрібний NAT‑чейн (короткоживучі потоки, невірні таймаути, говіркі пристрої).
Завдання 15: Підтвердіть, що таймаути RTP/SIP не вбиваються дефолтами фаєрвола
cr0x@server:~$ sudo sysctl net.netfilter.nf_conntrack_udp_timeout net.netfilter.nf_conntrack_udp_timeout_stream
net.netfilter.nf_conntrack_udp_timeout = 30
net.netfilter.nf_conntrack_udp_timeout_stream = 180
Що це означає: Якщо ці значення занадто малі для вашого середовища, RTP‑потоки можуть відкидатися в середині дзвінка під час короткої тиші або re‑INVITE‑танцю.
Рішення: Якщо ви бачите одностороннє аудіо після ~30 секунд тиші, збільшіть UDP‑таймаути або переконайтесь, що keepalives налаштовано.
Поради для тунелів: IPsec, WireGuard, OpenVPN
IPsec (IKEv2/ESP): надійний, поширений і легко зробити неправильно для QoS
IPsec — це робоча кінна праця. Він також любить робити ваш QoS невидимим, якщо ви навмисно не збережете мітки.
- ESP інкапсуляція ховає порти, тож «пріоритизувати UDP 10000–20000» не допоможе на WAN‑стороні; все стає ESP.
- Копіювання DSCP не всюди відбувається автоматично. Деякі стекі копіюють внутрішній DSCP у зовнішній; деякі — ні; деякі роблять це до включення NAT‑T.
- NAT‑T (UDP‑инкапсуляція) додає ще один заголовок і може змінити MTU і динаміку фрагментації.
Що робити: Пріоритизуйте трафік до шифрування, а потім переконайтесь, що VPN‑кінцевий вузол використовує це для планування пакетів у тунелі. Якщо ви застосовуєте QoS далі (під контролем ISP), вам потрібно зберегти зовнішній DSCP і перевірити це захопленнями.
WireGuard: легкий, швидкий, але не чарівний
Простота WireGuard — операційна краса. Але він не вирішує джиттер автоматично; він просто витрачає менше CPU‑циклів, ніж деякі старі конструкції.
- Типові вибори MTU важливі. 1420 — поширено; вашому середовищу може знадобитися ~1380, якщо ви складаєте PPPoE/VLAN.
- Проблема одного UDP‑потоку: з боку ISP це один потік, якщо ви не шейпите розумно. Ви повинні зробити чесне чергування на своїй стороні.
- Маркування: DSCP на внутрішніх пакетах не стає автоматично DSCP на зовнішніх UDP 51820 пакетах.
OpenVPN: гнучкий, іноді важчий, ніж ви думаєте
OpenVPN може бути цілком прийнятним для VoIP. Але він також може стати генератором джиттера, якщо ви запускаєте його в просторі користувача на малому CPU і пропускаєте багато дрібних пакетів.
- UDP‑режим зазвичай правильний вибір для VoIP. TCP‑режим може підсилювати затримку через семантику ретрансляцій («TCP meltdown»).
- Обробка в просторі користувача може бути видимою як джиттер під час сплесків трафіку.
- Стиснення — пастка в сучасних налаштуваннях: часто це ризик безпеки і може збільшити CPU‑джиттер.
QoS та shaping, які реально працюють через тунелі
Почніть із shaping, а не «пріоритету»
Якщо більше нічого не робити: шейпіть egress трохи нижче реальної WAN‑швидкості і використовуйте CAKE. Це змушує чергування відбуватись у вашій коробці (де ви контролюєте ситуацію), а не в таємничому буфері ISP (де ви не контролюєте).
Чому це допомагає VoIP через VPN:
- RTP‑пакети залишаються маленькими і частими; справедливе чергування дає їм часті черги.
- Великі аплоади розтягуються замість того, щоб будувати гігантську чергу.
- Затримка під навантаженням стає прогнозованою — саме це й потрібно jitter‑буферам.
Класифікація: маркуйте до шифрування, потім плануйте в тунелі
Є дві життєздатні моделі:
- Внутрішня класифікація + тунель‑свідомий shaping: класифікуйте RTP/SIP на LAN‑інтерфейсі, а потім шейпіть на WAN на основі міток фаєрвола. Це дозволяє уникнути потреби в DSCP на зовнішньому заголовку.
- DSCP end‑to‑end: маркуйте RTP EF і забезпечте, щоб тунель копіював DSCP у зовнішній заголовок, щоб downstream‑пристрої могли його поважати. Це чистіше, коли працює — але часто не працює без явного налаштування.
Не перестарайтеся з пріоритетом
Багато «QoS‑гайдів» радять сувору пріоритетну чергу для голосу. Це окей, якщо обсяг голосу невеликий і класифікація коректна. В реальному офісі помилки класифікації трапляються, а суворий пріоритет може задушити DNS, ACK‑и та контрольний трафік — спричиняючи дивний вид самоствореного збою, коли голос кришталево чистий, а все інше падає.
Другий короткий жарт (і це квота): суворий пріоритет QoS — як дати одному колезі єдиний ключ від конференц‑зали; зустріч ефективна, доки всі інші не почнуть відмикати двері.
Зробіть це вимірюваним: затримка під навантаженням як KPI
Ваш найкращий «до/після» — це не MOS з одного телефону. Це пінг‑затримка під навантаженням плюс RTP‑втрати/джиттер із захоплень у ключових точках. Якщо shaping працює, пінг під навантаженням покращується суттєво, а RTP‑джиттер стабілізується.
MTU, MSS, фрагментація: мовчазний вбивця голосу
Чому проблеми MTU проявляються як «джиттер»
Фрагментація не завжди призводить до втрат, але збільшує варіативність. Фрагменти можуть іти різними шляхами, ставати у різні черги або вибірково скидатися. Якщо невезуче — PMTUD ламається і великі пакети чорніють; тоді TCP‑ретрансляції затоплюють лінію і голос страждає побічно.
Типові стек‑конфігурації MTU в офісах
- Ethernet: 1500
- PPPoE: зазвичай 1492
- VLAN‑тег: зменшує корисну корисну вантажопідйомність, якщо не використовуються jumbo frames по‑всій дорозі
- WireGuard: часто близько 1420
- IPsec ESP/NAT‑T: змінна; може суттєво скорочувати ефективний MTU
Практичні правила
- Заклинюйте MSS для TCP в напрямку тунелю, щоб запобігти штормам фрагментації.
- Дозвольте необхідний ICMP (frag‑needed, time‑exceeded). Блокування його — як прибрати дорожні знаки і звинувачувати водіїв у запізненні.
- Встановлюйте MTU тунелю свідомо. Авто‑режим може бути «добре», але «добре» — не стратегія, коли CEO чує роботів.
Wi‑Fi і остання миля, за які ви досі звинувачуєте «VPN»
Wi‑Fi вводить джиттер за визначенням
Wi‑Fi — це середовище з розподілом доступу. Клієнти чергуються, ретранслюють і адаптують швидкість. Дивовижно, що VoIP на ньому взагалі працює, і причина в тому, що голос має малу пропускну спроможність. Але мала пропускна не означає малу чутливість.
Якщо ваші офісні телефони на Wi‑Fi:
- Віддавайте перевагу 5 GHz (або 6 GHz, якщо доступно) для меншого інтерференсу.
- Увімкніть WMM (Wi‑Fi Multimedia) і коректно зіставляйте DSCP у WMM‑категорії доступу.
- Слідкуйте за «липкими клієнтами», що тримаються за далекі AP і спричиняють повто́рення та зловживання ефіром.
Асиметрія останньої милі та поліси
Багато широкосмугових ліній асиметричні в аплоаді. VoIP — двонаправлений; аплоад часто важливіший, бо звідти офіс надсилає RTP провайдеру, і бекапи/синхронізація можуть наситити канал.
Також: ISP іноді полірує трафік так, що мікросплески губляться. Ваш шейпер має згладжувати сплески до того, як вони вдарять у модем. Якщо ви не шейпите — ISP зробить це за вас, погано.
Три корпоративні міні‑історії (біль, жаль і нудний успіх)
1) Інцидент, спричинений неправильною припущенням
Вони мігрували телефони в хмарний PBX і зберегли site‑to‑site VPN, бо «безпека вимагає, щоб весь трафік йшов через HQ». План міграції припускав, що голос — «просто ще один UDP‑потік», і оскільки графіки по ширині каналу виглядали добре, ніхто не турбувався.
Перший тиждень у продакшні — керівники почали скаржитись, що дзвінки ідеальні рано вранці і непридатні о 10:30. Така закономірність кричала «перевантаження», але NOC дивився на середнє завантаження і нічого тривожного не бачив — бо середні величини — це брехня, яку ваші графіки розповідають, щоб заспокоїти вас.
Захоплення на LAN‑стороні показало RTP з міткою EF. Захоплення на WAN‑стороні показало, що тунельні пакети — всі best‑effort. У HQ фаєрвол мав красиву QoS‑політику для портів голосу, але після IPsec пакети стали ESP і політика не спрацювала. Голос став у чергу за ранковим сплеском синхронізації хмарних сховищ і щотижневого оновлення кінцевих точок.
Виправлення не було екзотичним: шейпінг HQ‑uplink із CAKE, класифікація голосу до шифрування і планування в вищий рівень. Коли черга перемістилася з буфера ISP в їх контрольований шейпер — джиттер вирівнявся і дзвінки стабілізувалися. Неправильне припущення було в тому, що «ми вже маємо QoS», бо конфіг існує. Мережа не цікавилася конфігом; її цікавило, де фактично стоять пакети в черзі.
2) Оптимізація, що відзеркалювалась назад
Інша компанія мала невеликий філіал з скромним фаєрволом. VoIP через VPN був на межі під час піків, тож хтось «оптимізував», увімкнувши агресивну агрегацію пакетів і офлоади, плюс профіль продуктивності, що підвищував модерацію переривань, щоб знизити CPU.
Графіки CPU фаєрвола одразу покращилися. Команда святкувала. Потім helpdesk отримав новий тип скарг: «Люди звучать, ніби під водою» і «Кожні кілька секунд аудіо глючить». Це не корелювалося з шириною каналу; корелювалося зі сплесками трафіку.
Що сталося: модерація переривань і агрегація пакетів збільшили варіабельність затримки. Пакети не оброблялися рівномірно; вони приходили зупинками. RTP любить метроном. Замість нього він отримав джаз. Також деякі офлоади взаємодіяли з інкапсульованим трафіком, підвищуючи ретрансляції в інших потоках, що створило ще більше сплесків. Ідеальний зворотний зв’язок — як ехо, але для поганих рішень.
Вони відкочували «оптимізацію», потім використали shaping, щоб злегка обмежити WAN трохи нижче лінійної швидкості. CPU піднявся, але якість дзвінків стабілізувалася. Урок: оптимізація для середнього CPU може погіршити латентність у хвостах. VoIP живе у хвостах.
3) Нудна, але правильна практика, що врятувала день
Ще одна історія: компанія з десятками невеликих офісів запускала VoIP через WireGuard до регіонального хаба. Нічого особливого. Але у них була несексуальна звичка: кожен новий сайт отримував стандартизований «тест прийнятності голосу» з першого дня.
Тест включав пінг‑під‑навантаження, MTU‑DF‑пінг‑свіп і короткий синтетичний RTP‑потік, виміряний у хабі. Результати зберігалися для кожного сайту і порівнювалися з базовою лінією. Це було настільки рутинно, що молодші техніки могли запускати його без імпровізації.
Один офіс почав мати періодичні проблеми після заміни обладнання ISP. Провайдер наполягав, що лінія в порядку. Команда перезапустила тест і негайно побачила, що пінг‑під‑навантаження змінився зі «стабільного» на «американські гірки». MTU‑свіп також показав зменшену PMTU. Всередині нічого не змінили.
Завдяки базовим даним вони не сперечалися на рівні відчуттів. Показали виміряні докази, тимчасово підкоригували шейпер і MTU тунелю і підштовхнули ISP виправити провізію. Дзвінки покращилися того ж дня. Практика не була гламурною. Вона була правильною. Вона заощадила час і врятувала команду від безкінечних нарад із «але минулого року працювало».
Поширені помилки: симптом → корінна причина → виправлення
1) Симптом: дзвінки нормальні, поки хтось не завантажить великий файл
Корінна причина: bufferbloat на uplink; черги виникають у модемі/ISP, а не під вашим контролем.
Виправлення: шейпіть egress трохи нижче лінійної швидкості на справжньому WAN‑інтерфейсі (CAKE/FQ‑CoDel). Перевірте через ping‑під‑навантаження.
2) Симптом: одностороннє аудіо, особливо після хвилини тиші
Корінна причина: занадто низькі NAT/conntrack UDP‑таймаути; SIP/RTP‑мапи спливають.
Виправлення: збільшіть UDP‑таймаути, увімкніть SIP/RTP keepalives якщо підтримується, і забезпечте симетричну маршрутизацію.
3) Симптом: роботизоване аудіо з періодичними заїканнями, навіть коли пропускна здатність низька
Корінна причина: CPU/softirq‑вузьке місце на VPN‑шлюзі, часто перевантаження одного ядра або агресивна модерація переривань, що робить обробку сплесками.
Виправлення: перевірте навантаження по ядрах і softirq. Налаштуйте IRQ/RSS, зменшіть частоту пакетів (ptime) або оновіть апаратне забезпечення. Відкотіть «латентно‑ворожі» офлоади.
4) Симптом: випадкові обриви при увімкненні VPN, особливо для певних додатків
Корінна причина: MTU/PMTUD проблеми; ICMP frag‑needed блокується; фрагментація або чорні діри.
Виправлення: проведіть PMTU DF‑пінг‑свіп; clamp MSS; дозволіть ICMP; встановіть MTU тунелю явно.
5) Симптом: QoS налаштовано, але голос все одно поганий через VPN
Корінна причина: ви зіставляєте за внутрішніми портами, які приховані після шифрування; або DSCP не копіюється у зовнішній заголовок.
Виправлення: класифікуйте до шифрування за допомогою міток, шейпіть на WAN за цими мітками; або налаштуйте копіювання DSCP і перевірте захопленнями.
6) Симптом: джиттер лише у користувачів Wi‑Fi, дротові телефони в порядку
Корінна причина: Wi‑Fi‑повтори, інтерференція, зловживання ефіром, відсутня WMM/DSCP‑to‑WMM мапа.
Виправлення: заохочуйте використання 5/6 GHz, тонко налаштуйте AP, увімкніть WMM, зменшіть кількість повторів і розгляньте виділений SSID/VLAN для голосу.
7) Симптом: VPN «працює», але встановлення виклику повільне або періодично не вдається
Корінна причина: SIP ALG або «допоміжні» функції фаєрвола переписують SIP; або асиметрична маршрутизація через кілька WAN.
Виправлення: вимкніть SIP ALG, якщо він вам не потрібен; забезпечте узгодженість шляхів для сигналізації та медіа; використовуйте SBC, якщо архітектура цього вимагає.
Контрольні списки / покроковий план
Покроково: стабілізувати голос через VPN в офісі
- Заміруйте шлях трафіку: де кінцевий вузол тунелю, де виконується NAT, де справжнє вузьке місце (WAN‑egress)? Запишіть це.
- Виміряйте базу: пінг до стабільної зовнішньої цілі; захоплення RTP‑статистики на шлюзі; зафіксуйте симптоми дзвінків і час доби.
- Запустіть тест затримки під навантаженням: коротко наситіть аплоад; спостерігайте max пінгу і джиттер. Якщо стрибає — припиніть звинувачення PBX.
- Встановіть шейпінг на WAN‑egress: почніть з CAKE на 85–95% від реального up/down. Повторно протестуйте під навантаженням.
- Класифікуйте голос: маркуйте RTP EF (або еквівалент) на краю; переконайтесь, що шейпер це поважає. Якщо не можете зберегти DSCP у тунелі, використайте мітки фаєрвола.
- Виправте MTU/MSS: DF‑пінг‑свіп, clamp MSS, дозвольте необхідний ICMP, підкоригуйте MTU тунелю при потребі.
- Перевірте запас CPU: спостерігайте за навантаженням по ядрах і softirq під час одночасних дзвінків + навантаження. Якщо ви прив’язані до CPU — жодна політика QoS не допоможе.
- Перевірте Wi‑Fi окремо: якщо лише Wi‑Fi ламається, розглядайте це як проблему Wi‑Fi. Дротові тести — ваш контроль.
- Закріпіть моніторинг: відстежуйте затримку під навантаженням, дропи тунелю, qdisc‑дропи та RTP‑джиттер/втрати. Трендуйте. Зробіть це нудним.
Операційний чекліст: перед тим як змінювати щось під час інциденту
- Захопіть 30 секунд трафіку на LAN‑стороні і на WAN‑стороні (або на тунельному інтерфейсі) під час поганого дзвінка.
- Перевірте статистику qdisc і інтерфейсні дропи.
- Перевірте CPU по ядрах і softirq.
- Підтвердіть, чи uplink насичується (не середнє; поточні піки).
- Підтвердіть, чи DSCP присутній на RTP і чи виживає він інкапсуляцію.
- Запустіть DF‑пінг з кількома розмірами, щоб виявити регресії PMTU.
FAQ
1) Чи робить VPN за визначенням VoIP гіршим?
Ні. VPN додає оверхед і може ховати трафік від QoS, але звичайний вбивця — це чергування, спричинене перевантаженням, і погане управління чергами. Виправте це — і VoIP буде відмінно працювати через тунель.
2) Чи варто запускати VoIP поза VPN, щоб «виправити» це?
Іноді це дійсна архітектурна опція, особливо з хмарним PBX і SRTP/TLS уже на місці. Але не робіть цього як обхід bufferbloat — він і далі буде проблемою для всього іншого трафіку.
3) Що важливіше: затримка чи джиттер?
Для якості звуку користувачі часто сприймають як «рваний звук» — це джиттер. Для комфортної розмови важливіша затримка. На практиці вони пов’язані: jitter‑буфери міняють джиттер на затримку.
4) Чи варто використовувати DSCP в публічному інтернеті?
Через відкритий інтернет DSCP непослідовний. Всередині офісу і на вашому контрольованому еджі — це точно варто, бо інформує ваш шейпер і WMM‑мапінг Wi‑Fi. Розглядайте підтримку ISP як бонус, а не як залежність.
5) Яка єдино найкраща зміна для офісного VoIP через VPN?
Шейпінг WAN‑egress з CAKE (або FQ‑CoDel) з реалістичним обмеженням пропускної здатності та перевіркою пінгу під навантаженням. Це не гламурно. Це ефективно.
6) Чому мої графіки показують низьке завантаження, але дзвінки все одно глючать?
Бо середні величини ховають мікросплески і черги. Голос ламається через мілісекунди‑масштабні варіації. Дивіться на max затримку під навантаженням, інтерфейсні дропи і backlog qdisc — а не лише на п’ятихвилинні середні.
7) Чи змінювати кодеки, щоб виправити джиттер?
Вибір кодека може допомогти (деякі краще переносять втрати), і packetization впливає на частоту пакетів. Але якщо проблема в чергах uplink — зміни кодека лише пластир. Спочатку виправте мережу, потім оптимізуйте кодеки.
8) Чи хороший варіант VPN на TCP (або SIP через TCP)?
Для медіа (RTP) — ні, використовуйте UDP. Для SIP‑сигналізації TCP/TLS підходить. Але VPN на TCP для всього може підсилити затримку при втратах через ретрансляції і head‑of‑line blocking.
9) Що якщо VPN‑кінцевий вузол у хмарі, а не в офісі?
Тоді все одно потрібен шейпінг на офісному WAN‑egress. Хмарний шейпер не виправить офісну uplink‑чергу. Ви також можете додати шейпінг у хмарі, щоб захистити downstream, але перше вузьке місце зазвичай — аплоад філії.
10) Як визначити, чи проблема у ISP чи в моєму обладнанні?
Якщо шейпінг на вашому шлюзі суттєво покращує затримку під навантаженням — шлях ISP може бути в порядку; попереднє місце черги було неправильним. Якщо після шейпінгу і при здоровому CPU ви все ще бачите втрати/джиттер — збирайте захоплення і тисніть на ISP з доказами (зміни PMTU, шаблони втрат, кореляція по часу доби).
Висновок: наступні кроки, які ви можете зробити цього тижня
Якщо ваш офіс пропускає VoIP через VPN‑тунель і якість нестабільна — перестаньте сперечатися і почніть вимірювати. Виправлення зазвичай — невеликий набір нудних контролів:
- Запустіть пінг‑під‑навантаження і доведіть bufferbloat (або відкиньте його).
- Шейпіть справжній WAN‑egress з CAKE або FQ‑CoDel трохи нижче реальної лінійної швидкості.
- Класифікуйте голос до шифрування; не думайте, що QoS‑правила автоматично працюють, коли трафік став «просто тунелем».
- Перевірте MTU/PMTU і clamp MSS, щоб не створювати хаосу від фрагментації.
- Перевірте CPU/softirq на VPN‑кінці і відкотіть «оптимізації», що підвищують хвостову латентність.
Зробіть це — і VoIP через VPN стане нудним, що є найвищою похвалою, яку SRE може дати продуктивній системі.