Retornar una adreça des d'un script client-connect sembla que hauria d'establir la IP del client. No ho fa: l'únic canal del hook cap al servidor és un fitxer temporal el camí del qual arriba com a darrer argument de l'script, i l'adreça s'hi ha d'escriure amb la sintaxi ifconfig-push. Un script que imprimeix l'adreça o surt amb zero sense escriure res produeix un client connectat amb una adreça del pool, i el registre del servidor sembla perfectament sa.

La confusió és raonable, perquè diversos altres hooks sí que responen mitjançant codis de sortida o variables d'entorn. Aquest té el seu propi contracte, i el contracte comença amb un nom de fitxer.

El hook escriu un fitxer, no un valor de retorn

La declaració són dues línies: script-security 2 per permetre la crida, i després client-connect /etc/openvpn/server/assign-address.sh. Quan un client s'autentica, el servidor executa aquest script amb el camí del fitxer generat afegit com a darrer argument, que és $1 només si la declaració no hi passa arguments addicionals propis. Tot el que s'aplica a aquest client va en aquest fitxer com a directives ordinàries, una per línia, exactament com apareixerien en una configuració. Un embolcall que afegeix els seus propis paràmetres desplaça la posició, i el símptoma clàssic és un script que escriu en un camí que sembla --verbose.

L'estat de sortida és l'altra meitat del contracte. Zero vol dir accepta i llegeix el fitxer; qualsevol altra cosa rebutja la connexió, i així és com una identitat no assignada queda denegada en lloc de tornar-se silenciosament al pool. Escriviu la directiva completa abans de retornar èxit, perquè un fitxer mig escrit no esdevingui mai la configuració d'un client.

Dues directives mereixen atenció perquè interactuen amb tota la resta. ifconfig-push fixa l'adreça, mentre que una route enviada diu al client què és abastable a través del túnel; retorneu la primera i oblideu la segona i obteniu un client amb adreça i sense enlloc on anar. L'ordre dins del fitxer no importa, però la completesa sí. Un hook que envia una ruta per a un prefix al qual cap parell no pot arribar és el mateix error vist des de l'altre extrem.

Les entrades arriben per variables d'entorn: common_name, trusted_ip, ifconfig_pool_remote_ip i la resta. Tracteu-les totes com a cadenes de fora del servidor, mai com a fragments d'intèrpret d'ordres.

El mapatge d'adreces és una política, no aritmètica

Un drecera temptadora és analitzar el nom del certificat i fer servir els seus dígits com a darrer octet. Això no és un assignador, i falla de maneres ordinàries: dos noms amb el mateix sufix col·lideixen, un nom que acaba en 300 no és una adreça, i un certificat renombrat per un administrador mou un dispositiu en silenci. Valideu la pertinença a la subxarxa, el rang d'amfitrions utilitzable, les adreces reservades i la unicitat a cada crida, i manteniu el mapatge en una taula que una persona pugui llegir.

Qui controla el nom controla l'adreça, així que decidiu què representa realment common_name en aquest desplegament. Amb username-as-common-name activat, la identitat és l'inici de sessió i no el subjecte del certificat. No passeu mai aquest valor a l'avaluació de l'intèrpret d'ordres, i no deixeu mai que el client influeixi en un camí de fitxer.

Un assignador recolzat en un registre ha de sobreviure a la concurrència. Reserveu l'adreça atòmicament, gestioneu una escriptura fallida sense admetre un client mig configurat, i etiqueteu cada assignació amb la connexió que la posseeix, perquè una desconnexió tardana d'una sessió antiga no pugui alliberar una adreça que una de nova ja té. Diverses instàncies de servidor que comparteixen un pool fan aquest requisit més agut, no opcional.

La topologia decideix què significa ifconfig-push

Amb topology subnet a 10.77.0.0/24, ifconfig-push 10.77.0.20 255.255.255.0 és una adreça més la seva màscara de xarxa. Sota topology net30 el segon argument no és cap màscara sinó l'adreça del parell, de manera que copiar la forma de subxarxa en un servidor net30 us dona un client que s'associa i no pot passar trànsit. Canvieu la topologia deliberadament, mai perquè un exemple sembli coherent. Un servidor que ja funciona amb net30 té clients vius a l'adreçament antic, així que el canvi és una migració amb una finestra de manteniment, no una edició d'una línia.

Les adreces estàtiques han de quedar fora del pool dinàmic i fora de qualsevol altre assignament estàtic, incloses les que reparteixen fitxers client-config-dir ordinaris. Si dos mecanismes poden produir la mateixa adreça per a clients diferents, un d'ells ho acabarà fent.

Proveu quatre casos abans de confiar-hi

Executeu les mateixes comprovacions contra una identitat assignada, una de no assignada, una reconnexió i una fallada simulada del registre. openvpn --config client.ovpn --verb 4 mostra l'adreça assignada a la resposta push, i al servidor grep -A2 PUSH_REPLY /var/log/openvpn/openvpn.log confirma què s'ha enviat realment. Per a la identitat no assignada el resultat esperat és una connexió rebutjada, no una adreça del pool.

Després inspeccioneu el directori on el dimoni escriu aquests fitxers temporals. L'script s'executa en el context de servei degradat, així que un camí on root pot escriure però el dimoni no converteix cada connexió en un rebuig amb un error de permisos enterrat diverses línies més avall al registre.

Assignar no és autoritzar: una adreça fixada encara no dona accés a cada destinació darrere del servidor. Manteniu la política d'encaminament i tallafocs a la seva pròpia capa, i verifiqueu-la contra l'adreça que acabeu de fixar.

Articles relacionats