Làm cách nào tôi có thể triển khai ansible với mật khẩu trên mỗi máy chủ một cách an toàn?


108

Tôi muốn sử dụng ansible để quản lý một nhóm các máy chủ hiện có. Tôi đã tạo một ansible_hoststệp và đã thử nghiệm thành công (với -Ktùy chọn) với các lệnh chỉ nhắm mục tiêu đến một máy chủ duy nhất

ansible -i ansible_hosts host1 --sudo -K # + commands ...

Vấn đề của tôi bây giờ là mật khẩu người dùng trên mỗi máy chủ khác nhau, nhưng tôi không thể tìm ra cách xử lý vấn đề này trong Ansible.

Khi sử dụng -K, tôi chỉ được nhắc nhập một mật khẩu sudo duy nhất, mà sau đó dường như sẽ được thử cho tất cả các máy chủ tiếp theo mà không cần nhắc:

host1 | ...
host2 | FAILED => Incorrect sudo password
host3 | FAILED => Incorrect sudo password
host4 | FAILED => Incorrect sudo password
host5 | FAILED => Incorrect sudo password

Nghiên cứu cho đến nay:

  • một câu hỏi StackOverflow với một câu trả lời không chính xác ("sử dụng -K") và một câu trả lời của tác giả nói rằng "Phát hiện ra tôi cần mật khẩu sudo"

  • các tài liệu Ansible , có nội dung "Sử dụng sudo không mật khẩu giúp mọi thứ dễ dàng tự động hóa hơn, nhưng không bắt buộc ." (nhấn mạnh của tôi)

  • bảo mật này StackExchange câu hỏi mà mất nó như đọc rằng NOPASSWDlà cần thiết

  • bài viết "Cung cấp có thể mở rộng và có thể hiểu được ..." có nội dung:

    "chạy sudo có thể yêu cầu nhập mật khẩu, đó là cách chắc chắn để chặn Ansible mãi mãi. Cách khắc phục đơn giản là chạy visudo trên máy chủ đích và đảm bảo rằng người dùng Ansible sẽ sử dụng để đăng nhập không phải nhập mật khẩu"

  • bài viết "Playbook Ansible cơ bản" , trong đó nói

    "Ansible có thể đăng nhập vào máy chủ mục tiêu với quyền root và tránh sự cần thiết của sudo, hoặc để người dùng ansible không có mật khẩu, nhưng ý nghĩ về việc làm cho lá lách của tôi bị đe dọa sẽ nhảy lên ống thông hơi của tôi và chặn khí quản của tôi, vì vậy tôi không "

    Suy nghĩ của tôi chính xác, nhưng sau đó làm thế nào để mở rộng ra ngoài một máy chủ?

  • vấn đề ansible # 1227 , "Ansible nên yêu cầu mật khẩu sudo cho tất cả người dùng trong một cuốn sách", đã bị đóng cửa một năm trước bởi mpdehaan với nhận xét "Không thấy nhiều nhu cầu về điều này, tôi nghĩ rằng hầu hết mọi người đang sudo từ chỉ một tài khoản người dùng hoặc sử dụng khóa hầu hết thời gian. "

Vậy ... mọi người sử dụng Ansible như thế nào trong những tình huống như thế này? Thiết NOPASSWDtrong /etc/sudoers, tái sử dụng mật khẩu trên host hoặc cho phép SSH gốc đăng nhập tất cả dường như giảm khá mạnh mẽ trong an ninh.


2
Có một lý do bạn không sử dụng khóa SSH?
Trondh

22
Tôi đã sử dụng các khóa SSH; chúng không ảnh hưởng sudo(vẫn cần mật khẩu).
supervacuo

1
Đây có thể không chính xác là những gì bạn đang tìm kiếm, nhưng trên các hộp Ubuntu tôi vẫn sử dụng các khóa, tức là đặt khóa công khai của tôi vào / root / ủy quyền để lấy trực tiếp dưới quyền root. Rõ ràng nhược điểm là cho phép đăng nhập root qua ssh ... Tôi cũng không cho phép đăng nhập mật khẩu qua ssh và chạy fail2ban để tăng cường bảo mật.
senorsmile

