Home | 문태준 | 시스템어드민 메일링 | Sys Admin 세미나
Skip to end of metadata
Go to start of metadata

MCollective는 매우 짧은 시간에 많은 변경을 할 수 있는 강력한 툴이다. 강력한 기능을 가지고 있기 때문에 해당 프로그램을 잘못 사용할 때의 위험은 커진다. 이번 장에서는 이러한 위험을 줄일 수 있는지, 어떤 사용자가 해당 서버에 대해 작업을 하는 것을 어떻게 제허할 수 있는지 설명할 것이다.

현재의 상황에서 MCollective 셋텁은 단순한 보안 모델을 사용하고 있다. 이보다는 더 많은 보안 모델을 원할 수 있다. 다음은 다른 보안 플러그인을 사용하려는 이유를 설명한다:

  • Security(authentication) plugin : 현재의 설정은 컨텐츠에 대한 MD5 hash를 만드는 Pre-Shared Key 를 사용한다. 이것을 이용하여 서버는 plain-text 요청이 변경되지 않았다는 것을 확인한다. 이보다 더 강한 암호화 확인을 원할 수 있다.
  • Authorization plugin : 당시은 어떤 요청을 할 수 있거나 없을 수 있다. 특정 클라이언트가 특정 호스트 또는 특정 요청을 할 수 있는지 제한하는 보안 모델을 원할 수 있다.
  • Auditing plugin : 기본 로그 파일은 누가 특정 요청을 했는지에 대해 자세한 정보를 보여주지 않는다. 허용이나 거부된 요청과 누가 그 요청을 했는지 등 더 자세한 로그를 원할 수 있다.

MCollective 는 보안을 위한 plugin 아키텍쳐를 가지고 있기 때문에 이러한 상황을 개선하기 위해서 유연성을 찾을 수 있다. MCollective 를 위한 보안을 강화하는 방법에 정답은 없다. 대신에 자신의 필요성에 따라서 보안을 강화할 수 있다. 이번 장에서는 보안을 강화하기 위한 옵션들을 살펴볼 것이다.

이번 장에서는 클라이언트(요청을 보냄)와 서버(요청을 검증함) 사이의 authentication 과 authorization을 살펴볼 것이다. 이 부분은 미들웨어 전송과 관련한 보안에는 영향을 미치지 않는다.

보안은 플러그인을 통해서 제공이 되기 때문에 각 조직이나 각 collective 는 서로 다른 보안 모델을 사용할 수 있다. 우리는 MCollective 에서 사용 가능한 보안 플러그인을 비교할 것이다.

MCollective documentation refers to the authentication plugin as the security plugin. I don’t prefer this term, as there are distinct authorization and auditing plugins that are part of most people’s concept of security. I refer to it as the authentication plugin in this section for clarity, but the reader should be aware that the configuration files and Puppet Labs documentation refer to it as the security plugin.

Authentication 작동 방식

명령을 collective 로 보낼 때 클라이언트는 요청에 caller identification 을 내장하여 보낸다. 다음과 같이 작동을 한다.

  1. 사용자는 "mco puppet runone" 와 같은 요청을 만든다.
  2. 클라이언트 authentication/security plugin 은 caller 를 설정하고 명령의 메타데이터에 추가한다.
  3. client 는 미들웨어에 요청을 publish 한다.
  4. 서버의 authentication/security plugin은 는 메시지의 digest 를 검증한다.
  5. server authorization plugin 은 caller 가 이 요청에 대해 허가(authorized)가 있는지 검증을 한다.
  6.  서버는 요청을 처리한다.

우 리가 이미 사용을 하였던 Pre-Shared Key 플러그인은 caller 의 요청에 Unix uid 나 gid를 추가한다.  모든 클라이언트 시스템이 정확히 동일한 uid/gid 매킹을 가지고 있지 않고 local root 도 아니면 이 시나리오에서는 caller 정보는 신뢰를 할 수 없다. 당신이 알 수 있는 것은 오직 클라이언트가 정확한 Pre-Shared Key를 가지고 있다는 사실이다. 이것만으로 당신의 환경에서 충분한가?

