Empat puluh fail .ovpn untuk satu negara datang daripada pembekal, dan rancangannya kelihatan jelas: salin satu secara rawak ke tempatnya, kemudian mulakan terowong. Ditulis sebagai saluran paip di dalam ExecStart, rancangan itu mati semasa but dengan kod status yang tidak menerangkan apa-apa. Fail unit bukan skrip, dan pembaikannya ialah sama ada membawa shell masuk secara eksplisit atau berhenti memilih fail sama sekali.

Gejalanya: unit yang bermula dan terus mati

Status menunjukkan perkhidmatan gagal dalam sebahagian kecil saat, dan baris jurnal menamakan arahan yang tiada shell akan pernah terima. Tiada apa-apa tentang terowong muncul, kerana terowong itu tidak pernah bermula.

Membaca baris arahan yang tepat daripada jurnal ialah cara terpantas untuk mengesahkannya. systemd mengulangi apa yang dilaksanakannya, dan rentetan itu akan menunjukkan aksara saluran paip sebagai argumen literal dan bukan sebagai pengendali.

Mengapa ExecStart tidak boleh menjalankan saluran paip

systemd memecahkan baris arahan itu sendiri, menggunakan pengutipan dan penggantian pemboleh ubahnya sendiri, dan kemudian melaksanakan hasilnya secara langsung. Paip, pengubah halaan, pengembangan glob oleh shell dan penggantian arahan sememangnya bukan sebahagian daripada tatabahasa itu. Ini pilihan reka bentuk dan bukan ketinggalan: unit menyatakan secara deklaratif apa yang perlu dijalankan, dan logik shell tergolong dalam skrip yang dipanggil oleh unit. Kedua-dua pembaikan berpunca daripada itu, dan tidak satu pun memerlukan unit diberi lebih banyak keistimewaan.

Ia juga menerangkan kod keluar yang mengelirukan. Argumen pertama dianggap sebagai binari, jadi baris yang cacat gagal sebelum mana-mana bahagian logik anda berjalan.

Lakukan pemilihan dalam ExecStartPre

Pembaikan langsung ialah langkah persediaan yang memanggil shell secara eksplisit, menyimpan pemilihan dan permulaan dalam unit yang sama supaya kegagalan pada satu tidak membiarkan yang lain berjalan sendirian.

[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

Tiga perincian menentukan sama ada ini bertahan apabila berhadapan dengan mesin sebenar. Penamaan ialah perangkap pertama: systemd menggantikan %i semasa menghuraikan unit, jauh sebelum bash berjalan, jadi penentu itu mesti berada di luar tanda petik tunggal. xargs -r menghalang cp daripada berjalan tanpa argumen apabila glob tidak sepadan dengan apa-apa. Dan langkah persediaan yang gagal menghentikan unit, dan itulah hasil yang betul: bermula dengan konfigurasi semalam lebih buruk daripada tidak bermula. Pemilihan rawak yang sentiasa mengambil fail yang sama biasanya bukan nasib malang. Periksa sama ada fail yang disalin ditulis ganti oleh kemas kini pakej, atau sama ada glob hanya sepadan dengan satu entri lapuk.

Atau biarkan OpenVPN memilih titik akhir

OpenVPN sudah boleh menyimpan beberapa titik akhir dalam satu profil dan memilih antara mereka secara rawak, yang membuang shell, salinan dan akses tulis daripada laluan but sepenuhnya.

client
remote-random
<connection>
remote au1.example.net 1194 udp
</connection>
<connection>
remote au2.example.net 1194 udp
</connection>

Bentuk ini menyimpan pilihan pelayan di dalam fail yang ditulis oleh pembekal, jadi putaran yang menamakan semula fail tidak memecahkan unit. Ia juga menjadikan senarai calon boleh diaudit, yang tidak pernah berlaku pada glob ke atas direktori. Pengocokan masih berbaloi apabila profil berbeza dalam lebih daripada titik akhir: sijil berbeza, arahan penghalaan berbeza, dasar sifer berbeza. Dalam kes itu pilihan adalah antara konfigurasi penuh dan langkah shell ialah cara jujur untuk menyatakannya.

Baca semula instans dan fail yang digunakannya

Sahkan unit mana yang benar-benar berjalan sebelum nyahpepijat kandungannya. Perkhidmatan meta yang dibungkus dan templat ialah infrastruktur; unit yang sepadan dengan fail anda ialah instans yang dinamakan sempena fail itu.

systemctl list-units 'openvpn*'
systemctl cat [email protected]
journalctl -u openvpn@au -n 30 --no-pager

Instans yang tiada siapa ingat pernah mengaktifkannya biasanya mengesan kembali kepada fail konfigurasi tersesat dalam direktori pakej. Matikan instans bernama itu dan bukan templat, jika tidak, peningkatan pakej seterusnya akan membawanya kembali. Selepas perubahan, mulakan unit dan baca baris arahan yang dilaporkan jurnal, kemudian sahkan laluan konfigurasi yang benar-benar dibukanya. Satu pemeriksaan itu memisahkan pemilihan rawak yang berfungsi daripada perkhidmatan yang diam-diam menggunakan semula fail dari bulan lalu.

Artikel berkaitan