Playbook päättyy vihreänä, WireGuard-yksikkö on aktiivinen, handshake toimii, eikä uusi peer silti tavoita mitään. Kun playbook ilmoittaa onnistumisesta samalla kun palvelin ajaa eilistä konfiguraatiota, se on erityisen turhauttavaa, koska tulosteessa ei ole mitään väärää. Ansible teki täsmälleen mitä pyydettiin: se varmisti, että yksikkö on käynnistetty, ja yksikkö oli jo käynnistetty. Uudelleen kirjoitetun konfiguraatiotiedoston käyttöönotto on eri tehtävä, ja se tapahtuu vain, jos jokin käskee palvelun lukea sen uudelleen.

Katso, mitä toinen ajo todella raportoi

Aja playbook kahdesti muutetulla konfiguraatiolla ja vertaa yhteenvetoa. Toisen ajon pitäisi näyttää yksikön tehtävä ok eikä changed, koska jo käynnissä oleva palvelu jätetään suunnittelun mukaan rauhaan. Se on idempotenssia, joka toimii oikein, ja samalla syy siihen, miksi uusi tiedosto ei koskaan saavuta kerneliä.

Lisää diff-tulosteinen tarkistusajo nähdäksesi, mitkä tehtävät ylipäätään koskettaisivat jotain.

ansible-playbook -i inventory site.yml --check --diff
systemctl show wg-quick@wg0 -p ActiveEnterTimestamp -p NRestarts
stat -c '%y %n' /etc/wireguard/wg0.conf

Kolme aikaleimaa kertovat tarinan ennen kuin luet yhtäkään lokiriviä. Jos konfiguraatiotiedosto on uudempi kuin hetki, jolloin yksikkö aktivoitui, käynnissä oleva liitäntä rakennettiin vanhemmasta tiedostosta ja kaikki myöhemmät oireet johtuvat siitä.

Tämä ei ole Ansiblen vika. Sama käytös näkyy jokaisessa konfiguraationhallintatyökalussa, joka erottaa »varmista, että se on käynnissä» ja »varmista, että se on käynnissä tällä». Ero näyttää pedanttiselta, kunnes se maksaa iltapäivän.

Käynnistetty on tila, ei uudelleenlataus

state: started väittää yksikköä koskevan ehdon. Se ei lupaa, että palvelu lukee syötteensä uudelleen, eikä voi tietää, että tiedosto, jota se ei koskaan avannut, on muuttunut. wg-quick-käyttöönotossa syötteisiin kuuluvat liitännän konfiguraatio, osoitteet, reitit, DNS-tietueet ja mahdolliset post-up-koukut.

Siksi päivitetty tiedosto voi sisältää uuden peerin, toisen osoitteen tai muutetun reititysdirektiivin, kun taas käynnissä oleva liitäntä palvelee edelleen vanhaa joukkoa. Handshake onnistuu yhä, koska ladatut avaimet ja päätepisteet ovat vielä voimassa. Juuri se tekee viasta vaikeasti havaittavan ja selittää, miksi ihmiset jahtaavat DNS:ää tunnin ennen aikaleiman tarkistamista.

Kaksi muuta moduulivalintaa luullaan usein ratkaisuksi. daemon_reload saa systemdin lukemaan yksikkötiedostot uudelleen, millä ei ole merkitystä WireGuardin konfiguraatiotiedostolle. state: reloaded pyytää yksikköä suorittamaan uudelleenlataustoimintonsa, ja se, tekeekö se tarvitsemasi, riippuu täysin yksiköstä. Kumpikaan ei korvaa tietoa siitä, mitkä syötteet käynnissä oleva prosessi todella luki.

Asenna tiedosto ja ilmoita sitten handlerille

Malli, joka säilyttää idempotenssin ja silti soveltaa muutokset, on tavallinen: tiedoston kirjoittava tehtävä ilmoittaa handlerille, ja handler ajetaan vain, kun tiedosto todella muuttui. Toinen ajo ilman muutoksia ei tee mitään, ja sitä sinä haluat.

- name: write the interface configuration
  ansible.builtin.template:
    src: wg0.conf.j2
    dest: /etc/wireguard/wg0.conf
    owner: root
    mode: "0600"
  notify: apply wg0

- name: ensure the interface unit is enabled
  ansible.builtin.systemd_service:
    name: wg-quick@wg0
    enabled: true
    state: started

- name: apply wg0
  listen: apply wg0
  ansible.builtin.systemd_service:
    name: wg-quick@wg0
    state: restarted

Handlerit ajetaan playn lopussa, niitä ilmoittaneiden tehtävien jälkeen, joten myöhempi tehtävä samassa playssä voi nähdä yhä vanhan liitännän. Jos järjestyksellä on väliä, tyhjennä handlerit eksplisiittisesti komennolla meta: flush_handlers ennen tehtävää, joka riippuu uudesta konfiguraatiosta.

Käytä restartia reloadin sijaan, ellet ole varmistanut yksikön uudelleenlataustoimintoa. Ylävirran wg-quick-yksikkö tukee sellaista ja synkronoi WireGuardin konfiguraation, mutta ei aja uudelleen osoite-, reitti-, DNS- tai koukkumäärityksiä. Siksi reload reittidirektiivin lisäämisen jälkeen näyttää onnistuvan eikä muuta mitään.

Vertaa käynnissä olevaa laitetta tiedostoon

Tämän virheluokan sulkeva tarkistus on vertailu sen välillä, mitä kerneli pitää ja mitä tiedosto sanoo. Kaksi komentoa tuottaa vertailukelpoisen tulosteen, ja ero on poikkeama.

sudo wg showconf wg0
sudo wg-quick strip wg0
sudo diff <(sudo wg showconf wg0) <(sudo wg-quick strip wg0)

wg showconf tulostaa käynnissä olevan laitteen, myös yksityisen avaimen, joten kohtele tulostetta salaisuutena äläkä liitä sitä tikettiin. wg-quick strip tulostaa tiedoston ilman vain wg-quickille ominaisia avaimia, ja siksi nämä kaksi ylipäätään ovat vertailukelpoisia.

Ero peer-luettelossa tarkoittaa, ettei tiedostoa koskaan otettu käyttöön. Ero vain avaimissa tai päätepisteissä, joiden odotit muuttuvan, tarkoittaa, että jokin otti sen osittain käyttöön. Ei eroa tarkoittaa, että konfiguraatio on ajan tasalla ja vika on muualla, mikä itsessään on hyödyllinen tulos.

Maksa uudelleenkäynnistyksen hinta tietoisesti

Liitännän uudelleenkäynnistys pudottaa tunnelin, ja jos se kuljettaa hallintasessiotasi, käynnistys päättää session, joka sitä pyysi. Laita handler muutosikkunan taakse tai aja playbook hallintapolkua, joka ei riipu liitännän uudelleenkäynnistyksestä.

Hinta on syy, miksi ihmiset tarttuvat reloadiin. Se on järkevä vaisto ja muuttuu oikeaksi, kun tiedät, mitkä muutokset reload todella soveltaa. Ylävirran wg-quick-yksikössä se riittää peer- ja avainmuutoksiin; osoitteistukseen, reititykseen ja koukkuihin ei. Asian selvittäminen kerran on halvempaa kuin sen löytäminen muutosikkunan aikana.

systemd_service-moduulin dokumentaatio selittää eron started, restarted ja reloaded välillä, ja se kannattaa lukea kerran sen sijaan, että arvaisi vihreästä yhteenvedosta. Kaikki tässä läpikäynnissä seuraa tuosta yhdestä erosta.

Aiheeseen liittyvät artikkelit