Các lệnh của SELinux – Chế ngự SELinux không khó
Nắm được các lệnh của SELinux bạn mới có thể chế ngự được nó. Ở bài trước chúng ta đã biết SELinux là gì, phương thức hoạt động của nó thế nào. Bạn cũng đã biết cách tắt, bật SELinux tạm thời cũng như vĩnh viễn trên hệ thống. Ở bài này chúng ta sẽ làm quen một số các lệnh trong SELinux. Từ đó có thể áp dụng các thiết lập cơ bản trong SELinux cho hệ thống máy chủ của bạn.
Ngữ cảnh – Bộ quy tắc của SELinux
Việc kiểm soát các “khu vực” trên máy chủ để phục vụ cho các đối tượng bên ngoài truy cập vào được selinux quản lý thông qua các “bộ quy tắc”. Như vậy một thư mục trên máy được selinux áp đặt bộ quy tắc nào thì bất kỳ ai cũng chỉ có thể khai thác thư mục đó theo đúng giới hạn của bộ quy tắc đó mà thôi. Như vậy dù cho một chương trình hacker nào đó có thể chiếm được quyền hay giả mạo thì cũng không thể tác động đến toàn bộ máy chủ. Nó chỉ có thể tác động lên các khu vực theo giới hạn từ bộ quy tắc đã thiết lập trong SELinux.
Ta tạm gọi các bộ quy tắc đó là các ngữ cảnh (Context).
Một số ngữ cảnh tiêu biểu:
Tên ngữ cảnh | Mô tả giá trị ngữ cảnh |
httpd_sys_content_t | Thư mục và tệp chỉ đọc được Apache sử dụng |
httpd_sys_rw_content_t | Các thư mục và tệp có thể đọc và ghi được sử dụng bởi Apache. Nếu gán điều này cho thư mục nào thì bạn (hoặc ứng dụng) có thể tạo hoặc sửa đổi thư mục và tệp bên trong đó. |
httpd_log_t | Được Apache sử dụng để tạo ra (nếu chưa có) và nối thêm vào (nếu đã có) các tệp nhật ký ứng dụng web. |
httpd_cache_t | Gán cho một thư mục được Apache sử dụng để lưu vào bộ nhớ đệm, nếu bạn đang sử dụng mod_cache. |
Xem danh sách các ngữ cảnh
Để có danh sách đầy đủ các kiểu ngữ cảnh hãy sử dụng lệnh:
semanage fcontext -l
Danh sách trả lại có thể rất dài, Nếu bạn muốn khoanh vùng dịch vụ quan tâm, hãy thêm tên dịch vụ đó vào sau tùy chọn grep:
Chẳng hạn, xem các ngữ cảnh liên quan đến httpd, hãy sử dụng lệnh:
semanage fcontext -l | grep httpd
Kết quả trả lại:
[root@centos8 ~]# semanage fcontext -l | grep httpd /etc/WebCalendar(/.*)? all files system_u:object_r:httpd_sys_rw_content_t:s0 /etc/apache(2)?(/.*)? all files system_u:object_r:httpd_config_t:s0 /etc/apache-ssl(2)?(/.*)? all files system_u:object_r:httpd_config_t:s0 /etc/cherokee(/.*)? all files system_u:object_r:httpd_config_t:s0 /etc/drupal.* all files system_u:object_r:httpd_sys_rw_content_t:s0 /etc/glpi(/.*)? all files system_u:object_r:httpd_sys_rw_content_t:s0 /etc/horde(/.*)? all files system_u:object_r:httpd_sys_rw_content_t:s0 /etc/htdig(/.*)? all files system_u:object_r:httpd_sys_content_t:s0 /etc/httpd(/.*)? all files system_u:object_r:httpd_config_t:s0
- Như vậy hệ thống SELinux trên máy đã tồn tại sẵn nhiều “bộ quy tắc” ta gọi là các ngữ cảnh. Mỗi dịch vụ sẽ có một số ngữ cảnh của nó.
- Sử dụng tùy chọn | grep <tên dịch vụ> để xem các ngữ cảnh gán cho dịch vụ mà ta quan tâm.
Xem ngữ cảnh của một thư mục
Một thư mục có thể đang được áp dụng một bộ quy tắc SELinux nào đó. Để xem ngữ cảnh của một thư mục bạn có thể dùng lệnh:
ls -dZ < thư mục>
Ví dụ: xem ngữ cảnh nào đang gán cho thư mục /var/www/html
[root@lamp36 ~]# ls -dZ /var/www/html drwx--x--x. apache apache system_u:object_r:httpd_sys_content_t:s0 /var/www/html
Ta thấy ngữ cảnh httpd_sys_content_t đang được áp dụng cho thư mục /var/ww/html
Ví dụ xem ngữ cảnh nào đang gán cho thư mục /var/cache/httpd:
[root@lamp36 ~]# ls -dZ /var/cache/httpd drwx------. apache apache system_u:object_r:httpd_cache_t:s0 /var/cache/httpd
Gán ngữ cảnh lên một thư mục
Ta có thể tự mình gán một chính sách nào đó lên một thư mục cụ thể. Ví dụ trong tình huống ta xây dựng một hệ thống thư mục máy chủ web là /home/public_html, nó không giống như mặc định là /var/ww/html. Khi đó ta phải gán một số chính sách của SELinux lên thư mục /home/public_html. Để thiết lập chính sách lên một thư mục nào đó hãy sử dụng cấu trúc lệnh:
semanage fcontext -a -t <tên_ngữ_cảnh> "Tên_thư_mục"
Một số ví dụ:
Gán chính sách httpd_sys_content_t cho thư mục /var/www/html và các thư mục con cũng như các file trong nó:
semanage fcontext -a -t httpd_sys_content_t "/var/www/html(/.*)?"
Gán chính sách httpd_log_t cho thư mục /var/logs để ghi nhật ký ứng dụng:
semanage fcontext -a -t httpd_log_t "/var/logs(/.*)?"
Tạo chính sách để gán ngữ cảnh httpd_cache_t cho các thư mục bộ nhớ cache:
semanage fcontext -a -t httpd_cache_t "/var/www/cache(/.*)?"
Tạo chính sách để gán ngữ cảnh httpd_sys_rw_content_t cho thư mục uploads và tất cả các tệp con có thể đọc ghi:
semanage fcontext -a httpd_sys_rw_content_t "/var/www/html/uploads(/.*)?"
Gán chính sách đọc ghi cho file wp-config.php:
semanage fcontext -a httpd_sys_rw_content_t "/var/www/html/wp-config.php"
Áp dụng ngữ cảnh đã gán
Các chính sách bạn đã gán sẽ được sẵn sàng áp dụng cho cấu trúc thư mục. Tuy nhiên chúng chưa có hiệu lực. Bây giờ chúng ta sẽ sử dụng lệnh restorecon để áp dụng chúng. Đây cũng là lệnh tương tự mà bạn sẽ sử dụng để áp dụng lại các ngữ cảnh cho các thư mục ứng dụng nếu vì lý do nào đó mà chúng bị xóa hoặc bị hỏng.
restorecon -Rv /var/www
Tùy chọn -R có tính đệ quy để áp dụng cho các thư mục con trong thư mục chỉ định
Xem trạng thái cấp phép cho các dịch vụ
Mỗi một dịch vụ trên máy chủ sẽ được SELinux cấp cho một số quyền hạn nhất định. Tức là dịch vụ đó được làm gì và không được làm gì (ví dụ ftpd_anon_write -> off tức là dịch vụ ftp không được quyền ghi tệp lên thư mục). Trước tiên ta cần biết SELinux đang cấp phép cho những dịch vụ nào trên hệ thống. Xem các dịch vụ đang được cấp phép bằng lệnh:
semanage boolean -l
Kết quả:
[root@lamp36 ~]# semanage boolean -l SELinux boolean State Default Description privoxy_connect_any (on , on) Allow privoxy to connect any smartmon_3ware (off , off) Allow smartmon to 3ware mpd_enable_homedirs (off , off) Allow mpd to enable homedirs xdm_sysadm_login (off , off) Allow xdm to sysadm login xen_use_nfs (off , off) Allow xen to use nfs mozilla_read_content (off , off) Allow mozilla to read content ssh_chroot_rw_homedirs (off , off) Allow ssh to chroot rw homedirs mount_anyfile (on , on) Allow mount to anyfile cron_userdomain_transition (on , on) Allow cron to userdomain transition xdm_write_home (off , off) Allow xdm to write home ...
Thông tin được trình bày trên 4 cột:
- SELinux boolean: các đối tượng chịu sự kiểm soát của SELinux.
- State: trạng thái hiện thời của đối tượng. Nếu đối tượng nào bạn chưa điều chỉnh thì giá trị state này sẽ bằng với giá trị mặc định Default.
- Default: Các giá trị mặc định ban đầu mà SELinux thiết lập cho các đối tượng nó đang kiểm soát.
- Description: Mô tả ngắn về đối tượng
Danh sách trả lại có thể khá dài, tới vài trang màn hình. Để lọc bớt các kết quả không quan tâm, hay muốn xem trạng thái cấp phép cho một dịch vụ cụ thể ta sử dụng tùy chọn grep. Muốn xem trạng thái của selinux đối với dịch vụ nào ta sử dụng lệnh với cú pháp chung:
semanage boolean -l | grep <tên dịch vụ>
Ví dụ: xem trạng thái đối với ftpd services bằng câu lệnh:
semanage boolean -l | grep ftpd
Ta thu được:
[root@lamp36 ~]# semanage boolean -l | grep ftpd ftpd_use_cifs (off , off) Allow ftpd to use cifs ftpd_connect_db (off , off) Allow ftpd to connect db ftpd_use_fusefs (off , off) Allow ftpd to use fusefs ftpd_full_access (off , off) Allow ftpd to full access ftpd_use_passive_mode (off , off) Allow ftpd to use passive mode ftpd_use_nfs (off , off) Allow ftpd to use nfs ftpd_connect_all_unreserved (off , off) Allow ftpd to connect all unreserved ftpd_anon_write (off , off) Allow ftpd to anon write [root@lamp36 ~]#
Nhìn kết quả trên ta đọc được: dịch vụ chuyển file ftp hiện tại đang không được quyền truy cập đầy đủ (full access off) cũng như cấm ghi đối với các tài khoản khách vô danh (anon write off). Chúng ta có thể thay đổi các giá trị này, tuy nhiên vì chúng liên quan đến các chính sách bảo mật nên cần cân nhắc và chắc chắn trước khi thực hiện.
getsebool – Lấy trạng thái cấp phép hiện tại của dịch vụ
Lệnh getsebool với khóa -a cho phép ta đọc trạng thái cấp phép của một dịch vụ trên SELinux. Cú pháp chung của lệnh:
getsebool -a | grep <ten-dich-vu>
Ví dụ xem trạng thái cấp phép của các dịch vụ liên quan đến ftp
[root@lamp36 ~]# getsebool -a | grep ftp ftpd_anon_write --> off ftpd_connect_all_unreserved --> off ftpd_connect_db --> off ftpd_full_access --> off ftpd_use_cifs --> off ftpd_use_fusefs --> off ftpd_use_nfs --> off ftpd_use_passive_mode --> off httpd_can_connect_ftp --> off httpd_enable_ftp_server --> off tftp_anon_write --> off tftp_home_dir --> off
Nhìn vào kết quả trả lại chúng ta có thể thấy dịch vụ nào đang được cho phép: (on hoặc 1) dịch vụ nào đang bị cấm (off hoặc 0)
setsebool – Thay đổi trạng thái cấp phép 1 dịch vụ
Lệnh setsebool cho phép đặt trạng thái hiện tại của một hoặc nhiều boolean SELinux về một giá trị nhất định. Giá trị có thể là 1 trong 2 trạng thái logic (boolean):
- Trạng thái bật (hoạt động): 1 hoặc true hoặc on
- Trạng thái tắt (hoặc nghỉ): 0 hoặc false hoặc off
Cú pháp chung của lệnh:
setsebool [ -P ] boolean value | bool1=val1 bool2=val2 ...
Nếu không có tùy chọn -P, chỉ giá trị boolean hiện tại bị ảnh hưởng; thiết lập sẽ mất hiệu lực khi khởi động lại.
Nếu tùy chọn -P được cung cấp, tất cả các giá trị đang chờ xử lý sẽ được ghi vào tệp chính sách trên đĩa. Vì vậy, chúng sẽ được duy trì liên tục qua các lần khởi động lại.
Ví dụ: Thiết lập cấp phép đọc ghi cho dịch vụ samba:
setsebool -P allow_smbd_anon_write 1
Xem các port Selinux mở mặc định:
Ta có thể xem SELinux đang mở những port nào cho dịch vụ cụ thể nào sử dụng bằng lệnh semanage port -l (tùy chọn port -l hàm ý là list các port)
[root@lamp36 ~]# semanage port -l SELinux Port Type Proto Port Number afs3_callback_port_t tcp 7001 afs3_callback_port_t udp 7001 afs_bos_port_t udp 7007 afs_fs_port_t tcp 2040 afs_fs_port_t udp 7000, 7005 afs_ka_port_t udp 7004 afs_pt_port_t tcp 7002 afs_pt_port_t udp 7002
Danh sách có thể rất dài, ta khoanh vùng bằng tùy chọn | grep
Ví dụ: List các port mà SElinux đang cho phép httpd sử dụng:
semanage port -l | grep -w http_port_t
hoặc sử dụng sepolicy
sepolicy network -t http_port_t
Kết quả của cả 2 câu lệnh trên đều tương tự
# semanage port -l | grep -w http_port_t http_port_t tcp 8087, 8088, 80, 81, 443, 488, 8008, 8009, 8443, 9000
Tìm kiếm port đã được sử dụng hay chưa
Sử dụng lệnh semanage thêm tùy chọn grep. Ví dụ xem port 8088 đã sử dụng chưa:
# semanage port -l | grep 8088 http_port_t tcp 8087, 8088, 80, 81, 443, 488, 8008, 8009, 8443, 9000
Port tìm thấy sẽ được tô màu đỏ
Thêm một port vào dịch vụ nào đó
Thêm port 8001 cho dịch vụ httpd sử dụng với các kết nối tcp
semanage port -a -t http_port_t -p tcp 8001
Kết quả
8001: tcp unreserved_port_t 1024-32767 8001: udp unreserved_port_t 1024-32767
Xóa port với tham số -d thay cho -a
Lệnh xóa port cũng là lệnh thêm port tuy nhiên thay tham số -a bằng tham số -d. Ví dụ xóa port 8001 vừa thêm vào ở ví dụ trên:
semanage port -d -t http_port_t -p tcp 8001
Lời kết
Như vậy qua bài viết này, các bạn đã biết:
- Xem danh sách các ngữ cảnh trên SELinux
- Xem ngữ cảnh của một thư mục cụ thể
- Gán ngữ cảnh cho một thư mục cụ thể
- Xem trạng thái cấp phép cho các dịch vụ
- Thay đổi trạng thái cấp phép của một dịch vụ cụ thể
- Xem port, thêm vào và xóa bớt một port trong SELinux
Rất nhiều các chuyên gia khuyên rằng nên tắt SELinux để bớt rắc rối. Thực ra đây là một cách tồi tệ nhất vì chúng ta đã vô hiệu hóa hệ thống phòng thủ cho VPS của mình. Hy vọng với các kiến thức này, các bạn có thể làm chủ SELinux để bảo vệ VPS của mình.
Cường Còng – Chúc các bạn vui vẻ!