Những lợi thế của việc đặt các giá trị bí mật của một trang web là các biến môi trường là gì?


24

Các hướng dẫn của devops tại https://12factor.net/config đề nghị đưa bí mật trang web (mật khẩu cơ sở dữ liệu, khóa api, v.v.) vào các biến môi trường. Những lợi thế nào có thay vì sử dụng các tệp văn bản (JSON, XML, YAML, INI hoặc tương tự) bị bỏ qua khỏi kiểm soát phiên bản?

Tôi thấy việc sao chép một tệp cấu hình với các bí mật dễ dàng hơn nhiều so với việc xử lý các biến môi trường trong cấu hình .bash_profile và máy chủ web. Tôi có bỏ lỡ điều gì không?


1
Về lý thuyết, việc đọc một tệp dễ dàng hơn bộ nhớ để bạn có thể xem xét bề mặt tấn công lớn hơn và độ phức tạp nhỏ hơn.
Florin Asăvoaie

Nguyên tắc cơ bản của anh chàng nhà phát triển của tôi là lưu trữ các thiết lập trong các biến môi trường là tốt nhất chỉ được thực hiện trong các môi trường giống như docker. Ngoài máy ảo container, anh ta chấp thuận / thích tất cả các điểm khác của 12factor.net và việc sử dụng các tệp cấu hình. Không ai trong chúng ta thích bản chất không an toàn của các biến môi trường khi triển khai máy chủ thông thường.
Corey Ogburn

Câu trả lời:


21

Tác giả liệt kê lý do của họ, mặc dù nó hơi rời rạc. Đối số chính của họ là dễ dàng vô tình kiểm tra tệp cấu hình và các tệp cấu hình đó có các định dạng khác nhau và có thể nằm rải rác trên hệ thống (cả ba đều là đối số tầm thường tốt nhất cho cấu hình liên quan đến bảo mật như mã xác thực và thông tin xác thực).

Theo kinh nghiệm của riêng tôi, về cơ bản, bạn có ba tùy chọn sau, với các ưu điểm và nhược điểm liên quan:

Lưu trữ dữ liệu trong tập tin cấu hình.

Khi thực hiện phương pháp này, bạn nên cách ly chúng khỏi kho lưu trữ một cách lý tưởng và đảm bảo rằng chúng nằm ngoài khu vực mà ứng dụng lưu trữ nội dung của nó.

Ưu điểm:

  • Rất dễ dàng để cách ly và kiểm soát quyền truy cập, đặc biệt nếu bạn đang sử dụng những thứ như SELinux hoặc AppArmor để cải thiện bảo mật hệ thống tổng thể.
  • Nói chung dễ dàng thay đổi cho người dùng không có kỹ thuật (đây là một lợi thế cho phần mềm được xuất bản, nhưng không nhất thiết phải là phần mềm dành riêng cho tổ chức của bạn).
  • Dễ dàng quản lý trên các nhóm lớn máy chủ. Có tất cả các loại công cụ để triển khai cấu hình ngoài kia.
  • Hợp lý dễ dàng để xác minh cấu hình chính xác đang được sử dụng là gì.
  • Đối với một ứng dụng được viết tốt, bạn thường có thể thay đổi cấu hình mà không làm gián đoạn dịch vụ bằng cách cập nhật tệp cấu hình và sau đó gửi tín hiệu cụ thể đến ứng dụng (thường là SIGHUP).

Nhược điểm:

  • Lập kế hoạch thích hợp là cần thiết để giữ an toàn cho dữ liệu.
  • Bạn có thể phải học các định dạng khác nhau (mặc dù ngày nay chỉ có một số ít phải lo lắng và chúng thường có cú pháp tương tự).
  • Các vị trí lưu trữ chính xác có thể được mã hóa cứng trong ứng dụng, khiến việc triển khai có thể gặp vấn đề.
  • Phân tích cú pháp các tập tin cấu hình có thể có vấn đề.

Lưu trữ dữ liệu trong các biến môi trường.