27
@senorsmile cảm ơn bạn đã phản hồi! Thay vào đó, bạn có phiền khi đưa nó vào câu trả lời để tôi có thể đánh giá thấp bạn vì đã không đọc câu hỏi không?
supervacuo

4
tức là các ansible_ssh_passwordthiết lập chỉ áp dụng cho mật khẩu SSH (đầu mối là trong tên ...). & Tôi đã sử dụng đăng nhập SSH dựa trên khóa.
supervacuo

Câu trả lời:


53

Bạn chắc chắn đã thực hiện nghiên cứu của mình ...

Từ tất cả kinh nghiệm của tôi với khả năng tìm thấy những gì bạn muốn đạt được, không được hỗ trợ. Như bạn đã đề cập, ansible nói rằng nó không yêu cầu sudo không mật khẩu, và bạn đúng, nó không. Nhưng tôi vẫn chưa thấy bất kỳ phương pháp sử dụng nhiều mật khẩu sudo trong ansible, mà tất nhiên không chạy nhiều cấu hình.

Vì vậy, tôi không thể đưa ra giải pháp chính xác mà bạn đang tìm kiếm, nhưng bạn đã hỏi ...

"Vậy ... mọi người sử dụng Ansible như thế nào trong những tình huống như thế này? Đặt NOPASSWD trong / etc / sudoers, sử dụng lại mật khẩu trên các máy chủ hoặc cho phép đăng nhập SSH gốc có vẻ giảm mạnh bảo mật."

Tôi có thể cung cấp cho bạn một quan điểm về điều đó. Trường hợp sử dụng của tôi là các nút 1k trong nhiều trung tâm dữ liệu hỗ trợ một công ty SaaS toàn cầu, trong đó tôi phải thiết kế / thực hiện một số kiểm soát bảo mật cực kỳ chặt chẽ do tính chất kinh doanh của chúng tôi. Bảo mật luôn cân bằng hành động, khả năng sử dụng ít bảo mật hơn, quá trình này không khác gì nếu bạn đang chạy 10 máy chủ hoặc 1.000 hoặc 100.000.

Bạn hoàn toàn chính xác không sử dụng thông tin đăng nhập gốc thông qua mật khẩu hoặc khóa ssh. Trong thực tế, đăng nhập root nên bị vô hiệu hóa hoàn toàn nếu các máy chủ có cáp mạng được cắm vào chúng.

Hãy nói về việc tái sử dụng mật khẩu, trong một doanh nghiệp lớn, có hợp lý không khi yêu cầu sysadins có mật khẩu khác nhau trên mỗi nút? đối với một vài nút, có lẽ, nhưng quản trị viên / kỹ sư của tôi sẽ nổi loạn nếu họ phải có mật khẩu khác nhau trên 1000 nút. Việc thực hiện điều đó cũng gần như là không thể, mỗi người dùng sẽ phải lưu trữ mật khẩu riêng ở đâu đó, hy vọng là một keypass chứ không phải bảng tính. Và mỗi khi bạn đặt mật khẩu vào một vị trí có thể rút mật khẩu bằng văn bản đơn giản, bạn đã giảm đáng kể bảo mật. Tôi thực sự muốn biết nhiều hơn, một hoặc hai mật khẩu thực sự mạnh hơn là phải tham khảo tệp keypass mỗi khi họ cần đăng nhập hoặc gọi sudo trên máy.

Vì vậy, việc sử dụng lại và tiêu chuẩn hóa mật khẩu là điều hoàn toàn chấp nhận được và tiêu chuẩn ngay cả trong một môi trường an toàn. Mặt khác, ldap, keystone và các dịch vụ thư mục khác sẽ không cần tồn tại.

