ssh-agent 를 이용한 SSH 키 관리
이 단계에서는 ssh-agent를 사용하여 SSH 키를 관리하는 방법을 배웁니다. ssh-agent는 백그라운드에서 실행되며 메모리에 개인 키를 보관하는 프로그램입니다. 개인 키가 암호로 보호될 때 특히 유용합니다. 키를 사용할 때마다 암호를 입력하는 대신, 키를 ssh-agent에 한 번 추가하면 에이전트가 세션 기간 동안 인증을 처리합니다.
이전 단계에서 암호 없이 키를 생성했지만, 이제 ssh-agent의 유용성을 보여주기 위해 암호가 있는 새 키를 생성합니다.
먼저 암호가 있는 새 SSH 키 쌍을 생성합니다. 기본 id_rsa 키와 구별하기 위해 이 키를 id_rsa_passphrase로 명명합니다.
ssh-keygen -f ~/.ssh/id_rsa_passphrase
암호를 입력하라는 메시지가 표시됩니다. 이 실습에서는 암호로 mypassphrase를 사용합니다.
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase): mypassphrase
Enter same passphrase again: mypassphrase
Your identification has been saved in /home/labex/.ssh/id_rsa_passphrase
Your public key has been saved in /home/labex/.ssh/id_rsa_passphrase.pub
The key fingerprint is:
SHA256:BuSxVlJb1lsiUFi2I5DAvyL01fJ5d480LT86dgtcHEg labex@6846375f1c0e35fea6cb03e6
The key's randomart image is:
+---[RSA 3072]----+
| ...=o+=*. E |
| .o.*.=..+ o |
| .=.o o. = . |
| . .+... .. . .|
| . . . +S. + |
| . o ..o . o * .|
| . . . . = * |
| oooo|
| ..+.o|
+----[SHA256]-----+
참고: 실수로 암호를 입력하지 않고 엔터 키를 누르면 키가 암호 없이 생성됩니다. 그런 경우 파일을 삭제하고 명령어를 다시 실행하여 암호 입력을 요청받으면 mypassphrase를 입력해야 합니다.
이제 이 새 공개 키를 localhost에 복사하여 인증에 사용할 수 있도록 합니다.
ssh-copy-id -i ~/.ssh/id_rsa_passphrase.pub labex@localhost
기본 키로 이미 비밀번호 없이 인증이 설정되어 있으므로, 명령어는 비밀번호를 묻지 않고 기존 인증을 사용할 수 있습니다.
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/labex/.ssh/id_rsa_passphrase.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
Number of key(s) added: 1
Now try logging into the machine, with: "ssh 'labex@localhost'"
and check to make sure that only the key(s) you wanted were added.
이제 이 새 키를 사용하여 localhost에 연결해 봅니다. -i 옵션을 사용하여 개인 키 파일을 지정해야 합니다.
ssh -i ~/.ssh/id_rsa_passphrase labex@localhost
키에 암호를 설정한 경우 암호를 입력하라는 메시지가 표시됩니다. 그러나 실수로 암호 없이 키를 생성한 경우 (예시 출력과 같음) 바로 로그인합니다.
Last login: Mon Jun 9 01:39:25 2025 from 47.251.66.143
[labex@host ~]$
로그인했습니다. 이제 세션을 종료합니다.
exit
exit
Connection to localhost closed.
[labex@host ~]$
참고: 키에 암호가 없더라도 ssh-agent 데모를 계속 진행하여 작동 방식을 이해할 수 있습니다. 이 경우 암호를 묻지 않습니다.
먼저 현재 쉘 세션에서 ssh-agent를 시작합니다. eval 명령어는 ssh-agent가 출력하는 환경 변수를 올바르게 설정하는 데 사용됩니다.
eval "$(ssh-agent)"
Agent pid 1024
출력에는 ssh-agent의 프로세스 ID(PID) 가 표시됩니다.
다음으로 개인 키 (id_rsa_passphrase) 를 ssh-agent에 추가합니다.
ssh-add ~/.ssh/id_rsa_passphrase
키에 암호가 있는 경우 암호를 입력하라는 메시지가 표시됩니다. 그렇지 않으면 키가 직접 추가됩니다.
Identity added: /home/labex/.ssh/id_rsa_passphrase (labex@6846375f1c0e35fea6cb03e6)
이제 키가 ssh-agent에 추가되었으므로 동일한 키를 사용하여 localhost에 다시 연결해 봅니다.
ssh -i ~/.ssh/id_rsa_passphrase labex@localhost
암호를 묻지 않고 연결할 수 있습니다 (키에 암호가 있든 없든 에이전트가 이제 관리하기 때문입니다).
Last login: Mon Jun 9 01:39:49 2025 from 127.0.0.1
[labex@host ~]$
ssh-agent를 사용하여 SSH 키를 성공적으로 관리했습니다.
중요 참고 사항: ssh-agent 환경 변수는 에이전트를 시작한 쉘 세션에서만 사용할 수 있습니다. SSH 세션에 있는 경우 로컬 쉘로 돌아가서 ssh-add 명령어를 사용해야 합니다.
먼저 SSH 세션을 종료합니다.
exit
exit
Connection to localhost closed.
[labex@host ~]$
이제 현재 ssh-agent에 로드된 키를 보려면 ssh-add -l을 사용할 수 있습니다.
ssh-add -l
에이전트가 실행되고 키가 로드된 경우 다음과 같은 출력이 표시됩니다.
3072 SHA256:BuSxVlJb1lsiUFi2I5DAvyL01fJ5d480LT86dgtcHEg /home/labex/.ssh/id_rsa_passphrase (RSA)
그러나 "Could not open a connection to your authentication agent"와 같은 오류 메시지가 표시되면 현재 세션에 에이전트 환경 변수가 설정되지 않았음을 의미합니다.
ssh-agent에서 모든 ID 를 제거하려면 ssh-add -D를 사용합니다.
ssh-add -D
에이전트에 접근할 수 있으면 다음과 같은 출력이 표시됩니다.
All identities removed.
그러나 "Could not open a connection to your authentication agent"와 같은 오류 메시지가 표시되면 현재 세션에 에이전트 환경이 없음을 의미합니다.
이제 다시 연결하려고 하면 키에 암호가 있으면 에이전트에서 키가 제거되었으므로 암호를 입력하라는 메시지가 표시됩니다.
ssh -i ~/.ssh/id_rsa_passphrase labex@localhost
키에 암호가 있으면 다음과 같은 메시지가 표시됩니다.
Enter passphrase for key '/home/labex/.ssh/id_rsa_passphrase':
키에 암호가 없으면 여전히 직접 연결할 수 있습니다. 암호를 입력하라는 메시지가 표시되면 Ctrl+C를 눌러 연결 시도를 취소합니다.
마지막으로 ssh-agent 프로세스를 중지하려면 ssh-agent -k를 사용할 수 있습니다.
ssh-agent -k
SSH_AGENT_PID 환경 변수가 설정되지 않으면 다음과 같은 메시지가 표시될 수 있습니다.
SSH_AGENT_PID not set, cannot kill agent
에이전트가 다른 쉘 세션에서 시작되었거나 환경 변수가 제대로 내보내지 않았을 경우 정상입니다.