Thông thường, điều này được thực hiện bằng cách tìm nguồn danh sách các biến và giá trị môi trường từ tập lệnh khởi động, nhưng trong một số trường hợp, nó có thể chỉ nêu chúng trên dòng lệnh trước tên chương trình.

Ưu điểm:

  • So với phân tích tệp cấu hình, việc kéo một giá trị ra khỏi biến môi trường là chuyện nhỏ trong bất kỳ ngôn ngữ lập trình nào.
  • Bạn không phải lo lắng nhiều về việc vô tình xuất bản cấu hình.
  • Bạn đạt được một mức độ bảo mật nào đó bằng cách che khuất bởi vì cách làm này không phổ biến và hầu hết những người hack ứng dụng của bạn sẽ không nghĩ đến việc xem xét các biến môi trường ngay lập tức.
  • Quyền truy cập có thể được kiểm soát bởi chính ứng dụng (khi nó sinh ra các tiến trình con, nó có thể dễ dàng xóa sạch môi trường để xóa thông tin nhạy cảm).

Nhược điểm

  • Trên hầu hết các hệ thống UNIX, thật dễ dàng để có quyền truy cập vào các biến môi trường của quy trình. Một số hệ thống cung cấp các cách để giảm thiểu điều này ( ví dụ hidepidtùy chọn gắn kết /proctrên LInux), nhưng chúng không được bật theo mặc định và không bảo vệ chống lại các cuộc tấn công từ người dùng sở hữu quy trình.
  • Thật không tầm thường khi thấy các cài đặt chính xác mà một cái gì đó đang sử dụng nếu bạn xử lý chính xác vấn đề bảo mật được đề cập ở trên.
  • Bạn phải tin tưởng ứng dụng để cọ rửa môi trường khi nó sinh ra các tiến trình con, nếu không nó sẽ rò rỉ thông tin.
  • Bạn không thể dễ dàng thay đổi cấu hình mà không cần khởi động lại hoàn toàn ứng dụng.

Sử dụng các đối số dòng lệnh để truyền vào dữ liệu.

Nghiêm túc, tránh điều này bằng mọi giá, nó không an toàn và nó là một nỗi đau ở mông để duy trì.

Ưu điểm:

  • Thậm chí đơn giản để phân tích cú pháp hơn các biến môi trường trong hầu hết các ngôn ngữ.
  • Các tiến trình con không tự động kế thừa dữ liệu.
  • Cung cấp một cách dễ dàng để nhanh chóng kiểm tra các cấu hình cụ thể khi phát triển ứng dụng.

Nhược điểm:

  • Giống như các biến môi trường, thật dễ dàng để đọc dòng lệnh của quy trình khác trên hầu hết các hệ thống.
  • Vô cùng tẻ nhạt để cập nhật cấu hình.
  • Đặt giới hạn cứng cho thời gian cấu hình có thể là bao lâu (đôi khi thấp tới 1024 ký tự).

1
Một điểm không quan trọng là không khởi động (tái) khởi động máy chủ, mà không cần phải cung cấp bất kỳ mật khẩu thủ công nào, cuối cùng chúng ở đâu đó trên đĩa cho điều đó
PlasmaHH

7
Trên hầu hết các hệ thống UNIX, bạn có thể đọc khá nhiều bất kỳ biến môi trường quy trình nào mà không cần bất kỳ đặc quyền quan trọng nào. -- Bạn có thể mở rộng về điều đó? Tệp / Proc / #### / môi trường chỉ có thể đọc được bởi chủ sở hữu, vì vậy bạn cần phải root hoặc có sudo.
rrauenza

Tôi nghĩ rằng một số xu hướng cấu hình env này cũng xuất phát từ những thứ như docker nơi bạn sử dụng một thùng chứa tiêu chuẩn và định cấu hình nó bằng cách chuyển các biến env cho vùng chứa.
rrauenza