Khi chúng tôi chuyển sang người dùng tự động, các phím ssh hoạt động rất tốt để giúp bạn tham gia, nhưng bạn vẫn cần phải vượt qua sudo. Lựa chọn của bạn là mật khẩu được tiêu chuẩn hóa cho người dùng tự động (có thể chấp nhận được trong nhiều trường hợp) hoặc để bật NOPASSWD như bạn đã chỉ ra. Hầu hết người dùng tự động chỉ thực hiện một vài lệnh, do đó, hoàn toàn có thể và chắc chắn mong muốn kích hoạt NOPASSWD, nhưng chỉ đối với các lệnh được phê duyệt trước. Tôi khuyên bạn nên sử dụng quản lý cấu hình của mình (trong trường hợp này) để quản lý tệp sudoers của bạn để bạn có thể dễ dàng cập nhật danh sách lệnh không cần mật khẩu.

Bây giờ, có một số bước bạn có thể thực hiện khi bạn bắt đầu nhân rộng để tiếp tục cách ly rủi ro. Mặc dù chúng tôi có 1000 nút, nhưng không phải tất cả chúng đều là máy chủ 'sản xuất', một số là môi trường thử nghiệm, v.v. . Nhưng người dùng tự động an toàn hơn một chút, ví dụ, một công cụ tự động mà quản trị viên không sản xuất có thể truy cập có người dùng & thông tin không thể được sử dụng trong sản xuất. Nếu bạn muốn khởi chạy ansible trên tất cả các nút, bạn phải thực hiện theo hai đợt, một lần cho việc không sản xuất và một lần cho sản xuất.

Mặc dù vậy, chúng tôi cũng sử dụng con rối, vì đây là một công cụ quản lý cấu hình bắt buộc, vì vậy hầu hết các thay đổi đối với tất cả các môi trường sẽ bị đẩy ra ngoài.

Rõ ràng, nếu yêu cầu tính năng mà bạn trích dẫn được mở lại / hoàn thành, những gì bạn muốn làm sẽ hoàn toàn được hỗ trợ. Mặc dù sau đó, bảo mật là một quá trình đánh giá rủi ro và thỏa hiệp. Nếu bạn chỉ có một vài nút mà bạn có thể nhớ mật khẩu mà không cần dùng đến ghi chú sau, thì mật khẩu riêng sẽ an toàn hơn một chút. Nhưng đối với hầu hết chúng ta, nó không phải là một lựa chọn khả thi.


Cảm ơn, @Zeb - Tôi đã tưởng tượng rằng người dùng có hàng chục đến hàng nghìn máy chủ sẽ sử dụng NOPASSWDvì lý do chính đáng (có thể được hỗ trợ bởi các quy tắc tường lửa chặt chẽ hơn, v.v. ), nhưng thật tốt khi đọc trường hợp sử dụng và suy nghĩ của bạn về mối đe dọa mô hình.
supervacuo

16
Tuy nhiên, một nhận xét về đề xuất của bạn về việc hạn chế sudocác lệnh "được chấp thuận trước" (điều này đã xảy ra với tôi khi tôi phát hiện ra rằng điều đó NOPASSWDlà bắt buộc khá nhiều). Thật không may, điều này dường như hoàn toàn không được hỗ trợ - ansible không hứa hẹn gì về việc gọi trực tiếp ví dụ chown hoặc mkdirnhị phân, và cần có khả năng để sudo /bin/shhầu hết các mô-đun hoạt động.
supervacuo

Tôi dường như nhớ lại một trong những kỹ sư của tôi phàn nàn về điều đó một thời gian trước, điều đó thật khó chịu.
Zeb

36

Từ Ansible 1.5 trở đi, có thể sử dụng một vault được mã hóa cho host_vars và các biến khác. Điều này ít nhất cho phép bạn lưu trữ một biến trên mỗi máy chủ (hoặc mỗi nhóm) ansible_sudo_passmột cách an toàn. Thật không may, --ask-vault-passsẽ chỉ nhắc một mật khẩu vault cho mỗi lần gọi có thể tìm thấy, vì vậy bạn vẫn bị ràng buộc với một mật khẩu vault duy nhất cho tất cả các máy chủ mà bạn sẽ sử dụng cùng nhau.

Tuy nhiên, đối với một số mục đích sử dụng, đây có thể là một cải tiến so với việc có một mật khẩu sudo duy nhất trên nhiều máy chủ, vì một kẻ tấn công không có quyền truy cập vào các máy chủ lưu trữ được mã hóa của bạn vẫn sẽ cần một mật khẩu sudo riêng cho mỗi máy (hoặc nhóm máy) mà anh ta hoặc cô ta tấn công.


