Opensource(오픈 소스)/Vault

Vault로 클라이언트 SSH CA 키 관리하기

hippo 데브옵스 2022. 7. 11. 00:14

Vault로 유효 기간이 존재하는 인증서 관리

  • 인증서를 직접 발급 수행하는 것은 매우 번거러운일
  • Vault를 사용하면 SSH 인증서를 매우 쉽게 관리하고 발급 가능

Vault를 사용하기 위해서는 모든 클라이언트 Server에 Vault가 설치 필요

1. hashicorp_vault 설치

$ yum install -y yum-utils
$ yum-config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo
$ yum -y install vault

2. hashicorp_vault 설치 확인

$ vault -v



Vault 서버 기본 설정

1. Vault SSH secret engine 활성화

$ vault secrets enable -path=ssh-client-signer ssh
Success! Enabled the ssh secrets engine at: ssh-client-signer/

# SSH secret enbine 생성 확인
$ vault secrets list
Path                       Type         Accessor              Description
----                        ----          --------                 -----------
ssh-client-signer/     ssh          ssh_241cbffa         n/a

2. SSH CA 생성

$ vault write ssh-client-signer/config/ca generate_signing_key=true
Key              Value
---                -----
public_key    ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDALoH6ItfBjGnqNJAwFa1xUzOJ38WVosCNZQ3o2BlFJxhXvejU1CalDQDCZXEK8SIxeOqKC3mu/nIGMLYR5lwWRgl5r3janyLw8174MSM1wgSy9ZcURZrivicafKrH2WQAXJ6TKsrlhR5GODwxRCciD02l8LgbvaBs8pt1SRmvCc17xBAMuwu/A0pBU+tHotfiBqeLlQThi2mhpRSZ9u2cIt4neP/g+1/hMDxjlhmge7ehQBNYyWc2n8HDubCYT+z2GANk8vk6DhXs5iaLozM1lALXQZlbK3MpIVh1HySnIewuw3rjgBlOc9sJMcrnQYdrb/EnJzLrcL4Sb4NmzB5gPW29vTc0Thkt4T4ghTCriOLCFjKihlc9sO8rsZ6fV10i/qfUONcrZYp1wVS18WOKQEBblgXp94L/Kl/mRVHFRicNDSVsZij9pHZovRprE3RkqO87qF67ZhcL3yzAVfkoRrWqDzG5PFpjGHLa3mV3nmL1vBKhL9/tkxbxz6svWkPYFSbxZx+JRSzzp3VPqFzSEiBmFNloCCVZfdSUMi5RlAD7r2NaCUR0+tXf0Io/YzXDuzMWk4Gq0FbJ+LWgfo1mXpj+iElmW4YS+oI6jyLVyQZEHZMvGcdiXyIZI76cdvqsjWL2C5e7O7p0ktTFmZfiBxHUUt3FbVZ+PqXk6H86uQ==

3. SSH Server에서 key를 read할 수 있도록 정책 설정

$ vi /vault/config/policy/ssh_policy.tf
path "ssh-client-signer/config/ca" {
  capabilities = ["read"]
}

4. SSH Server에서 key를 read할 수 있도록 정책 적용

$ cd /vault/config/policy/
$ vault policy write ssh-pubkey-read ssh_policy.tf
Success! Uploaded policy: ssh-pubkey-read

# SSH 정책 확인
$ vault policy list
default
ssh-pubkey-read

5. SSH Server에서 VAULT 서버로 접속할 Token 생성 → VAULT의 token값을 사용하기 위해서는 별도 저장 필요

$ vault token create -policy=ssh-pubkey-read
Key                        Value
---                         -----
token                     s.fX6YPfJI8xvi8NKZiI8O12UF
token_accessor       aUTigEQ0p2oNwoLUA8jMjWr6
token_duration       768h
token_renewable     true
token_policies         ["default" "ssh-pubkey-read"]
identity_policies      []
policies                   ["default" "ssh-pubkey-read"]

※ ssh-server에서 export 시켜주면 Vault 서버에서 SSH 인증서 public 키를 가져올 수 있음


6. SSH Client에서 Vault에 CA 사인 요청할 수 있도록 생성

  1. default_user
    • SSH 로그인에 사용될 유저 이름
    • default_user로 hippo 유저로 고정
    • 여러 사용자에 대해 허용할 것이라면 valid_principals 항목을 따로 정의해서 사용 필요
  1. ttl

    • CA가 사인한 키의 유효 기간을 의미

    • role을 통해 생성된 SSH 키는 5분 동안만 유효

      $ vault write ssh-client-signer/roles/my-role -<<"EOF"
      {
        "allow_user_certificates": true,
        "allowed_users": "*",
        "default_extensions": [
          {
            "permit-pty": ""
          }
        ],
        "key_type": "ca",
        "default_user": "hippo",
        "ttl": "5m0s"
      }
      EOF
      Success! Data written to: ssh-client-signer/roles/my-role