@rrauenza Quyền sở hữu của một quy trình không phải là một đặc quyền đáng kể trừ khi bạn làm rất tốt việc phân tách mọi thứ bằng tài khoản và bạn thực sự chỉ cần khả năng của CAP_SYS_ADMIN (mà root hoàn toàn có) nếu bạn không phải là chủ sở hữu. Ngoài ra, liên quan đến điều biến môi trường, có lẽ bạn đúng, nhưng đó là một thiết kế bên lề ngay cả với Docker.
Austin Hemmelgarn

3
Tôi đồng ý với quan điểm @rrauenza đưa ra. Câu trả lời là khá tuyệt vời xung quanh, nhưng tôi muốn làm rõ về cách chính xác bạn có thể đọc khá nhiều bất kỳ biến môi trường quy trình nào mà không cần bất kỳ đặc quyền quan trọng nào . Về " và bạn thực sự chỉ cần khả năng CAP_SYS_ADMIN (mà root hoàn toàn có) ...", nếu một tác nhân độc hại có quyền root, thảo luận thêm là dư thừa và CAP_SYS_ADMIN cũng có thể là đặc quyền gốc (xem man7.org/linux /man-pages/man7/capabilities.7.html , CAP_SYS_ADMINGhi chú cho nhà phát triển kernel )
Nubarke

13

Các biến môi trường sẽ được kế thừa bởi mỗi tiến trình con của máy chủ web. Đó là mọi phiên kết nối với máy chủ và mọi chương trình được sinh ra bởi chúng. Các bí mật sẽ được tự động tiết lộ cho tất cả các quy trình đó.

Nếu bạn giữ bí mật trong các tệp văn bản, chúng phải có thể đọc được bởi quy trình máy chủ và do đó cũng có khả năng bởi mọi quy trình con. Nhưng ít nhất các chương trình phải đi và tìm thấy chúng; chúng không được cung cấp tự động. Bạn cũng có thể làm cho một số quy trình con chạy trong các tài khoản khác nhau và làm cho các bí mật chỉ có thể đọc được bằng các tài khoản đó. Ví dụ, suEXEC thực hiện điều này trong Apache.


1
"Đó là mỗi phiên kết nối với máy chủ" là một tuyên bố sai lệch. Bạn không thể mở phiên http đến máy chủ và có quyền truy cập vào các biến môi trường, bạn cũng không thể đăng nhập vào trình bao trên máy chủ đó và lấy chúng trừ khi bạn có quyền truy cập root hoặc sở hữu quy trình máy chủ web.
Segfault

Mọi quy trình được sinh ra bởi máy chủ web đều kế thừa môi trường của nó, trừ khi bạn thực hiện các bước hoạt động khác. Một trang HTML không có khả năng sử dụng thông tin đó, nhưng một tập lệnh thì có.
Andrew Schulman

Trong khi chính xác, câu trả lời này có thể làm với một số điều chỉnh / nhượng bộ, đặc biệt là liên quan đến các phiên học kỳ . Trong lần đọc đầu tiên, nó dường như vẽ việc sử dụng các biến môi trường trong một ánh sáng xấu gần như để đề xuất khả năng tiết lộ thông tin cho một khách hàng bên ngoài. Ngoài ra, một sự nhượng bộ có thể so sánh với suexec có thể được thực hiện đối với cài đặt giới hạn của env-vars, ví dụ như cài đặt env-vars (a la MYVAR=foo /path/to/some/executable) giới hạn cho một quá trình và chỉ dành cho trẻ em - và khi các trình nền chính cần thiết có thể chà / thiết lập lại / sửa đổi môi trường của các quá trình con.
shalomb

2

Ngay cả khi có một số sự đánh đổi liên quan đến bảo mật được thực hiện khi nói đến các biến hoặc tệp môi trường, tôi không nghĩ rằng bảo mật là động lực chính cho khuyến nghị này. Hãy nhớ rằng các tác giả của 12factor.net cũng là (hoặc cũng là?) Của Heroku PaaS. Bắt mọi người sử dụng các biến môi trường có thể đơn giản hóa sự phát triển của họ khá nhiều. Có rất nhiều định dạng và vị trí tập tin cấu hình khác nhau và thật khó để họ có thể hỗ trợ tất cả. Biến môi trường là dễ dàng trong so sánh.

