Product SiteDocumentation Site

14.5. Pengantar SELinux

14.5.1. Prinsip-prinsip

SELinux (Security Enhanced Linux) adalah sistem Mandatory Access Control yang dibangun pada antarmuka LSM (Linux Security Modules) Linux. Dalam prakteknya, kernel mengkuiri SELinux sebelum setiap panggilan sistem untuk mengetahui apakah proses terotorisasi untuk melakukan operasi tertentu.
SELinux menggunakan seperangkat aturan — secara kolektif dikenal sebagai kebijakan — untuk mengotorisasi atau melarang operasi. Aturan-aturan tersebut sulit untuk dibuat. Untungnya, dua kebijakan standar (targeted dan strict) disediakan untuk menghindari sebagian besar pekerjaan konfigurasi.
Dengan SELinux, pengelolaan hak ini benar-benar berbeda dari sistem Unix tradisional. Hak-hak proses tergantung pada konteks keamanan. Konteks didefinisikan oleh identitas pengguna yang memulai proses, peran dan domain yang dibawa oleh pengguna saat itu. Hak benar-benar tergantung pada domain, tetapi transisi antara domain dikontrol oleh peran. Terakhir, transisi yang mungkin antar peran tergantung pada identitas.
Konteks keamanan dan pengguna Unix

Gambar 14.1. Konteks keamanan dan pengguna Unix

Dalam prakteknya, sewaktu Anda login, pengguna akan diberi konteks keamanan standar (tergantung pada peran yang mereka harus mampu dukung). Ini mendefinisikan domain saat ini, dan dengan demikian domain yang akan dibawa oleh proses anak baru. Jika Anda ingin mengubah peran saat ini dan domain yang terkait, Anda harus menjalankan newrole -r role_r -t domain_t (biasanya ada hanya satu domain yang diperbolehkan untuk peran yang diberikan, sehingga parameter -t seringkali dapat ditinggalkan). Perintah ini mengotentikasi Anda dengan meminta Anda untuk mengetik kata sandi. Fitur ini melarang program untuk secara otomatis beralih peran. Perubahan tersebut hanya dapat terjadi jika mereka secara eksplisit diizinkan dalam kebijakan SELinux.
Tentu saja hak tidak berlaku untuk semua objek (berkas, direktori, soket, perangkat, dll). Mereka bisa bervariasi dari objek ke objek. Untuk mencapai hal ini, setiap objek dikaitkan dengan suatu tipe (ini dikenal sebagai pelabelan). Hak domain kemudian dinyatakan dengan set operasi yang (tidak) diizinkan pada tipe tersebut (dan, secara tidak langsung, pada semua objek yang dilabeli tipe tertentu).
Secara default, program mewarisi domainnya dari pengguna yang memulai, tetapi kebijakan SELinux standar berharap banyak program penting untuk dijalankan di domain yang terdedikasi. Untuk mencapai ini, executable yang diberi label dengan tipe khusus (sebagai contoh ssh diberi label dengan ssh_exec_t, dan ketika program dimulai, secara otomatis beralih ke domain ssh_t). Mekanisme transisi otomatis domain ini menjadikannya mungkin untuk memberikan hanya hak yang diperlukan oleh setiap program. Ini adalah prinsip dasar SELinux.
Transisi otomatis antar domain

Gambar 14.2. Transisi otomatis antar domain

14.5.2. Menyiapkan SELinux

