Waktu aktif yang panjang hanya membuktikan bahwa proses start berhasil dengan hak istimewa yang dimiliki daemon pada saat itu. Kegagalan yang penting di sini datang kemudian: klien baru terhubung, daftar pencabutan diganti, skrip bantu perlu menulis berkas. Masing-masing adalah pembukaan baru yang dilakukan oleh akun tanpa hak istimewa, dengan pertanyaan izinnya sendiri dan pesan galatnya sendiri. Tiga keputusan memisahkan konfigurasi yang terus berfungsi dari yang gagal pada peristiwa berikutnya.

Pisahkan yang dimuat lebih awal dari yang dibuka kemudian

Deskriptor adalah pegangan pada deskripsi berkas yang terbuka, dan mode akses ditetapkan saat deskripsi itu dibuat. Mengubah pengguna proses sesudahnya tidak menutup pegangan, karena itu berkas kunci yang dibaca sebagai root tetap berfungsi setelah penurunan. Modenya pun tidak berubah: pegangan yang dibuka untuk membaca tidak menjadi dapat ditulis, dan pegangan yang dapat ditulis tidak dicabut hanya karena akun kehilangan haknya atas jalur tersebut. Kedua fakta ini menjelaskan sebagian besar perilaku mengejutkan dalam laporan-laporan ini.

Separuh lainnya adalah memori. Daemon dapat mengurai sertifikat, menyimpan bahan yang sudah diurai, dan menutup berkasnya; yang tetap dipakai adalah data, bukan berkas terbuka. Jadi lalu lintas yang berlanjut tidak membuktikan bahwa sebuah deskriptor terbuka maupun bahwa nama jalurnya dapat dijangkau. Itu hanya membuktikan bahwa bahan yang dibutuhkan sesi saat ini diperoleh sebelumnya.

Pembukaan berikutnya adalah transaksi lain. Ia berjalan dengan kredensial saat ini, konteks keamanan saat ini, dan tampilan pemasangan saat ini, sehingga jalur yang terbaca saat start dapat ditolak pada koneksi berikutnya. Rotasi menambah jebakan: menulis berkas baru pada nama jalur yang sama meninggalkan deskriptor yang ada tetap terikat pada objek lama, sehingga pemuatan ulang dapat tampak berhasil sementara daemon masih memakai isi sebelumnya. Bandingkan inode yang dipegang proses dengan yang ada di disk sebelum mempercayai bahwa rotasi berlaku.

Sebutkan tiga pembacaan runtime dan kapan masing-masing terjadi

Tiga sumber daya biasanya dibuka jauh setelah inisialisasi, dan gagal pada saat yang berbeda. Berkas konfigurasi khusus klien dibaca ketika klien itu terhubung, sehingga dapat rusak bagi satu pengguna sementara yang lain berjalan terus. Data pencabutan diperiksa saat autentikasi peering dan lagi ketika berkasnya diganti. Direktori sementara hanya disentuh ketika skrip atau plugin menulis sesuatu.

Tidak satu pun dari ketiganya termasuk jalur start, karena itu server yang sehat selama berminggu-minggu dapat gagal pada koneksi berikutnya. Kategori ini juga menyebut pemilik perbaikannya: dua yang pertama adalah izin baca pada konfigurasi di bawah akun daemon, dan yang ketiga adalah lokasi yang dapat ditulis dengan tujuan sempit.

Path reopened laterWhat triggers the openFirst sign when it fails
Client configuration fileA connection for that client identityOne client rejected while others connect
Revocation dataPeer authentication, including after replacementRevoked and valid peers both refused
Script or plugin temporary directoryA helper needs to create a fileThe helper exits with a path error

persist-key menjawab pertanyaan yang lebih sempit daripada dugaan kebanyakan orang. Ia menjaga berkas kunci tetap terbuka selama reset SIGUSR1 dan ping-restart yang didokumentasikan, dan ia tidak melakukan apa pun untuk berkas CCD, data pencabutan, berkas eksekusi pembantu, atau start ulang proses secara penuh. Semuanya tetap mengikuti jalur pembukaannya sendiri, di bawah akun mana pun yang berjalan saat itu.

Pastikan akun dan tampilan yang sebenarnya dimilikinya