Nó không mất nhiều trí tưởng tượng để đoán một số cuộc hội thoại đã có.

Nhà phát triển A: "Ah tệp UI cấu hình bí mật này quá lộn xộn! Chúng ta có thực sự cần phải có một trình đơn thả xuống giữa json, xml và csv không?"

Nhà phát triển B: "Ồ, cuộc sống sẽ rất tuyệt vời nếu chỉ có mọi người sử dụng các biến môi trường cho cấu hình ứng dụng."

Nhà phát triển A: "Trên thực tế có một số lý do liên quan đến bảo mật hợp lý để làm điều đó. Các biến môi trường có thể sẽ không được kiểm tra vô tình vào kiểm soát nguồn."

Nhà phát triển B: "Bạn không đặt các biến môi trường bằng một tập lệnh khởi chạy trình nền hay tập tin cấu hình?"

Nhà phát triển A: "Không có trong Heroku! Chúng tôi sẽ khiến họ nhập chúng vào UI."

Nhà phát triển B: "Ôi, cảnh báo tên miền của tôi cho 12factor.net vừa mới tắt."1


1 : nguồn: tạo thành.


1

TL; DR

Có một số lý do để sử dụng các biến môi trường thay vì các tệp cấu hình, nhưng hai lý do phổ biến nhất cần bỏ qua là giá trị tiện ích của cấu hình ngoài băng tầnphân tách nâng cao giữa các máy chủ, ứng dụng hoặc vai trò tổ chức. Thay vì trình bày một danh sách đầy đủ tất cả các lý do có thể, tôi chỉ đề cập đến hai chủ đề này trong câu trả lời của tôi và chạm nhẹ vào ý nghĩa bảo mật của chúng.

Cấu hình ngoài băng: Tách bí mật khỏi mã nguồn

Nếu bạn lưu trữ tất cả các bí mật của mình trong một tệp cấu hình, bạn phải phân phối các bí mật đó cho mỗi máy chủ. Điều đó có nghĩa là kiểm tra các bí mật trong kiểm soát sửa đổi cùng với mã của bạn hoặc có một kho lưu trữ hoặc cơ chế phân phối hoàn toàn riêng biệt cho các bí mật.

Mã hóa bí mật của bạn không thực sự giúp giải quyết vấn đề này. Tất cả những gì làm là đẩy vấn đề xuống một lần, bởi vì bây giờ bạn cũng phải lo lắng về quản lý và phân phối khóa!

Nói tóm lại, các biến môi trường là một cách tiếp cận để di chuyển dữ liệu trên mỗi máy chủ hoặc mỗi ứng dụng ra khỏi mã nguồn khi bạn muốn tách sự phát triển khỏi các hoạt động. Điều này đặc biệt quan trọng nếu bạn đã xuất bản mã nguồn!

Tăng cường phân tách: Máy chủ, ứng dụng và vai trò

Mặc dù bạn chắc chắn có thể có một tệp cấu hình để giữ bí mật của mình, nhưng nếu bạn lưu trữ các bí mật trong mã nguồn, bạn có một vấn đề cụ thể. Bạn có một chi nhánh hoặc kho lưu trữ riêng cho mỗi bộ bí mật không? Làm thế nào để bạn đảm bảo đúng bộ bí mật đến đúng máy chủ? Hoặc bạn có giảm bảo mật bằng cách có "bí mật" giống nhau ở mọi nơi (hoặc có thể đọc được ở mọi nơi, nếu bạn có tất cả trong một tệp), và do đó tạo ra rủi ro lớn hơn nếu bất kỳ một điều khiển bảo mật nào của hệ thống không thành công?