Dukungan SELinux dibangun ke dalam kernel standar yang disediakan oleh Debian. Alat-alat Unix inti yang mendukung SELinux tanpa modifikasi apapun. Karena itu relatif mudah untuk mengaktifkan SELinux.
Perintah apt install selinux-basics selinux-policy-default secara otomatis akan menginstal paket-paket yang diperlukan untuk mengkonfigurasi sistem SELinux.
Paket selinux-policy-default berisi serangkaian standar aturan. Secara default, kebijakan ini hanya membatasi akses untuk beberapa layanan yang terbuka lebar. Sesi pengguna yang tidak dibatasi dan tidak mungkin bahwa SELinux akan memblokir operasi pengguna yang sah. Namun, ini meningkatkan keamanan layanan sistem yang berjalan pada mesin. Untuk mennyiapkan sebuah kebijakan yang setara dengan aturan lama yang "ketat", Anda hanya perlu menonaktifkan modul unconfined (manajemen modul dirinci lebih lanjut dalam bagian ini).
Setelah kebijakan diinstal, Anda harus melabeli semua berkas yang tersedia (yang berarti menugaskan ke mereka suatu tipe). Operasi ini harus secara manual dimulai dengan fixfiles relabel.
Sistem SELinux kini siap. Untuk mengaktifkannya, Anda harus menambahkan parameter kernel Linux selinux=1 security=selinux. Parameter audit=1 memungkinkan log SELinux yang mencatat semua operasi yang ditolak. Akhirnya, parameter enforcing=1 membawa aturan ke aplikasi: tanpa itu SELinux bekerja dalam pengaturan mode permisif dimana tindakan yang ditolak dicatat tapi masih dijalankan. Anda justru harus memodifikasi berkas konfigurasi bootloader GRUB untuk menambahkan parameter yang diinginkan. Salah satu cara mudah untuk melakukan ini adalah untuk mengubah variabel GRUB_CMDLINE_LINUX dalam /etc/default/grub dan menjalankan update-grub. SELinux akan aktif setelah reboot.
Perlu dicatat bahwa skrip selinux-activate mengotomatiskan operasi itu dan memaksa pelabelan pada boot berikutnya (yang menghindari berkas baru tanpa label diciptakan sementara SELinux masih belum aktif dan sementara pelabelan terjadi).

14.5.3. Mengelola Sistem SELinux

Kebijakan SELinux adalah seperangkat aturan modular, dan instalasinya mendeteksi dan memungkinkan secara otomatis semua modul yang relevan berdasarkan layanan yang sudah terpasang. Maka sistem ini seketika operasional. Namun, ketika layanan diinstal setelah kebijakan SELinux, Anda harus mampu secara manual memfungsikan modul yang sesuai. Itulah tujuan dari perintah semodule. Lebih jauh, Anda harus mampu mendefinisikan peran yang setiap pengguna dapat mendukungnya, dan ini dapat dilakukan dengan perintah semanage.
Dua perintah tersebut dapat digunakan untuk mengubah konfigurasi SELinux saat ini, yang disimpan di /etc/selinux/default/. Tidak seperti berkas konfigurasi lain yang dapat Anda temukan di /etc/, semua berkas yang tidak boleh diubah dengan tangan. Anda harus menggunakan program-program yang dirancang untuk tujuan ini.

14.5.3.1. Mengelola Modul SELinux

Modul-modul SELinux yang tersedia disimpan dalam direktori /usr/share/selinux/default/. Untuk mengaktifkan salah satu modul ini dalam konfigurasi saat ini, Anda harus menggunakan semodule -i module.pp.bz2. Ekstensi pp.bz2 singkatan dari policy package (paket kebijakan, dikompresi dengan bzip2).
Menghapus modul dari konfigurasi saat ini dilakukan dengan semodule -r modul. Akhirnya, perintah semodule -l menampilkan daftar modul yang saat ini diinstal. Itu juga mengeluarkan nomor versi mereka. Modul dapat diaktifkan secara selektif dengan semodule -e dan dinonaktifkan dengan semodule -d.
# semodule -i /usr/share/selinux/default/abrt.pp.bz2
libsemanage.semanage_direct_install_info: abrt module will be disabled after install as there is a disabled instance of this module present in the system.
# semodule -l
accountsd
acct
[...]
# semodule -e abrt
# semodule -d accountsd
# semodule -l
abrt
acct
[...]
# semodule -r abrt
libsemanage.semanage_direct_remove_key: abrt module at priority 100 is now active.semodule -l
semodule seketika memuat konfigurasi baru kecuali jika Anda menggunakan opsi -n. Perlu dicatat bahwa program bertindak secara default pada konfigurasi saat ini (yang ditunjukkan oleh variabel SELINUXTYPE di /etc/selinux/config), tetapi Anda dapat memodifikasi yang lain dengan menyatakan opsi -s.

