Hazarda OpenVPN-elekto en systemd: kial ExecStart fiaskas
systemd ne estas ŝelo, do miksita kopio ene de ExecStart mortas. Movu la elekton al ExecStartPre, aŭ lasu OpenVPN mem elekti servilon.
Kvardek .ovpn-dosieroj por unu lando alvenas de provizanto, kaj la plano ŝajnas evidenta: kopiu hazardan en la ĝustan lokon, poste startigu la tunelon. Skribite kiel tubaro ene de ExecStart, tiu plano mortas ĉe la starto kun statuskodo, kiu klarigas nenion. La unuodosiero ne estas skripto, kaj la riparaĵo estas aŭ eksplicite enporti ŝelon aŭ tute ĉesi elekti dosierojn.
La simptomo: unuo, kiu startas kaj tuj mortas
La statuso montras, ke la servo fiaskis en frakcio de sekundo, kaj la protokola linio nomas komandon, kiun neniu ŝelo iam ricevus. Nenio pri la tunelo aperas, ĉar la tunelo neniam komenciĝis.
Legi la precizan komandlinion el la protokolo estas la plej rapida maniero konfirmi tion. systemd eĥas tion, kion ĝi ekzekutis, kaj la ĉeno montros la signojn de la tubaro kiel laŭvortajn argumentojn anstataŭ kiel operatorojn.
Kial ExecStart ne povas ruli tubaron
systemd mem dividas la komandlinion, aplikas sian propran citadon kaj anstataŭigon de variabloj, kaj poste ekzekutas la rezulton rekte. Tuboj, alidirektado, globa etendado fare de ŝelo kaj anstataŭigo de komandoj simple ne apartenas al tiu gramatiko. Ĝi estas projekta elekto, ne manko: unuo deklaras, kion ruli, kaj ŝela logiko apartenas al skripto, kiun la unuo vokas. Ambaŭ riparaĵoj sekvas el tio, kaj neniu postulas doni pli da privilegioj al la unuo.
Ĝi ankaŭ klarigas la misgvidan elirkodon. La unua argumento estas traktata kiel la duumaĵo, do misformita linio fiaskas antaŭ ol io ajn el via logiko ruliĝas.
Faru la elekton en ExecStartPre
La rekta riparaĵo estas prepara paŝo, kiu eksplicite vokas ŝelon, tenante la elekton kaj la starton en la sama unuo, por ke fiasko en unu ne lasu la alian ruliĝi sola.
[Service]
Type=notify
ExecStartPre=/bin/bash -c "ls /etc/openvpn/profiles/au* | shuf -n 1 | xargs -r -I{} cp -f {} /etc/openvpn/%i.conf"
ExecStart=/usr/sbin/openvpn --config /etc/openvpn/%i.conf
Tri detaloj decidas, ĉu tio postvivos renkonton kun reala maŝino. Nomado estas la unua kaptilo: systemd anstataŭigas %i dum la analizo de la unuo, longe antaŭ ol bash ruliĝas, do la specifilo devas stari ekster unuoblaj citiloj. xargs -r malhelpas, ke cp ruliĝu sen argumento, kiam la globo kongruas kun nenio. Kaj fiaska prepara paŝo haltigas la unuon, kaj tio estas la ĝusta rezulto: starti kun la hieraŭa agordo estas pli malbone ol ne starti. Hazarda elekto, kiu ĉiam prenas la saman dosieron, kutime ne estas malbona sorto. Kontrolu, ĉu la kopiita dosiero estas superskribata de pakaĵa ĝisdatigo, aŭ ĉu la globo kongruas nur kun unu kaduka enskribo.
Aŭ lasu OpenVPN elekti la finpunkton
OpenVPN jam povas teni plurajn finpunktojn en unu profilo kaj hazarde elekti inter ili, kio tute forigas la ŝelon, la kopiadon kaj la skribpermeson el la starta vojo.
client
remote-random
<connection>
remote au1.example.net 1194 udp
</connection>
<connection>
remote au2.example.net 1194 udp
</connection>
Ĉi tiu formo tenas la servilelekton ene de la dosiero, kiun verkis la provizanto, do rotacio, kiu renomas dosierojn, ne rompas la unuon. Ĝi ankaŭ igas la kandidataran liston aŭdeblan, kion globo super dosierujo neniam faras. La miksado ankoraŭ meritas sian lokon, kiam profilo diferencas en pli ol finpunkto: malsamaj atestiloj, malsamaj enkursigaj direktivoj, malsama ĉifra politiko. En tiu kazo la elekto estas inter tutaj agordoj, kaj ŝela paŝo estas la honesta maniero esprimi tion.
Legi returne la instancon kaj la dosieron, kiun ĝi uzis
Konfirmu, kiu unuo efektive ruliĝas, antaŭ ol sencimigi ĝian enhavon. La pakaĵa meta-servo kaj la ŝablono estas infrastrukturo; la unuoj respondaj al viaj dosieroj estas la instancoj nomitaj laŭ ili.
systemctl list-units 'openvpn*'
systemctl cat [email protected]
journalctl -u openvpn@au -n 30 --no-pager
Instanco, kiun neniu memoras ŝaltinta, kutime devenas de vaganta agorda dosiero en la pakaĵa dosierujo. Malŝaltu tiun nomitan instancon anstataŭ la ŝablonon, alie la sekva pakaĵa ĝisdatigo revenigos ĝin. Post la ŝanĝo, startigu la unuon kaj legu la komandlinion, kiun la protokolo raportas, poste konfirmu la agordan vojon, kiun ĝi efektive malfermis. Tiu unu kontrolo apartigas funkciantan hazardan elekton de servo, kiu silente reuzas dosieron el la pasinta monato.