Unde se plasează o limită lunară de date pentru fiecare cont OpenVPN
O limită care se resetează la fiecare reconectare nu este o limitare. Urmăriți consumul pe cont, taxați fiecare diferență de octeți o singură dată și faceți epuizarea să blocheze admiterea.
O limită care se resetează de fiecare dată când tunelul se reconectează nu este o limitare, și exact asta se obține când un contor de octeți este înșurubat pe un server VPN fără un loc unde să păstreze stare durabilă. Contorul aparține unei sesiuni; limita aparține unei persoane sau unui contract de dispozitiv. Toată dificultatea funcției vine din această nepotrivire, așa că verificările de mai jos privesc unde locuiește starea și ce strat are voie să decidă.
Legați limita de un cont, nu de un tunel
Începeți prin a numi subiectul limitei. O persoană poate deține trei certificate de dispozitiv, și niciunul nu ar trebui să primească un buget lunar independent doar pentru că se autentifică separat. Un identificator de cont stabil care supraviețuiește reconectărilor, adreselor noi de tunel și mutării pe o a doua poartă este singura ancoră pe care o poate folosi o limită. Numele comun al unui certificat funcționează ca acea cheie doar când politica dvs. de emitere garantează un cont pe nume.
O adresă de tunel atribuită nu este niciodată răspunsul. Adresele sunt reciclate, pool-urile sunt partajate, iar același cont poate apărea de două ori pe două porți în același minut. Dacă registrul se bazează pe o adresă, deconectarea și reconectarea sunt suficiente pentru a umple din nou rezervorul.
Înregistrați suficient pe sesiune pentru ca aritmetica să fie auditabilă: contul, perioada de facturare, instanța porții, identitatea sesiunii, ultimii contoare observate și totalul angajat. Includeți o generație de pornire a demonului în identitatea sesiunii, pentru că un server repornit refolosește ID-urile de client, iar o potrivire naivă ar moșteni linia de bază anterioară.
Stabiliți unitatea, direcția și granița de resetare
Patru definiții trebuie stabilite în scris înainte de a începe orice colectare. Limita numără octeții pe care clientul îi trimite, pe cei pe care îi primește sau suma ambelor? Un gigabyte este 10^9 octeți sau 2^30? La ce oră locală și în ce fus orar se întoarce perioada? Și ce anume măsoară contorul, dat fiind că suprasarcina tunelului și retransmisiile sunt incluse, în timp ce dimensiunea fișierului aplicației și factura unui furnizor nu sunt?
Nicio dintre aceste alegeri nu este greșită, dar implementarea și numărul pe care clientul îl vede trebuie să fie de acord. Două jumătăți ale aceluiași sistem care nu sunt de acord asupra GiB, sau asupra unei schimbări care are loc la miezul nopții UTC în loc de ora locală, produc exact tipul de tichet care erodează încrederea în întreaga limită.
Transformați totalurile de octeți într-o singură diferență taxată
Interfața de administrare raportează linii BYTECOUNT_CLI periodice care poartă un ID de client plus totaluri cumulative de octeți în fiecare direcție, iar comanda bytecount stabilește cât de des ajung acestea. Din punctul de vedere al serverului, cifra primită numără octeții trimiși de client, iar cifra trimisă numără octeții livrați acestuia. Setați intervalul la ceva ce registrul poate absorbi; un interval foarte scurt cumpără o precizie pe care de fapt nu o obțineți.
O singură constrângere modelează întregul design: socketul de administrare acceptă o singură conexiune de control. Un exportator de monitorizare, o interfață grafică și controllerul dvs. nu pot deschide fiecare pe a sa. Decideți ce proces deține canalul și lăsați celelalte să citească starea din el, pentru că această interfață acordă acțiuni administrative și oricum nu ar trebui expusă în afara gazdei.
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
Angajați împreună noile linii de bază și creșterea de consum, astfel încât reluarea unei probe să nu taxeze nimic în loc să taxeze de două ori. Un contor care merge înapoi este un semnal, nu o datorie: înseamnă că sesiunea a fost înlocuită sau că demonul a fost repornit, iar răspunsul corect este să reconciliați identitatea sesiunii în loc să creditați o sumă negativă.
Calea de deconectare necesită aceeași grijă. Dacă un eveniment final poartă totaluri de sfârșit de sesiune, taxați doar diferența față de ultima probă angajată. Adăugarea totalului complet după ce eșantionarea periodică a fost deja taxată este cea mai frecventă dublă numărare în sistemele de limită făcute acasă. Sesiunile care traversează o graniță de perioadă au nevoie și ele de o regulă, deoarece un singur total final nu poartă informații despre când octeții au trecut de miezul nopții.
Epuizarea să refuze admiterea, nu doar să omoare tunelul
Când un cont atinge limita, trebuie să se întâmple două lucruri: sesiunile existente se termină, iar cele noi sunt refuzate. Protocolul de administrare oferă client-kill după ID-ul de client, ceea ce rezolvă prima jumătate atâta timp cât enumerați fiecare sesiune vie a contului în loc să ucideți singura adresă pe care ați observat-o din întâmplare.
A doua jumătate este locul unde designurile de limită eșuează. Doar uciderea este o cursă cu bucla de reconectare a clientului, care va reveni bucuros câteva secunde mai târziu. Admiterea trebuie să consulte registrul partajat, iar într-o implementare cu mai multe porți acea verificare nu poate fi un fișier pe mașină. Fiecare instanță care poate accepta o autentificare trebuie să vadă aceeași stare epuizată.
Reconectările bazate pe token merită propriul test. OpenVPN 2.6 poate valida un token de sesiune intern cu auth-gen-token, sărind peste apelul de autentificare extern pe care controllerul dvs. îl folosea pentru a impune plafonul. Un token încă valid dovedește deci identitatea, nu limita rămasă, iar fiecare instanță nouă de client trebuie să consulte în continuare registrul. Dacă activați în schimb management-client-auth, controllerul devine autentificatorul și moștenește obligația de a analiza singur starea sesiunii și de a refuza tokenurile expirate sau invalide.
Acceptați depășirea pe care o creează eșantionarea
Observarea periodică plus deconectarea vă oferă o limită eșantionată cu o toleranță cunoscută. Un client poate depăși cu aproximativ un interval de raportare plus timpul de care are nevoie controllerul pentru a acționa, iar sesiunile concurente pe un cont multiplică acea fereastră. Spuneți asta în interfață în loc să anunțați o tăiere exactă la ultimul octet pe care nu o puteți livra.
Un plafon dur real este o altă problemă de inginerie: aplicarea în interiorul căii de forwardare, legată de același cont de-a lungul sesiunilor. Citirea contoarelor mai rapid nu este același lucru și nu rezistă unui client care pur și simplu deschide mai multe tuneluri.
Înainte de lansare, rulați cazurile de acceptare care sparg implementările naive: reconectări repetate, două dispozitive simultan, reporniri ale controllerului și ale porții, un eveniment de deconectare pierdut, o schimbare la mijlocul sesiunii și o încercare de reconectare cu token imediat după epuizare. Apoi decideți modul de eșec pentru întreruperile contabilității. Un registru durabil protejează consumul pe care l-ați înregistrat; nu poate învia observații care nu au ajuns niciodată, iar clientul merită să știe în care dintre cele două situații se află.