3
Các ansible_sudo_passtùy chọn dường như mới, quá - và dường như làm những gì tôi đã được yêu cầu. Một mật khẩu vault duy nhất là lý tưởng cho mục đích của tôi, là tốt. Cảm ơn!
supervacuo

Có cách nào để tránh mã hóa tất cả host_vars bằng phương pháp này không? (một hạn chế tiềm năng ghi nhận của Alex Dupuy)
supervacuo

1
@supervacuo - Để tránh mã hóa tất cả các máy chủ lưu trữ, chỉ cần sử dụng thư mục var máy chủ chứa main.yml (không được mã hóa) và secret.yml (được mã hóa) - xem phần cuối của phần tài liệu này trong đó nói về nhóm "raleigh" - cùng kỹ thuật làm việc cho vars máy chủ và vars nhóm. Tôi sử dụng điều này rất nhiều, biến thể duy nhất là nếu một bí mật chỉ cần thiết cho một số playbook thì việc lưu trữ nó trong một cây khác hoàn toàn và bao gồm thông qua một đường dẫn bao gồm tên máy chủ hoặc tên var.
RichVel

1
Nếu tôi đã mã hóa giá trị 'ansible_ssh_pass' trong vault, vậy tôi cũng cần sao chép giá trị 'ansible_sudo_pass'? Có cách nào để giá trị sudo_pass thứ hai chỉnh lại giá trị 'ssh_pass' đầu tiên không?
emeraldjava

Bảo hiểm tốt về sử dụng mật khẩu vaulted có thể được tìm thấy ở đây: stackoverflow.com/a/37300030/5025060
CODE-REaD

22

Với Ansible 1.5, có thể đặt biến ansible_sudo_pass bằng cách sử dụng lookup('password', …):

ansible_sudo_pass: "{{ lookup('password', 'passwords/' + inventory_hostname) }}"

Tôi thấy điều này thuận tiện hơn so với việc sử dụng các tệp trong host_vars/một số lý do:

  • Tôi thực sự sử dụng with_password: "passwords/{{ inventory_hostname}} encrypt=sha256_crypt" để cung cấp mật khẩu cho người dùng từ xa triển khai (cần thiết cho sudo ), vì vậy chúng đã có trong các tệp (mặc dù việc tra cứu bản rõ này làm mất giá trị muối được lưu trữ trong tệp khi tạo giá trị băm) .

  • Điều này chỉ giữ lại các mật khẩu trong tệp (không có ansible_sudo_pass:bản rõ được biết) cho một số tăng epsilon trong bảo mật mật mã. Quan trọng hơn, điều đó có nghĩa là bạn không mã hóa tất cả các biến cụ thể của máy chủ khác, để chúng có thể được đọc mà không cần mật khẩu vault.

  • Đặt mật khẩu vào một thư mục riêng biệt giúp dễ dàng giữ các tệp khỏi tầm kiểm soát nguồn hoặc sử dụng một công cụ như git-crypt để lưu trữ chúng ở dạng mã hóa (bạn có thể sử dụng mã này với Ansible trước đó thiếu tính năng vault). Tôi sử dụng git-crypt và vì tôi chỉ kiểm tra kho lưu trữ ở dạng được giải mã trên các hệ thống tệp được mã hóa, tôi không bận tâm đến vault và do đó không cần nhập mật khẩu vault. (Sử dụng cả hai tất nhiên sẽ an toàn hơn.)

Bạn cũng có thể sử dụng chức năng tra cứu với ansible_ssh_pass ; điều này thậm chí có thể xảy ra với các phiên bản trước của Ansible không có ansible_sudo_pass .


2
Cuối cùng tôi cũng đã thử làm điều này (cảm ơn!), Nhưng không thể thấy nó sẽ hoạt động như thế nào nếu không có git-crypt; theo như tôi có thể thấy Có vẻ như Ansible chưa có hỗ trợ cho việc sử dụng lookuptrên một hầm được mã hóa. Các passwordtài liệu mô-đun nói rằng có một số hỗ trợ chưa được xác nhận cho việc lưu trữ được mã hóa, nhưng tôi vẫn chưa tìm thấy chi tiết. Bất kì manh mối nào?
supervacuo

