Limit, który resetuje się za każdym razem, gdy tunel łączy się ponownie, nie jest ograniczeniem, i dokładnie to się dostaje, gdy licznik bajtów przykręca się do serwera VPN bez miejsca na trwały stan. Licznik należy do sesji; limit należy do osoby albo do umowy na urządzenie. Cała trudność tej funkcji wynika z tej niezgodności, więc poniższe sprawdzenia dotyczą tego, gdzie mieszka stan i która warstwa może decydować.

Przypnij limit do konta, nie do tunelu

Zacznij od nazwania podmiotu limitu. Jedna osoba może mieć trzy certyfikaty urządzeń i żaden z nich nie powinien dostawać niezależnego miesięcznego budżetu tylko dlatego, że uwierzytelnia się osobno. Stabilny identyfikator konta, który przetrwa ponowne połączenia, nowe adresy tunelu i przeprowadzkę na drugą bramę, jest jedyną kotwicą, której limit może użyć. Nazwa pospolita certyfikatu działa jako ten klucz tylko wtedy, gdy polityka wydawania gwarantuje jedno konto na nazwę.

Przydzielony adres tunelu nigdy nie jest odpowiedzią. Adresy są recyklingowane, pule są współdzielone, a to samo konto może pojawić się dwa razy na dwóch bramach w tej samej minucie. Jeśli księga opiera się na adresie, rozłączenie i ponowne połączenie wystarczą, by znowu napełnić zbiornik.

Zapisuj per sesja tyle, by arytmetyka była audytowalna: konto, okres rozliczeniowy, instancję bramy, tożsamość sesji, ostatnio zaobserwowane liczniki i zatwierdzoną sumę. Uwzględnij generację startu demona w tożsamości sesji, bo zrestartowany serwer używa ponownie identyfikatorów klientów, a naiwne dopasowanie odziedziczyłoby poprzednią linię bazową.

Ustal jednostkę, kierunek i granicę resetu

Cztery definicje trzeba ustalić na piśmie, zanim zacznie się jakiekolwiek zbieranie. Czy limit liczy bajty wysyłane przez klienta, odbierane, czy sumę obu? Czy gigabajt to 10^9 bajtów, czy 2^30? O której godzinie lokalnej i w której strefie czasowej przewraca się okres? I co dokładnie mierzy licznik, skoro narzut tunelu i retransmisje są wliczone, a rozmiar pliku aplikacji i faktura dostawcy nie?

Żaden z tych wyborów nie jest błędny, ale implementacja i liczba, którą widzi klient, muszą się zgadzać. Dwie połowy tego samego systemu, które nie zgadzają się co do GiB albo co do przełączenia o północy UTC zamiast czasu lokalnego, produkują dokładnie ten rodzaj zgłoszenia, który podkopuje zaufanie do całego limitu.

Zamień sumy bajtów na jedną naliczoną różnicę

Interfejs zarządzania raportuje okresowe linie BYTECOUNT_CLI niosące identyfikator klienta oraz skumulowane sumy bajtów w każdym kierunku, a polecenie bytecount ustala, jak często przychodzą. Z punktu widzenia serwera odebrana liczba liczy bajty wysłane przez klienta, a wysłana liczba liczy bajty mu dostarczone. Ustaw interwał na coś, co księga może wchłonąć; bardzo krótki interwał kupuje precyzję, której w rzeczywistości nie dostajesz.

Jedno ograniczenie kształtuje cały projekt: gniazdo zarządzania przyjmuje jedno połączenie sterujące. Eksporter monitoringu, GUI i twój kontroler nie mogą otworzyć każdy swojego. Zdecyduj, który proces posiada kanał, i pozwól pozostałym czytać z niego stan, bo ten interfejs daje działania administracyjne i tak czy inaczej nie powinien być wystawiany poza host.

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

Zatwierdź nowe linie bazowe i przyrost zużycia razem, żeby odtworzenie próbki nie naliczało niczego zamiast naliczać dwa razy. Licznik cofający się jest sygnałem, nie długiem: oznacza, że sesja została zastąpiona albo demon został zrestartowany, a poprawną odpowiedzią jest uzgodnienie tożsamości sesji, a nie zaksięgowanie kwoty ujemnej.

Ścieżka rozłączenia wymaga tej samej troski. Jeśli zdarzenie końcowe niesie sumy końca sesji, nalicz tylko różnicę względem ostatniej zatwierdzonej próbki. Dodanie pełnej sumy po tym, jak okresowe próbkowanie zostało już naliczone, to najczęstsze podwójne liczenie w domowych systemach limitów. Sesje przekraczające granicę okresu też potrzebują reguły, bo jedna suma końcowa nie niesie informacji, kiedy bajty przekroczyły północ.

Wyczerpanie ma odmawiać wstępu, a nie tylko zabijać tunel

Gdy konto osiąga swój limit, muszą się stać dwie rzeczy: istniejące sesje się kończą, a nowe są odrzucane. Protokół zarządzania oferuje client-kill po identyfikatorze klienta, co załatwia pierwszą połowę, o ile wyliczysz każdą żywą sesję konta, zamiast zabijać jeden adres, który przypadkiem zauważyłeś.

Druga połowa to miejsce, w którym projekty limitów zawodzą. Samo zabicie to wyścig z pętlą ponownego łączenia klienta, która chętnie wróci kilka sekund później. Wstęp musi konsultować współdzieloną księgę, a przy wdrożeniu z wieloma bramami ten test nie może być plikiem na maszynę. Każda instancja, która może przyjąć logowanie, musi widzieć ten sam stan wyczerpania.

Ponowne połączenia oparte na tokenie zasługują na własny test. OpenVPN 2.6 potrafi wewnętrznie zweryfikować token sesji przez auth-gen-token, pomijając zewnętrzne wywołanie uwierzytelniania, którego twój kontroler używał do egzekwowania limitu. Token, który nadal jest ważny, dowodzi więc tożsamości, a nie pozostałego limitu, i każda nowa instancja klienta nadal musi konsultować księgę. Jeśli zamiast tego włączysz management-client-auth, kontroler staje się uwierzytelniaczem i dziedziczy obowiązek samodzielnej analizy stanu sesji i odrzucania tokenów wygasłych lub nieprawidłowych.

Zaakceptuj przekroczenie, które tworzy próbkowanie

Okresowa obserwacja plus rozłączenie dają limit próbkowany o znanej tolerancji. Klient może przekroczyć o około jeden interwał raportowania plus czas potrzebny kontrolerowi na reakcję, a równoczesne sesje na jednym koncie mnożą to okno. Powiedz to w interfejsie, zamiast reklamować dokładne odcięcie na ostatnim bajcie, którego nie możesz dostarczyć.

Prawdziwy twardy pułap to inny problem inżynierski: egzekwowanie wewnątrz ścieżki przekazywania, powiązane z tym samym kontem przez sesje. Szybsze czytanie liczników nie jest tym samym i nie przetrwa klienta, który po prostu otwiera więcej tuneli.

Przed wdrożeniem uruchom przypadki akceptacyjne, które łamią naiwne implementacje: powtarzane ponowne połączenia, dwa urządzenia naraz, restarty kontrolera i bramy, utracone zdarzenie rozłączenia, przełączenie w środku sesji i próba ponownego połączenia tokenem zaraz po wyczerpaniu. Potem zdecyduj tryb awarii dla przerw w rozliczaniu. Trwała księga chroni zapisane zużycie; nie może wskrzesić obserwacji, które nigdy nie dotarły, a klient zasługuje na wiedzę, w której z tych dwóch sytuacji się znajduje.

Powiązane artykuły