Къде принадлежи месечната квота за данни при профил в OpenVPN
Квота, която се нулира при всяко повторно свързване, не е ограничение. Отчитайте потреблението по профил, начислявайте всяка разлика в байтове веднъж и направете изчерпването пречка за допускане.
Квота, която се нулира при всяко повторно свързване на тунела, не е ограничение и точно това получавате, когато брояч на байтове се прикачи към VPN сървър без място за трайно състояние. Броячът принадлежи на сесия; квотата принадлежи на човек или на договор за устройство. Цялата трудност на функцията идва от това несъответствие, затова проверките по-долу са за това къде живее състоянието и кой слой има право да взема решение.
Привържете квотата към профил, а не към тунел
Започнете с назоваване на субекта на квотата. Един човек може да има три сертификата за устройства и никой от тях не бива да получава независим месечен бюджет само защото се удостоверява отделно. Стабилен идентификатор на профила, който оцелява при повторни свързвания, нови адреси на тунела и преместване към втори шлюз, е единствената котва, която квотата може да използва. Общото име на сертификат работи като такъв ключ само когато политиката ви за издаване гарантира един профил на име.
Назначеният адрес на тунела никога не е отговорът. Адресите се преизползват, пуловете се споделят и един и същ профил може да се появи два пъти на два шлюза в една и съща минута. Ако регистърът се води по адрес, прекъсването и повторното свързване са достатъчни, за да напълнят резервоара отново.
Записвайте достатъчно за всяка сесия, за да е проверима аритметиката: профилът, периодът на фактуриране, инстанцията на шлюза, идентичността на сесията, последно наблюдаваните броячи и потвърдения общ сбор. Включете поколение на стартиране на демона в идентичността на сесията, защото рестартиран сървър преизползва идентификатори на клиенти и наивно съвпадение би наследило предишната базова линия.
Фиксирайте единицата, посоката и границата на нулиране
Четири дефиниции трябва да бъдат уредени писмено, преди да започне каквото и да е събиране. Квотата брои ли байтовете, които клиентът изпраща, байтовете, които получава, или сумата от двете? Един гигабайт 10^9 байта ли е или 2^30? В кой местен час и в коя часова зона се превключва периодът? И какво точно измерва броячът, като се има предвид, че режийните разходи на тунела и повторните предавания са включени, а размерът на файла на приложението и фактурата на доставчика не са?
Нито един от тези избори не е грешен, но реализацията и числото, което клиентът вижда, трябва да съвпадат. Две половини на една и съща система, които не са на едно мнение за GiB или за превключване в полунощ UTC вместо местно време, пораждат точно онзи тикет, който подкопава доверието в цялата квота.
Превърнете общите байтове в една начислена разлика
Интерфейсът за управление отчита периодични редове BYTECOUNT_CLI, носещи идентификатор на клиент плюс натрупани общи байтове във всяка посока, а командата bytecount задава колко често пристигат. От гледна точка на сървъра получената стойност брои байтовете, които клиентът е изпратил, а изпратената стойност брои байтовете, доставени до него. Задайте интервала на нещо, което регистърът може да поеме; много краткият интервал купува точност, която всъщност не получавате.
Едно ограничение оформя целия дизайн: управляващият сокет приема една контролна връзка. Експортьор за мониторинг, GUI и вашият контролер не могат всеки да отвори своя. Решете кой процес притежава канала и оставете другите да четат състояние от него, защото този интерфейс дава административни действия и така или иначе не бива да се излага извън хоста.
rx_delta = sample.rx_now - session.prev_rx
tx_delta = sample.tx_now - session.prev_tx
charge = rx_delta + tx_delta
# same transaction:
ledger.total += charge
session.prev_rx, session.prev_tx = sample.rx_now, sample.tx_now
Записвайте новите базови линии и увеличението на потреблението заедно, така че повторното изиграване на извадка да не начислява нищо вместо да начислява два пъти. Брояч, който се движи назад, е сигнал, а не дълг: означава, че сесията е заменена или демонът е рестартиран, и правилният отговор е да съгласувате идентичността на сесията, вместо да кредитирате отрицателна сума.
Пътят на прекъсване се нуждае от същото внимание. Ако финално събитие носи общи суми за края на сесията, начислете само разликата от последната потвърдена извадка. Добавянето на пълната сума, след като периодичното вземане на извадки вече е начислено, е най-честото двойно отчитане в домашно изработени системи за квоти. Сесиите, които пресичат границата на период, също се нуждаят от правило, тъй като една финална сума не носи информация кога байтовете са преминали полунощ.
Изчерпването да отказва допускане, а не само да убива тунела
Когато профил достигне лимита си, трябва да се случат две неща: съществуващите сесии приключват, а новите се отказват. Протоколът за управление предоставя client-kill по идентификатор на клиент, което урежда първата половина, стига да изброите всяка жива сесия за профила, вместо да убиете единствения адрес, който случайно сте забелязали.
Втората половина е мястото, където дизайните на квоти се провалят. Едно убиване само по себе си е надпревара с цикъла за повторно свързване на клиента, който с удоволствие ще се върне секунди по-късно. Допускането трябва да се допитва до споделения регистър, а при разгръщане с няколко шлюза тази проверка не може да бъде файл на всяка машина. Всяка инстанция, която може да приеме вход, трябва да вижда едно и също изчерпано състояние.
Повторните свързвания с токен заслужават собствен тест. OpenVPN 2.6 може да валидира токен за сесия вътрешно с auth-gen-token, пропускайки външното извикване за удостоверяване, което вашият контролер използваше за налагане на тавана. Затова токен, който все още е валиден, доказва идентичност, а не остатъчна квота, и всяка нова клиентска инстанция все още трябва да се допитва до регистъра. Ако вместо това включите management-client-auth, контролерът става удостоверител и наследява задължението сам да анализира състоянието на сесията и да отхвърля изтекли или невалидни токени.
Приемете превишаването, което създава вземането на извадки
Периодичното наблюдение плюс прекъсването ви дават квота по извадки с известен толеранс. Клиент може да превиши с приблизително един интервал на отчитане плюс времето, нужно на контролера да действа, а едновременните сесии на един профил умножават този прозорец. Кажете го в интерфейса, вместо да рекламирате точно отсичане на последния байт, което не можете да осигурите.
Истинският твърд таван е различен инженерен проблем: налагане вътре в пътя за препращане, свързано с един и същ профил през сесиите. По-бързото четене на броячи не е същото нещо и не издържа на клиент, който просто отваря повече тунели.
Преди пускане изпълнете приемните случаи, които чупят наивните реализации: повтарящи се повторни свързвания, две устройства едновременно, рестартиране на контролера и шлюза, загубено събитие за прекъсване, превключване по средата на сесия и опит за повторно свързване с токен веднага след изчерпване. След това решете режима на отказ при прекъсвания в отчитането. Трайният регистър защитава записаното потребление; той не може да възкреси наблюдения, които никога не са пристигнали, и клиентът заслужава да знае в коя от тези две ситуации е.