Xác thực qua PAM có thể thành công khi bạn chạy client bằng tay và thất bại với AUTH_FAILED ngay khi systemd khởi động cùng hồ sơ đó. Mật khẩu không đổi giữa các lần chạy ấy; thứ thay đổi là tập ràng buộc quanh tiến trình đặt câu hỏi cho PAM. PAM trả lời qua một helper mà khả năng tự đổi thông tin xác thực của nó chính là thứ một unit được gia cố loại bỏ. Hãy tìm helper đó và ranh giới nó cần trước khi chạm vào danh sách năng lực.

unix_chkpwd là tệp nhị phân trả lời câu hỏi của PAM

Với xác thực mật khẩu cục bộ, pam_unix hiếm khi tự đọc tệp băm. Nó chạy unix_chkpwd, thứ mà các bản phân phối cài đặt setuid root hoặc setgid shadow để một mật khẩu có thể được kiểm tra thay cho một tiến trình không có việc gì phải đọc /etc/shadow. Hãy bỏ khả năng giành lấy danh tính đó, helper không thể hoàn tất việc kiểm tra, nên mô-đun trả về một lỗi xác thực thông thường.

Sự cố khi đó trông như vấn đề thông tin xác thực trong mọi nhật ký mà client thấy được. Đó là cái bẫy: client báo lại điều PAM nói với nó, còn PAM chỉ báo rằng chồng xác thực đã nói không. Chạy helper bằng tay với quyền root cũng chẳng chứng minh gì, vì nó đi qua một đường quyền mà dịch vụ không bao giờ dùng. Hãy đọc unit mà systemd thực sự đã nạp, rồi đọc nhật ký hệ thống cho lần thử nó đã thực hiện. Hai góc nhìn đó tách một vấn đề sandbox khỏi một vấn đề sai mật khẩu.

Đọc unit trước khi đọc nhật ký mật khẩu

Một unit đóng gói có thể mang theo drop-in mà bạn không viết, và cấu hình hiệu lực là kết quả hợp nhất. Hãy in unit theo cách systemd nhìn thấy nó, cùng với các thiết lập sandbox quyết định việc helper có thể tự nâng quyền hay không. Ở giai đoạn này, kiểm tra chỉ đọc là đủ.

systemctl cat [email protected]
systemctl show [email protected] -p User -p Group -p CapabilityBoundingSet -p AmbientCapabilities -p NoNewPrivileges
journalctl -u [email protected] -b

Lệnh đầu tiên cho thấy unit và các drop-in của nó đến từ đâu, điều này quan trọng vì một ghi đè thêm vào vài tháng trước sống lâu hơn ký ức về lý do nó tồn tại. Lệnh thứ hai in các giá trị sandbox mà hai mục tiếp theo dựa vào.

Hãy so sánh những gì bạn thấy với một máy chủ đang chạy tốt cùng bản phân phối và phiên bản. Một khác biệt ở User, CapabilityBoundingSet hoặc NoNewPrivileges là manh mối cụ thể; một khác biệt trong phần bình luận văn xuôi thì không. Hãy ghi lại các giá trị trước khi thay đổi bất cứ thứ gì, vì so sánh về sau với một mục tiêu đang động chẳng chứng minh gì. Nếu dịch vụ chạy dưới một tài khoản không đặc quyền với tập giới hạn rỗng, helper gần như chẳng có gì để làm việc.

Chuyển đổi thông tin xác thực, truy cập tệp và chính sách là ba ranh giới

Bắt đầu từ điều xảy ra trong lúc exec. Một tệp nhị phân setuid hay một tệp mang file capabilities kích hoạt việc chuyển đổi thông tin xác thực, nên danh tính tạo ra không phải là phần tiếp nối của bên gọi. Tập giới hạn chặn thứ mà tệp nhị phân như vậy có thể giành được, và NoNewPrivileges chặn hoàn toàn việc giành setuid, setgid và file capabilities. Bất kỳ điều nào trong ba điều đó đều có thể dừng helper trong khi mọi chức năng khác của dịch vụ vẫn nguyên vẹn.