Tanyakan kepada daemon yang berjalan akun mana yang dipakainya alih-alih memercayai berkas unit, lalu bandingkan jawabannya dengan yang ditetapkan unit. Ketidakcocokan adalah hal pertama yang harus diselesaikan, karena setiap pemeriksaan izin berikutnya berjalan sebagai siapa proses itu sebenarnya. Lalu telusuri jalur itu komponen demi komponen; penelusuran dinilai pada setiap tingkat, sehingga berkas yang terbaca di dalam direktori yang tidak dapat ditembus tetap tidak terbaca. Mode akhir berkas adalah pertanyaan terakhir, bukan yang pertama.

Namespace dan kotak pasir layanan menambahkan batas yang tidak dijelaskan kepemilikan dan bit mode. Jalur yang terlihat di shell Anda bisa tidak ada atau hanya-baca di dalam chroot, namespace pemasangan, atau unit yang menyembunyikan direktori rumah. Modul keamanan menambah satu lapisan lagi, sehingga berkas yang tampak terbaca masih dapat ditolak saat dibuka.

ps -o user:12,pid,args -C openvpn
systemctl show -p User -p Group -p ProtectHome -p RootDirectory [email protected]
sudo -u openvpn namei -l /etc/openvpn/ccd/alice

Pembacaan yang berhasil di shell administrator tidak menguji satu pun dari syarat gabungan itu. Jalankan pemeriksaan sebagai akun daemon, dengan namespace dan kotak pasir yang sama, atau terima bahwa hasilnya menggambarkan shell Anda dan bukan server. Perintah ketiga adalah versi murah dari uji itu: ia mencetak mode setiap komponen dan gagal pada komponen pertama yang tidak dapat ditembus akun daemon.

Beri penulisan runtime direktori sendiri

Pembacaan hanyalah separuh daftar. Skrip pembantu mungkin perlu membuat berkas status, plugin mungkin perlu menulis keadaan di samping konfigurasinya, dan penulisan itu tidak tercakup oleh menjadikan pohon konfigurasi dapat ditulis. Beri direktori tertentu izin tulis yang dibutuhkan fungsinya, dengan pemilik dan mode yang dapat Anda jelaskan. Utamakan akses hanya-baca untuk semua yang hanya dibaca.

Pisahkan izin kunci privat dari berkas kebijakan. Kunci yang harus dibaca ulang setelah reset punya syarat berbeda dari berkas klien yang dibaca pada setiap koneksi, dan satu mode longgar untuk keduanya memberi akses lebih daripada yang diminta masalah. Akun daemon khusus dengan kepemilikan sempit lebih mudah diaudit daripada grup luas. Ketika kunci harus bertahan melewati reset, persist-key menghapus pembacaan ulang alih-alih memperlebar direktori.

Putuskan dari peristiwa yang dapat Anda ulang

Tunnel yang hidup membuktikan satu jalur di dalam kode. Peristiwa yang membutuhkan berkas itu adalah satu-satunya uji yang mencakup pembukaan yang Anda pedulikan, entah itu koneksi klien baru, berkas pencabutan yang diganti, reset lunak yang diizinkan, atau start ulang yang direncanakan. Pilih peristiwanya, jalankan, dan simpan galat pertama, bukan yang terakhir.

Untuk reset lunak, satu sinyal dan log unit menunjukkan apakah kunci dibaca ulang. Kirim sinyalnya, lalu baca baris terakhir yang ditulis unit:

systemctl kill -s SIGUSR1 [email protected]
journalctl -u [email protected] -n 40 --no-pager

Jangan menyimpulkan bahwa daemon yang disusupi tidak lagi dapat mengubah berkas hanya karena hak istimewanya diturunkan. Apa yang masih bisa dilakukannya bergantung pada kredensial yang tersisa, kemampuannya, direktori yang dapat ditulisinya, dan deskriptor dapat-tulis mana pun yang masih dipegangnya. Penurunan hak istimewa mempersempit kewenangan, dan daftar pembukaan runtime itulah yang menunjukkan seberapa jauh. Tuliskan batas itu di samping konfigurasi agar orang berikutnya tidak perlu menemukannya lagi.

Artikel terkait