리눅스 ssh-keygen 사용법 - ed25519 키 생성과 개인키 보안 관리
이 명령어를 언제 쓰는가
서버에 접속할 때마다 비밀번호를 치고 있다면, 또는 배포 스크립트가 비밀번호를 물어봐서 자동화가 막혀 있다면 키 기반 인증으로 넘어갈 때다. ssh-keygen은 그 첫 단계인 키 쌍 생성을 담당한다.
키 쌍은 두 개의 파일로 만들어진다. 개인키는 내 노트북에만 두고 절대 밖으로 내보내지 않는다. 공개키는 접속하려는 서버의 ~/.ssh/authorized_keys에 넣는다. 접속 시 서버가 낸 문제를 개인키로만 풀 수 있으므로, 비밀번호를 네트워크로 보내지 않고도 신원을 증명한다.
비밀번호 인증은 무차별 대입 공격의 표적이 된다. 인터넷에 22번 포트를 열어 둔 서버의 /var/log/auth.log를 보면 하루에도 수천 번씩 로그인 시도가 들어온다. 키 기반 인증으로 바꾸고 비밀번호 인증을 끄는 것이 지금의 표준이다.
기본 형식
ssh-keygen -t ed25519 -C "주석"
- -t — 키 알고리즘. 특별한 이유가 없으면
ed25519다. - -C — 공개키 끝에 붙는 주석. 나중에 authorized_keys에서 누구의 어느 기기 키인지 구분하는 유일한 단서다.
hscho@macbook-2026-08처럼 사람+기기+시점을 넣는다.
실행하면 저장 경로와 패스프레이즈를 묻고 두 개의 파일을 만든다.
Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/hscho/.ssh/id_ed25519):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/hscho/.ssh/id_ed25519
Your public key has been saved in /home/hscho/.ssh/id_ed25519.pub
The key fingerprint is:
SHA256:sxYtl0Y3tOc/2aq6liNv97B7LXr4GML2/864E9beij0 hscho@macbook-2026-08
공개키는 한 줄짜리 텍스트다.
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJhem9D+5DR/SmMo7cFNmR8vJj7oZIk4gXwBaAW31VjY hscho@macbook-2026-08
키 알고리즘 고르기
| 알고리즘 | 권장 여부 | 비고 |
|---|---|---|
ed25519 | 기본 선택 | 키가 짧고 빠르며 안전하다. OpenSSH 6.5(2014) 이후 지원 |
rsa (4096비트) | 호환용 | 아주 오래된 장비·어플라이언스가 ed25519를 못 받을 때만 |
ecdsa | 권장하지 않음 | NIST 곡선에 대한 신뢰 문제와 구현 난이도 때문에 ed25519가 대체했다 |
dsa | 쓰지 마라 | 1024비트 고정으로 안전하지 않다. OpenSSH 9.8에서 기본 비활성, 10.0에서 제거됐다 |
자주 쓰는 옵션
| 옵션 | 의미 | 예시 |
|---|---|---|
-t | 키 알고리즘 | ssh-keygen -t ed25519 |
-f | 저장할 파일 경로 | -f ~/.ssh/id_ed25519_deploy |
-C | 주석 | -C 'deploy@ci-runner' |
-b | 키 길이. RSA일 때만 의미가 있다 | -t rsa -b 4096 |
-p | 기존 키의 패스프레이즈 변경 | ssh-keygen -p -f ~/.ssh/id_ed25519 |
-l -f | 키의 지문 출력 | ssh-keygen -lf ~/.ssh/id_ed25519.pub |
-y -f | 개인키에서 공개키를 다시 뽑는다 | ssh-keygen -y -f ~/.ssh/id_ed25519 |
-R 호스트 | known_hosts에서 해당 항목 삭제 | ssh-keygen -R 10.0.1.20 |
-a | 개인키 암호화 반복 횟수(높을수록 무차별 대입에 강함) | -a 100 |
실전 예제
1) 새 노트북에서 개인 키를 만든다. 가장 기본이 되는 형태다. 패스프레이즈는 반드시 넣는다.
ssh-keygen -t ed25519 -a 100 -C "hscho@macbook-2026-08"
만들고 나면 권한을 확인한다. 개인키는 600, 공개키는 644, ~/.ssh 디렉터리는 700이어야 한다.
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519
chmod 644 ~/.ssh/id_ed25519.pub
ls -l ~/.ssh
-rw------- 1 hscho staff 464 Aug 25 22:19 id_ed25519
-rw-r--r-- 1 hscho staff 103 Aug 25 22:19 id_ed25519.pub
2) 용도별로 키를 나눈다. 개인 접속용 키와 CI 배포용 키를 같이 쓰지 않는다. 키 하나가 유출됐을 때 폐기 범위를 좁히기 위해서다.
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_deploy -C "deploy@github-actions"
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_prod -C "hscho@prod-bastion"
여러 키를 쓰면 어떤 호스트에 어떤 키를 쓸지 ~/.ssh/config에 적어 둔다.
Host prod-bastion
HostName 203.0.113.10
User hscho
IdentityFile ~/.ssh/id_ed25519_prod
IdentitiesOnly yes
IdentitiesOnly yes가 중요하다. 이게 없으면 ssh가 에이전트에 등록된 모든 키를 순서대로 시도하는데, 서버의 MaxAuthTries(기본 6)를 넘겨 정작 맞는 키를 써 보기도 전에 끊기는 일이 생긴다.
3) 지문을 확인해 authorized_keys의 주인을 찾는다. 서버에 등록된 키가 누구 것인지 확인할 때 쓴다.
ssh-keygen -lf ~/.ssh/id_ed25519.pub
256 SHA256:sxYtl0Y3tOc/2aq6liNv97B7LXr4GML2/864E9beij0 hscho@macbook-2026-08 (ED25519)
서버 쪽에서 등록된 키 전부의 지문을 뽑으려면 이렇게 한다.
while read -r line; do
[ -n "$line" ] && echo "$line" | ssh-keygen -lf -
done < ~/.ssh/authorized_keys
4) 패스프레이즈를 잊었거나 바꿔야 할 때. 개인키 자체는 그대로 두고 암호화만 다시 한다. 기존 패스프레이즈를 알아야 가능하다.
ssh-keygen -p -a 100 -f ~/.ssh/id_ed25519
5) 공개키 파일을 잃어버렸을 때 개인키에서 복원한다. 개인키만 있으면 공개키는 언제든 다시 만들 수 있다. 반대는 불가능하다.
ssh-keygen -y -f ~/.ssh/id_ed25519 > ~/.ssh/id_ed25519.pub
6) 서버를 재설치한 뒤 호스트 키 경고가 뜰 때 정리한다. 서버를 밀고 다시 세우면 호스트 키가 바뀌어 REMOTE HOST IDENTIFICATION HAS CHANGED! 경고가 뜬다. 원인을 확인한 뒤에만 지운다.
ssh-keygen -R 10.0.1.20
ssh-keygen -R '[10.0.1.20]:2222' # 비표준 포트는 대괄호 표기
함정과 주의점
패스프레이즈 없는 개인키는 파일에 적어 둔 비밀번호와 같다. 노트북을 잃어버리거나, 백업이 유출되거나, 실수로 저장소에 커밋되면 그 키로 열리는 모든 서버가 함께 넘어간다. 매번 입력하기 번거롭다는 것이 유일한 반론인데, 그건 ssh-agent가 해결한다. 세션당 한 번만 입력하면 된다.
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
ssh-add -l # 등록된 키 확인
ssh-add -D # 전부 해제
맥에서는 ssh-add --apple-use-keychain ~/.ssh/id_ed25519로 키체인에 맡길 수 있다. CI 서버처럼 사람이 없는 환경이 문제인데, 이때는 패스프레이즈 없는 키를 쓰되 권한을 최소로 좁힌 전용 계정에만 등록하고, authorized_keys 항목에 command=, from=, no-pty 제한을 건다.
개인키 권한이 느슨하면 ssh가 아예 거부한다. 다른 사용자가 읽을 수 있는 개인키는 위험하므로 OpenSSH가 사용을 막는다. 키를 복사하거나 압축을 풀면 권한이 644로 풀리는 경우가 흔하다.
Permissions 0644 for '/home/hscho/.ssh/id_ed25519' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
chmod 600으로 고친다. 홈 디렉터리 자체가 그룹 쓰기 가능(775)이어도 서버 쪽에서 거부당하므로 함께 확인한다.
ssh-keygen의 기본 키 타입은 버전에 따라 다르다. OpenSSH 9.5(2023년 10월)부터 -t를 생략하면 ed25519가 만들어지지만, 그 이전 버전에서는 3072비트 RSA가 만들어진다. RHEL 8·9나 Ubuntu 20.04처럼 OpenSSH 8.x가 올라간 서버가 아직 많다. 항상 -t ed25519를 명시한다.
RSA 키 자체와 ssh-rsa 서명 알고리즘은 다른 이야기다. OpenSSH 8.8(2021)부터 SHA-1 기반의 ssh-rsa 서명이 기본 비활성화됐다. 그래서 최신 클라이언트로 오래된 서버에 붙을 때 no matching host key type found나 Their offer: ssh-rsa 같은 오류를 만난다. RSA 키가 나쁜 것이 아니라 서명 방식이 낡은 것이라, 서버가 rsa-sha2-256을 지원하도록 OpenSSH를 올리는 것이 정답이다. 그때까지 임시로 붙어야 한다면 아래처럼 해당 호스트에만 한정해서 허용하고, 반드시 기한을 정해 정리한다.
Host legacy-appliance
HostName 10.0.9.5
PubkeyAcceptedAlgorithms +ssh-rsa
HostKeyAlgorithms +ssh-rsa
개인키를 서버로 복사하는 것은 방향이 거꾸로다. 초보자가 자주 하는 실수인데, 서버에 올려야 하는 것은 .pub 확장자가 붙은 공개키뿐이다. 개인키를 여러 서버에 뿌려 놓으면 서버 한 대만 뚫려도 전부 넘어간다. 여러 서버를 거쳐 들어가야 한다면 개인키를 옮기지 말고 ssh -J bastion,target(ProxyJump)이나 에이전트 포워딩(ssh -A)을 쓴다. 에이전트 포워딩도 중간 서버의 root가 소켓을 가로챌 수 있으므로 신뢰하는 호스트에만 쓴다.
키를 만들었다고 끝이 아니다. 폐기 절차도 함께 정한다. 퇴사자나 폐기된 CI 러너의 공개키가 authorized_keys에 몇 년째 남아 있는 서버가 정말 많다. 주석(-C)을 성실히 붙이고, 반기마다 전 서버의 authorized_keys를 뽑아 지문 목록을 대조하는 절차를 만들어 둔다.
함께 보면 좋은 명령어
- ssh-copy-id — 만든 공개키를 서버의 authorized_keys에 안전하게 등록한다. ssh-keygen 다음 단계다.
- ssh —
ssh -vvv로 어떤 키를 어떤 순서로 시도하는지 볼 수 있다. 키 인증이 안 될 때 가장 먼저 본다. - ssh-agent / ssh-add — 패스프레이즈를 세션당 한 번만 입력하게 해 준다. 패스프레이즈를 실제로 쓰게 만드는 열쇠다.