DEVELOPMENT NOTE2

Oracle Cloud에서 잃어버린 SSH 접근 복구하기

OCI Serial Console과 GRUB root shell로 새 SSH 공개키를 등록한 과정

#oracle-cloud#ubuntu#ssh#recovery#operations
아카이브로 돌아가기

Windows 노트북을 정리하고 MacBook으로 바꾸면서 Oracle Cloud Ubuntu instance의 SSH 개인키를 잃어버렸다. 남아 있던 .pem은 OCI CLI와 API용 키였고 instance의 authorized_keys와 짝이 아니었다.

text
Permission denied (publickey)

SSH 인증 단계까지 도달했으므로 network보다 키 문제를 먼저 확인했다. 일반 SSH로 새 키를 등록할 수 없어 OCI Instance Console Connection과 GRUB root shell을 사용했다.

이 내용은 내가 관리하고 Console 권한을 가진 instance를 복구한 기록이다. Root shell은 운영체제 파일을 직접 바꿀 수 있는 강한 권한이며 잘못된 partition이나 명령은 부팅 상태를 더 망가뜨릴 수 있다. OCI와 Ubuntu image, firmware와 GRUB 구성에 따라 화면과 장치 이름도 달라진다.

Console 연결용 RSA 키를 만들었다

처음 만든 ed25519 key는 당시 Console Connection 화면에서 거부됐다.

text
Invalid ssh public key type "ssh-ed25519"

RSA 4096 key를 따로 만들고 공개키만 Console Connection에 등록했다.

bash
ssh-keygen -t rsa -b 4096 -f ~/.ssh/<recovery-key> -C "oci-console-recovery"
cat ~/.ssh/<recovery-key>.pub

이 key는 Serial Console 인증용이며 아직 일반 SSH를 복구한 것은 아니다. 절차는 Oracle의 Instance Console Connection 문서를 기준으로 진행했다.

Serial Console에서 GRUB로 들어갔다

OCI Console에서 local connection을 만들고 상태가 Active가 된 뒤 생성된 Linux/macOS 연결 명령을 사용했다. 당시에는 바깥 SSH와 ProxyCommand 안쪽 SSH 모두에 -i로 개인키를 지정했다. Mac OpenSSH와 RSA 조합에 필요한 HostKeyAlgorithms, PubkeyAcceptedAlgorithms도 추가했다. 식별자가 포함된 실제 명령은 기록하지 않았다.

Serial Console 연결 뒤 Ubuntu login prompt가 나왔지만 account password가 없었다. Instance를 reboot하고 UEFI Boot Manager에서 Ubuntu를 선택한 직후 Escgrub> prompt에 들어갔다. Timing은 환경마다 다를 수 있다.

장치를 추측하지 않고 ls로 확인했다.

text
grub> ls
grub> ls (<boot-partition>)/
grub> ls (<root-partition>)/

vmlinuzinitrd.img가 있는 boot partition, root filesystem과 UUID를 찾았다. 실제 번호와 UUID는 해당 instance에만 맞으므로 공개하지 않았다.

임시 root shell로 부팅했다

확인한 값으로 init=/bin/bash를 지정했다.

text
set root=(<boot-partition>)
linux /vmlinuz root=UUID=<root-filesystem-uuid> rw init=/bin/bash
initrd /initrd.img
boot

root@(none):/# prompt가 나타났다. 일반 service가 올라온 상태가 아니므로 SSH key 복구에 필요한 파일만 수정했다.

authorized_keys에 새 공개키를 추가했다

Root filesystem을 writable로 다시 mount하고 기존 key를 지우지 않은 채 새 공개키를 한 줄 추가했다.

bash
mount -o remount,rw /
mkdir -p /home/<instance-user>/.ssh
printf '%s\n' '<public-key>' >> /home/<instance-user>/.ssh/authorized_keys
 
chown -R <instance-user>:<instance-user> /home/<instance-user>/.ssh
chmod 700 /home/<instance-user>/.ssh
chmod 600 /home/<instance-user>/.ssh/authorized_keys
sync

소유권과 permission이 넓거나 잘못되면 SSH가 key를 무시할 수 있어 함께 맞췄다. 복구 선택지를 줄이지 않기 위해 접속을 확인하기 전 기존 공개키는 제거하지 않았다.

복구용 root shell에서 빠져나오기 위해 당시에는 reboot -f를 사용했다. 평소 실행 중인 서버에서 사용할 명령이 아니라 init 대신 bash로 부팅한 상황의 기록이다.

일반 SSH 경로를 확인했다

정상 boot 뒤 새 개인키로 접속했다.

bash
ssh -i ~/.ssh/<recovery-key> <instance-user>@<instance-address>

Ubuntu shell에 들어가 공개키와 개인키가 맞고 authorized_keys permission이 유효하며 Serial Console이 아닌 일반 SSH가 복구됐음을 확인했다. 임시 Console Connection은 이후 삭제했다.

이번 복구는 OCI account와 Console 권한이 남아 있었기 때문에 가능했다. SSH를 되찾았다고 개인키 하나에 의존하는 구조와 Cloud account, 공개 port, backup 문제가 해결된 것은 아니었다. 접속 복구와 안전한 운영 준비는 별개의 작업이었다.