Giới thiệu về SELinux trên CentOS 7 - Phần 2: Tệp và Quy trình
Trong phần đầu tiên của loạt bài về SELinux , ta đã biết cách bật và tắt SELinux cũng như cách thay đổi một số cài đặt policy bằng cách sử dụng các giá trị boolean. Trong phần thứ hai này, ta sẽ nói về bối cảnh bảo mật file và quy trình.Để làm mới bộ nhớ của bạn từ hướng dẫn trước, ngữ cảnh bảo mật file là một loại và ngữ cảnh bảo mật quy trình là một miền .
Ghi chú
Các lệnh, gói và file được hiển thị trong hướng dẫn này đã được thử nghiệm trên CentOS 7. Các khái niệm vẫn giữ nguyên cho các bản phân phối khác.
Trong hướng dẫn này, ta sẽ chạy các lệnh với quyền là user root trừ khi có quy định khác. Nếu bạn không có quyền truy cập vào account root và sử dụng account khác có quyền sudo, bạn cần đặt trước các lệnh bằng từ khóa sudo
.
Tạo account user thử nghiệm
Đầu tiên, hãy tạo bốn account user để chứng minh các khả năng của SELinux khi ta tiếp tục.
- Người sử dụng thường xuyên
- user chuyển mạch
- Tài khoản khách
- user bị hạn chế
Bạn hiện phải là user root . Ta hãy chạy lệnh sau để thêm account regularuser:
- useradd -c "Regular User" regularuser
Sau đó, ta chạy lệnh passwd
để thay đổi password của nó:
- passwd regularuser
Đầu ra sẽ yêu cầu ta nhập password mới. Sau khi được cung cấp, account sẽ sẵn sàng để đăng nhập:
Changing password for user regularuser. New password: Retype new password: passwd: all authentication tokens updated successfully.
Hãy tạo các account khác nữa:
- useradd -c "Switched User" switcheduser
- passwd switcheduser
- useradd -c "Guest User" guestuser
- passwd guestuser
- useradd -c "Restricted Role User" restricteduser
- passwd restricteduser
SELinux cho các quá trình và file
Mục đích của SELinux là bảo mật cách xử lý truy cập file trong môi trường Linux. Nếu không có SELinux, một quy trình hoặc ứng dụng như daemon Apache sẽ chạy trong ngữ cảnh của user đã chạy nó. Vì vậy, nếu hệ thống của bạn bị xâm phạm bởi một ứng dụng giả mạo đang chạy dưới quyền của user root, thì ứng dụng có thể làm bất cứ điều gì nó muốn vì root có tất cả các quyền trên mọi file .
SELinux cố gắng tiến thêm một bước nữa và loại bỏ nguy cơ này. Với SELinux, một quy trình hoặc ứng dụng sẽ chỉ có các quyền mà nó cần để hoạt động và KHÔNG CÒN GÌ nữa. Chính sách SELinux cho ứng dụng sẽ xác định loại file nào nó cần truy cập và những quy trình nào nó có thể chuyển sang. Các policy của SELinux được viết bởi các nhà phát triển ứng dụng và được vận chuyển cùng với bản phân phối Linux hỗ trợ nó. Về cơ bản, policy là một tập hợp các luật ánh xạ các quy trình và user với các quyền của họ.
Ta bắt đầu thảo luận về phần này của hướng dẫn bằng cách hiểu ý nghĩa của các ngữ cảnh và miền SELinux.
Phần đầu tiên của bảo mật đặt một nhãn trên mỗi thực thể trong hệ thống Linux. Nhãn giống như bất kỳ thuộc tính quy trình hoặc file nào khác (chủ sở hữu, group , ngày tạo, v.v.); nó cho thấy bối cảnh của tài nguyên. Vậy bối cảnh là gì? Nói một cách đơn giản, ngữ cảnh là một tập hợp các thông tin liên quan đến bảo mật giúp SELinux đưa ra các quyết định kiểm soát truy cập. Mọi thứ trong hệ thống Linux đều có thể có ngữ cảnh bảo mật: account user , file , folder , daemon hoặc cổng đều có thể có ngữ cảnh bảo mật của chúng. Tuy nhiên, bối cảnh bảo mật sẽ có ý nghĩa khác nhau đối với các loại đối tượng khác nhau.
Các bác sĩ cho biết thêm:
Bối cảnh file SELinux
Hãy bắt đầu bằng cách hiểu ngữ cảnh file SELinux. Hãy xem kết quả của một lệnh ls -l thông thường đối với folder / etc.
- ls -l /etc/*.conf
Điều này sẽ cho ta thấy một kết quả quen thuộc:
... -rw-r--r--. 1 root root 19 Aug 19 21:42 /etc/locale.conf -rw-r--r--. 1 root root 662 Jul 31 2013 /etc/logrotate.conf -rw-r--r--. 1 root root 5171 Jun 10 07:35 /etc/man_db.conf -rw-r--r--. 1 root root 936 Jun 10 05:59 /etc/mke2fs.conf ...
Đơn giản, phải không? Bây giờ hãy thêm cờ -Z:
- ls -Z /etc/*.conf
Như vậy, ta có thêm một cột thông tin sau quyền sở hữu user và group :
... -rw-r--r--. root root system_u:object_r:locale_t:s0 /etc/locale.conf -rw-r--r--. root root system_u:object_r:etc_t:s0 /etc/logrotate.conf -rw-r--r--. root root system_u:object_r:etc_t:s0 /etc/man_db.conf -rw-r--r--. root root system_u:object_r:etc_t:s0 /etc/mke2fs.conf ...
Cột này hiển thị bối cảnh bảo mật của file . Một file được cho là đã được gắn nhãn với ngữ cảnh bảo mật của nó khi bạn có thông tin này cho nó. Ta hãy xem xét kỹ hơn một trong các bối cảnh bảo mật.
-rw-r--r--. root root system_u:object_r:etc_t:s0 /etc/logrotate.conf
Bối cảnh bảo mật là phần này:
system_u:object_r:etc_t:s0
Có bốn phần và mỗi phần của ngữ cảnh bảo mật được phân tách bằng dấu hai chấm (:). Phần đầu tiên là ngữ cảnh user SELinux cho file . Ta sẽ thảo luận về user SELinux sau, nhưng hiện tại, ta có thể thấy rằng đó là system_u . Mỗi account user Linux ánh xạ tới một user SELinux và trong trường hợp này, user root sở hữu file được ánh xạ tới user SELinux system_u . Việc ánh xạ này được thực hiện bởi policy SELinux.
Phần thứ hai chỉ định role SELinux, là object_r . Để tìm hiểu các role của SELinux, hãy xem lại bài viết đầu tiên của SELinux.
Điều quan trọng nhất ở đây là phần thứ ba, loại file được liệt kê ở đây là etc_t . Đây là phần xác định loại file hoặc folder thuộc về. Ta có thể thấy rằng hầu hết các file thuộc loại etc_t trong folder /etc
Về mặt giả thuyết, bạn có thể nghĩ kiểu như một loại “ group ” hoặc thuộc tính cho file : đó là một cách phân loại file .
Ta cũng có thể thấy một số file có thể thuộc các kiểu khác, như locale.conf
có kiểu locale_t . Ngay cả khi tất cả các file được liệt kê ở đây có cùng một user và chủ sở hữu group , các loại của chúng có thể khác nhau.
Ví dụ khác, hãy kiểm tra các ngữ cảnh loại cho các folder chủ của user :
- ls -Z /home
Thư mục chính sẽ có kiểu ngữ cảnh khác: user_home_dir_t
drwx------. guestuser guestuser unconfined_u:object_r:user_home_dir_t:s0 guestuser drwx------. root root system_u:object_r:lost_found_t:s0 lost+found drwx------. regularuser regularuser unconfined_u:object_r:user_home_dir_t:s0 regularuser drwx------. restricteduser restricteduser unconfined_u:object_r:user_home_dir_t:s0 restricteduser drwx------. switcheduser switcheduser unconfined_u:object_r:user_home_dir_t:s0 switcheduser drwx------. sysadmin sysadmin unconfined_u:object_r:user_home_dir_t:s0 sysadmin
Phần thứ tư của bối cảnh bảo mật, s0 , liên quan đến bảo mật đa cấp hoặc MLS. Về cơ bản, đây là một cách khác để thực thi policy bảo mật của SELinux và phần này cho thấy độ nhạy của tài nguyên ( s0 ). Ta sẽ nói ngắn gọn về độ nhạy và các danh mục sau. Đối với hầu hết các cài đặt vani của SELinux, ba bối cảnh bảo mật đầu tiên quan trọng hơn.
Bối cảnh quy trình SELinux
Bây giờ ta hãy nói về bối cảnh bảo mật quy trình.
Khởi động các dịch vụ Apache và SFTP. Ta đã cài đặt các dịch vụ này trong hướng dẫn SELinux đầu tiên.
- service httpd start
- service vsftpd start
Ta có thể chạy lệnh ps
với một vài cờ để hiển thị các tiến trình Apache và SFTP đang chạy trên server của ta :
- ps -efZ | grep 'httpd\|vsftpd'
cờ -Z được sử dụng để hiển thị các ngữ cảnh SELinux. Đầu ra hiển thị user đang chạy quy trình, ID quy trình và ID quy trình mẹ:
system_u:system_r:httpd_t:s0 root 7126 1 0 16:50 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND system_u:system_r:httpd_t:s0 apache 7127 7126 0 16:50 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND system_u:system_r:httpd_t:s0 apache 7128 7126 0 16:50 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND system_u:system_r:httpd_t:s0 apache 7129 7126 0 16:50 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND system_u:system_r:httpd_t:s0 apache 7130 7126 0 16:50 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND system_u:system_r:httpd_t:s0 apache 7131 7126 0 16:50 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND system_u:system_r:ftpd_t:s0-s0:c0.c1023 root 7209 1 0 16:54 ? 00:00:00 /usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 root 7252 2636 0 16:57 pts/0 00:00:00 grep --color=auto httpd\|vsftpd
Bối cảnh bảo mật là phần này:
system_u:system_r:httpd_t:s0
Bối cảnh bảo mật có bốn phần: user , role , domain và độ nhạy. User , role và độ nhạy hoạt động giống như các ngữ cảnh tương tự cho các file (được giải thích trong phần trước). Miền là duy nhất cho các quy trình.
Trong ví dụ trên, ta có thể thấy rằng một vài quy trình đang chạy trong domain httpd_t , trong khi một quy trình đang chạy trong domain ftpd_t .
Vậy domain làm gì cho các quy trình? Nó cung cấp cho quá trình một ngữ cảnh để chạy bên trong. Nó giống như một bong bóng xung quanh quá trình giới hạn nó. Nó cho quá trình biết những gì nó có thể làm và những gì nó không thể làm. Sự hạn chế này đảm bảo mỗi domain quy trình chỉ có thể hoạt động trên một số loại file nhất định và không có gì hơn.
Sử dụng mô hình này, ngay cả khi một quy trình bị tấn công bởi một quy trình hoặc user độc hại khác, điều tồi tệ nhất mà nó có thể làm là làm hỏng các file mà nó có quyền truy cập. Ví dụ: daemon vsftp sẽ không có quyền truy cập vào các file được sử dụng bằng say, sendmail hoặc samba. Hạn chế này được thực hiện từ cấp kernel : nó được thực thi khi policy SELinux tải vào bộ nhớ, và do đó kiểm soát truy cập trở thành bắt buộc .
Quy ước đặt tên
Trước khi ta đi xa hơn, đây là một lưu ý về quy ước đặt tên SELinux. User SELinux có hậu tố là “_u”, role có hậu tố là “_r” và loại (đối với file ) hoặc domain (đối với quy trình) có hậu tố là “_t”.
Cách xử lý truy cập tài nguyên
Lúc này, ta đã thấy rằng các file và quy trình có thể có các ngữ cảnh khác nhau và chúng bị giới hạn ở các loại hoặc domain riêng của chúng. Vậy một tiến trình chạy như thế nào? Để chạy, một tiến trình cần truy cập các file của nó và thực hiện một số hành động trên chúng (mở, đọc, sửa đổi hoặc thực thi). Ta cũng đã biết rằng mỗi quy trình chỉ có thể có quyền truy cập vào một số loại tài nguyên nhất định (tệp, folder , cổng, v.v.).
SELinux quy định các luật truy cập này trong một policy . Các luật truy cập tuân theo cấu trúc câu lệnh cho phép tiêu chuẩn:
allow <domain> <type>:<class> { <permissions> };
Ta đã nói về các domain và các loại. Lớp xác định những gì tài nguyên thực sự đại diện (tệp, folder , softlink , thiết bị, cổng, con trỏ, v.v.)
Đây là ý nghĩa của câu lệnh cho phép chung này:
- Nếu một quy trình thuộc domain nhất định
- Và đối tượng tài nguyên mà nó đang cố gắng truy cập thuộc loại và lớp nhất định
- Sau đó cho phép truy cập
- Khác từ chối quyền truy cập
Để xem cách này hoạt động như thế nào, hãy xem xét bối cảnh bảo mật của trình httpd đang chạy trên hệ thống CentOS 7 của ta :
system_u:system_r:httpd_t:s0 7126 ? 00:00:00 httpd system_u:system_r:httpd_t:s0 7127 ? 00:00:00 httpd system_u:system_r:httpd_t:s0 7128 ? 00:00:00 httpd system_u:system_r:httpd_t:s0 7129 ? 00:00:00 httpd system_u:system_r:httpd_t:s0 7130 ? 00:00:00 httpd system_u:system_r:httpd_t:s0 7131 ? 00:00:00 httpd
Thư mục chính mặc định cho web server là /var/www/html
. Hãy tạo một file trong folder đó và kiểm tra ngữ cảnh của nó:
- touch /var/www/html/index.html
- ls -Z /var/www/html/*
Ngữ cảnh file cho nội dung web của ta sẽ là httpd_sys_content_t :
-rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 /var/www/html/index.html
Ta có thể sử dụng lệnh sesearch
để kiểm tra loại truy cập được phép cho daemon httpd:
- sesearch --allow --source httpd_t --target httpd_sys_content_t --class file
Các cờ được sử dụng với lệnh này khá dễ hiểu: domain nguồn là httpd_t , cùng một domain Apache đang chạy. Ta quan tâm đến tài nguyên đích là file và có ngữ cảnh kiểu httpd_sys_content_t . Đầu ra của bạn sẽ giống như sau:
Found 4 semantic av rules: allow httpd_t httpd_sys_content_t : file { ioctl read getattr lock open } ; allow httpd_t httpd_content_type : file { ioctl read getattr lock open } ; allow httpd_t httpd_content_type : file { ioctl read getattr lock open } ; allow httpd_t httpdcontent : file { ioctl read write create getattr setattr lock append unlink link rename execute open } ;
Lưu ý dòng đầu tiên:
allow httpd_t httpd_sys_content_t : file { ioctl read getattr lock open } ;
Điều này nói rằng daemon httpd ( web server Apache) có quyền điều khiển I / O, đọc, lấy thuộc tính, khóa và mở quyền truy cập vào các file thuộc loại httpd_sys_content . Trong trường hợp này, index.html
của ta có cùng loại.
Tiến thêm một bước nữa, trước tiên hãy sửa đổi trang web ( /var/www/html/index.html
). Chỉnh sửa file để chứa nội dung này:
<html> <title> This is a test web page </title> <body> <h1>This is a test web page</h1> </body> </html>
Tiếp theo, ta sẽ thay đổi quyền của folder /var/www/
và nội dung của nó, tiếp theo là khởi động lại daemon httpd:
- chmod -R 755 /var/www
- service httpd restart
Sau đó, ta sẽ cố gắng truy cập nó từ trình duyệt:
Ghi chú
Tùy thuộc vào cách server của bạn được cài đặt , bạn có thể phải bật cổng 80 trong firewall IPTables để cho phép truy cập HTTP đến từ bên ngoài server . Ta sẽ không đi vào chi tiết về cách kích hoạt các cổng trong IPTables tại đây. Có một số bài báo DigitalOcean tuyệt vời về chủ đề mà bạn có thể sử dụng.
Càng xa càng tốt. Daemon httpd được phép truy cập một loại file cụ thể và ta có thể thấy nó khi truy cập qua trình duyệt. Tiếp theo, hãy làm cho mọi thứ khác đi một chút bằng cách thay đổi ngữ cảnh của file . Ta sẽ sử dụng lệnh chcon
cho nó. Cờ --type
cho lệnh cho phép ta chỉ định một kiểu mới cho tài nguyên đích. Ở đây, ta đang thay đổi loại file thành var_t .
- chcon --type var_t /var/www/html/index.html
Ta có thể xác nhận việc thay đổi loại:
- ls -Z /var/www/html/
-rwxr-xr-x. root root unconfined_u:object_r:var_t:s0 index.html
Tiếp theo, khi ta cố gắng truy cập trang web (tức là trình httpd cố gắng đọc file ), bạn có thể gặp lỗi Forbidden hoặc bạn có thể thấy trang chung chung của CentOS "Testing 123":
Vậy điều gì đang xảy ra ở đây? Rõ ràng là một số quyền truy cập hiện đang bị từ chối, nhưng đó là quyền truy cập của ai? Theo như SELinux có liên quan, web server chỉ được phép truy cập một số loại file nhất định và var_t không phải là một trong những ngữ cảnh đó. Vì ta đã thay đổi ngữ cảnh của file index.html thành var_t, Apache không thể đọc được nữa và ta gặp lỗi.
Để làm cho mọi thứ hoạt động trở lại, hãy thay đổi loại file bằng lệnh restorecon
. Lựa chọn -v hiển thị sự thay đổi của các nhãn ngữ cảnh:
- restorecon -v /var/www/html/index.html
restorecon reset /var/www/html/index.html context unconfined_u:object_r:var_t:s0->unconfined_u:object_r:httpd_sys_content_t:s0
Nếu ta cố gắng truy cập trang bây giờ, nó sẽ hiển thị lại dòng chữ "Đây là trang web thử nghiệm".
Đây là một khái niệm quan trọng cần hiểu: đảm bảo các file và folder có ngữ cảnh chính xác là yếu tố then chốt đảm bảo SELinux đang hoạt động như bình thường. Ta sẽ thấy một trường hợp sử dụng thực tế ở cuối phần này, nhưng trước đó, hãy nói về một vài điều nữa.
Kế thừa ngữ cảnh cho các file và folder
SELinux thực thi một cái gì đó mà ta có thể gọi là "kế thừa ngữ cảnh". Điều này nghĩa là trừ khi được chỉ định bởi policy , các quy trình và file được tạo với ngữ cảnh của cha mẹ chúng.
Vì vậy, nếu ta có một quy trình được gọi là “proc_a” tạo ra một quy trình khác được gọi là “proc_b”, thì quy trình được tạo ra sẽ chạy trong cùng một domain với “proc_a” trừ khi được policy SELinux chỉ định khác.
Tương tự, nếu ta có một folder có kiểu “some_context_t”, thì các file hoặc folder nào được tạo trong đó sẽ có cùng loại ngữ cảnh trừ khi policy quy định khác.
Để minh họa điều này, hãy kiểm tra các ngữ cảnh của folder /var/www/
:
- ls -Z /var/www
Thư mục html
trong /var/www/
có ngữ cảnh kiểu httpd_sys_content_t . Như ta đã thấy trước đây, index.html
bên trong nó có cùng ngữ cảnh (tức là ngữ cảnh của file cha):
drwxr-xr-x. root root system_u:object_r:httpd_sys_script_exec_t:s0 cgi-bin drwxr-xr-x. root root system_u:object_r:httpd_sys_content_t:s0 html
Kế thừa này không được bảo toàn khi các file được sao chép sang một vị trí khác. Trong thao tác sao chép, file hoặc folder được sao chép sẽ giả định là ngữ cảnh loại của vị trí đích. Trong đoạn mã bên dưới, ta đang sao chép index.html
(với ngữ cảnh loại “httpd_sys_content_t”) vào folder /var/
:
- cp /var/www/html/index.html /var/
Nếu ta kiểm tra ngữ cảnh của file đã sao chép, ta sẽ thấy nó đã được thay đổi thành var_t , ngữ cảnh của folder mẹ hiện tại của nó:
- ls -Z /var/index.html
-rwxr-xr-x. root root unconfined_u:object_r:var_t:s0 /var/index.html
Sự thay đổi ngữ cảnh này có thể bị overrides bởi mệnh đề --preserver=context
trong lệnh cp
.
Khi các file hoặc folder được di chuyển, ngữ cảnh ban đầu được giữ nguyên. Trong lệnh sau, ta đang di chuyển /var/index.html
vào folder /etc/
:
- mv /var/index.html /etc/
Khi ta kiểm tra ngữ cảnh của file đã di chuyển, ta thấy rằng ngữ cảnh var_t đã được giữ nguyên trong folder /etc/
:
- ls -Z /etc/index.html
-rwxr-xr-x. root root unconfined_u:object_r:var_t:s0 /etc/index.html
Vậy tại sao ta lại quan tâm đến ngữ cảnh file ? Tại sao khái niệm sao chép và di chuyển này lại quan trọng? Hãy suy nghĩ về điều đó: có thể bạn đã quyết định sao chép tất cả các file HTML của web server của bạn vào một folder riêng trong folder root . Bạn đã làm điều này để đơn giản hóa quá trình backup và cũng để thắt chặt bảo mật: bạn không muốn bất kỳ hacker nào dễ dàng đoán được vị trí các file trang web . Bạn đã cập nhật kiểm soát truy cập của folder , thay đổi file cấu hình web để trỏ đến vị trí mới, khởi động lại dịch vụ nhưng vẫn không hoạt động. Có lẽ sau đó bạn có thể xem các bối cảnh của folder và các file của nó như là bước khắc phục sự cố tiếp theo. Hãy chạy nó như một ví dụ thực tế.
SELinux in Action: Kiểm tra lỗi ngữ cảnh file
Đầu tiên, hãy tạo một folder có tên www
dưới folder root . Ta cũng sẽ tạo một folder gọi là html
dưới www
.
- mkdir -p /www/html
Nếu ta chạy ls -Z
, ta sẽ thấy các folder này đã được tạo với ngữ cảnh default_t :
- ls -Z /www/
drwxr-xr-x. root root unconfined_u:object_r:default_t:s0 html
Tiếp theo, ta sao chép nội dung của folder /var/www/html
vào /www/html
:
- cp /var/www/html/index.html /www/html/
Tệp được sao chép sẽ có ngữ cảnh là default_t . Đó là bối cảnh của folder mẹ.
Bây giờ ta chỉnh sửa file httpd.conf
để trỏ đến folder mới này làm folder root của trang web. Ta cũng sẽ phải nới lỏng quyền truy cập cho folder này.
- vi /etc/httpd/conf/httpd.conf
Đầu tiên, ta comment vị trí hiện có cho root tài liệu và thêm chỉ thị DocumentRoot
mới vào /www/html
:
# DocumentRoot "/var/www/html" DocumentRoot "/www/html"
Ta cũng comment về phần quyền truy cập cho root tài liệu hiện có và thêm một phần mới:
#<Directory "/var/www"> # AllowOverride None # Allow open access: # Require all granted #</Directory> <Directory "/www"> AllowOverride None # Allow open access: Require all granted </Directory>
Ta giữ nguyên vị trí của folder cgi-bin
. Ta không đi sâu vào cấu hình Apache chi tiết ở đây; ta chỉ muốn trang web của ta hoạt động cho các mục đích SELinux.
Cuối cùng, khởi động lại daemon httpd:
- service httpd restart
Khi server đã được khởi động lại, việc truy cập trang web sẽ cho ta lỗi “403 Forbidden” (hoặc trang “Đang kiểm tra 123” mặc định) mà ta đã thấy trước đây.
Lỗi đang xảy ra do ngữ cảnh của file index.html
đã thay đổi trong quá trình sao chép. Nó cần được thay đổi về ngữ cảnh ban đầu (httpd_sys_content_t).
Nhưng ta làm như thế nào?
Thay đổi và khôi phục các khung cảnh file SELinux
Trong một mẫu mã trước đó, ta đã thấy hai lệnh để thay đổi nội dung file : chcon
và restorecon
. Chạy chcon
là một biện pháp tạm thời. Bạn có thể sử dụng nó để tạm thời thay đổi ngữ cảnh file hoặc folder để khắc phục lỗi từ chối truy cập. Tuy nhiên, phương pháp này chỉ là tạm thời: nhãn hệ thống file hoặc chạy lệnh restorecon
sẽ hoàn nguyên file về ngữ cảnh ban đầu.
Ngoài ra, việc chạy chcon
yêu cầu bạn phải biết ngữ cảnh chính xác cho file ; cờ --type
chỉ định ngữ cảnh cho đích. restorecon
không cần chỉ định này. Nếu bạn chạy restorecon
, file sẽ được áp dụng lại ngữ cảnh chính xác và các thay đổi sẽ được thực hiện vĩnh viễn.
Nhưng nếu bạn không biết ngữ cảnh chính xác của file , làm sao hệ thống biết được ngữ cảnh nào cần áp dụng khi chạy restorecon
?
Một cách thuận tiện, SELinux “ghi nhớ” ngữ cảnh của mọi file hoặc folder trong server . Trong CentOS 7, ngữ cảnh của các file đã tồn tại trong hệ thống được liệt kê trong file /etc/selinux/targeted/contexts/files/file_contexts
. Đó là một file lớn và nó liệt kê mọi loại file được liên kết với mọi ứng dụng được hỗ trợ bởi bản phân phối Linux. Bối cảnh của các folder và file mới được ghi lại trong file /etc/selinux/targeted/contexts/files/file_contexts.local
. Vì vậy, khi ta chạy lệnh restorecon
, SELinux sẽ tra cứu ngữ cảnh chính xác từ một trong hai file này và áp dụng nó cho đích.
Đoạn mã bên dưới hiển thị phần extract từ một trong các file :
- cat /etc/selinux/targeted/contexts/files/file_contexts
... /usr/(.*/)?lib(/.*)? system_u:object_r:lib_t:s0 /opt/(.*/)?man(/.*)? system_u:object_r:man_t:s0 /dev/(misc/)?agpgart -c system_u:object_r:agp_device_t:s0 /usr/(.*/)?sbin(/.*)? system_u:object_r:bin_t:s0 /opt/(.*/)?sbin(/.*)? system_u:object_r:bin_t:s0 /etc/(open)?afs(/.*)? system_u:object_r:afs_config_t:s0 ...
Để thay đổi vĩnh viễn ngữ cảnh của file index.html của ta trong /www/html
, ta phải thực hiện theo quy trình hai bước.
- Đầu tiên ta chạy lệnh
semanage fcontext
. Thao tác này sẽ ghi ngữ cảnh mới vào file/etc/selinux/targeted/contexts/files/file_contexts.local
. Nhưng nó sẽ không gắn nhãn lại cho chính file . Ta sẽ làm điều này cho cả hai folder .
- semanage fcontext --add --type httpd_sys_content_t "/www(/.*)?"
- semanage fcontext --add --type httpd_sys_content_t "/www/html(/.*)?"
Để đảm bảo, ta có thể kiểm tra database ngữ cảnh file ( lưu ý ta đang sử dụng file file_contexts.local
):
- cat /etc/selinux/targeted/contexts/files/file_contexts.local
Bạn sẽ thấy các bối cảnh được cập nhật:
# This file is auto-generated by libsemanage # Do not edit directly. /www(/.*)? system_u:object_r:httpd_sys_content_t:s0 /www/html(/.*)? system_u:object_r:httpd_sys_content_t:s0
Tiếp theo, ta sẽ chạy lệnh restorecon
. Điều này sẽ gắn nhãn lại file hoặc folder với những gì đã được ghi ở bước trước:
- restorecon -Rv /www
Điều này sẽ đặt lại ngữ cảnh ở ba cấp: cấp cao nhất /www
folder /www
, folder /www/html
dưới nó và index.html
trong /www/html
:
restorecon reset /www context unconfined_u:object_r:default_t:s0->unconfined_u:object_r:httpd_sys_content_t:s0 restorecon reset /www/html context unconfined_u:object_r:default_t:s0->unconfined_u:object_r:httpd_sys_content_t:s0 restorecon reset /www/html/index.html context unconfined_u:object_r:default_t:s0->unconfined_u:object_r:httpd_sys_content_t:s0
Nếu bây giờ ta cố gắng truy cập trang web, nó sẽ hoạt động.
Có một công cụ tiện lợi được gọi là matchpathcon
có thể giúp khắc phục các sự cố liên quan đến ngữ cảnh. Lệnh này sẽ xem xét ngữ cảnh hiện tại của một tài nguyên và so sánh nó với những gì được liệt kê trong database ngữ cảnh SELinux. Nếu khác, nó sẽ đề xuất thay đổi cần thiết. Hãy kiểm tra điều này với file /www/html/index.html
. Ta sẽ sử dụng cờ -V
xác minh ngữ cảnh:
- matchpathcon -V /www/html/index.html
Đầu ra matchpathcon
phải cho thấy rằng ngữ cảnh đã được xác minh.
/www/html/index.html verified.
Đối với file được gắn nhãn không chính xác, thông báo sẽ cho biết ngữ cảnh phải là:
/www/html/index.html has context unconfined_u:object_r:default_t:s0, should be system_u:object_r:httpd_sys_content_t:s0
Chuyển đổi domain
Cho đến nay ta đã thấy cách các quy trình truy cập tài nguyên hệ thống file . Bây giờ ta sẽ xem cách các quy trình truy cập các quy trình khác.
Chuyển đổi domain là phương pháp trong đó quá trình thay đổi ngữ cảnh của nó từ domain này sang domain khác. Để hiểu nó, giả sử bạn có một quy trình gọi là proc_a đang chạy trong ngữ cảnh của contexta_t. Với quá trình chuyển đổi domain , proc_a có thể chạy một ứng dụng (một chương trình hoặc một tập lệnh thực thi) được gọi là app_x sẽ tạo ra một quy trình khác. Quá trình mới này có thể được gọi là proc_b và nó có thể đang chạy trong domain contextb_t. Vì vậy, hiệu quả là contexta_t đang chuyển đổi sang contextb_t thông qua app_x. File thực thi app_x đang hoạt động như một điểm vào của contextb_t. Dòng chảy có thể được minh họa dưới đây:
Trường hợp chuyển đổi domain khá phổ biến trong SELinux. Hãy xem xét quá trình vsftpd đang chạy trên server của ta . Nếu nó không chạy, ta có thể chạy lệnh service vsftpd start
để khởi động daemon.
Tiếp theo, ta xem xét quy trình systemd. Đây là tổ tiên của tất cả các quy trình. Đây là sự thay thế của quá trình System V init và chạy trong ngữ cảnh của init_t . :
- ps -eZ | grep init
system_u:system_r:init_t:s0 1 ? 00:00:02 systemd system_u:system_r:mdadm_t:s0 773 ? 00:00:00 iprinit
Quá trình chạy trong domain init_t là quá trình tồn tại trong thời gian ngắn: nó sẽ gọi file thực thi binary /usr/sbin/vsftpd
, có ngữ cảnh kiểu ftpd_exec_t . Khi file thực thi binary bắt đầu, nó trở thành daemon vsftpd và chạy trong domain ftpd_t .
Ta có thể kiểm tra bối cảnh domain của các file và quy trình:
- ls -Z /usr/sbin/vsftpd
Cho ta thấy:
-rwxr-xr-x. root root system_u:object_r:ftpd_exec_t:s0 /usr/sbin/vsftpd
Kiểm tra quá trình:
- ps -eZ | grep vsftpd
Cho ta thấy:
system_u:system_r:ftpd_t:s0-s0:c0.c1023 7708 ? 00:00:00 vsftpd
Vì vậy, ở đây quá trình chạy trong domain init_t đang thực thi một file binary với kiểu ftpd_exec_t . Tệp đó bắt đầu một daemon trong domain ftpd_t .
Quá trình chuyển đổi này không phải là thứ mà ứng dụng hoặc user có thể kiểm soát. Điều này đã được quy định trong policy SELinux tải vào bộ nhớ khi hệ thống khởi động. Trong một server không phải của SELinux, user có thể bắt đầu một quy trình bằng cách chuyển sang một account mạnh hơn (miễn là họ có quyền làm như vậy). Trong SELinux, việc truy cập như vậy được kiểm soát bởi các policy được viết sẵn. Và đó là một lý do khác mà SELinux được cho là thực hiện Kiểm soát Truy cập Bắt buộc.
Quá trình chuyển đổi domain tuân theo ba luật nghiêm ngặt:
Tiến trình mẹ của domain nguồn phải có quyền thực thi đối với ứng dụng nằm giữa cả hai domain (đây là điểm vào ).
Bối cảnh file cho ứng dụng phải được xác định như một điểm vào cho domain đích.
Miền root phải được phép chuyển đổi sang domain đích.
Lấy ví dụ daemon vsftpd ở trên, hãy chạy lệnh sesearch
với các lựa chọn khác nhau để xem liệu daemon có tuân theo ba luật này hay không.
Đầu tiên, domain nguồn init_t cần có quyền thực thi trên ứng dụng entrypoint với ngữ cảnh ftpd_exec_t. Vì vậy, nếu ta chạy lệnh sau:
- sesearch -s init_t -t ftpd_exec_t -c file -p execute -Ad
Kết quả cho thấy rằng các quy trình trong domain init_t có thể đọc, lấy thuộc tính, thực thi và mở các file của ngữ cảnh ftpd_exec_t:
Found 1 semantic av rules: allow init_t ftpd_exec_t : file { read getattr execute open } ;
Tiếp theo, ta kiểm tra xem file binary có phải là điểm nhập cho domain đích ftpd_t hay không:
sesearch -s ftpd_t -t ftpd_exec_t -c file -p entrypoint -Ad
Và thực sự là như vậy:
Found 1 semantic av rules: allow ftpd_t ftpd_exec_t : file { ioctl read getattr lock execute execute_no_trans entrypoint open } ;
Và cuối cùng, domain nguồn init_t cần có quyền chuyển đổi sang domain đích ftpd_t:
- sesearch -s init_t -t ftpd_t -c process -p transition -Ad
Như ta có thể thấy bên dưới, domain nguồn có quyền đó:
Found 1 semantic av rules: allow init_t ftpd_t : process transition ;
Miền không xác định
Khi ta đưa ra khái niệm domain , ta đã so sánh nó với một bong bóng giả định xung quanh quy trình: một thứ quy định những gì quy trình có thể và không thể làm. Đây là những gì hạn chế quá trình.
SELinux cũng có các quy trình chạy trong các domain chưa xác định. Như bạn có thể tưởng tượng, các quy trình không xác định sẽ có tất cả các loại quyền truy cập trong hệ thống. Ngay cả khi đó, toàn quyền truy cập này không phải là tùy ý: toàn quyền truy cập cũng được chỉ định trong policy SELinux.
Ví dụ về domain quy trình chưa xác định sẽ là domain không xác định_t. Đây là cùng một domain đã đăng nhập mà user chạy các quy trình của họ theo mặc định. Ta sẽ nói về user và quyền truy cập của họ để xử lý domain trong các phần tiếp theo.
Kết luận
Hôm nay, ta đã đề cập đến một số khái niệm SELinux rất quan trọng ở đây. Quản lý ngữ cảnh file và quy trình là trọng tâm của việc triển khai SELinux thành công. Như ta sẽ thấy trong phần tiếp theo và cuối cùng của loạt bài này , vẫn còn một mảnh ghép khác của câu đố: user SELinux.
Các tin liên quan
Giới thiệu về SELinux trên CentOS 7 - Phần 1: Các khái niệm cơ bản2014-09-05
Giới thiệu về SELinux trên CentOS 7 - Phần 3: Người dùng
2014-09-05
Cách cài đặt puppet ở chế độ độc lập trên CentOS 7
2014-09-04
Cách cài đặt Node.js trên server CentOS 7
2014-08-18
Cách sử dụng Logstash và Kibana để tập trung log trên CentOS 7
2014-07-15
Cách sử dụng Logstash và Kibana để tập trung log trên CentOS 6
2014-07-08
Cách thiết lập DavMail trên CentOS 6
2014-02-13
Cách cài đặt Ruby 2.1.0 trên CentOS 6.5 bằng RVM
2014-01-22
Cách cài đặt ZeroMQ từ nguồn trên VPS CentOS 6 x64
2013-12-23
Cách cài đặt Diễn đàn Máy đơn giản trên CentOS 6
2013-12-05