더 세부적인 접근 통제를 위해 SSL, AES 또는 SSHKey security plugins을 원할 수 있다. 이러한 각각의 플러그인은 caller 의 identity 를 검증하기 위한 암호화된 공개키를 사용한다.

Pre-Shared Key Authentication

설명 생략

Figure 13-1. The data is passed in the clear with an MD5 hash of the contents and the Pre-Shared Key

 

Figure 13-2. The data and a MD5 hash of the contents and the Pre-Shared Key are both encrypted during transit

Puppet Setup

SSL Authentication

SSL security plugin 을 사용하면 각 클라이언트가 보내는 명령에는 유일한 개인키와 공개키가 있어야 한다. 모든 서버는 동일한 공개키와 개인키를 공유할 것이다. 이렇게 하면 각 클라이언트 요청은 암호화가 된다. 이러한 보안 모델에서는 다음과 같이 구성이 된다:

  • 모든 서버는 단일한 public/private keypair 를 공유한다.
  • 각 클라이언트는 서버 public key를 가지고 있어야 한다.
  • 각 클라이언트는 자신의 private key 로 각 요청을 사인해야 한다.
  • 각 서버는 요청을 검증하기 위해서 클라이언트의 public key를 가지고 있어야 한다.

이러한 설정에서 클라이언트는 다음과 같이 작동을 한다:

  1. Insert a caller field comprised of the client certificate’s filename into the request

  2. Serialize the message body, the message time, and the time-to-live

  3. Insert a hash field containing a cryptographic signature of the serialized data

Figure 13-3. The data is passed in the clear with a SSL-signed hash of the contents

서버에서 메시지를 받을 때, 클라이언트의 public key를 이용하여 signature 를 검증하고 메시지가 적절한 caller 에서 왔는지 message time과 time-tolive 가 변경되지 않았는지 확인을 한다.

이것을 미들웨어의 TLS 암호화와 결합을 하면 암화화된 터널(TLS 에서 제공)과 클라이언트 요청에 대한 암호화 검증을 함께 사용할 수 있다. 이것이 Puppet Lab의 추천 사항이다.

 

Figure 13-4. The data and a SSL-signed hash of the contents are encrypted by TLS

Server Configuration

SSL security 모델을 쓰면 server의 개인키와 공개키는 동일하고 모든 서버에서 공유가 된다. 다음과 같이 서버 keypair 를 만들 수 있다:

이 파일들을 mcollective 디렉토리로 옮기고 안전하게 보호한다.:

이 키들을 사용하기 위해서 server.cfg 에 설정된 PSK plugin 설정을 제거하고 다음을 추가한다:

Puppet 으로 설치하고 동기화하기

이 책의 Puppet module을 쓰고 있다면 다음 명령어를 통해서 이 키들을 Puppet module 디렉토리로 옮긴다. Puppet 모듈은 자동으로 모든 서버에 해당 키를 배포할 것이다:

다음의 Hiera 설정은 server.cfg 에서 이에 해당하는 설정을 활성화한다:

Client Configuration

각 클라이언트는 자신의 요청을 검증하기 위해 공개키와 개인키가 필요하다. 가장 일반적인 방법은 자신만의 공개키와 개인키를 만들고 절대로 다른 곳에는 공유하지 않는 것이다.

다 른 방법은 각 팀마다 인증서를 만들고 오직 해당 팀만 개인키에 접근 할 수 있도록 하는 것이다. 중요한 것은 어떤 것을 허가하고 audit 할 것인가 하는 것이다. 그룹키를 공유해서 인증을 사용한다면 어떤 사용자가 요청을 했는지 알 수가 없다.

개인키는 안전하게 보관을 해야 하고 인가되지 않는 다른 사용자에게 공유가 되면 안된다. 공개키는 모든 MCollective 서버에 배포가 되어야 하며 이 키를 이용하여 요청을 사인할 때 사용한다.

Create a client identity

클라이언트 키를 저장할 디렉토리를 먼저 생성하자:

Trusted TLS connector 를 위해서 이미 Puppet 키를 생성했다면 그것을 다음과 같이 재사용할 수 있다:

아래는 다른 방법으로 인증서를 생성하는 방법이기 때문에 설명은 생략.

If you created a new identity with a different CA from “CA-Verified TLS Clients” on page 139, you may have everything except the public key. Create that now using these steps:

If you don’t have an existing keypair, you can generate a client keypair using Puppet as described in “CA-Verified TLS Clients” on page 139, or you can create a new key‐pair using openssl :

Create a config file

각 클라이언트는 유일한 키 세트가 필요하기 때문에 각 keypair 마다 별도의 설정 파일을 만들어야 한다. 오직 한 사용자(개인 데스트탑이나 랩탑)만 사용하는 시스템이라면 다음의 내용을 글로벌 client 설정파일인 /etc/mcollective/client.cfg 에 추가할 수 있다. 그게 아니라면 아래 라인을 각 유저의 개별 클라이언트 설정으로 추가해야 한다.

클라이언트 설정에 대해서 처음으로 체크하는 파일은 각 사용자의 홈 디렉토리의 .mcollective 이다. 이 파일이 존재하면 글로벌 클라이언트 설정은 무시가 된다. 설정 파일은 전체 내용을 담고 있어야 하고 완전히 필요한 설정이 들어가 있어야 한다.:

This defies the standard Unix/Linux convention, where dot-program would be a directory containing configuration files specific to the program. A prevailing convention for a directory containing files for MCollective is .mcollective.d. We used this directory when creating the public and private key files earlier.

SSL 인증을 활성화하기 위해서 securityprovider 라인을 변경해야 한다. psk 나 다른 security connecotr 를 가리키는 설정은 제거를 해야 한다. 클라이언트는 the hash for server 를 암호화하기 때문에 클라이언트 설정에서는 서버의 공유를 한 공개키를 가리키는 설정이 있어야 한다. 변경 사용은 다음과 같다:

또 다른 방법은 쉘 환경에서 각 사용자에 대한 키 위치에 대해서 지정을 하는 것이다:

export MCOLLECTIVE_SSL_PRIVATE=/home/user/.mcollective.d/private_keys/user.pem

export MCOLLECTIVE_SSL_PUBLIC=/home/user/.mcollective.d/public_keys/user.pem

이 책의 GitHub 레포에서 mcollective::userconfig 라고 된 Puppet class가 있다. 이 모듈을 통해서 자동으로 각각의 user key pairs 를 만든다. 불행히도 이것만으로는 모든 상황을 다를 수는 없으며 http://bit.ly/1ryhxxe 모듈을 살펴보기 바란다.

Key Synchronization

SSL 인증을 위해서는 다음과 같이 세가지 동기화 이슈를 처리해야 한다:

  • 모든 서버는 동일한 공개키와 개인키를 가지고 있어야 한다.
  • 모든 서버는 모든 클라이언트의 공개키를 가지고 있어야 한다.
  • 모든 클라이언트는 공유된 서버의 공개키를 가지고 있어야 한다.

Puppet 모듈은 이러한 세가지동기화 이슈를 처리할 수 있다. 다음과 같이 파일을 위치하면 된다:

Type

Puppet server 에서의 경로

Server Private Key

modulepath/mcollective/files/ssl/server/private.pem

Server Public Key

modulepath/mcollective/files/ssl/server/public.pem

Client Public Keys

modulepath/mcollective/files/ssl/clients

Puppet 모듈을 사용하지 않으면 다음과 같이 하면 된다:

  • The client public keys to each server’s /etc/mcollective/ssl/clients/ folder
  • The server public key to each client as /etc/mcollective/ssl/server/public.pem:

RSA Authentication AES Encryption

설명 생략

Server Configuration

Client Configuration

Key Synchronization

SSHKey Authentication

설명 생략

Puppet

Authorization

이 번 섹션에서는 authorization(권한 부여)에 대해서 다룬다. authorization 는 어떠한 요청을 MCollective 서버에서 처리하기전에 마지막으로 하는 체크이다. authorization 은 강력하면서도 유연한 MCollective 보안을 제공한다. authorization 은 MCollective 가 제공하는 기능중 가장 사용하지 않고 간과하는 부분이라고 생각을 한다.

우리가 이전에 작업을 했던 것은 authentication 에 기반하여 누가 요청을 보낼 수 있는지만 제한을 한다. 정확한 비밀번호, pre-shared key, 사인한 인증서가 있는 사람이라면 어느 시스템에 아무 요청이나 할 수 있다. 이것은 제한 없는 강력한 힘을 가지고 있다.

