호스트 별 암호로 보안 기능을 안전하게 구현하려면 어떻게해야합니까?


108

기존 서버 그룹을 관리 하기 위해 ansible 을 사용하고 싶습니다 . ansible_hosts파일 을 만들고 -K단일 호스트 만 대상으로하는 명령을 사용하여 옵션 으로 성공적으로 테스트했습니다.

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

내 문제는 각 호스트의 사용자 비밀번호가 다르지만 Ansible에서이를 처리하는 방법을 찾을 수 없다는 것입니다.

을 사용하면 -K단일 sudo 비밀번호를 입력하라는 메시지가 표시되며 프롬프트가 표시되지 않는 모든 후속 호스트에 대해 시도되는 것 같습니다.

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

지금까지 조사 :

  • 하나의 오답 ( "use ")과 저자가 "암호없는 sudo가 필요하다는 것을 알았습니다"라는 응답이 있는 StackOverflow 질문-K

  • "암호가없는 sudo를 사용하면 작업을보다 쉽게 ​​자동화 할 수 있지만 필수는 아닙니다 ." 라는 Ansible docs (강조 광산)

  • 이 보안 StackExchange 질문NOPASSWD 은 필요한 것으로 읽습니다.

  • "확장 가능하고 이해하기 쉬운 프로비저닝 ..." 기사 :

    "sudo를 실행하려면 암호를 입력해야 할 수 있습니다. 이는 Ansible을 영원히 차단하는 확실한 방법입니다. 간단한 수정은 대상 호스트에서 visudo를 실행하고 사용자가 Ansible에서 로그인 할 때 암호를 입력 할 필요가 없도록하는 것입니다."

  • 기사 "기본 Ansible 플레이 북" 말한다,

    "Ansible은 루트로 대상 서버에 로그인하여 sudo를 필요로하지 않거나, asible 사용자가 암호없이 sudo를 갖도록 할 수 있지만, 그렇게하는 생각은 내 비장이 협곡을 도약하고 내 관을 막을 수있는 위협이됩니다. 하지마 "

    내 생각은 정확하지만 단일 서버 이상으로 확장하는 방법은 무엇입니까?

  • ansible issue # 1227 , "Ansible은 Playbook의 모든 사용자에게 sudo 암호를 요청해야합니다."는 1 년 전에 mpdehaan에 의해 "이것에 대한 많은 수요를 보지 못했지만 대부분의 사람들이 하나에서 sudoing하고 있다고 생각합니다. 사용자 계정 또는 대부분의 키 사용 "

그렇다면 ... 이런 상황에서 사람들은 Ansible을 어떻게 사용하고 있습니까? 에서 설정 NOPASSWD하고 /etc/sudoers호스트에서 비밀번호를 재사용하거나 루트 SSH 로그인을 사용하면 보안이 크게 저하되는 것처럼 보입니다.


2
SSH 키를 사용하지 않는 이유가 있습니까?
Trondh

22
이미 SSH 키를 사용하고 있습니다. 그들은 영향을 미치지 않습니다 sudo(여전히 비밀번호가 필요합니다).
supervacuo '12

1
이것은 정확히 당신이 찾고있는 것이 아닐 수도 있지만 우분투 상자에서는 여전히 키를 사용합니다. 즉, 공개 키를 / root / authorized_keys에 넣어 루트로 직접 가져옵니다. 명백한 단점은 ssh를 통한 루트 로그인을 허용하는 것입니다 ... 또한 ssh를 통한 비밀번호 로그인을 허용하지 않으며 추가 보안을 위해 fail2ban을 실행합니다.
senorsmile

27
@senorsmile 답변 주셔서 감사합니다! 질문을 읽지 않아서 당신을 공감할 수 있도록 대신 답을 만들어 주시겠습니까?
supervacuo

4
, ansible_ssh_password설정은 SSH 비밀번호에만 적용됩니다 (단서 이름은 ...). & 나는 이미 키 기반 SSH 로그인을 사용하고 있습니다.
supervacuo

답변:


53

당신은 확실히 연구를 완료했습니다 ...

당신이 달성하고자하는 것을 할 수있는 것에 대한 나의 모든 경험에서 지원되지 않습니다. 당신이 언급했듯이, ansible은 암호가없는 sudo가 필요하지 않다고 말하고 정확합니다. 그러나 당연히 여러 구성을 실행하지 않고도 여러 sudo 암호를 사용할 수있는 방법을 아직 보지 못했습니다.

그래서, 당신이 찾고있는 정확한 솔루션을 제공 할 수는 없지만 요청했습니다 ...

