PrivateTmp: el hook va escriure el fitxer, però on ha anat?
Un espai temporal privat amaga el fitxer en lloc d’esborrar-lo. Comprova l’arrel del procés abans de canviar la unitat i després dona una ruta real a les dades compartides.
Els hooks informen d’èxit, i la mateixa ruta encara sembla buida des d’una shell. Totes dues afirmacions poden ser certes alhora, perquè un servei systemd pot viure en el seu propi espai de noms de muntatge amb un directori temporal privat. Un cop entès això, la pregunta interessant és si l’escriptura va arribar a tenir èxit.
Dos directoris temporals, una sola ruta
La configuració d’aïllament dona a la unitat una visió privada dels directoris temporals en lloc de fer-los només de lectura. Els processos fora de la unitat no poden veure què hi escriu, i tot el que deixa enrere es descarta quan la unitat s’atura. Per tant, una ruta impresa pel hook i una ruta comprovada des d’una shell poden referir-se a objectes diferents amb el mateix nom.
Això és un problema de visibilitat, i sembla un problema de pèrdua de dades. No s’ha esborrat res, perquè el fitxer és simplement en un espai de noms del qual la shell no és membre. La mateixa ordre es comporta diferent quan s’executa dins de la unitat, i aquesta és l’observació que normalment resol la discussió. Llegeix la configuració de la unitat abans de concloure res sobre l’escriptura.
Separa l’invisible de l’impossible d’escriure
Una escriptura correcta i una obertura fallida produeixen proves diferents, i aquesta distinció decideix la reparació. Si el hook diu que el fitxer s’ha creat però un lector extern no el troba, tens una qüestió d’espai de noms. Si el hook informa d’un error de permisos o d’una obertura fallida, el fitxer no s’ha escrit mai i cap canvi d’espai de noms ajudarà.
systemctl show [email protected] -p PrivateTmp -p User -p Group -p RuntimeDirectory
systemctl show [email protected] -p MainPID --value
sudo ls -l /proc/PID/root/tmp/client-stateLa ruta de l’arrel del procés exposa la pròpia visió del sistema de fitxers del servei, subjecta a les comprovacions de permisos sobre aquell procés mentre encara s’executa. Llegeix el registre de la unitat en la mateixa sessió, perquè un error d’escriptura i un fitxer absent es confonen fàcilment quan algú ja ha decidit la causa.
Dona a les dades compartides una ubicació explícita
Les dades que només necessita el servei pertanyen al seu directori temporal privat. Les dades que un altre procés ha de llegir necessiten una ruta definida per a tots dos, amb un propietari, un mode i una caducitat declarats. Decideix quin dels dos casos tens abans d’editar la unitat. La majoria d’aquests incidents vénen de tractar un fitxer privat com a compartit.
[Service]
RuntimeDirectory=openvpn-hook-office
RuntimeDirectoryMode=0750Un directori d’execució col·loca la carpeta sota l’àrea d’execució del sistema, la crea per a l’usuari i el grup configurats de la unitat i l’elimina quan la unitat s’atura. Afegeix-lo mitjançant un drop-in perquè la unitat del paquet quedi intacta, després recarrega el gestor i reinicia aquella instància, acceptant que els seus clients es tornaran a connectar.
Conserva qualsevol directori d’execució que la unitat instal·lada ja requereixi. Substituir la llista en lloc d’afegir-hi coses és una manera habitual de trencar una funció no relacionada que ningú relaciona amb el canvi.
Dues capes de privilegis poden no coincidir
El gestor de serveis crea el directori per a l’usuari configurat de la unitat, mentre que el dimoni VPN pot baixar per separat al seu propi compte abans d’executar un hook de connexió. Són capes diferents, i poden anomenar identitats diferents.
Un directori propietat de root amb un mode restrictiu és perfectament visible per a un dimoni que ja ha renunciat als privilegis, i tot i així no hi pot escriure. L’error es llegeix aleshores com un problema de permisos tot i que la ruta existeix exactament on esperaves. Compara el propietari del directori amb la identitat que informa el hook. Quan difereixen, el mode mai no era la pregunta.
Comprova la identitat amb què s’executa realment el hook abans de canviar la propietat. Canviar l’usuari d’execució del servei per arreglar un directori pot alterar l’accés als dispositius i els privilegis de xarxa en altres llocs, cosa que és un preu alt per a un problema petit.
Verifica tota la transferència
Confirma quatre coses alhora: el hook escriu sota la seva identitat real, el lector previst pot consumir el fitxer, els usuaris no relacionats no poden, i aturar la unitat neteja com s’ha dissenyat. Que aparegui un fitxer al directori temporal compartit de l’amfitrió no és cap requisit, i normalment és senyal que l’intercanvi no va obtenir mai la seva pròpia ruta. Prova el lector després d’un reinici, no només durant la primera execució. El comportament de neteja forma part del disseny, així que observa’l en lloc de suposar-lo.
L’estat persistent pertany a un lloc amb una vida útil equivalent, ja que un directori d’execució ha de desaparèixer. Tria la ubicació per la vida útil i no per la comoditat. Aquest hàbit evita la propera versió d’aquesta mateixa investigació.