작은 환경에서는 괜찮다. 그렇지만 여러 팀이 있고 다양한 많은 시스템이 있으며 다양한 agent plugin 을 가지고 있다면 어떤 사용자가 어떤 리소스를 사용할 수 있는지 제한하고 싶을 것이다. authorization 플러그인을 사용하면 특정 사용자, 특정 호스트, 특정 agent 등을 제한할 수 있다.

authorization 은 authentication 에서 선택한 것에 따라 의존성이 있다. authorization 플러그인은 security (authentication) 플러그인을 통해서 검증한 caller 와 request 정보를 사용하고 해당 요청을 허용할지 말지를 결정한다.

authorization 정책을 내릴 때 조심해야 한다. You should ensure you have another method to log in to each server to fix any mistake or a safety-net policy that will allow you to regain access.

한 명 이상의 관리자가 있는 환경에서 배포를 할 때, 모든 서버를 위해 ActionPolicy authorization 플러그인을 배포할 것을 권장한다.  ActionPolicy 는 각 agent 별로 정책 룰을 사용할 수 있다. 그래서 agent 기반으로 허용이나 거부할 수 있는 유연성을 제공한다.

Rule Format

ActionPolicy 룰의 포맷은 다음 필드에 따라 탭으로 구분한다:

필드#이름설명
1

Policy

allow 또는 deny 
2Caller요청에서 제공한 The caller 문자

* (always matches)

One Caller string (discussed in the next section)

3Action

An action provided by the agent the policy rule is for

* (always matches)

A space-separated list of actions

4FactsFacts that must be true about the target server

* (always matches)

A space-separated list of fact=value pairs (matches if every

listed fact matches)

Any valid compound filter string

5ClassesPuppet classes that apply to the target server

Absent or * (always matches)

A space-separated list of class names (matches if every listed

class is present)

Any valid compound filter string

다른 파일 포맷을 사용하는 authorization policy 를 만들어서 자체 영역에 기반하여 authorization을 하는 커스텀 agent 를 만들 수도 있다. 이에 대해서는 Part III에서 다룰 것이다.

Caller IDs

어떤 authorization 플러그인을 사용을 하든지 상관없이 요청에서 caller 필드는 사용할 수 있다. 이 필드는 어떤 security provider 플러그인을 사용하는지에 따라 다르게 설정이 된다.

  • PSK security 플러그인 : 클라이언트 애플을 실행하는 user의 uid=uid 를 caller ID로 설정한다.
    • plugin.psk.callertype 에서 gid, user, group 또는 identity 로 변경할 수 있다. uid 와 usernames 은 호스트에 걸쳐서 동일하지 않을 수도 있기 때문에 신뢰할 수 있는 수단은 아니다.
  • TLS security 플러그인 : .pem 확장자 없이 cert=client's public key filename 을 caller ID로 설정한다.
    • 서버는 ssl_client_cert_dir 또는 aes.client_cert_dir 을 검색하여 요청을 검증하기 위한 동일한 이름의 공개키를 찾는다.
  • SSH security 플러그인 : 클라이언트를 실행한 sshkey=username 을 caller ID로 설정한다.
    • 서버는 유저의 authorized_keys를 검색하여 요청을 검증하기 위한 SSH 공개키를 찾는다.

Defining ActionPolicy with Puppet

이 책에서 제공한 Puppe 모듈을 통해서 ActivePolicy 모듈을 설치하고 설정할 수 있다. Puppet 에서 정책을 정의하는 방법은 두가지가 있다:

  • Hieara 데이터에서 동적으로 룰 생성
  • 정적인 정책 파일을 배포

이 두가지를 섞어서 쓸 수도 있다. 어떤 정책은 정적인 파일에 두고 어떤 설정은 Hiera 에 둔다.

Creating a simple policy in Hiera

다음은 간단한 ActionPolicy 설정으로 다른 요청은 모두 거부하고 정책을 업데이트 하기 위해 Puppet 실행만 허용을 하는 예제이다. 설정에서 잘못된 것이 발생하지 않도록 하는 좋은 보안장치이다.