14.5.3.2. Mengelola Identitas

Setiap kali seorang pengguna login, mereka mendapatkan identitas SELinux. Identitas ini mendefinisikan peran yang mereka akan mampu dukung. Dua pemetaan itu (dari pengguna ke identitas dan dari identitas ini ke peran) dapat dikonfigurasi dengan perintah semanage.
Anda harus membaca halaman manual semanage(8). Semua konsep yang dikelola memiliki halaman manual mereka sendiri; sebagai contoh, semanage-login(8). Bahkan jika sintaks perintah cenderung menjadi serupa untuk semua konsep yang dikelola, dianjurkan untuk membaca halaman manualnya. Anda akan menemukan pilihan umum untuk semua sub perintah: -a untuk menambahkan, -d untuk menghapus, -m untuk memodifikasi, -l untuk menampilkan daftar, dan -t untuk menunjukkan tipe (atau domain).
semanage login -l daftar pemetaan saat ini antara pengidentifikasi pengguna dan identitas SELinux. Pengguna yang tidak memiliki entri eksplisit mendapatkan identitas yang ditunjukkan dalam entri __default__. Perintah semanage login -a -s user_u pengguna akan mengasosiasikan identitas user_u kepada pengguna tertentu. Akhirnya, semanage login -d pengguna menghapus entri pemetaan yang ditetapkan ke pengguna ini.
# semanage login -a -s user_u rhertzog
# semanage login -l

Login Name           SELinux User         MLS/MCS Range        Service

