Una cuota que se reinicia cada vez que el túnel se reconecta no es un límite, y eso es exactamente lo que se obtiene cuando se atornilla un contador de bytes a un servidor VPN sin un lugar donde guardar estado duradero. El contador pertenece a una sesión; la cuota pertenece a una persona o a un contrato de dispositivo. Toda la dificultad de la función viene de ese desajuste, así que las comprobaciones de abajo tratan de dónde vive el estado y qué capa tiene permiso para decidir.

Fije la cuota a una cuenta, no a un túnel

Empiece por nombrar el sujeto de la cuota. Una persona puede tener tres certificados de dispositivo, y ninguno debería recibir un presupuesto mensual independiente solo porque se autentican por separado. Un identificador de cuenta estable que sobreviva a reconexiones, nuevas direcciones de túnel y un traslado a una segunda puerta de enlace es el único ancla que puede usar una cuota. El nombre común de un certificado sirve como esa clave solo cuando su política de emisión garantiza una cuenta por nombre.

Una dirección de túnel asignada nunca es la respuesta. Las direcciones se reciclan, las agrupaciones se comparten y la misma cuenta puede aparecer dos veces en dos puertas de enlace en el mismo minuto. Si el libro mayor se basa en una dirección, desconectar y volver a conectar basta para rellenar el depósito.

Registre lo suficiente por sesión para que la aritmética sea auditable: la cuenta, el periodo de facturación, la instancia de la puerta de enlace, la identidad de la sesión, los últimos contadores observados y el total comprometido. Incluya una generación de arranque del demonio en la identidad de la sesión, porque un servidor reiniciado reutiliza identificadores de cliente y una correspondencia ingenua heredaría la línea base anterior.

Fije la unidad, la dirección y el límite de reinicio

Hay que fijar cuatro definiciones por escrito antes de que empiece cualquier recogida. ¿La cuota cuenta los bytes que el cliente envía, los que recibe o la suma de ambos? ¿Un gigabyte son 10^9 bytes o 2^30? ¿A qué hora local y en qué zona horaria cambia el periodo? Y ¿qué mide exactamente el contador, dado que la sobrecarga del túnel y las retransmisiones están incluidas mientras que el tamaño del archivo de la aplicación y la factura de un proveedor no?

Ninguna de esas elecciones es errónea, pero la implementación y el número que ve el cliente deben coincidir. Dos mitades del mismo sistema que discrepan sobre GiB, o sobre un cambio que ocurre a medianoche UTC en lugar de la hora local, producen exactamente la clase de ticket que erosiona la confianza en toda la cuota.

Convierta los totales de bytes en un solo delta cobrado

La interfaz de gestión informa líneas BYTECOUNT_CLI periódicas que llevan un identificador de cliente más totales acumulados de bytes en cada dirección, y la orden bytecount fija con qué frecuencia llegan. Desde el punto de vista del servidor, la cifra recibida cuenta los bytes que el cliente ha enviado y la cifra enviada cuenta los bytes entregados a él. Fije el intervalo en algo que el libro mayor pueda absorber; un intervalo muy corto compra una precisión que en realidad no se obtiene.

Una restricción da forma a todo el diseño: el socket de gestión acepta una única conexión de control. Un exportador de monitorización, una GUI y su controlador no pueden abrir cada uno la suya. Decida qué proceso posee el canal y deje que los demás lean el estado de él, porque esta interfaz concede acciones administrativas y en cualquier caso no debería exponerse fuera del 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

Comprometa las nuevas líneas base y el incremento de uso a la vez, para que reproducir una muestra no cobre nada en lugar de cobrar dos veces. Un contador que retrocede es una señal, no una deuda: significa que la sesión se sustituyó o que el demonio se reinició, y la respuesta correcta es reconciliar la identidad de la sesión en lugar de abonar un importe negativo.

La ruta de desconexión necesita el mismo cuidado. Si un evento final lleva totales de fin de sesión, cobre solo la diferencia respecto de la última muestra comprometida. Añadir el total completo después de que el muestreo periódico ya se haya cobrado es el doble cómputo más habitual en los sistemas de cuota caseros. Las sesiones que cruzan un límite de periodo también necesitan una regla, ya que un solo total final no lleva información sobre cuándo los bytes cruzaron la medianoche.

Haga que el agotamiento deniegue la admisión, no solo que mate el túnel

Cuando una cuenta alcanza su límite, deben ocurrir dos cosas: las sesiones existentes terminan y las nuevas se rechazan. El protocolo de gestión ofrece client-kill por identificador de cliente, lo que resuelve la primera mitad siempre que enumere cada sesión viva de la cuenta en lugar de matar la única dirección que se fijó.

La segunda mitad es donde fallan los diseños de cuota. Una muerte por sí sola es una carrera contra el bucle de reconexión del cliente, que volverá encantado unos segundos después. La admisión debe consultar el libro mayor compartido, y en un despliegue con varias puertas de enlace esa comprobación no puede ser un archivo por máquina. Cada instancia que pueda aceptar un inicio de sesión debe ver el mismo estado agotado.

Las reconexiones basadas en testigos merecen su propia prueba. OpenVPN 2.6 puede validar un testigo de sesión internamente con auth-gen-token, saltándose la llamada de autenticación externa que su controlador usaba para imponer el tope. Un testigo que sigue siendo válido, por tanto, demuestra identidad, no cuota restante, y cada nueva instancia de cliente debe seguir consultando el libro mayor. Si activa management-client-auth en su lugar, el controlador se convierte en autenticador y hereda la obligación de analizar el estado de la sesión y rechazar testigos caducados o inválidos por su cuenta.

Acepte el exceso que crea el muestreo

La observación periódica más la desconexión le dan una cuota muestreada con una tolerancia conocida. Un cliente puede excederse en aproximadamente un intervalo de informe más el tiempo que tarda el controlador en actuar, y las sesiones concurrentes en una cuenta multiplican esa ventana. Dígalo en la interfaz en lugar de anunciar un corte exacto en el último byte que no puede entregar.

Un techo duro de verdad es otro problema de ingeniería: aplicación dentro de la ruta de reenvío, ligada a la misma cuenta a través de las sesiones. Leer los contadores más rápido no es lo mismo, y no sobrevive a un cliente que simplemente abre más túneles.

Antes del despliegue, ejecute los casos de aceptación que rompen las implementaciones ingenuas: reconexiones repetidas, dos dispositivos a la vez, reinicios del controlador y de la puerta de enlace, un evento de desconexión perdido, un cambio a mitad de sesión y un intento de reconexión con testigo justo después del agotamiento. Después decida el modo de fallo para las interrupciones de contabilidad. Un libro mayor duradero protege el uso que registró; no puede resucitar observaciones que nunca llegaron, y el cliente merece saber en cuál de esas dos situaciones está.

Artículos relacionados