Oracle Cloud Infrastructure(OCI) 무료 인스턴스에서
Permission denied (publickey)오류로 SSH 접속이 막혔다면, 이 글이 가장 빠른 해결책을 제공합니다. Console Connection 생성, Cloud Shell 수정, 키 포맷 변경까지 모두 시도했지만 실패한 분들을 위해 OCI Run Command를 통한 authorized_keys 재등록 방법을 단계별로 정리했습니다.
Oracle Cloud Infrastructure(OCI)에서 무료 인스턴스를 생성한 후 SSH로 접속하려 할 때, ‘Permission denied (publickey)’ 오류가 발생하거나 인증키를 분실하는 경우가 종종 있습니다. 이번 글에서는 이러한 문제를 해결하고 다시 서버에 안전하게 접속하는 방법을 단계별로 알아보겠습니다.
목차
1.오라클 서버 인증키에서 발생한 에러 메시지
$ ssh -i "ssh-key-2026-06-20.key" -p 1234 [email protected]
[email protected]: Permission denied (publickey).언뜻 보면 키 파일이 잘못되었거나, 키 포맷 문제처럼 보입니다. 하지만 이 판단이 바로 첫 번째 함정입니다. 이 오류의 진짜 원인을 파악하려면 먼저 OCI의 SSH 키 구조를 이해해야 합니다.
2. 오라클 서버 인증키: OCI SSH 키의 두 종류
많은 사용자들이 SSH 접속 오류 앞에서 곧바로 키 포맷 변환, 권한 수정, 새 키 생성 등을 시도합니다. 하지만 OCI에는 용도가 전혀 다른 두 종류의 SSH 키가 존재하며, 이 차이를 모르면 어떤 방법을 써도 실패합니다.
두 가지 문 비유
오라클 서버에 들어가기 위해 두 개의 문 앞에 서 있습니다.
첫 번째 문 (직렬 콘솔용 비상구)
- OCI Console에서
[Generate a key pair for me]를 선택해 생성하는 키가 사용하는 문입니다. - 이 키는 Oracle Cloud 시스템이 관리하며, 서버가 완전히 먹통이 됐을 때 직렬 콘솔(Serial Console)로 긴급 접근하기 위한 비상 열쇠입니다.
ssh -o ProxyCommand=...형태의 복잡한 명령어로 접속합니다.- 이 키는 서버 내부의
ubuntu계정과 직접적인 관련이 없습니다.
두 번째 문 (일반 SSH 접속용 출입문)
- 개발자가 매일 서버에 들어가서 작업할 때 사용하는 일반 출입문입니다.
ssh -i "key.pem" ubuntu@서버IP형태로 접속합니다.- 이 키의 공개키(public key) 내용이 서버 내부의
/home/ubuntu/.ssh/authorized_keys파일에 등록되어 있어야만 접속이 됩니다.
| 구분 | 직렬 콘솔용 키 | 일반 SSH 접속용 키 |
|---|---|---|
| 생성 위치 | OCI Console (Oracle 관리) | 로컬 컴퓨터 (사용자 직접 생성) |
| 용도 | 긴급 비상 접근 (직렬 콘솔) | 일상적인 SSH 접속 |
| 등록 위치 | OCI 시스템 내부 | 서버의 ~/.ssh/authorized_keys |
| 접속 방식 | ProxyCommand 사용 | ssh -i key user@host |
결론: OCI Console에서 만든 키로 일반 SSH 접속(111.111.111.111:1111)을 시도하는 것은, 비상구 열쇠로 일반 출입문을 열려는 것과 같습니다. 문 자체와 열쇠가 짝이 맞지 않으니 Permission denied가 나오는 것이 당연합니다.
SSH 공개키 인증 동작 원리
SSH 공개키 인증이 어떻게 작동하는지 이해하면 문제의 본질이 명확해집니다:
- 클라이언트: “나는 이 개인키(private key)를 가지고 있어요” 라고 서버에 알림
- 서버:
authorized_keys파일에서 해당 공개키(public key)를 찾음 - 서버: 공개키로 암호화한 챌린지를 클라이언트에 전송
- 클라이언트: 개인키로 챌린지를 복호화해서 응답
- 서버: 검증 성공 → 접속 허용 / 실패 →
Permission denied
즉, 서버의 authorized_keys에 공개키가 없으면 절대 접속할 수 없습니다. 키 포맷이 맞아도, 권한이 올바라도 소용없습니다.
OCI Console에서 SSH 키 변경이 안 되는 이유
OCI 웹 콘솔 메뉴를 통해 이미 생성된 인스턴스의 SSH 키를 직접 변경하거나 수정하는 기능은 기본적으로 제공되지 않습니다. 많은 사용자가 가장 헷갈려하는 부분입니다.
이유는 두 가지입니다:
① 인스턴스 생성 시점에만 등록: SSH 공개키는 OCI가 서버(인스턴스)를 처음 만들 때 cloud-init을 통해 서버 내부 파일(authorized_keys)에 딱 한 번 주입하는 정보입니다. 마치 자물쇠(공개키)를 문에 달고 열쇠(개인키)는 사용자에게 주는 방식입니다.
② 보안 설계 원칙: 서버가 생성된 후에는 클라우드 관리자(OCI)조차 서버 내부 파일을 마음대로 수정하지 못하도록 설계되어 있습니다. 이는 클라우드 제공자가 고객 서버에 무단 접근하는 것을 방지하는 Zero Trust 보안 원칙입니다. 따라서 SSH 키 변경은 클라우드 관리 메뉴가 아니라, 서버 내부 파일을 직접 수정해야만 가능합니다.
3. 원인 진단 과정
개념을 이해했으니 이제 체계적으로 원인을 진단해 봅니다.
3.1 네트워크 연결 확인 (성공)
가장 먼저 확인해야 할 것은 네트워크 수준에서의 연결 가능 여부입니다. Permission denied와 Connection refused는 완전히 다른 문제입니다.
# PowerShell에서 포트 연결 테스트
Test-NetConnection 999.999.999.999 -Port 8888
# 결과
TcpTestSucceeded : True ← 네트워크 연결 성공!TcpTestSucceeded : True라는 결과는 중요한 정보를 담고 있습니다:
- IP가 차단된 것이 아님
- 포트 (예:8888) 이 방화벽(OCI Security List)에서 열려 있음
- SSH 데몬(sshd)이 해당 포트에서 실행 중임
즉, 네트워크는 완벽하게 정상이었습니다. 문제는 순수하게 SSH 인증 레이어에 있었습니다.
3.2 SSH verbose 로그 분석
SSH 접속 시 -vvv 옵션을 추가하면 인증 과정의 상세 로그를 볼 수 있습니다. 이 로그가 문제의 핵심을 보여줍니다.
# 상세 로그 확인
ssh -vvv -i "ssh-key-2026-06-20.key" -p 888 [email protected](오라클IP)
# 핵심 로그 부분
debug1: Offering public key: my_new_key RSA SHA256:W3ZDFFGDZw explicit
debug3: receive packet: type 51
debug1: Authentications that can continue: publickey로그 해석:
Offering public key: 클라이언트가 공개키를 서버에 제시하고 있음receive packet: type 51: SSH 프로토콜에서type 51은SSH_MSG_USERAUTH_FAILURE(인증 실패) 패킷Authentications that can continue: publickey: 서버가 publickey 인증 방식만 허용하고 있음
결론: 서버가 클라이언트의 공개키를 거부하고 있음. 즉, 서버의 authorized_keys에 해당 공개키가 등록되어 있지 않음.
3.3 원인 종합 분석
| 원인 | 설명 |
|---|---|
| 키 생성 위치 | 로컬에서 키를 생성했지만 인스턴스 authorized_keys에 등록되지 않음 |
| Console Connection 오해 | SSH 키를 등록하는 기능이 아님 (비상 접근 통로일 뿐) |
| Run Command 사용 | Oracle Cloud Agent를 통한 원격 명령어 실행 방법 |
| VNC Console | 대체 접속 방법 |
4. 실패했던 방법들 — 왜 안 되는가 완전 분석
저도 아래 방법으로 시도했습니다. 각 방법이 왜 실패했는 분석 내용입니다.
❌ 실패 1: Console Connection 생성
시도: OCI Console → Compute → Instances → Console Connection 생성
결과: Console Connection은 생성되었지만, 일반 SSH 접속 여전히 불가
왜 실패했나? Console Connection은 VNC(Virtual Network Computing) 및 Serial Console 접속을 위한 기능입니다. 네트워크가 완전히 단절되었거나 OS가 부팅 문제를 겪을 때 물리 서버의 콘솔에 접근하는 것처럼 서버에 접근하는 비상 통로입니다. SSH 키를 서버에 등록하는 기능과는 전혀 별개입니다.
Console Connection을 생성하면 ssh -o ProxyCommand=... 형태의 명령어가 제공되며, 이 명령어는 직렬 콘솔용 키를 사용해야만 접속됩니다. 일반 SSH 접속(-p 54321 ubuntu@IP)과 완전히 다른 경로입니다.
❌ 실패 2: OCI Console에서 SSH Keys 추가 시도
시도: 인스턴스 Edit 화면에서 SSH Keys 섹션 찾기
결과: Edit 화면에 SSH Keys 섹션이 존재하지 않음
왜 실패했나? 앞서 설명한 OCI 보안 설계 원칙 때문입니다. OCI는 인스턴스 생성 시점 이후에 클라우드 관리 메뉴에서 SSH 키를 변경하는 기능을 의도적으로 제공하지 않습니다. 일부 인스턴스 유형에서는 Boot Volume의 커스텀 데이터(cloud-init) 섹션은 수정할 수 있지만, 이미 실행 중인 인스턴스의 authorized_keys를 외부에서 직접 수정하는 GUI 메뉴는 존재하지 않습니다.
❌ 실패 3: Cloud Shell에서 authorized_keys 수정
시도: OCI Cloud Shell에서 ~/.ssh/authorized_keys에 키 내용 추가
결과: Cloud Shell 환경의 authorized_keys만 수정됨 (인스턴스와 완전 무관)
왜 실패했나? OCI Cloud Shell은 Oracle이 관리하는 별도의 독립 컨테이너 환경입니다. 브라우저에서 직접 CLI를 사용할 수 있도록 제공하는 가상 터미널이며, 여러분의 OCI 인스턴스(141.147.157.212)와는 완전히 다른 서버입니다.
Cloud Shell의 홈 디렉토리(~)는 여러분의 인스턴스 홈 디렉토리가 아닙니다. Cloud Shell에서 파일을 수정하면 Cloud Shell 자체 환경만 변경될 뿐, 인스턴스에는 아무런 영향을 주지 않습니다.
Cloud Shell (별도 컨테이너) 인스턴스
~/.ssh/authorized_keys ≠ /home/ubuntu/.ssh/authorized_keys
↑ 여기를 수정했음 ↑ 여기를 수정해야 함❌ 실패 4: 다양한 SSH 키 포맷 시도
시도: 여러 종류의 키 파일을 -i 옵션으로 번갈아 사용
| 키 파일 | 포맷 | 결과 |
|---|---|---|
my_new_key | OpenSSH | ❌ 실패 |
oci_key | OpenSSH | ❌ 실패 |
ssh-key-2026-06-20.key | PEM | ❌ 실패 (키 미등록) |
oci_pem | PEM (새로 생성) | ❌ 실패 (키 미등록) |
왜 실패했나? 키 포맷(PEM vs OpenSSH)은 클라이언트 측 개인키를 읽는 방식의 차이일 뿐, 인증 실패와는 무관합니다. 문제는 어떤 키를 사용하든 그 키의 공개키가 서버 authorized_keys에 없다는 것입니다. 아무리 완벽한 열쇠를 가져와도 서버의 자물쇠와 짝이 맞지 않으면 열리지 않습니다.
PEM과 OpenSSH 키 포맷의 기술적 차이:
| 특징 | PEM 형식 | OpenSSH 형식 |
|---|---|---|
| 헤더 | -----BEGIN RSA PRIVATE KEY----- | -----BEGIN OPENSSH PRIVATE KEY----- |
| 표준 | PKCS#1 (RFC 3447) | RFC 4716 / OpenSSH 자체 형식 |
| 도입 시기 | 전통적 (오래된 표준) | OpenSSH 6.5+ (2014년 이후) |
| 호환성 | 대부분 도구와 호환 | 최신 SSH 클라이언트 필요 |
| 권장 용도 | 범용 (OCI, AWS 등) | 최신 리눅스 환경 |
두 형식 모두 SSH 인증에 사용 가능하며, 형식 자체가 Permission denied의 원인이 되지는 않습니다.
5. 최종 해결: Run Command로 SSH 키 등록하기
이제 핵심 해결책입니다. OCI Run Command는 Oracle Cloud Agent를 통해 인스턴스 내부에 직접 스크립트를 실행할 수 있는 강력한 기능입니다. SSH 접속 없이도 서버 내부 명령어를 실행할 수 있어, SSH 키가 잠겼을 때 최적의 해결 수단입니다.
Oracle Cloud Agent란? OCI 인스턴스에 기본 설치되어 실행 중인 에이전트 소프트웨어입니다. 인스턴스 모니터링, 플러그인 관리, Run Command 실행 등을 담당합니다. SSH와 독립적으로 OCI 내부 네트워크를 통해 통신하므로, SSH 키 문제가 있어도 사용할 수 있습니다.
5.1 SSH 키 생성 (Windows PowerShell)
먼저 로컬 Windows에서 새 SSH 키 쌍을 생성합니다. 이 키의 공개키를 서버에 등록할 것입니다.
# PowerShell에서 SSH 키 생성 (PEM 형식)
ssh-keygen -t rsa -b 4096 -f G:\orcleCloud\ssh-key-2026-06-20.key -m pem -C "ubuntu"각 옵션 의미:
| 옵션 | 값 | 의미 |
|---|---|---|
-t rsa | rsa | RSA 알고리즘 사용 (가장 범용적) |
-b 4096 | 4096 | 키 길이 4096비트 (2048보다 강력한 보안) |
-f | 파일 경로 | 키 파일 저장 경로 |
-m pem | pem | 개인키를 PKCS#1 PEM 형식으로 저장 |
-C "ubuntu" | ubuntu | 키 코멘트 (식별용, 인증과 무관) |
# 생성된 공개키 내용 확인 (이 내용을 서버에 등록해야 함)
cat G:\orcleCloud\ssh-key-2026-06-20.key.pub출력 예시:
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC... ubuntu이 한 줄이 **공개키(public key)**입니다. 이 내용 전체를 복사해두세요.
5.2 Windows 키 파일 권한 설정 (icacls)
Windows에서 SSH 키 파일은 반드시 소유자만 읽을 수 있도록 권한을 제한해야 합니다. 권한이 너무 느슨하면 SSH 클라이언트가 키 파일 사용을 거부합니다.
# 상속된 권한 모두 제거
icacls G:\orcleCloud\ssh-key-2026-06-20.key /inheritance:r
# 현재 사용자에게만 읽기 권한 부여
icacls G:\orcleCloud\ssh-key-2026-06-20.key /grant:r "arhat:R"icacls 옵션 의미:
/inheritance:r: 부모 디렉토리에서 상속된 권한(ACL)을 제거하고 명시적 권한만 남김/grant:r "사용자명:R": 지정한 사용자에게 읽기(R) 권한만 부여 (r플래그는 기존 권한 교체)
리눅스와의 비교: 리눅스에서는
chmod 600 ~/.ssh/id_rsa로 소유자 읽기/쓰기만 허용합니다. Windows의icacls가 그 역할을 담당합니다.
5.3 OCI Run Command 실행 (핵심 단계)
이제 OCI Console에서 Run Command를 사용해 서버 내부에 공개키를 등록합니다.
OCI Console 경로:
Compute → Instances → [해당 인스턴스 클릭] → Run Command → Create command실행할 스크립트 (전체 붙여넣기):
bash
#!/bin/bash
# SSH 디렉토리 생성 (없는 경우)
mkdir -p /home/ubuntu/.ssh
chmod 700 /home/ubuntu/.ssh
# 공개키 추가 (앞서 복사한 .pub 파일 내용 전체 입력)
echo 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCuAFNVTDOuUOJLt2i/JFhIE8RHWcKbJxYGAmPAxZE+CYtvGhv4QIQoWQfX8N34Yhey/yqaVO2hPE/pGnJz108Qj35RrqBtpDDDDDASK6LkvNiFrm/u7b1tNnva9onih' >> /home/ubuntu/.ssh/authorized_keys
# 권한 설정
chmod 600 /home/ubuntu/.ssh/authorized_keys
chown -R ubuntu:ubuntu /home/ubuntu/.ssh스크립트 각 줄의 의미:
| 명령어 | 의미 |
|---|---|
mkdir -p /home/ubuntu/.ssh | .ssh 디렉토리 생성 (-p: 이미 존재해도 오류 없음) |
chmod 700 /home/ubuntu/.ssh | .ssh 디렉토리: 소유자만 읽기/쓰기/실행 가능 (SSHd 보안 요구사항) |
echo '공개키' >> authorized_keys | 공개키를 authorized_keys 파일에 추가 (>>: 기존 내용 유지하며 추가) |
chmod 600 /home/ubuntu/.ssh/authorized_keys | authorized_keys: 소유자만 읽기/쓰기 가능 (SSHd 보안 요구사항) |
chown -R ubuntu:ubuntu /home/ubuntu/.ssh | .ssh 디렉토리와 모든 파일의 소유자를 ubuntu로 설정 |
중요:
chmod 700과chmod 600설정은 선택사항이 아닙니다. SSH 데몬(sshd)은.ssh디렉토리와authorized_keys의 권한이 지나치게 느슨하면 보안 위험으로 간주하고 해당 키를 무시합니다. 권한이 잘못되면 키를 등록해도 여전히Permission denied가 발생할 수 있습니다.
>>와>의 차이:>>연산자는 파일 끝에 내용을 추가합니다. 만약 기존에 다른 키가 등록되어 있다면>를 사용하면 덮어쓰게 됩니다. 여러 키를 등록하려면>>를 사용하세요.
5.4 Run Command 제출 및 결과 확인
- OCI Console에서 스크립트 입력 후
Run버튼 클릭 - 상태가
Succeeded로 변경될 때까지 대기 (보통 10~30초) - 출력 로그에서 오류 없이 완료되었는지 확인
5.5 접속 성공 확인
# 드디어 접속 성공!
ssh -i "ssh-key-2026-06-20.key" -p 888 [email protected]접속 성공 화면:
Welcome to Ubuntu 24.04 LTS (GNU/Linux 5.15.0-... aarch64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/pro
ubuntu@instance-200328-1021:~$ubuntu@instance-200328-1021:~$ 프롬프트가 보이면 성공입니다!
6. 심화: OCI 설계 이해
Console Connection의 진짜 역할 — 비상구
OCI Console Connection은 SSH 키 분실, OS 부팅 실패, 네트워크 설정 오류 등 일반 SSH 접속이 완전히 불가능한 상황을 위한 최후의 수단입니다.
| 상황 | Console Connection 필요 여부 |
|---|---|
| SSH 키 미등록 (이번 케이스) | Run Command로 해결 가능 (Console Connection 불필요) |
| SSH 데몬 다운 | Console Connection 필요 |
| 방화벽으로 모든 포트 차단 | Console Connection 필요 |
| OS 부팅 실패 | Console Connection 필요 |
/etc/ssh/sshd_config 오설정 | Console Connection 필요 |
이번 경우에는 SSH 데몬은 정상 동작 중이었고 Run Command를 통해 authorized_keys를 수정할 수 있었으므로, Console Connection 없이 해결이 가능했습니다.
Run Command 동작 원리
Run Command는 다음 경로로 명령어를 전달합니다:
OCI Console
↓ (HTTPS / OCI 내부 API)
Oracle Cloud Agent (인스턴스 내부에서 실행 중)
↓ (로컬 실행)
root 권한으로 스크립트 실행
↓
결과를 OCI Console로 반환이 경로는 SSH와 완전히 독립적입니다. SSH 포트가 막혀 있어도, SSH 키가 없어도, Oracle Cloud Agent가 실행 중이라면 Run Command를 사용할 수 있습니다.
주의: Run Command는 root 권한으로 실행됩니다. 따라서
/home/ubuntu/.ssh/authorized_keys를 수정한 후 반드시chown -R ubuntu:ubuntu /home/ubuntu/.ssh로 소유권을 ubuntu 사용자로 변경해야 합니다. root 소유의authorized_keys는 ubuntu 사용자 SSH 인증에서 무시될 수 있습니다.
OCI 메뉴 기능 vs 내부 수정 비교표
| 구분 | 방법 | 역할 |
|---|---|---|
| 웹 메뉴 | Console Connection 생성 | 서버 내부로 들어갈 수 있는 비상 통로 확보 |
| 웹 메뉴 | Run Command 실행 | SSH 없이 원격으로 내부 명령어 실행 |
| 내부 수정 | authorized_keys 파일 직접 수정 | 실제 사용할 새 공개키 등록 |
| 내부 수정 | /etc/ssh/sshd_config 수정 | SSH 서버 설정 변경 (포트, 인증 방식 등) |
핵심: OCI는 키를 바꾸는 GUI 메뉴 대신, 비상구(Run Command 또는 Console Connection)를 통해 들어가서 직접 바꾸게 하는 방식을 채택하고 있습니다. 이것이 OCI의 보안 철학입니다.
8. 핵심 교훈 및 체크리스트
OCI SSH 접속 불가 시 빠른 진단 체크리스트
[ ] 1. 포트 연결 테스트
Test-NetConnection 서버IP -Port 포트번호
→ TcpTestSucceeded: True이면 네트워크 정상, SSH 인증 문제
[ ] 2. SSH verbose 로그 확인
ssh -vvv -i key.pem user@IP
→ "type 51" (SSH_MSG_USERAUTH_FAILURE) 확인 시 키 미등록 문제
[ ] 3. 키 등록 여부 확인
→ 서버의 /home/ubuntu/.ssh/authorized_keys에 공개키가 있는가?
→ 없다면 Run Command로 등록
[ ] 4. 파일 권한 확인
→ .ssh 디렉토리: chmod 700
→ authorized_keys: chmod 600
→ 소유자: ubuntu:ubuntu
[ ] 5. Windows 로컬 키 파일 권한 확인
icacls key.pem → 소유자만 읽기 가능해야 함핵심 인사이트 5가지
① Permission denied (publickey) ≠ 키 포맷 문제
오류 메시지만 보고 키 포맷(PEM/OpenSSH)을 바꾸거나 새 키를 생성하는 것은 의미가 없습니다. 가장 먼저 확인해야 할 것은 “그 키의 공개키가 서버 authorized_keys에 등록되어 있는가”입니다.
② OCI Run Command는 강력한 비상 도구
SSH 없이도 인스턴스 내부에 명령어를 실행할 수 있는 Run Command는 SSH 잠금 상황의 최적 해결 수단입니다. Oracle Cloud Agent가 실행 중인 한 언제든 사용 가능합니다.
③ Cloud Shell ≠ 인스턴스
Cloud Shell은 OCI가 제공하는 별도의 가상 터미널 환경입니다. Cloud Shell에서의 파일 수정은 인스턴스에 아무런 영향을 주지 않습니다. 두 환경을 명확히 구분해야 합니다.
④ 포트 연결 테스트를 먼저
Permission denied와 Connection refused는 완전히 다른 레이어의 문제입니다. 오류 메시지 수정에 앞서 Test-NetConnection으로 TCP 레벨 연결부터 확인하면 불필요한 시도를 줄일 수 있습니다.
⑤ SSH 키는 PEM 형식으로 생성하는 것이 안전
OpenSSH 형식도 최신 환경에서는 완벽히 동작하지만, OCI, AWS 등 주요 클라우드 환경과의 범용 호환성을 위해 -m pem 옵션으로 PEM 형식으로 생성하는 것을 권장합니다.