__default__          unconfined_u         s0-s0:c0.c1023       *
rhertzog             user_u               s0                   *
root                 unconfined_u         s0-s0:c0.c1023       *
# semanage login -d rhertzog
semanage user -l menampilkan daftar pemetaan antara identitas pengguna SELinux dan peran yang diperbolehkan. Menambahkan identitas baru memerlukan untuk mendefinisikan peran yang sesuai dan awalan pelabelan yang digunakan untuk menetapkan suatu tipe ke berkas pribadi (/home/pengguna/*). Awalan harus dipilih di antara user, staff, dan sysadm. Awalan "staff" menghasilkan berkas-berkas bertipe "staff_home_dir_t". Menciptakan identitas pengguna baru SELinux dilakukan dengan semanage user -a -R peran -P awalan identitas. Akhirnya, Anda dapat menghapus identitas pengguna SELinux dengan semanage user -d identitas.
# semanage user -a -R 'staff_r user_r' -P staff test_u
# semanage user -l

                Labeling   MLS/       MLS/                          
SELinux User    Prefix     MCS Level  MCS Range                      SELinux Roles

root            sysadm     s0         s0-s0:c0.c1023                 staff_r sysadm_r system_r
staff_u         staff      s0         s0-s0:c0.c1023                 staff_r sysadm_r
sysadm_u        sysadm     s0         s0-s0:c0.c1023                 sysadm_r
system_u        user       s0         s0-s0:c0.c1023                 system_r
test_u          staff      s0         s0                             staff_r user_r
unconfined_u    unconfined s0         s0-s0:c0.c1023                 system_r unconfined_r
user_u          user       s0         s0                             user_r
# semanage user -d test_u

14.5.3.3. Mengelola Konteks Berkas, Port, dan Boolean

Setiap modul SELinux menyediakan satu set berkas aturan pelabelan, tapi juga dimungkinkan untuk menambahkan aturan pelabelan kustom untuk memenuhi kasus tertentu. Sebagai contoh, jika Anda ingin server web dapat membaca berkas dalam hirarki berkas /srv/www/, Anda bisa menjalankan semanage fcontext -a -t httpd_sys_content_t "/srv/www(/.*)?" diikuti oleh restorecon -R /srv/www/. Perintah awal mendaftarkan aturan pelabelan baru dan yang kedua mereset tipe berkas menurut aturan pelabelan saat ini.
Demikian pula, port TCP/UDP diberi label dalam cara yang memastikan bahwa hanya daemon yang sesuai yang dapat mendengarkan mereka. Misalnya, jika Anda ingin server web dapat mendengarkan pada port 8080, Anda harus menjalankan semanage port -m -t http_port_t -p tcp 8080.
Beberapa modul SELinux mengekspor opsi boolean yang dapat Anda tala untuk mengubah perilaku aturan default. Utilitas getsebool dapat digunakan untuk memeriksa opsi-opsi itu (getsebool boolean menampilkan salah satu pilihan, dan getsebool -a untuk semua). Perintah setsebool boolean nilai mengubah nilai saat ini dari opsi boolean. Opsi -P membuat perubahan permanen, itu berarti bahwa nilai baru menjadi default dan akan dipelihara antar reboot. Contoh di bawah menghibahkan server web akses ke direktori home (ini berguna ketika pengguna memiliki website pribadi dalam ~/public_html/).
# getsebool httpd_enable_homedirs
httpd_enable_homedirs --> off
# setsebool -P httpd_enable_homedirs on
# getsebool httpd_enable_homedirs
httpd_enable_homedirs --> on

14.5.4. Mengadaptasi Aturan

Karena kebijakan SELinux modular, mungkin menarik untuk mengembangkan modul baru untuk aplikasi (mungkin kustom) yang kekurangan mereka. Modul-modul baru ini kemudian akan menyelesaikan kebijakan acuan.
Untuk membuat modul baru, paket selinux-policy-dev diperlukan, serta selinux-policy-doc. Yang kedua berisi dokumentasi aturan standar (/usr/share/doc/selinux-policy-doc/html/) dan berkas sampel yang dapat digunakan sebagai template untuk membuat modul baru. Pasang berkas tersebut dan pelajari lebih dekat:
$ cp /usr/share/doc/selinux-policy-doc/Makefile.example Makefile
$ cp /usr/share/doc/selinux-policy-doc/example.fc ./
$ cp /usr/share/doc/selinux-policy-doc/example.if ./
$ cp /usr/share/doc/selinux-policy-doc/example.te ./
Berkas .te adalah yang paling penting. Itu mendefinisikan aturan-aturan. Berkas .fc mendefinisikan "file contexts (konteks berkas)", itu adalah jenis yang ditetapkan ke berkas yang terkait dengan modul ini. Data di dalam berkas .fc digunakan selama langkah pelabelan berkas. Terakhir, berkas .if mendefinisikan antarmuka modul: ini adalah satu set "fungsi umum" yang modul lain dapat gunakan untuk berinteraksi secara benar dengan modul yang Anda buat.

14.5.4.1. Menulis suatu berkas .fc

Membaca contoh di bawah ini mestinya cukup untuk memahami struktur berkas tersebut. Anda dapat menggunakan ekspresi reguler untuk menetapkan konteks keamanan yang sama untuk beberapa berkas, atau bahkan seluruh pohon direktori.

Contoh 14.2. berkas example.fc

# myapp executable will have:
# label: system_u:object_r:myapp_exec_t
# MLS sensitivity: s0
# MCS categories: <none>

/usr/sbin/myapp         --      gen_context(system_u:object_r:myapp_exec_t,s0)

14.5.4.2. Menulis suatu Berkas .if

Dalam contoh di bawah, antarmuka yang pertama ("myapp_domtrans") mengendalikan siapa yang dapat menjalankan aplikasi. Yang kedua ("myapp_read_log") menghibahkan hak baca pada berkas log aplikasi.
Setiap antarmuka harus menghasilkan seperangkat aturan yang dapat ditanam dalam berkas .te yang valid. Anda harus menyatakan semua tipe yang Anda gunakan (dengan makro gen_require), dan menggunakan direktif standar untuk memberikan hak. Namun, perlu diketahui bahwa Anda dapat menggunakan antarmuka yang disediakan oleh modul lain. Bagian berikutnya akan memberikan penjelasan lebih lanjut tentang bagaimana untuk mengekspresikan hak tersebut.

Contoh 14.3. Berkas example.if

## <summary>Myapp example policy</summary>
## <desc>
##      <p>
##              More descriptive text about myapp.  The <desc>
##              tag can also use <p>, <ul>, and <ol>
##              html tags for formatting.
##      </p>
##      <p>
##              This policy supports the following myapp features:
##              <ul>
##              <li>Feature A</li>
##              <li>Feature B</li>
##              <li>Feature C</li>
##              </ul>
##      </p>
## </desc>
#

########################################
## <summary>
##      Execute a domain transition to run myapp.
## </summary>
## <param name="domain">
##      Domain allowed to transition.
## </param>
#
interface(`myapp_domtrans',`
        gen_require(`
                type myapp_t, myapp_exec_t;
        ')

        domtrans_pattern($1,myapp_exec_t,myapp_t)
')

########################################
## <summary>
##      Read myapp log files.
## </summary>
## <param name="domain">
##      Domain allowed to read the log files.
## </param>
#
interface(`myapp_read_log',`
        gen_require(`
                type myapp_log_t;
        ')

        logging_search_logs($1)
        allow $1 myapp_log_t:file r_file_perms;
')

14.5.4.3. Menulis suatu Berkas .te

Silakan lihat berkas example.te:
policy_module(myapp,1.0.0) 1

########################################
#
# Declarations
#

type myapp_t; 2
type myapp_exec_t;
domain_type(myapp_t)
domain_entry_file(myapp_t, myapp_exec_t) 3

type myapp_log_t;
logging_log_file(myapp_log_t) 4

type myapp_tmp_t;
files_tmp_file(myapp_tmp_t)

########################################
#
# Myapp local policy
#

allow myapp_t myapp_log_t:file { read_file_perms append_file_perms }; 5

allow myapp_t myapp_tmp_t:file manage_file_perms;
files_tmp_filetrans(myapp_t,myapp_tmp_t,file)

1

Modul harus diidentifikasi oleh nama dan nomor versinya. Direktif ini diperlukan.

2

Jika modul memperkenalkan tipe baru, itu harus menyatakan mereka dengan direktif seperti ini. Jangan ragu untuk menciptakan tipe sebanyak yang diperlukan daripada memberikan terlalu banyak hak yang tidak berguna.

3

Antarmuka tersebut mendefinisikan tipe myapp_t sebagai domain proses yang harus digunakan oleh setiap executable yang dilabeli dengan myapp_exec_t. Secara implisit, ini menambah atribut exec_type pada objek tersebut, yang pada gilirannya memungkinkan modul lain untuk memberikan hak untuk mengeksekusi program-program tersebut: sebagai contoh, modul userdomain memungkinkan proses dengan domain user_t, staff_t, dan sysadm_t untuk mengeksekusi mereka. Domain aplikasi terbatas yang lain tidak akan memiliki hak untuk mengeksekusi mereka, kecuali aturan memberi mereka hak-hak yang sama (ini adalah kasus, misalnya, dari dpkg dengan domainnya dpkg_t).

4

logging_log_file adalah antarmuka yang disediakan oleh kebijakan referensi. Itu menunjukkan bahwa berkas yang dilabeli dengan tipe yang diberikan adalah berkas log yang seharusnya mendapatkan keuntungan dari aturan terkait (misalnya memberikan hak kepada logrotate sehingga dapat memanipulasi mereka).

5

Direktif allow adalah petunjuk dasar yang digunakan untuk mengesahkan suatu operasi. Parameter pertama adalah domain proses yang diperbolehkan untuk mengeksekusi operasi. Yang kedua mendefinisikan objek dimana proses dari domain sebelumnya dapat memanipulasi. Parameter ini berbentuk "tipe:kelas" dimana tipe adalah tipe SELinux dan kelas menggambarkan sifat objek (berkas, direktori, soket, fifo, dll). Parameter terakhir menjelaskan hak akses (operasi yang diizinkan).
Izin didefinisikan sebagai serangkaian operasi yang diperbolehkan dan mengikuti template ini: { operasi1 operasi2 }. Namun, Anda juga dapat menggunakan makro yang mewakili izin yang paling berguna. /usr/share/selinux/devel/include/support/obj_perm_sets.spt memuat daftar mereka.
Halaman web berikut menyediakan daftar relatif lengkap dari kelas objek, dan izin yang dapat diberikan.
Sekarang Anda hanya perlu menemukan set minimalis aturan-aturan yang diperlukan untuk memastikan bahwa aplikasi atau layanan target bekerja dengan baik. Untuk mencapai ini, Anda harus memiliki pengetahuan yang baik tentang bagaimana aplikasi bekerja dan jenis data apa yang dikelola dan/atau dihasilkan.
Namun, pendekatan empiris mungkin. Setelah objek relevan dilabeli dengan benar, Anda dapat menggunakan aplikasi dalam mode permisif: operasi yang akan dilarang dicatat tetapi masih berhasil. Dengan menganalisis log, Anda sekarang dapat mengidentifikasi operasi yang akan diizinkan. Berikut adalah contoh seperti entri log:
avc:  denied  { read write } for  pid=1876 comm="syslogd" name="xconsole" dev=tmpfs ino=5510 scontext=system_u:system_r:syslogd_t:s0 tcontext=system_u:object_r:device_t:s0 tclass=fifo_file permissive=1
Untuk lebih memahami pesan ini, marilah kita pelajari sepotong demi sepotong.

Tabel 14.1. Analisis jejak SELinux

PesanDeskripsi
avc: deniedOperasi telah ditolak.
{ read write }Operasi ini memerlukan izin read dan write.
pid=1876Proses dengan PID 1876 menjalankan operasi (atau mencoba untuk menjalankannya).
comm="syslogd"Proses adalah instance dari program syslogd.
name="xconsole"Objek target dinamai xconsole. Kadang-kadang Anda dapat juga memiliki variabel "path" — dengan path lengkap — sebagai pengganti.
dev=tmpfsPerangkat yang mewadahi objek target ini adalah tmpfs (suatu sistem berkas di memori). Untuk disk sungguhan, Anda bisa melihat partisi yang mewadahi objek (misalnya: "sda3").
ino=5510Objek diidentifikasi oleh nomor inode 5510.
scontext=system_u:system_r:syslogd_t:s0Ini adalah konteks keamanan dari proses yang menjalankan operasi.
tcontext=system_u:object_r:device_t:s0Ini adalah konteks keamanan objek target.
tclass=fifo_fileObjek target adalah suatu berkas FIFO.
Dengan mengamati entri log ini, mungkin untuk membangun sebuah aturan yang akan memungkinkan operasi ini. Sebagai contoh: allow syslogd_t device_t:fifo_file { read write }. Proses ini dapat diotomatiskan, dan itu persis apa yang ditawarkan oleh perintah audit2allow (dari paket policycoreutils). Pendekatan ini hanya berguna jika berbagai objek sudah benar dilabeli menurut apa harus dibatasi. Dalam hal apapun, Anda harus hati-hati meninjau aturan yang dihasilkan dan memvalidasi mereka menurut pengetahuan Anda tentang aplikasi. Secara efektif, pendekatan ini cenderung untuk memberikan hak lebih daripada yang benar-benar diperlukan. Solusi yang tepat seringkali adalah dengan menciptakan tipe baru dan memberikan hak hanya pada tipe tersebut. Terjadi juga bahwa operasi yang ditolak tidak fatal ke aplikasi, dalam hal itu mungkin lebih baik untuk hanya menambahkan aturan "dontaudit" untuk menghindari entri log meskipun ada penyangkalan efektif.

14.5.4.4. Mengkompilasi Berkas

Setelah 3 berkas (example.if, example.fc, dan example.te) sesuai harapan Anda untuk aturan baru, ubah nama mereka menjadi myapp.extension dan jalankan make NAME=devel untuk menghasilkan suatu modul dalam berkas myapp.pp (Anda dapat seketika memuatnya dengan semodule -i myapp.pp). Jika beberapa modul yang didefinisikan, make akan membuat semua berkas .pp yang sesuai.