Memahami pelabelan port dengan semanage port untuk service di luar port default, pemetaan service ke port type, serta pelabelan paket dan koneksi lewat SECMARK dan CONNSECMARK di netfilter.

Di episode 12 kita menulis policy kustom dan melihat aturan allow myapp_t http_port_t:tcp_socket name_connect. Ada pertanyaan yang sengaja kita tunda: dari mana http_port_t itu berasal, dan bagaimana SELinux tahu port 8080 bukan bagian dari http_port_t kecuali kita beri tahu? Jawabannya adalah pelabelan port — salah satu data paling sering diutak-atik oleh admin, dan sumber denial "misterius" yang paling umum saat service dipindah ke port non-default.
Di episode ini kita bedah seluruh lapisan jaringan: pelabelan port (objek yang di-bind oleh socket), pelabelan interface dan node (untuk jaringan MLS), hingga pelabelan paket dan koneksi lewat interaksi dengan netfilter/iptables. Di akhir episode kalian tidak akan lagi menebak-nebak saat sebuah daemon gagal listen di port kustom.
Di SELinux, deny ala "port tidak bisa di-bind" bukanlah keputusan kernel networking — ia keputusan policy. Ketika sebuah proses memanggil bind(), kernel tidak hanya memeriksa apakah port itu kosong; ia juga meminta keputusan LSM: bolehkah domain ini melakukan name_bind pada socket dengan label port tersebut? Aturan allow httpd_t http_port_t:tcp_socket name_bind hanya berlaku jika port yang di-bind berlabel http_port_t.
Inilah analoginya: port type adalah "ruangan kantor" yang ditandai pintunya. Policy memberi tiap domain izin memasuki ruangan tertentu (httpd_t boleh masuk http_port_t). Ketika kalian memindahkan web server ke port 8080, kalian tidak menambah izin baru — kalian cukup mengganti papan nama pintu 8080 menjadi http_port_t. Kalau papan namanya salah (masih port_t generik), pintu tetap tertutup meski policy-nya sudah benar.
Direktori pelabelan port dikelola di userspace (libsemanage), bukan di dalam policy binary — itulah mengapa ia bisa diubah tanpa rekompilasi policy. Perintahnya:
semanage port -lssh_port_t tcp 22
http_port_t tcp 80, 81, 443, 488, 8008, 8009, 8443, 9000
mysql_port_t tcp 1186, 3306, 63132-63164
postgresql_port_t tcp 5432
redis_port_t tcp 6379Perhatikan pola yang sangat penting: satu port type bisa menampung banyak port, dan satu port hanya punya satu label. http_port_t bukan "port 80" — ia adalah kategori yang mencakup deretan port. Karena itu, memindahkan nginx ke port 8080 (yang sudah ada di daftar) tidak perlu apa-apa; yang butuh tindakan adalah port yang belum terdaftar sama sekali.
Ketika service kalian harus listen di port yang belum berlabel sesuai domain, tambahkan dengan semanage port -a:
semanage port -a -t http_port_t -p tcp 8080Bentuk umumnya selalu -a (add), -t (tipe), -p (protokol), lalu nomor port. Tanpa langkah ini, denial name_bind muncul persis seperti ini:
avc: denied { name_bind } for pid=4321 comm="nginx"
scontext=system_u:system_r:httpd_t:s0
tcontext=system_u:object_r:port_t:s0 tclass=tcp_socketPerhatikan tcontext: labelnya port_t — tipe default untuk semua port yang belum dilabel secara eksplisit. Inilah ciri khas "port belum di-label": target selalu port_t, bukan jenis port service. Satu perintah semanage port -a menyelesaikannya, dan berlaku langsung tanpa restart service — label port dibaca pada saat bind().
Pemetaan ini bukan sembarang — ia konvensi yang dibangun refpolicy agar setiap domain hanya berurusan dengan portnya sendiri:
| Service | Port umum | Port type |
|---|---|---|
| nginx / httpd | 80, 443 | http_port_t |
| sshd | 22 | ssh_port_t |
| MySQL | 3306 | mysql_port_t |
| PostgreSQL | 5432 | postgresql_port_t |
| Redis | 6379 | redis_port_t |
| DNS (named) | 53 | dns_port_t |
Rutinitas yang benar saat memindahkan service ke port baru: cari tahu port type apa yang diizinkan domain tersebut, lalu label port barunya dengan tipe yang sama. Cara paling akurat untuk menemukan port type yang diizinkan adalah menelusuri policy, bukan menebak:
sesearch --allow -s httpd_t -c tcp_socket -p name_bindallow httpd_t http_port_t : tcp_socket { name_bind };
allow httpd_t http_cache_port_t : tcp_socket { name_bind };Hasil ini membaca langsung policy aktif — kalian melihat aturan yang benar-benar berlaku, bukan dugaan dari nama tipe. Jika kalian menjalankan beberapa instance dengan port berbeda, jangan lupa semanage port -m untuk mengubah label port yang sudah ada, dan -d untuk menghapus:
semanage port -m -t http_port_t -p tcp 8443
semanage port -d -p tcp 8080Kebiasaan yang disarankan: cek entri kustom kalian dengan semanage port -l -C (flag -C menampilkan hanya perubahan lokal) — ini cara tercepat untuk memastikan tidak ada port label ganda yang bentrok saat maintenance.
Naik satu level: bagaimana sebuah koneksi "dilabeli"? Fakta dasar yang sering salah dipahami: SELinux tidak melabeli paket secara implisit. Yang dilabeli adalah socket (objek kernel tipe tcp_socket, udp_socket, dst). Label socket diwarisi dari konteks proses yang membuatnya. Ketika httpd_t membuat socket dan menerima koneksi, socket itu berkonteks httpd_t; pasangan koneksi (peer) boleh berlabel domain lain selama policy mengizinkan komunikasinya.
Di level network secara global, ada tiga objek yang bisa dilabel: interface (semanage interface), node/host (semanage node), dan port (semanage port). Pelabelan interface dan node menjadi penting terutama pada kebijakan MLS (episode 9): dengan NetLabel/CIPSO, sebuah paket yang datang dari jaringan di-label berdasarkan node asalnya, lalu diverifikasi terhadap klasifikasi sensitivitas yang diminta penerima. Untuk kebijakan targeted biasa, pelabelan port adalah yang paling sering dipakai.
Bagian paling menarik: SELinux dan netfilter/iptables bukan sistem terpisah — mereka berkolaborasi. SELinux menyediakan klasifikasi sk_policy, dan iptables menyediakan target yang memicu klasifikasi tersebut. Dua target di tabel security:
Pola klasik untuk melabeli lalu lintas HTTP masuk dan keluar:
iptables -t security -A INPUT -j SECMARK --selctx system_u:object_r:httpd_packet_t
iptables -t security -A INPUT -j CONNSECMARK --save
iptables -t security -A OUTPUT -j CONNSECMARK --restoreKemudian policy menyatakan domain mana yang boleh berkomunikasi dengan paket berlabel itu:
allow httpd_t httpd_packet_t:packet recv;
allow httpd_t httpd_packet_t:packet send;Perhatikan class packet dan permission send/recv — ini class yang hanya relevan setelah SECMARK dipakai. Tanpa target SECMARK di iptables, aturan packet di policy tidak akan pernah dipicu. Inilah jembatan yang sering terlupakan: policy SELinux mengatur apa yang boleh, netfilter memutuskan paket mana yang dilabel.
Caution
Sekali kalian memasang aturan SECMARK di tabel security, seluruh lalu lintas yang cocok akan diverifikasi terhadap policy paket. Jika tidak ada aturan allow yang cocok, koneksi di-drop dengan denial avc: denied { recv } pada class packet. Urutan debugging yang benar: periksa iptables -t security -L -v untuk memastikan label diterapkan, baru telusuri policy dengan sesearch --allow -c packet.
Perspektif yang menyatukan semuanya: pelabelan port adalah peta di userspace yang dijawab pada saat bind(), sedangkan SECMARK adalah peta di kernel yang dijawab pada saat paket lewat netfilter. Keduanya menghasilkan label yang sama-sama dievaluasi oleh LSM hook — satu sumber keputusan (policy), banyak titik pelabelan.
Pada episode 13 ini kalian telah membedah pelabelan jaringan SELinux dari bawah ke atas: memahami bahwa bind() pada port yang salah label menghasilkan denial name_bind dengan tcontext=port_t; mengelola peta port dengan semanage port -a/-m/-d/-l dan membaca perubahan lokal lewat -C; memetakan service ke port type yang benar menggunakan sesearch --allow -c tcp_socket -p name_bind; memahami bahwa SELinux melabeli socket (bukan paket) dan mewariskan konteks proses pembuatnya; serta menyusun pelabelan paket dan koneksi dengan SECMARK dan CONNSECMARK di tabel security iptables beserta aturan class packet di policy.
Inti yang harus kalian bawa:
name_bind dengan tcontext=port_t berarti port belum di-label, bukan policy yang kurang.sesearch pada policy aktif, bukan dari nama tipe.Sekarang jaringan kalian berlabel konsisten dari port sampai paket. Tapi konsistensi label saja tidak cukup — yang membuat sistem aman adalah seberapa banyak domain yang benar-benar terkunci, dan seberapa sedikit privilege yang tersisa. Di episode 14 berikutnya kita masuk ranah Hardening & Least Privilege: mengurangi domain unconfined, mengonfinasi user dan service, mematikan boolean yang tidak terpakai, menganalisis policy dengan sesearch, dan membawa baseline OpenSCAP/CIS ke mesin kalian. Sampai jumpa di episode 14!