"그래서 ... 이런 상황에서 사람들이 Ansible을 어떻게 사용하고 있습니까? / etc / sudoers에서 NOPASSWD를 설정하고, 호스트에서 암호를 재사용하거나 루트 SSH 로그인을 활성화하면 보안이 크게 저하되는 것 같습니다."

나는 그것에 대해 하나의 견해를 줄 수 있습니다. 유스 케이스는 글로벌 SaaS 회사를 지원하는 여러 데이터 센터의 1k 노드로, 비즈니스 특성으로 인해 엄청나게 엄격한 보안 제어를 설계 / 구현해야합니다. 보안은 항상 균형을 유지하고, 사용 편의성은 보안 성을 떨어 뜨립니다. 10 대의 서버 또는 1,000 또는 100,000을 실행하는 경우이 프로세스는 다르지 않습니다.

비밀번호 또는 ssh 키를 통해 루트 로그인을 사용하지 않는 것이 절대적으로 정확합니다. 실제로 서버에 네트워크 케이블이 연결되어 있으면 루트 로그인을 완전히 비활성화해야합니다.

대기업에서 암호 재사용에 대해 이야기 할 수 있도록 sysadmins에게 각 노드마다 다른 암호를 요구하도록 요청하는 것이 합리적입니까? 아마도 두 노드에 대해서는 1000 노드에서 다른 암호를 가져야한다면 관리자 / 엔지니어는 음소거 할 것입니다. 거의 불가능한 구현도 각 사용자는 스프레드 시트가 아닌 키 패스 (keypass)가있는 곳에 암호를 저장해야합니다. 암호를 일반 텍스트로 가져올 수있는 위치에 암호를 넣을 때마다 보안이 크게 저하되었습니다. 기계에 로그인하거나 sudo를 호출해야 할 때마다 키 패스 파일을 참조해야하는 것보다 하나 또는 두 개의 정말로 강력한 암호를 알고 있습니다.

따라서 암호 재사용 및 표준화는 안전한 환경에서도 완벽하게 수용 가능하고 표준적인 것입니다. 그렇지 않으면 ldap, keystone 및 기타 디렉토리 서비스가 필요하지 않습니다.

자동화 된 사용자로 옮길 때, ssh 키는 사용자를 참여시키는 데 효과적이지만 여전히 sudo를 거쳐야합니다. 선택은 자동화 된 사용자를위한 표준화 된 비밀번호 (대부분의 경우 허용) 또는 지적한대로 NOPASSWD를 활성화하는 것입니다. 대부분의 자동화 된 사용자는 몇 가지 명령 만 실행하므로 NOPASSWD를 활성화하는 것이 가능하지만 사전 승인 된 명령에 대해서만 가능합니다. 암호가없는 명령 목록을 쉽게 업데이트 할 수 있도록 구성 관리 (이 경우 사용 가능)를 사용하여 sudoers 파일을 관리하는 것이 좋습니다.

이제 위험을 더욱 격리시키기 위해 확장을 시작하면 취할 수있는 몇 가지 단계가 있습니다. 우리는 1000 개 정도의 노드를 가지고 있지만 모든 서버가 '생산'서버는 아니며 일부는 테스트 환경 등입니다. 모든 관리자가 프로덕션 서버에 액세스 할 수있는 것은 아니며 다른 서버와 동일한 SSO 사용자 / 패스 | 키를 사용할 수있는 서버 . 그러나 자동화 된 사용자는 좀 더 안전합니다. 예를 들어 비 프로덕션 관리자가 액세스 할 수있는 자동화 된 도구에는 프로덕션에서 사용할 수없는 사용자 및 자격 증명이 있습니다. 모든 노드에서 asible을 시작하려면 프로덕션이 아닌 경우와 프로덕션의 경우 두 개의 배치로 실행해야합니다.

또한 꼭두각시는 강제적 인 구성 관리 도구이기 때문에 모든 환경에 대한 대부분의 변경 사항이 적용되기 때문에 꼭두각시를 사용합니다.

인용 한 기능 요청이 다시 열리거나 완료되면 원하는 것을 완전히 지원할 수 있습니다. 그럼에도 불구하고 보안은 위험 평가 및 타협의 프로세스입니다. 포스트잇 메모를 사용하지 않고 암호를 기억할 수있는 노드가 몇 개만있는 경우 별도의 암호가 약간 더 안전합니다. 그러나 우리 대부분에게는 실현 가능한 옵션이 아닙니다.


