Один шейпер tc сам по себе не ограничивает каждого клиента VPN
Ограничению на клиента нужны идентичность для подсчёта, два направления и точка классификации. Один шейпер на туннеле — не одна квота на пользователя.
Инструкция звучит полно: ограничить каждого клиента VPN до 20 Mbit/s. Но она не полна, и одна дисциплина очереди на интерфейсе туннеля этого не обеспечит. «На клиента» может означать на адрес туннеля, на устройство или на учётную запись, и каждый выбор классифицирует пакеты по-разному. Прежде чем писать любое правило, решите, какой именно из них называет требование.
Всё ниже — о расстоянии между этим предложением и чем-то работающим.
Что сначала должно означать «на клиента»
Адрес туннеля легко классифицировать и легко переиспользовать. Устройство сложнее, потому что одна учётная запись может нести несколько, а устройство может иметь несколько адресов, особенно с IPv6. Для политики справедливости учётная запись — самая осмысленная единица и самая трудная для обнаружения в заголовке пакета. Каждое определение подразумевает свой ключ подсчёта, поэтому политика, которая дрейфует между ними, не сделает того, что обещает описание.
Направление — второе недостающее слово. Отдача, загрузка и суммарно — три разных требования, и одно правило выхода на одном интерфейсе редко покрывает оба пути.
Выберите точку, где клиент ещё виден
Каждое направление определяется относительно интерфейса. То, что покидает туннель сервера в сторону удалённого клиента, считается загрузкой для этого клиента; то, что клиент отправляет, входит в туннель и затем выходит к своему назначению. Выберите точку планирования для каждого направления и спросите, какие поля там существуют. До NAT источника отдача ещё несёт внутренний адрес клиента; после трансляции простое совпадение по источнику может его уже не идентифицировать.
На зашифрованном пути заголовки принадлежат транспорту VPN, поэтому фильтру, сопоставляющему внутренние адреса, нечего сопоставлять. Проект может классифицировать раньше и передать метку более позднему планировщику, но эта передача должна быть намеренной: метки пакетов, метки соединений и классы планировщика — это разное состояние, а не одно передаваемое дальше значение.
Вёдра не появляются сами
Ведро токенов, привязанное к интерфейсу, формирует любой трафик, который его использует; оно не создаёт новое ведро на каждый адрес источника. Проект на основе классов вместо этого раскладывает выбранный трафик по классам, фильтры решают членство, а руководство HTB отделяет скорость класса от его потолка, когда у родителя есть свободная полоса. Если цель — жёсткий предел, задайте потолок и намеренно решите поведение заимствования; не рассматривайте каждую цифру скорости как абсолютный максимум.
Когда требование на клиента, две одновременные передачи должны делить одну квоту. Давать каждому потоку полную скорость — другая политика, и она проходит любую проверку, которая смотрит только одну загрузку.
Два устройства, одна учётная запись, одна квота?
Раздельное ограничение двух адресов устройств никогда не складывается в одну квоту на уровне учётной записи, даже когда оба устройства входят как один и тот же человек. То же относится ко всей локальной сети, транслируемой за одним партнёром, или к дополнительным адресам IPv6, которых классификатор вовсе не ожидал. Держите связь адреса и идентичности актуальной и помните, что стабильный адрес упрощает карту, но не удостоверяет владельца.
Определите также поведение всплесков и очереди. Вёдра токенов допускают короткие всплески выше среднего, а буферизация добавляет задержку; ограничивать избыток и ставить его в очередь на потом — разные решения с разными симптомами.
Для проверки запустите две передачи с одного клиента, добавьте второго клиента и прочитайте счётчики классов в каждом направлении.