7. SSH Client에서 Vault에 CA 사인 update할 수 있도록 정책 설정

$ /vault/config/policy/
$ vi /vault/config/policy/sign_policy.tf
path "ssh-client-signer/sign/my-role" {
  capabilities = ["update"]
}

8. SSH Client에서 Vault에 CA 사인 update할 수 있도록 정책 적용

$ vault policy write require-ssh-sign sign_policy.tf
Success! Uploaded policy: require-ssh-sign

# 생성된 정책 확인
$ vault policy list
default
require-ssh-sign

9. SSH Client에서 VAULT 서버로 접속할 Token 생성 → VAULT의 token값을 사용하기 위해서는 별도 저장 필요

$ vault token create -policy=require-ssh-sign
Key                         Value
---                          -----
token                      s.HI8wvigrGvJuhUsk1H9ANmcl
token_accessor        0jom4yW0a8Nb4Cvw85NVCRtv
token_duration        768h
token_renewable      true
token_policies          ["default" "require-ssh-sign"]
identity_policies       []
policies                    ["default" "require-ssh-sign"]

※ ssh-client에서 export 시켜주면 Vault에서 CA 사인할 수 있는 public 키를 가져올 수 있음



SSH Server 설정 → SSH를 통해 접속하는 대상 서버

1. SSH Server에서 Vault server 접근할 수 있도록 환경변수 설정

  • VAULT_TOKEN 값은 SSH-Server에서 key를 read할 수 있도록 정책 설정 → s.fX6YPfJI8xvi8NKZiI8O12UF

  • VAULT 접속 도메인 설정 → [테스트 도메인]:8200

    # 환경 변수 적용
    export VAULT_ADDR=https://[테스트 도메인]:8200
    export VAULT_TOKEN=s.fX6YPfJI8xvi8NKZiI8O12UF
    
    # 영구적인 환경 변수 적용
    $ echo -e "\n#SSH\nexport VAULT_ADDR=https://[테스트 도메인]:8200" >> /etc/bashrc
    $ echo -e "export VAULT_TOKEN=s.fX6YPfJI8xvi8NKZiI8O12UF" >> /etc/bashrc

2. Vault server에서 CA의 public Key를 SSH Server에 전송

  • Vault server에서 public key 추출

      $ vault read -field=public_key ssh-client-signer/config/ca > /root/trusted-user-ca-keys.pem
    
      # 생성한 CA의 public key 확인
      $ cat /root/trusted-user-ca-keys.pem
      ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDALoH6ItfBjGnqNJAwFa1xUzOJ38WVosCNZQ3o2BlFJxhXvejU1CalDQDCZXEK8SIxeOqKC3mu/nIGMLYR5lwWRgl5r3janyLw8174MSM1wgSy9ZcURZrivicafKrH2WQAXJ6TKsrlhR5GODwxRCciD02l8LgbvaBs8pt1SRmvCc17xBAMuwu/A0pBU+tHotfiBqeLlQThi2mhpRSZ9u2cIt4neP/g+1/hMDxjlhmge7ehQBNYyWc2n8HDubCYT+z2GANk8vk6DhXs5iaLozM1lALXQZlbK3MpIVh1HySnIewuw3rjgBlOc9sJMcrnQYdrb/EnJzLrcL4Sb4NmzB5gPW29vTc0Thkt4T4ghTCriOLCFjKihlc9sO8rsZ6fV10i/qfUONcrZYp1wVS18WOKQEBblgXp94L/Kl/mRVHFRicNDSVsZij9pHZovRprE3RkqO87qF67ZhcL3yzAVfkoRrWqDzG5PFpjGHLa3mV3nmL1vBKhL9/tkxbxz6svWkPYFSbxZx+JRSzzp3VPqFzSEiBmFNloCCVZfdSUMi5RlAD7r2NaCUR0+tXf0Io/YzXDuzMWk4Gq0FbJ+LWgfo1mXpj+iElmW4YS+oI6jyLVyQZEHZMvGcdiXyIZI76cdvqsjWL2C5e7O7p0ktTFmZfiBxHUUt3FbVZ+PqXk6H86uQ==
    
      # scp를 통해 /etc/ssh 디렉토리 아래로 trusted-user-ca-keys.pem 파일 이동
      $ ls -al /etc/ssh/trusted-user-ca-keys.pem
      -rw-r--r-- 1 root root 725 Mar  1 17:39 /etc/ssh/trusted-user-ca-keys.pem