@Zeb에게 감사드립니다. 수십에서 수천 대의 서버를 사용하는 사용자는 NOPASSWD어쨌든 보안상의 이유로 방화벽 규칙 등으로 지원 될 것 같지만 위협에 대한 사용 사례와 생각을 읽는 것이 좋습니다 모델.
supervacuo

16
그러나 "사전 승인 된" sudo명령으로 제한하는 것에 대한 귀하의 제안에 대한 한 가지 의견 NOPASSWD은 (필요한 것을 발견했을 때 나에게 발생했습니다 ). 불행하게도,이 것 뿐만 아니라 완벽하게 지원되지 않는 - ansible 호출에 대해 어떠한 약속도하지 않습니다 예를 들어, chown 또는 mkdir직접 바이너리를하고, 할 수 있어야 sudo /bin/sh대부분의 모듈이 작동하려면.
supervacuo

나는 내 엔지니어 중 한 명이 그에 대해 불평하는 것을 기억하는 것 같습니다.
Zeb

36

Ansible 1.5부터 host_vars 및 기타 변수에 암호화 된 볼트 를 사용할 수 있습니다 . 이렇게하면 최소한 호스트 별 (또는 그룹 별) ansible_sudo_pass변수를 안전하게 저장할 수 있습니다 . 불행하게도, --ask-vault-pass호출 할 수있을 때마다 단일 저장소 암호 만 프롬프트하므로 함께 사용할 모든 호스트에 대해 단일 저장소 암호로 제한됩니다.

그럼에도 불구하고 암호화 된 host_vars에 액세스 할 수없는 공격자가 여전히 공격하는 모든 컴퓨터 (또는 컴퓨터 그룹)에 대해 별도의 sudo 암호를 필요로하기 때문에 일부 용도의 경우 여러 호스트에서 단일 sudo 암호를 사용하는 것보다 개선 된 것일 수 있습니다.


3
ansible_sudo_pass옵션도 새로운 것 - 내가 요구 한 것을 할 것 같다. 하나의 볼트 암호가 나의 목적에도 이상적입니다. 감사!
supervacuo

이 방법을 사용하여 모든 암호화를 피하는 host_vars방법이 있습니까? (Alex Dupuy가 지적한 잠재적 한계)
supervacuo

1
@supervacuo - 모든 호스트 바르 암호화를 피하기 위해, 단지 main.yml (암호화되지 않은) 및 secret.yml (암호화)를 포함하는 호스트 var 디렉토리를 사용하는 -의 마지막 부분 참조 이 문서 섹션 동일한 기술 - 그것은 "롤리"그룹에 대해 이야기 호스트 변수 및 그룹 변수에 적용됩니다. 나는 이것을 많이 사용하지만, 유일한 변형은 비밀이 일부 플레이 북에만 필요하다면 다른 트리에 완전히 저장하고 호스트 또는 var 이름을 포함하는 경로를 통해 포함하는 것이 유용 할 수 있다는 것입니다.
RichVel

1
볼트에서 'ansible_ssh_pass'값을 암호화 한 경우 'ansible_sudo_pass'값도 복제해야합니까? 두 번째 sudo_pass 값이 첫 번째 'ssh_pass'값을 참조하는 방법이 있습니까?
emeraldjava

아치형 암호 사용에 대한 자세한 내용은 여기를 참조하십시오. stackoverflow.com/a/37300030/5025060
CODE-REaD

22

Ansible 1.5에서는 다음을 사용하여 ansible_sudo_pass 변수 를 설정할 수 있습니다 lookup('password', …).

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

host_vars/여러 가지 이유로 파일을 사용하는 것보다 이것이 더 편리하다는 것을 알았습니다 .

  • 실제로 with_password: "passwords/{{ inventory_hostname}} encrypt=sha256_crypt"배포 원격 사용자 의 암호를 프로비저닝하는 데 사용하므로 sudo에 필요 하므로 이미 파일에 존재합니다 (해당 값을 생성하면 이러한 일반 텍스트 조회를 수행하면 파일에 저장된 솔트 값이 손실되지만) .

  • 이렇게 ansible_sudo_pass:하면 암호화 보안이 엡실론 증가하기 위해 파일에 암호 만 ( 알려진 일반 텍스트는 아님) 유지됩니다. 더 중요한 것은 다른 모든 호스트 관련 변수를 암호화하지 않으므로 볼트 암호없이 읽을 수 있다는 의미입니다.

  • 비밀번호를 별도의 디렉토리에 저장하면 파일을 소스 제어에서 벗어나거나 git-crypt 와 같은 도구를 사용하여 암호화 된 형태로 저장할 수 있습니다 (볼트 기능이없는 초기 Ansible과 함께 사용할 수 있음). 나는 git-crypt를 사용하고 암호화 된 파일 시스템에서 해독 된 형태로 저장소를 체크 아웃하기 때문에 볼트를 신경 쓰지 않으므로 볼트 암호를 입력 할 필요가 없습니다. (둘 다 사용하는 것이 더 안전합니다.)