Nếu bạn muốn có những bí mật duy nhất trên mỗi máy chủ hoặc cho mỗi ứng dụng, các biến môi trường sẽ giải quyết vấn đề phải quản lý vô số tệp. Nếu bạn thêm máy chủ, ứng dụng hoặc vai trò mới, bạn không phải tạo tệp mới hoặc cập nhật tệp cũ: bạn chỉ cần cập nhật môi trường của hệ thống được đề cập.

Chia tay những suy nghĩ về an ninh

Mặc dù việc thăm dò kỹ lưỡng về bảo mật kernel / bộ nhớ / tập tin nằm ngoài phạm vi của câu trả lời này, đáng để chỉ ra rằng các biến môi trường trên mỗi hệ thống được triển khai đúng cách không kém an toàn so với các bí mật "được mã hóa". Trong cả hai trường hợp, hệ thống đích vẫn phải giữ bí mật được giải mã trong bộ nhớ tại một số điểm để sử dụng nó.

Cũng đáng chỉ ra rằng khi các giá trị được lưu trữ trong bộ nhớ dễ bay hơi trên một nút nhất định, không có tệp trên đĩa nào có thể được sao chép và tấn công ngoại tuyến. Đây thường được coi là một lợi thế cho các bí mật trong bộ nhớ, nhưng chắc chắn nó không được kết luận.

Vấn đề của các biến môi trường so với các kỹ thuật bí mật quản lý khác thực sự hơn là về an ninh và khả năng sử dụng thương mại-offs hơn là về tuyệt đối. Số dặm của bạn có thể thay đổi.


2
Điều này không thuyết phục, bởi vì tất cả các nhược điểm bạn đề cập cho các tệp cấu hình cũng áp dụng cho các biến môi trường. Biến môi trường dữ liệu cấu hình. Họ không tự đặt ra một cách kỳ diệu. Chúng phải được phân phối cho mỗi hệ thống và một số loại cơ chế cấu hình phải được sử dụng để đặt chúng.
jpaugh

@jpaugh Bạn đang làm một người đàn ông rơm tranh luận và tấn công những điều tôi chưa bao giờ nói. Các vấn đề tôi giải quyết là cấu hình ngoài băng và phân tách dữ liệu. Như đã giải thích rõ ràng, bạn có thể làm những điều này theo bất kỳ cách nào bạn muốn. Nếu bạn thích, bạn có thể đăng công khai các bí mật của mình cùng với mã của bạn trên GitHub, nhưng điều đó chắc chắn có vẻ không khôn ngoan trong trường hợp chung. Tuy nhiên, chỉ bạn mới có thể xác định sự đánh đổi cần thiết để hệ thống của bạn hoạt động đúng trong một mô hình mối đe dọa nhất định.
CodeGnome

2
Tất cả các điểm của bạn đều đúng, ngoại trừ việc nó áp dụng cho các biến môi trường nhiều như bất kỳ dữ liệu cấu hình nào khác. Nếu bạn lưu trữ các biến môi trường trong các tệp, thì bạn có thể cam kết chúng; và nếu bạn gửi chúng ra khỏi băng tần, việc thực hiện trong tệp sẽ dễ dàng hơn bằng cách nhập chúng ra. Nhưng nếu bạn thích gõ chúng, tại sao không gõ một đối tượng JSON thay vào đó và đọc nó trên stdin? Điều đó thực sự an toàn hơn dòng lệnh.
jpaugh

1

Cá nhân, tôi không khuyên bạn nên thiết lập các biến môi trường .bashrcvì chúng có thể hiển thị cho tất cả các quy trình được bắt đầu bởi trình bao nhưng để đặt chúng ở cấp trình nền / trình giám sát (tập lệnh init / rc, cấu hình systemd) để phạm vi của chúng được giới hạn ở những nơi cần thiết .

