‫Tiếp theo một lên.
‫Đây là một vấn đề lớn.
‫Không chạy ứng dụng của bạn dưới dạng root trong vùng chứa nếu bạn
‫có thể tránh được.
‫Nếu tôi làm điều này thực sự nhanh chóng, trên một bản demo
‫nhỏ ở đây.
‫Được rồi. Tôi có Docker đang chạy, ít nhất tôi
‫nên làm như vậy. Được rồi.
‫Và nếu tôi chỉ chạy ...
‫Nếu tôi chỉ chạy Nginx, đúng rồi, và tôi
‫tạo một docker trên vùng
‫chứa đó.
‫Chúng ta thấy gì ở đây?
‫Bên trong vùng chứa, Nginx bắt đầu một quy trình ở
‫gốc, và sau đó nó tạo một quy trình
‫mới với tư cách là người dùng không phải
‫root. Xem người dùng đó 101 tuổi như thế nào.
‫Đây là điều phổ biến của rất nhiều chương trình dựa
‫trên daemon như MySQL, Postgres, Nginx.
‫Rất nhiều trong số chúng không phải là ngôn ngữ lập trình sẽ
‫tự động làm điều này. Vì vậy, điều này là an toàn.
‫Điều này đang làm là cho phép Nginx sinh ra
‫các quy trình worker không chạy dưới quyền root
‫để thực hiện phần lớn công việc.
‫Vì vậy, họ có một quy trình chính chạy dưới dạng root, nhưng đó
‫không phải là thứ chấp nhận kết nối và thực hiện
‫phần lớn công việc. Hầu hết đó là
‫trong các quy trình công nhân này. Họ chạy như một người dùng bình
‫thường, có nghĩa là nếu có lỗ hổng trong Nginx, rất có
‫thể khi các kết nối đến đang đến
‫và ai đó đang cố gắng khai thác giao thức Nginx
‫HTTP, nó sẽ bị khóa hoặc bỏ tù, đối với người dùng này
‫tại .. . hầu hết thời gian trừ khi
‫có một lỗ hổng nghiêm trọng ở đây.
‫Dưới đây, và sau đó họ bị giới hạn những gì họ có
‫thể làm, phải không. Ngay cả khi họ tiếp quản quá trình
‫đó bằng cách nào đó, họ vẫn bị giới hạn với tư cách là người dùng.
‫Vì vậy, điều này là OK.
‫Điều này vẫn không chạy dưới dạng root thực
‫sự bên trong vùng chứa. Những gì tôi thực sự đang nói
‫đến là nếu bạn chạy một
‫ứng dụng Python hoặc một ứng dụng Node, hoặc
‫một cái gì đó tương tự mà nó là một ngôn ngữ lập trình, thì
‫đó sẽ là thứ được mặc định là root vì ngôn
‫ngữ lập trình trong vùng chứa không ' t biết chương trình của bạn
‫hoạt động như thế nào. Nó không biết bạn muốn nó làm gì.
‫Vì vậy, nó sẽ thực hiện root theo mặc định, và đó là
‫nhiều hơn về khả năng tương thích của ứng dụng.
‫Chúng tôi có thể nói rằng chúng tôi muốn điều này được bảo mật
‫theo mặc định, nhưng Docker đã chọn để tất cả các vùng chứa chính thức này thực sự
‫chạy dưới dạng root cho các ngôn ngữ lập trình.
‫Hãy đi kiểm tra xem.
‫Ối. Không phải cái đó.
‫Firefox.
‫Vì vậy, nếu chúng ta đi, hãy nói, hãy chuyển sang Hub.
‫Hãy chỉ làm Node.
‫Điều này là phổ biến của hầu hết các ngôn ngữ.
‫Tôi chỉ lấy Node làm ví dụ.
‫Inside Node, nếu
‫tôi đi vào một trong các Dockerfiles ở đây.
‫Sau đó, tôi tìm kiếm người dùng.
‫Bạn sẽ nhận thấy rằng tôi không thực sự tìm thấy bất cứ điều gì.
‫Nó chỉ có người dùng này thêm ở đây.
‫Bạn sẽ nhận thấy rằng nó thực hiện điều này, đúng.
‫Về mặt kỹ thuật, nó thêm một nhóm có tên là Node và nó
‫thêm một người dùng được gọi là Node.
‫Nếu bạn tìm kiếm phần còn lại của tệp này, bạn nhận ra rằng nó không bao
‫giờ thay đổi đối với người dùng đó với khổ thơ U S
‫E R, đúng không.
‫Bạn sẽ thấy nút người dùng ở đó ở đâu đó dưới dạng một dòng.
‫Họ không làm vậy vì đó là công việc của bạn.
‫Vì vậy, những gì bạn nên làm trong Dockerfile
‫cấp thấp của mình. Vì vậy, bất kỳ Dockerfile
‫nào bạn đang tạo từ những hình ảnh chính thức
‫này cho các ngôn ngữ lập trình, bạn nên tận dụng lợi thế của những
‫người dùng mà họ đang tạo cho bạn. Nếu họ không tạo những người dùng đó, bạn có thể tự
‫tạo một người dùng theo cách tương tự. Bạn chỉ có thể
‫đánh cắp thứ hai dòng nhỏ này và thay đổi thành bất
‫kỳ người dùng nào bạn muốn. Nếu nó dành cho Python, bạn có
‫thể chỉ cần gọi nó là người dùng Python, bất cứ điều gì.
‫Nếu bạn đang làm điều đó, thì các ứng
‫dụng bạn chạy sẽ không chạy dưới quyền root trong
‫vùng chứa. Theo mặc định,
‫nếu bạn chỉ chạy bất kỳ ứng dụng Node tiêu chuẩn nào, ứng dụng đó sẽ sử dụng người
‫dùng gốc trong một vùng chứa.
‫Tại sao cái này lại quan trọng đến vậy?
‫Vâng, hai điều.
‫Một, nếu ai đó có thể đột nhập ứng dụng của bạn
‫và xâm nhập vào ứng dụng của bạn và giành quyền truy cập
‫vào hệ thống tệp, nếu họ ... nếu ứng dụng đó là root, thì trong
‫vùng chứa, họ có thể làm bất cứ điều gì họ muốn trong
‫vùng chứa, đúng không. Họ có thể
‫ghi tệp vào hệ thống tệp. Họ có thể cài đặt nhiều chương trình hơn trong vùng
‫chứa đó có thể chạy bất cứ khi nào họ muốn trong vùng chứa đó.
‫Vì vậy, chúng tôi thực sự không muốn họ làm điều đó.
‫Chúng tôi muốn chúng rất hạn chế.
‫Vì vậy, nếu ứng dụng của bạn hỗ trợ nó,
‫bạn biết đấy, hãy làm điều này. Về cơ bản, bạn đảm bảo rằng bạn
‫có sẵn người dùng.
‫Sau đó, tôi có một ví dụ từ DockerCon ở đây.
‫Tại DockerCon, tôi đã có một buổi nói chuyện toàn bộ về Node. js, và một trong
‫những chủ đề là về người dùng.
‫Hãy để tôi xem nếu tôi có thể tìm thấy điều đó.
‫Xem những gì tôi đã làm ở đây? Nó là một tập tin khá đơn giản.
‫Tôi sẽ liên kết cái này và đưa nó vào.
‫Trong Dockerfile này.
‫Vì vậy, trong Dockerfile này, tôi có ...
‫Tôi không tạo người dùng vì hình ảnh
‫Node đã tạo cho tôi. Tôi chỉ thay đổi thành nút người dùng.
‫Sau đó, tôi đang cài đặt các gói của mình với hai dòng này và sau
‫đó, tôi sẽ chạy nó.
‫Bạn sẽ nhận thấy rằng tôi phải bắt đầu
‫sử dụng tùy chọn chown trong các lệnh sao chép của mình để đảm bảo rằng các
‫tệp của tôi bây giờ là người dùng giống như người dùng mà chương trình
‫của tôi sẽ chạy. Nếu không, có thể có vấn đề,
‫phải không. Ứng dụng của tôi có lẽ ... nếu
‫nó không thể đọc các tập tin, thì nó không thể chạy nó, phải không.
‫Vì vậy, tôi cần thay đổi các quyền đó.
‫Tôi có thể làm điều đó với một lớp lót trên lệnh sao chép.
‫Bạn cũng sẽ thấy ở đây rằng tôi đang tạo thư mục và cũng
‫chia nhỏ nó để bất cứ khi nào ứng dụng được sao chép
‫vào, tôi chỉ muốn đảm bảo, cực kỳ chắc chắn rằng
‫các quyền ở đó để nó có thể viết.
‫Bởi vì phút tôi thay đổi người dùng này, thì
‫lệnh sao chép này, hoặc cụ thể là lệnh chạy này, sẽ chạy với tư
‫cách người dùng đó. Nếu nó không có quyền
‫ghi vào các thư mục, thì nó cũng sẽ không thành công.
‫Vì vậy, lý do mà Docker không làm điều này cho bạn là bởi vì họ
‫biết rằng mọi thứ của bạn có thể sẽ bị hỏng.
‫Vì vậy, bạn cần thực hiện thêm các bước này.
‫Nhưng, không khó lắm đâu. Nó thực sự không phải.
‫Bạn có thể thực hiện tất cả kiểm tra này trong một ngày và
‫sau đó bạn sẽ muốn chạy hệ thống của mình thông qua CI đầy đủ
‫và kiểm tra đầy đủ trên máy chủ của bạn bởi vì đôi khi, và PHP là
‫một trong những thứ không tốt trong việc này.
‫PHP thích chạy một loạt các tệp nhật ký và thực hiện
‫một loạt các ghi vào đĩa.
‫Thực sự, bất cứ thứ gì cho phép người dùng tải lên sẽ
‫được ghi vào đĩa. Vì vậy, bạn phải đảm
‫bảo các quyền đó là chính xác để khi mọi người đang viết tệp, chẳng hạn như
‫giả sử họ đang chạy một blog WordPress.
‫Blog WordPress đó sẽ được ghi vào đĩa khi người dùng
‫tải hình ảnh lên blog của họ.
‫Bạn muốn đảm bảo rằng các quyền đó sẽ hoạt động.
‫Vì vậy, bạn chắc chắn sẽ phải thực hiện một số thử nghiệm.
‫Khi bạn đã thực hiện xong điều đó, bây giờ ứng dụng của
‫bạn sẽ không chạy dưới dạng root. Vì vậy, nó không thể có toàn
‫quyền kiểm soát trong vùng chứa. Một lý do khác
‫mà bạn muốn làm điều này là nếu có một
‫lỗ hổng trong Linux, rất hiếm hoặc Docker, cũng rất hiếm,
‫thì khả năng chúng sẽ thoát ra khỏi vùng
‫chứa này sẽ ít hơn. Điều đó chỉ xảy ra, à, một
‫lần mà tôi rất biết, và tôi thực sự ghi lại một chút
‫về nó ở đây.
‫BÒ bẩn. Dirty COW là
‫một lỗ hổng trong Linux cho phép bạn thoát
‫ra khỏi
‫vùng chứa, đúng không. Việc thay đổi người dùng của bạn ngay
‫tại đây, không nhất
‫thiết phải giải quyết được toàn bộ vấn đề, nhưng
‫chắc chắn nó không ảnh hưởng đến vấn đề đó.
‫Các lỗ hổng bảo mật khác, nó có thể sẽ bảo vệ chống lại.
‫Nhưng đây là một thực hành tốt nhất.
‫Tôi nghĩ rằng nếu bạn có một nhóm bảo mật,
‫họ sẽ khăng khăng rằng bạn không chạy mọi thứ dưới dạng root.
‫Vì vậy, bạn sẽ làm
‫điều đó.