authorization 을 활성화 했지만 default policy 를 명시하지 않으면 allow_unconfigured 를 활성화한 서버에서는 authorization 이 활성화 되며 기본 allow 정책이 활성화된다:

mcollective 에서 plugin.actionpolicy.allow_unconfigured = 0 이 기본값이며 no 이다. (문태준 추가)

 

이 러한 Hiera 정의는 기본 정책으로 "deny"를 가지는 한줄의 default_deny.policy 파일을 생성한다. 이러한 기본 policy 는 해당 agent 에 대해서 정책을 정의하지 않는 모든 agent 에 적용이 된다.

다음에는 두 라인에 걸쳐 puppet.policy 라는 이름의 정책 파일을 만들 것이다: 기본은 deny 이고 사용자가 runonce와 runall 명령을 사용할 수 있도록 허용한다.

모든 것이 정확히 지정되었을 때, puppet runonce 와 puppet rullall 명령에 대한 요청만 성공할 것이다. 다른 요청은 실패한다:

Allowing more commands

위에서 구현을 한대로, 이 정책은 사용자에게 많은 권한을 허용하지 않는다. 이것을 확장해서 좀 더 실제 상황에 맞는 정책을 만들어 보자.

각 정책에서, default 속성은 각 agent 에 대한 기본 정책을 정의한다. 해당 agent 에 대해 정책 파일에서 지정하지 않는 부분은 여기에서 정의한 내용에 따라 허용 또는 거부당할 수 있다.

각 룰에는 유일한 title 이 필요하다. title 은 숫자로 시작하며 실행을 할 때 순서를 제어한다. MCollective 모듈은 파일의 title을 해당 룰을 정의하는 곳의 상단에 주석으로 저장한다. 이렇게 해서 정책 파일을 읽고 이해할 수 있도록 돕는다.

title 다음에 정의할 키/값의 dictionary 가 있다.

  • policy action
  • authentication plugin에서 제공하는 유요한 사용자나 key(certname 등)
  • 허용할 agent actions
  • 룰에 적용 가능한 facts
  • 룰에 적용 가능한 Classes

여 기에 기초해 각 agent 별로 정책을 만들어보자. 예를 들어 다음의 정책은 대부분의 정책은 허용을 하지만 admins 만 files 또는 Puppet agent 를 disable 하는 것을 허용한다. callerid 는 callertype을 group 으로 설정한 PSK security provider 로 가정을 한다.

다음은 SSL key 가 jane.doe 인 어떤 개발자에게 development 박스에서 서비스에 접근할 수 있도록 설정을 한다. callerid 는 SSL 또는 AES security provider 라고 가정을 한다:

특정 룰이 없는 특정 agenet 에 대하여 모든 요청을 허용하거나 거부하려면 간단하게 룰을 정의할 수 있다. 예를 들어 다음은 서버의 패키지에 대하여 어떤 사용자도 제어를 할 수 있도록 설정한다:

이와 비슷하게 글로벌 기본은 allow 로 설정을 하고 하나의 agent 에 대한 모든 요청은 거부하도록 설정할 수 있다. 예를 들면 다음은 shell command 만 제외하고 모든 것을 허용하는 설정이다.

Distributing policy files

Hiera 를 사용하지 않는다면, Puppet 모듈을 이용하여 정책 파일을 배포할 수 있다.

특 정 agent 에 대한 설정을 수동으로 하려면 정책 파일을 만들어서 Puppet module 의 files/policies/ 디렉토리에 두면 된다. 이 디렉토리에서 예제 정책을 찾을 수 있다. 이 디렉토리는 mcollective::serer class를 통해서 모든 노드에 동기화가 된다.

각 파일은 기본 정책만 제외하고 agentname.policy 로 이름을 만들어야 하며 .policy 로 파일이름이 끝나야 한다.  기본 정책은 authorization_default_policy class 나 Hiear 파라미터를 통해서 다음과 같이 설정을 한다:

이렇게 설정을 하면 기본 룰은 default_deny.policy 로 파일 이름이 생긴다.  authorization 을 활성화 했지만 default policy 를 명시하지 않으면 allow_unconfigured 를 활성화한 서버에서는 authorization 이 활성화 되며 기본 allow 정책이 활성화된다

