Mengarahkan host virtual Subversion ke alamat VPN mengubah situs mana yang menjawab permintaan, bukan siapa yang boleh mengirimnya. Pemeriksaan akses terjadi nanti, menurut aturan di bagian yang cocok dengan URL, dan nama host tidak pernah masuk ke keputusan itu. Jika ServerName adalah satu-satunya perubahan Anda, repositori tetap sama mudah dijangkau seperti kemarin. Dua pertanyaan terpisah harus dijawab dalam konfigurasi: soket mana yang menerima koneksi dan identitas apa yang dibawa permintaan.

Apa yang sebenarnya ditentukan ServerName

Hosting virtual berbasis nama membandingkan header Host dengan entri ServerName dan ServerAlias, memilih satu host, dan membiarkannya menangani permintaan. Koneksi itu sendiri sudah diterima sebelumnya oleh soket Listen yang menjadi milik server, bukan host. Karena itu nama yang tampak privat tidak memberi perlindungan: klien mana pun yang mencapai soket dapat mengirim header Host tersebut. Nama adalah kunci perutean, dan kunci perutean dipilih oleh pemanggil.

Anda dapat melihat pemetaan tanpa menebak. apachectl -S mencetak setiap host, port, dan namanya, serta menandai mana yang default untuk alamat tersebut.

RequireAll adalah wadah yang membuat kedua pemeriksaan wajib

Apache 2.4 membungkus direktif Require dari satu bagian dalam RequireAny implisit, jadi dua direktif telanjang berarti salah satunya cukup. Tambahkan wadahnya dan maknanya berbalik:

<Location /svn/repo>
    AuthType Basic
    AuthName "Subversion"
    AuthBasicProvider file
    AuthUserFile /etc/apache2/svn.htpasswd
    <RequireAll>
        Require ip 10.8.0.0/24
        Require valid-user
    </RequireAll>
</Location>

RequireAll menuntut kedua syarat: alamat sumber di dalam rentang terowongan dan pengguna yang diterima repositori. Itulah yang seharusnya berarti hanya-VPN untuk URL Subversion. Referensi mod_authz_core mendokumentasikan aturan wadah. Pertahankan blok di dalam Location yang ada untuk repositori dan biarkan direktif DAV yang sudah berfungsi tetap di tempatnya, karena fragmen ini tidak menggantikan AuthType, berkas kata sandi, maupun otorisasi tingkat jalur.

Uji sumber berasal dari mod_authz_host, jadi pastikan modul itu dimuat sebelum men-debug hal lain: apachectl -M | grep authz_host.

Alamat yang dievaluasi Apache adalah alamat soket

Require ip membandingkan dengan alamat yang dicatat Apache untuk koneksi, yang tidak selalu alamat yang dianggap dimiliki klien.

Ketika VPN merutekan alamatnya tanpa penerjemahan, Apache melihat alamat terowongan dan 10.8.0.0/24 cocok. Ketika gateway menerjemahkan, Apache melihat gateway dan aturan itu diam-diam tidak cocok dengan apa pun; hal yang sama terjadi di belakang penyeimbang beban yang mengakhiri TLS di depan host. Untuk kasus itu ada mod_remoteip. RemoteIPHeader X-Forwarded-For bersama RemoteIPTrustedProxy untuk penyeimbang menggantikan alamat yang dicatat, dan baru setelah itu rentang punya sesuatu untuk dibandingkan.

Mempercayai header penerusan sembarang lebih buruk daripada tidak punya aturan sama sekali. Klien mana pun dapat mengirim X-Forwarded-For berisi 10.8.0.9 dan memenuhi pemeriksaan rentang yang tidak pernah ditambatkan ke hop tepercaya.

Lapisi pendengar dan kebijakan repositori

Binding adalah kontrol terpisah dan sering kali yang lebih sederhana. Listen 10.8.0.1:443 menentukan soket mana yang ada, dan permintaan tidak dapat memilih host pada soket yang tidak pernah dibuka. Harganya adalah urutan mulai: jika antarmuka terowongan mati saat Apache mulai, binding gagal dan layanan tidak menyala. Pasangkan dengan urutan unit, atau ikat ke alamat yang ada secara independen dari terowongan.

Izin jalur tetap di AuthzSVNAccessFile. Akun yang sah untuk situs bukan pemberian yang sama dengan akses tulis ke jalur proyek, dan aturan jaringan tidak mengubahnya.

Perhatikan penggabungan bagian ketika blok berada dalam berkas yang disertakan. Apache menggabungkan wadah otorisasi di seluruh bagian bersarang dan bagian yang cocok paling spesifik dapat menggantikan persyaratan alih-alih menambahkannya, sehingga aturan pada /svn mungkin tidak mencapai /svn/repo/trunk setelah bagian yang lebih sempit mendefinisikan miliknya.

Buktikan kedua penolakan sebelum Anda menyebutnya selesai

Uji empat permintaan, bukan satu. Di dalam VPN dengan akun yang sah Anda seharusnya mendapatkan daftar repositori. Di dalam VPN dengan kata sandi salah Anda seharusnya mendapatkan 401, bukan daftar. Dari luar VPN dengan kredensial yang sah Anda seharusnya mendapatkan 403, dan permintaan publik yang sama ke nama host alternatif harus gagal dengan cara yang sama.

Satu perintah per kasus cukup: curl -sI -u user:pass https://svn.example.com/svn/repo/, lalu baca baris status. Ulangi kasus yang berfungsi melalui klien sungguhan juga, karena svn info melatih metode DAV yang akan digunakan commit dan pembaruan.

Jika salah satu dari empat hasil tidak sesuai dengan kebijakan yang Anda maksudkan, konfigurasi belum selesai, dan mengganti nama host tidak akan mengubahnya.

Artikel terkait