Khi các nhóm riêng biệt quản lý các hoạt động, các biến môi trường cung cấp giao diện dễ dàng cho các hoạt động để đặt môi trường cho ứng dụng mà không cần phải biết về các tệp / định dạng cấu hình và / hoặc sử dụng để xáo trộn nội dung của chúng. Điều này đặc biệt đúng trong cài đặt đa ngôn ngữ / đa khung trong đó các nhóm hoạt động có thể chọn hệ thống triển khai (HĐH, quy trình giám sát) dựa trên nhu cầu vận hành (dễ triển khai, khả năng mở rộng, bảo mật, v.v.).

Một xem xét khác là các đường ống CI / CD - vì mã đi qua các môi trường khác nhau(ví dụ: dev, test / qa, dàn dựng, sản xuất) các chi tiết môi trường (vùng triển khai, chi tiết kết nối cơ sở dữ liệu, thông tin xác thực, địa chỉ IP, tên miền, v.v.) được thiết lập tốt nhất bởi các công cụ / khung quản lý cấu hình chuyên dụng và được ứng dụng sử dụng các quy trình từ môi trường (trong DRY, viết một lần, chạy mọi lúc mọi nơi). Theo truyền thống, nơi các nhà phát triển có xu hướng quản lý các mối quan tâm vận hành này, họ có xu hướng kiểm tra các tệp hoặc mẫu cấu hình bên cạnh mã - và sau đó kết thúc thêm cách giải quyết và sự phức tạp khác khi các yêu cầu vận hành thay đổi (ví dụ: môi trường / triển khai / trang web mới xuất hiện, khả năng mở rộng / bảo mật cân nhắc,

  • Env-vars đơn giản hóa cấu hình / độ phức tạp ở quy mô.
  • Env-vars đặt cấu hình hoạt động vuông góc với nhóm chịu trách nhiệm về các khía cạnh không liên quan đến của ứng dụng theo cách không ràng buộc (nếu không chuẩn).
  • Env-vars hỗ trợ hoán đổi các quy trình chính / giám sát viên (ví dụ: god, monit, giám sát, sysvinit, systemd, v.v.) để quay lại ứng dụng - và chắc chắn là cả hệ thống triển khai (HĐH, hình ảnh container, v.v.) phát triển / thay đổi. Mặc dù mọi khung ngôn ngữ hiện nay đều có một số quy trình thời gian chạy, nhưng chúng có xu hướng hoạt động kém hơn, phù hợp hơn với môi trường dev và / hoặc tăng độ phức tạp trong môi trường sản xuất đa ngôn ngữ / đa khung.

Để sản xuất, tôi ưu tiên cài đặt các ứng dụng trong môi trường, ví dụ như /etc/default/myapplication.confđược quản lý cấu hình triển khai và chỉ có thể đọc được bằng cách rootđó systemd(hoặc bất cứ điều gì khác cho vấn đề đó) có thể sinh ra ứng dụng theo người dùng hệ thống bị tước quyền riêng tư trong Riêng tư nhóm . Theo mặc định, các nhóm người dùng dành riêng cho opssudo- các tệp này không thể đọc được. Đây là 12factor tuân thủ hỗ trợ tất cả các ưu điểm của Dev + Ops plus có tất cả các lợi ích của bảo mật tốt trong khi vẫn cho phép các nhà phát triển / người thử nghiệm thả vào Môi trường của chính họ trong môi trường dev / qa / test.


0

Từ quan điểm của nhà phát triển, việc lưu trữ dữ liệu cấu hình trong các biến môi trường giúp đơn giản hóa việc triển khai giữa các môi trường khác nhau - phát triển, QA và sản xuất - và giải phóng các nhà phát triển khỏi phải lo lắng về việc triển khai tệp cấu hình sai.

Các ứng dụng web Azure cung cấp tùy chọn để sử dụng mẫu này và nó hoạt động rất tốt.

Ngoài ra, nó giữ cho dữ liệu nhạy cảm có khả năng nằm ngoài tầm kiểm soát nguồn. Bỏ qua các tệp đó khỏi kiểm soát nguồn không thực sự khả thi (ít nhất là trong .NET) vì rất nhiều cấu hình soạn sẵn cần thiết cũng có trong các tệp đó.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.