allow_psk_root.policy_example 은 간단한 기본 정책을 보여준다. (allow_psk_root.policy_example 은 puppet module 의 files/policies/ 에 있는 파일을 말함) 여기서는 클라이언트 시스템의 root를 제외한 다른 사람의 요청은 모두 거부한다. 자신의 데스크탑에서 root 로 될 수 있기 때문에 안전하지는 않지만 기능만을 보여주는 것이다. Puppet module 의 files/policies 디렉토리에 여러가지 다른 예제들이 있다.

새 로운 정책을 만들었을 때 문제가 생기는 것을 Puppet 으로 고치려면 files/policies/puppet.policy_example 파일의 첫번째 룰을 포함할 것을 추천한다. 여기서는 authorization 셋업을 고치기 위해서 클라이언트에서 Puppet 을 실행하는 것을 허용하는 Puppet 정책을 설정한다. 테스팅을 하고나서 위험이 있다고 생각하면 비활성화한다.

Defining ActionPolicy Manually

ActionPolicy agent (http://bit.ly/1rdgJf8) 를 다운로드 받고 p25 "Installing from Source" 의 문서대로 설치를 한다. 그러고나서 각 server.cfg 파일에 다음 내용을 추가한다.

각 agent 에 대하여 기본 정책 파일과 정책 파일을 만든다.  정책 파일을 각 서버의 /etc/mcollective/policies/ 디릭토리에 설치한다.

다음은 예제용 service 정책 파일이다:

각 agent 별로 다르게 정책을 만들 수 있다. 파일 이름은 agentname.policy 이며 동일한 디렉토리에 설치한다. 이 디렉토리는 모든 서버에 동기화가 되어야 한다.

기본 정책을 활성화하면, 특정 정책을 설정하지 않는 모든 agent 에 적용이 된다. 기본 정책이 없고 allow_unconfigured 가 활성화(기본값임)되어 있으면 해당 agent 에 대한 모든 요청은 거부될 것이다.

Auditing

이 시점에 MCollective 는 짧은 시간에 몇천대의 서버에 변경을 할 수 있는 강력한 툴이라는 것을 실감했을 것이다. 각 서버에서 처리된 요청에 대해서 어떻게 로그를 남기는지 확인해야 한다.

auditing 요청을 위한 자신만의 플러그인을 만들 수도 있다. (20장에서 설명) 그렇지만 MCollective 는 필요에 따라 맞추어서 사용할 수 있는 기본 audit 플러그인이 있다. 기본 audit 플러그인은 각 서버에서 받는 모든 요청 사항, 해당 요청을 허용했는지 거부했는지 등을 디스크의 로그파일에 기록할 수 있다.

server 설정 파일에서 다음과 같이 활성화를 한다.

main MCollective 로그와 다르게 이 플러그인은 로그파일 로테이션 기능을 지원하지 않는다. logrotaet 를 설정하거나 이 부분을 다루어야 한다.

이 책의 Puppet module을 이용한다면 다음과 같이 class 파라미터를 설정하 로그파일과 로그로테이트 스크립트를 설정할 수 있다.

누가 요청을 보냈는지 남는 로그의 값은 p163 "Authorization"에서 설명을 한대로 어떤 security provider 를 썼는지에 따라서 다르다. 다음은 client identity 가 geode 인 경구의 로그를 보여준다.

audit 로그은 authentication 이나 authorization 실패에 대한 정보는 담고 있지 않다. 이러한 정보는 mail logfile 인 mcollective.log 에서 DEBUG 로그레벨로 정보를 수집할 수 있다.

결론

이번 장에서는 활성화하거나 커스터마이징할 수 있는 세가지 타입의 security plugins 를 설명하였다.

  • Security (authentication) plugin :  PSK, SSL, AES 또는 SSHKey security plugin 을 선택할 수 있으며 요청자에 대한 authentication 을 제공함.

  • Authorization plugin : ActionPolicy plugin 은 사용자가 어떤 요청을 서버에 보낼 수 있는지 제한을 함

  • Auditing plugin : LogFile plugin 을 통해 디스크에 처리한 모든 요청을 상세하게 기록할 수 있음

MCollective의 플러그인 구조는 자신의 필요성에 따라 MCollective 환경을 설정할 수 있는 유연성을 부여한다.

Labels
  • No labels