조회 기능을 ansible_ssh_pass 와 함께 사용할 수도 있습니다 . ansible_sudo_pass 가없는 이전 버전의 Ansible에서도 가능합니다 .


2
나는 드디어 (! 감사)이 시도에 주변에 도착하지만하지 않고 어떻게 작동하는지 볼 수 없습니다 git-crypt; 최대한 멀리 볼 수. Ansible 이 아직lookup 암호화 된 볼트 에서 사용 하도록 지원하지 않는 것 같습니다 . password모듈 문서는 암호화 저장을위한 몇 가지로 아직 문서화되지 않은 지원이 있다고 말하지만, 나는 세부 정보를 찾기 위해 아직있다. 단서가 있습니까?
supervacuo

19

pass를 사용 하는 것은 sudo 암호를 제공하는 간단한 방법입니다. pass는 파일 당 하나의 암호를 저장하므로 git 또는 다른 방법을 통해 암호를 쉽게 공유 할 수 있습니다. 또한 안전합니다 (GnuPG 사용). gpg-agent를 사용하는 경우 각 사용시 암호를 입력하지 않고도 사용할 수 있습니다.

servers/foo서버용 foo으로 저장된 비밀번호를 제공하려면 다음과 같이 인벤토리 파일에서 비밀번호를 사용하십시오.

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

이전에 gpg-agent의 키를 잠금 해제 한 경우 암호를 입력 할 필요없이 사용할 수 있습니다.


3

그럼에도 불구하고 이것은 매우 오래된 스레드입니다.

  • 우리는 두 가지 인증 시스템을 사내에서 사용하며 시스템 관리는 팀의 로컬 워크 스테이션에서 수행됩니다.
  • 나는 여러 인증 시스템을 차별화 vars_plugin하는 Ansible ( https://gist.github.com/mfriedenhagen/e488235d732b7becda81 에서 다소 완전한 구현을 찾을 수 있음 )을 작성했습니다.
  • 인증 시스템의 이름은 그룹별로 다릅니다.
  • 사용 된 로그인 / 스도 사용자는 그룹 및 관리자별로 다릅니다.
  • 그래서 암호 환경에서 python-keyring 라이브러리를 통해 관리자 환경에서 해당 암호를 가져옵니다 (Mac OS X의 키 체인을 사용하지만 설명서 kwallet Gnome 및 _win_crypto도 지원됨).
  • 명령 줄 프로그램 보안이 호스트가 사용하는 모든 인증 시스템의 암호에 대한 액세스를 요청한다는 사실을 알리기 위해 Mac OS X 키 체인의 암호에 대한 권한을 설정했습니다. 따라서 "anible -s all -m ping" 스페이스 바를 누르면 암호를 선택하는 두 개의 프롬프트 (각 인증 시스템마다 하나씩)가 표시됩니다.

매우 깔끔하게 보입니다. 감사합니다. 암호를 두 곳에 저장할 필요가 없다는 생각이 좋습니다. 현재 KeepassX를 사용하고 있는데 (GNOME 키링이 이식성이 좋지 않기 때문에) 아마도 python-keepass일을 할 수 있습니까?
supervacuo

내가 이해하는 한, 파이썬 키링은 이것에 대한 추상화이므로 동료가 다른 OS를 사용할 수 있습니다. 또는 keepassx db를 USB 스틱에 저장하고 다른 OS가있는 워크 스테이션에서 관리해야합니까?
Mirko Friedenhagen

이해; 그놈이 아닌 시스템에서 암호에 액세스하려면 KeepassX를 이미 사용해야하므로 암호를 저장하면 gnome-keyring중복 레코드가 유지됩니다. 아직 방법이 더 좋은 사용하는 것보다 NOPASSWD,하지만 ...
supervacuo을

0

이를 수행하는 한 가지 방법은 환경 변수를 사용하는 것입니다.

예 :

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

그런 다음 연극에서 다음을 사용하여 sudo 비밀번호를 찾을 수 있습니다.

lookup('env', 'pass1') 
lookup('env', 'pass2') 
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.