Tiếp theo, hãy tách việc vượt qua kiểm soát tùy ý trên diện rộng khỏi quyền đọc hẹp. CAP_DAC_OVERRIDE bỏ qua các kiểm tra tùy ý ở gần như mọi nơi, trong khi CAP_DAC_READ_SEARCH bao gồm việc đọc và duyệt thư mục với những quyền bổ sung riêng. Chúng là những công cụ khác nhau với bán kính ảnh hưởng khác nhau, và không cái nào là cách viết hãy để PAM đọc tệp shadow.

Cuối cùng, hãy hỏi liệu chính sách bắt buộc có cho phép hành động đó hay không. Một năng lực Linux không ghi đè SELinux, và có nó chẳng chứng minh gì về một quy tắc thực thi kiểu. Hãy coi việc từ chối truy cập tệp và việc từ chối một năng lực là hai bằng chứng khác nhau, vì chúng nêu ra những cách sửa khác nhau và thường là những người phụ trách khác nhau. Hãy đọc mọi trường của bản ghi thay vì chỉ một từ denied. Tệp thực thi nào đã làm hành động, nó chạy trong miền nào, nó chạm vào kiểu mục tiêu nào, lớp đối tượng nào liên quan và chính sách đã từ chối quyền nào - mỗi điều đó thu hẹp câu trả lời theo một cách khác.

Lôi việc từ chối ra khỏi nhật ký kiểm toán

Trên một máy chủ ở chế độ enforcing, dấu vết kiểm toán là nơi duy nhất ghi lại một lần từ chối. Hãy truy vấn các sự kiện gần đây và đọc chúng theo dấu thời gian của lần đăng nhập thất bại, không phải theo thời điểm bạn bắt đầu điều tra.

ausearch -m AVC,USER_AVC -ts recent

Một kết quả rỗng không phải bằng chứng của sự vô tội. Nó có nghĩa hoặc là kiểm toán không thu thập dữ liệu, hoặc là cửa sổ của bạn đã bỏ sót lần thử, và cả hai khả năng đều phải được loại trừ trước khi bạn loại trừ chính sách.

Hướng dẫn khắc phục sự cố SELinux của Red Hat đặt việc kiểm tra nhãn và cấu hình trước việc tạo quy tắc cho phép, đó cũng là thứ tự đúng cho vấn đề này. Một tệp nhị phân helper bị dán nhãn sai và một lỗ hổng trong chính sách tạo ra những lần từ chối tương tự nhưng cần cách sửa khác nhau. Tạo một quy tắc cho phép cho lỗi dán nhãn sẽ che giấu khiếm khuyết và để bản cập nhật gói tiếp theo đưa nó trở lại. Hãy xác nhận nhãn trên helper đã cài trước khi viết bất kỳ chính sách nào.

Chứng minh thay đổi bằng một lần đăng nhập được nhận và một lần bị từ chối

Chỉ thay đổi ranh giới mà bạn đã chứng minh, rồi kiểm tra cả hai kết cục. Một tài khoản cần xác thực phải thành công, và một tài khoản sai mật khẩu vẫn phải thất bại. Một thay đổi khiến mọi lần thử đều thành công là đã gỡ bỏ xác thực chứ không phải đã sửa nó.

Hãy thực hiện một lần kết nối thật và đọc nhật ký ngay sau đó. Dòng chứng minh bản sửa là mục pam_unix(openvpn:auth) cho lần thử đó: nó phải ghi xác thực thành công, và không bản ghi AVC nào được mang cùng giây đó.

journalctl -u [email protected] -n 30 --no-pager
ss -tnp | grep openvpn

Một đường hầm chạy được cũng cần kết nối lại, vì các thay đổi sandbox phá lần kết nối thứ hai thường xuyên hơn lần đầu. Hãy kiểm tra ổ cắm đã thiết lập sau khi kết nối lại và xác nhận vẫn chính unit đó phục vụ nó.

Bài viết liên quan