Semuanya berjalan sampai runner build membutuhkan soket host yang sama dengan yang dipakai tamu VPN, dan saat itu tidak ada yang bisa menjelaskan mengapa sebuah pekerjaan dapat membaca kunci gateway. Semuanya dipasang di satu mesin karena muat, dan setiap tamu diberi akses luas karena itu cara tercepat membuatnya berjalan. Hasilnya adalah host yang batas kepercayaannya adalah kabel listrik. Memisahkan peran membutuhkan lebih sedikit kerja daripada kedengarannya, dan dimulai dengan memberi nama peran itu.

Tiga peran yang saat ini berbagi segalanya

Entri VPN, sekumpulan layanan privat, dan runner build menginginkan hal yang berbeda. Yang pertama membutuhkan port publik dan jaringan sempit di sisi privat. Yang kedua membutuhkan penyimpanan persisten dan rahasia aplikasi. Yang ketiga menjalankan kode yang ditulis orang lain.

Memberi ketiganya akses yang sama itulah yang membuat gejalanya membingungkan, karena kemudian salah satu dari mereka dapat memengaruhi yang lain. Pekerjaan build yang dapat menjangkau soket hypervisor adalah pekerjaan yang dapat menghentikan VPN. Tamu layanan dengan rute ke jaringan manajemen dapat mengubah konfigurasi switch. Hak istimewa adalah masalahnya, dan daftar proses hanyalah tempat hal itu terlihat. Memberi nama peran lebih dulu memberi setiap hak istimewa tempat untuk hidup.

Sketsa di bawah adalah titik awal untuk pemisahan itu, bukan janji ketersediaan tinggi. Perlakukan sebagai hipotesis yang harus diverifikasi, bukan sebagai rancangan jadi.

Pisahkan tiga peran, bukan tiga proses

Tiga tamu di satu host memberi tiga kumpulan hak istimewa dan tiga posisi jaringan. Mereka tidak memberi tiga domain kegagalan, dan rancangan harus mengatakannya dengan lantang.

Pemisahan hanya membantu jika kompromi pada satu tamu tidak otomatis memberi hak kepada yang lain, dan itu pengaturan hypervisor, bukan konvensi penamaan. Menyebut VM sebagai gateway tidak mencegah tamu lain menjangkau host. Baca konfigurasi switch virtual alih-alih nama host, lalu pastikan setiap tamu berada di tempat yang Anda anggap.

host
├─ vpn-gw      10.60.10.2/24   public 51820/udp only
├─ services    10.60.0.10/24   no route to the management network
└─ ci-runner   10.60.20.2/24   outbound only, no host socket

Tuliskan topologi lalu verifikasi dengan alat yang memilikinya. Tamu yang muncul di bridge yang salah adalah temuan, bukan detail. Perbaiki jaringan sebelum mengubah konfigurasi layanan apa pun.

Biarkan tamu VPN hanya membuka pintu yang dimilikinya

Publikasikan port tunnel di router dan tidak ada yang lain. Port administrasi tamu berada di jalur manajemen, bukan di internet, dan antarmuka hypervisor sendiri juga berada di sana.

Jaringan di sisi privat harus menjangkau layanan yang dibutuhkan pengguna jarak jauh dan berhenti di sana. Autentikasi aplikasi tetap menyala, karena tunnel adalah transportasi dan bukan login. Jaga tabel rute tamu VPN cukup kecil untuk dijelaskan dalam satu kalimat. Jika Anda tidak dapat menjelaskannya sesederhana itu, batasnya sudah kabur.

virsh net-list --all
virsh net-dumpxml lab-private
sudo nft list ruleset | grep -n -E '51820|10.60'

Apa pun yang mendengarkan di host dan tidak diperlukan untuk manajemen seharusnya tidak mendengarkan sama sekali. Itu termasuk API hypervisor, yang mudah dibiarkan terbuka pada antarmuka publik.

Pekerjaan build memerlukan jenis batas yang berbeda

Pekerjaan CI menjalankan perintah yang dikendalikan repositori, jadi kepercayaannya bergantung pada siapa yang dapat mendorong kode. Eksekutor shell menjalankan perintah itu sebagai pengguna runner di host, dan itu batas terluas yang tersedia.

Eksekutor kontainer lebih sempit, dan kontainer berhak istimewa bukan salah satu yang sempit. Jaga runner di tamunya sendiri dengan cakupan jaringannya sendiri, dan beri hanya akses artefak dan penerapan yang dibutuhkan pekerjaan. Pekerja sekali pakai mengurangi keadaan yang disimpan; mereka tidak mengurangi keterjangkauan atau paparan rahasia. Keduanya masih memerlukan batas eksplisit.

Tamu layanan memiliki data, jadi rencana cadangannya adalah yang harus berfungsi. Jaga repositori, unggahan, dan basis data dalam jadwal yang sama. Uji pemulihan alih-alih membaca status pekerjaan.

Rencanakan kegagalan yang dibagi ketiganya

Satu host adalah satu domain kegagalan. Reboot menghapus tunnel dan setiap layanan privat pada saat yang sama, dan justru saat itulah jalan masuk paling penting.

Pertahankan akses konsol yang tidak bergantung pada tamu VPN, entah itu konsol fisik, antarmuka manajemen out-of-band, atau konsol penyedia. Snapshot yang disimpan di disk yang sama bukan salinan independen, dan cadangan yang berjalan di dalam tamu yang dilindunginya juga bukan. Lalu uji boot dingin sebagai urutan, bukan daftar periksa: host, jaringan virtual, jalur tunnel, dan satu aplikasi bernama di bawah akun biasa.

virsh list --all
systemctl is-active libvirtd
curl -sS -m 5 -o /dev/null -w '%{http_code}\n' https://10.60.0.10/
ss -ltnp | grep -E ':51820|:443'

Urutan mulai proses tidak membuktikan apa pun tentang rute dan DNS, jadi uji jalurnya, bukan status unit. Jalur itulah yang benar-benar dibutuhkan pengguna jarak jauh.

Artikel terkait