3. SSH 설정 → TrustedUserCAKeys /etc/ssh/trusted-user-ca-keys.pem 설정

$ vi /etc/ssh/sshd_config
Port 22000
#AddressFamily any
#ListenAddress 0.0.0.0
#ListenAddress ::

# TrustedUserCAKeys 추가
TrustedUserCAKeys /etc/ssh/trusted-user-ca-keys.pem

4. SSH 재시작 및 상태 확인

$ systemctl restart sshd

# 상태 확인
$ systemctl status sshd
● sshd.service - OpenSSH server daemon
   Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled; vendor preset: enabled)
   Active: active (running) since Tue 2022-03-01 17:47:07 KST; 3s ago
     Docs: man:sshd(8)
           man:sshd_config(5)
 Main PID: 62539 (sshd)
    Tasks: 1
   Memory: 1.0M
   CGroup: /system.slice/sshd.service
           └─62539 /usr/sbin/sshd -D



SSH Client 설정 → SSH 서버에 접속하는 SSH 클라이언트 서버

1. SSH Client에서 Vault server 접근할 수 있도록 환경변수 설정

  • VAULT_TOKEN 값은 SSH-Client에서 Vault Server에 CA사인 요청할 수 있도록 정책 설정 → s.HI8wvigrGvJuhUsk1H9ANmcl

  • VAULT 접속 도메인 설정 → https://[테스트 도메인]:8200

      # 환경 변수 적용
      export VAULT_ADDR=https://[테스트 도메인]:8200
      export VAULT_TOKEN=s.HI8wvigrGvJuhUsk1H9ANmcl
    
      # 영구적인 환경 변수 적용
      echo -e "\n#SSH\nexport VAULT_ADDR=https://[테스트 도메인]:8200" >> /etc/bashrc
      echo -e "export VAULT_TOKEN=s.HI8wvigrGvJuhUsk1H9ANmcl" >> /etc/bashrc

2. SSH key 생성 → 모두 enter로 넘어감

$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:ubVlwjtNjjxM9xoOdw6h8rSTF+zGfTeGt64/E1FIUwU root@180-70-134-115
The key's randomart image is:
+---[RSA 2048]----+
|             .E++|
|              ...|
|                .|
|         o     . |
|        S =.*   .|
|         * &oo . |
|        o %+*o+ .|
|         +oB=B.*o|
|          o+o.B=*|
+----[SHA256]-----+

3. 생성한 key를 Vault server에 사인 요청하고 응답 결과 key를 저장

$ vault write -field=signed_key ssh-client-signer/sign/my-role public_key=@/root/.ssh/id_rsa.pub > /root/.ssh/id_rsa-cert.pub

# id_rsa.pub에 사인 요청을 해서 접속 확인
$ cat /root/.ssh/id_rsa-cert.pub
ssh-rsa-cert-v01@openssh.com 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

4. SSH Client 에서 SSH Server로 접속 확인 → 결과 정상 접속

$ ssh -p 22000 hippo@[SSH 접속 서버 IP]
Last login: Tue Mar  1 17:59:26 2022 from [SSH 클라이언트 서버 IP]

5. 5분뒤 접속 가능한지 확인 → Vault server에서 sign 유효 시간을 5분으로 설정

  • test하기 위해 5분 뒤에 생성했던 id_rsa-cert.pub로 접속 시도 → 실패

  • 인증서 서명 유효기간이 만료되어 password로 접속 시도 하는 것을 확인 → 직접 비밀번호를 모르기에 오류 발생

  • 새롭게 id_rsa-cert.pub을 생성한 후에 다시 로그인 시도

    $ ssh -p 22000 hippo@[SSH 접속 서버 IP]
    no such identity: /root/.ssh/id_ed25519: No such file or directory
    hippo@[SSH 접속 서버 IP]'s password:
    
    # 새롭게 인증서 만들어서 로그인 시도
    $ vault write -field=signed_key ssh-client-signer/sign/my-role public_key=@/root/.ssh/id_rsa.pub > /root/.ssh/id_rsa-cert.pub
    $ ssh -p 22000 hippo@[SSH 접속 서버 IP]
    Last login: Tue Mar  1 17:59:55 2022 from [SSH 클라이언트 서버 IP]