19

Sử dụng pass là một phương pháp đơn giản để cung cấp ansible với mật khẩu sudo. pass lưu trữ một mật khẩu cho mỗi tệp giúp bạn dễ dàng chia sẻ mật khẩu thông qua git hoặc các phương thức khác. Nó cũng an toàn (sử dụng GnuPG) và nếu bạn đang sử dụng gpg-agent, nó cho phép bạn sử dụng ansible mà không cần nhập mật khẩu cho mỗi lần sử dụng.

Để cung cấp mật khẩu được lưu trữ như servers/foocho máy chủ footới ansible, hãy sử dụng nó trong tệp kiểm kê như thế này:

[servers]
foo ansible_sudo=True \
    ansible_sudo_pass="{{ lookup('pipe', 'pass servers/foo') }}"

Cho rằng bạn đã mở khóa cho gpg-agent trước đó, điều này sẽ chạy ansible mà không cần nhập bất kỳ mật khẩu nào.


3

Tuy nhiên, đây là một chủ đề khá cũ:

  • Chúng tôi sử dụng hai hệ thống xác thực khác nhau, quản lý máy móc được thực hiện từ các máy trạm địa phương trong nhóm của tôi.
  • Tôi đã viết một vars_pluginAnsible (một triển khai khá đầy đủ có thể được tìm thấy tại https://gist.github.com/mfriedenhagen/e488235d732b7becda81 ) để phân biệt một số hệ thống xác thực:
  • Tên của hệ thống xác thực là nhóm cụ thể.
  • Người dùng đăng nhập / sudo được sử dụng là nhóm và quản trị viên cụ thể.
  • Vì vậy, tôi kéo người dùng từ môi trường của quản trị viên và mật khẩu tương ứng thông qua thư viện khóa python từ mật khẩu an toàn (chúng tôi sử dụng móc khóa của Mac OS X, nhưng từ tài liệu kwallet Gnome và _win_crypto cũng được hỗ trợ).
  • Tôi đặt quyền cho mật khẩu trong móc khóa của Mac OS X để thông báo cho tôi về thực tế, rằng bảo mật chương trình dòng lệnh yêu cầu quyền truy cập vào mật khẩu cho mọi hệ thống xác thực được sử dụng bởi máy chủ, vì vậy tôi chạy "ansible -s all -m ping" và nhận được hai lời nhắc (một cho mỗi hệ thống xác thực) trong đó tôi nhấn phím cách và tìm mật khẩu.

Điều này trông rất gọn gàng, cảm ơn bạn - Tôi thích ý tưởng không phải lưu trữ mật khẩu ở hai nơi. Hiện tại tôi đang bị kẹt khi sử dụng KeepassX (vì khóa Gnome có vẻ không dễ mang theo) nhưng có lẽ tôi có thể làm python-keepassviệc?
supervacuo

Theo tôi hiểu, python-keyring là một sự trừu tượng cho việc này, vì vậy các đồng nghiệp của bạn có thể sử dụng các HĐH khác. Hoặc bạn có lưu trữ db keepassx của mình trên thẻ nhớ USB và phải quản trị từ các máy trạm với các hệ điều hành khác nhau không?
Mirko Friedenhagen

hiểu; Tôi có nghĩa là tôi đã phải sử dụng KeepassX để có quyền truy cập vào mật khẩu trên các hệ thống không phải là Gnome, vì vậy lưu trữ chúng trong gnome-keyringđó có nghĩa là giữ các bản ghi trùng lặp. Vẫn cách đẹp hơn so với sử dụng NOPASSWD, mặc dù ...
supervacuo

0

Một cách có thể để làm điều này là sử dụng các biến môi trường.

ví dụ

pass1=foo pass2=bar ansible-playbook -i production servers.xml

Sau đó, trong các lần phát, bạn có thể tra cứu mật khẩu sudo bằng cách sử dụng:

lookup('env', 'pass1') 
lookup('env', 'pass2') 
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.