SSH 키와 인증
130분 안팎
학습 목표
실습 VM에 공개키를 등록하고 키 권한·사용자·포트 오류를 로그와 연결합니다.
개념
연결 성공과 로그인 성공을 나눕니다
SSH로 서버에 들어가는 과정은 목적지 이름·경로·포트 확인 뒤에도 계속됩니다. 서버가 신뢰할 대상인지 확인하고 접속 사용자를 인증해야 원격 명령을 실행할 수 있습니다. 이번 목표는 공개키를 등록한 실습 계정으로 접속하고, 잘못된 사용자와 키의 실패를 TCP 실패와 구분하는 것입니다. Permission denied (publickey)를 보고 방화벽을 더 열면 이미 연결된 인증 문제는 해결되지 않습니다.
두 종류의 키를 구분합니다
호스트 키는 서버의 신원을 확인하는 데 쓰고 사용자 키는 접속자의 인증에 쓰입니다. 클라이언트 known_hosts에는 신뢰한 서버 호스트 정보가 남으며 서버 계정의 authorized_keys에는 허용할 사용자 공개키가 들어갑니다. 두 파일의 목적이 다르므로 authorized_keys를 수정해 호스트 키 경고를 해결하려 하지 않습니다. 서버마다 다른 계정에 공개키를 넣으면 접속 사용자를 잘못 선택했을 때도 인증은 실패합니다.
처음 접속할 때 보이는 지문을 VM 콘솔에서 읽은 해당 서버 호스트 공개키 지문과 대조합니다. 같은 알고리즘과 키를 비교하는지도 확인합니다. 단지 화면에 yes를 입력할 수 있다는 이유로 검증된 서버라고 기록하지 않습니다. ssh-keyscan은 네트워크에서 제시한 키를 수집할 수 있지만 그 수집 자체가 서버 신원을 증명하지는 않습니다. 별도 경로인 VM 콘솔에서 확인한 지문과 대조한 뒤 신뢰 정보를 보관합니다.
REMOTE HOST IDENTIFICATION HAS CHANGED는 저장한 신뢰 정보와 현재 제시된 호스트 키가 다르다는 경고입니다. 재설치나 주소 재사용도 후보지만 다른 서버나 중간자도 배제할 수 없습니다. 먼저 연결을 중단하고 구성도·VM 콘솔·변경 기록을 확인합니다. 원인이 확인된 해당 항목만 갱신합니다. known_hosts 전체를 삭제하거나 StrictHostKeyChecking=no를 상시 쓰는 방법은 다음 접속의 확인 근거까지 없앱니다.
개인키는 클라이언트에 남깁니다
실습용 키 파일은 기존 키와 다른 이름인 ~/.ssh/bootcamp_m05로 생성합니다. 생성 전에 그 파일이 없는지 확인해 이미 사용하는 키를 덮어쓰지 않습니다. ssh-keygen -t ed25519 -f 뒤에 이 경로를 지정하고 암호 문구는 대화형으로 입력합니다. 암호 문구를 명령 인자로 기록하거나 레슨 산출물에 넣지 않습니다. 자동 검사에 사용할 때에는 필요하면 로컬 ssh-agent에 키를 올리고 실습을 진행하며 개인키를 서버·저장소·보고서로 복사하지 않습니다.
.pub 파일만 bcops의 authorized_keys에 추가합니다. 기존 공개키가 있다면 보존합니다. VM 콘솔에서 bcops의 홈 경로와 소유권을 확인하고 .ssh 디렉터리는 0700, authorized_keys는 0600으로 관리합니다. 일반적으로 권한을 좁히는 권장값이며 인증 성공의 모든 조건을 대신하지 않습니다. 홈 상위 경로의 소유권·쓰기 권한과 sshd의 AuthorizedKeysFile·StrictModes 등 실제 설정도 서버 로그와 함께 봅니다.
클라이언트의 개인키 권한도 0600으로 좁힙니다. UNPROTECTED PRIVATE KEY FILE 경고가 보이면 클라이언트가 개인키 사용을 거부했는지 먼저 읽습니다. 서버의 authorized_keys만 바꾸면 이 단계의 오류가 남습니다. 파일을 찾지 못했다는 메시지는 키 경로·현재 홈을 확인할 단서입니다. 파일이 없는데 다른 에이전트 키로 우연히 성공하면 입력 조건이 달라지므로 시험에서는 지정한 IdentityFile과 IdentitiesOnly를 사용합니다.
사용자·포트·키를 명시합니다
ssh -p 22 -i ~/.ssh/bootcamp_m05 bcops@192.168.56.10처럼 세 항목을 적습니다. 접속 사용자를 생략하면 로컬 사용자 이름으로 시도할 수 있어 맥의 사용자와 VM 계정이 달라 문제가 생깁니다. -i는 키 파일 선택이고 -p는 서버 포트 선택입니다. 공개키를 bcops에 등록했는데 bcweb로 접속하면 동일한 인증 대상이 아닙니다. 서비스 계정 bcweb에 로그인 권한을 추가하는 대신 운영 실습 계정 bcops를 사용합니다.
BatchMode=yes는 대화형 비밀번호 입력을 기다리지 않는 검사에 유용합니다. 암호화된 개인키가 에이전트에 준비되지 않았으면 키 인증도 실패할 수 있으므로 사전 준비를 확인합니다. ConnectTimeout으로 연결 대기 범위를 제한하고 원격 명령 id -un의 결과로 실제 계정을 확인합니다. 접속 종료 코드 0만 저장하는 것보다 bcops 출력까지 비교하면 다른 사용자나 잘못된 원격 명령을 구분하기 쉽습니다.
로그는 실패한 단계와 연결합니다
-vv는 클라이언트가 어떤 키를 제시하고 어떤 인증 방법을 시도했는지 볼 단서입니다. 개인키 내용은 출력하지 않지만 사용자·주소·경로 등의 정보가 포함될 수 있어 보고서 범위를 검토합니다. Permission denied (publickey)는 공개키 인증이 성립하지 않았다는 결과이며 틀린 사용자·미등록 키·서버 정책·파일 접근 조건이 후보입니다. 키가 무조건 틀렸다고 단정하지 않고 Offering public key와 서버의 거부 이유를 함께 봅니다.
서버에서 배포판의 실제 SSH 유닛 이름을 확인하고 journalctl -u ssh 또는 -u sshd로 해당 시각을 조회합니다. 로그 보관 방식이 파일인 배포판은 관리자에게 허용된 인증 로그를 함께 확인합니다. Failed publickey의 사용자·출발지와 클라이언트 기록을 대조합니다. 빈 저널은 인증이 성공했다는 증거가 아닙니다. 잘못된 사용자와 잘못된 키를 한 번씩 시험하고 동일한 실패 결과 안에서도 입력 조건과 서버 근거가 어떻게 다른지 기록합니다.
Connection refused는 인증 전에 SSH 리스너와 거부 정책을 볼 단서이며 Connection timed out는 경로·필터·상대 응답을 조사할 단서입니다. 이 단계에서는 authorized_keys를 고치는 것보다 ss와 서버 상태 확인이 앞섭니다. 정상 키 인증 사례를 확보한 뒤 사용자만 바꾸거나 키만 바꿉니다. 학습용 wrong 키의 공개키는 등록하지 않습니다. 비밀번호 등 대체 인증으로 성공하면 실패 주입이 성립하지 않았으므로 원문을 보고 검사 조건을 정리합니다.
로그 분류와 실제 등록을 각각 확인합니다
로컬 과제는 오류 문자열을 다음 확인 행동으로 연결합니다. 호스트 지문 경고가 있으면 먼저 신원을 확인하고, 개인키 권한 경고는 클라이언트 파일을, publickey 실패는 사용자·키·서버 로그를 봅니다. 빈 문자열은 성공이라고 바꾸지 않고 KEEP_RAW_LOG로 남깁니다. 이 함수는 OpenSSH의 모든 버전별 문구를 해석하는 운영 파서가 아니라 지정된 실습 메시지에 대한 판단 연습입니다.
VM 완료 기록에는 공개키 지문, 등록 계정, 파일 소유권·모드, 성공한 id -un, 실패 두 건의 원문과 서버 로그 시각을 남깁니다. 개인키나 암호 문구는 제출하지 않습니다. 기존 관리 접속을 끄는 작업은 이번 범위가 아니며 키 등록 성공 전 비밀번호 정책을 급히 바꾸지 않습니다. 더 많은 접속 옵션은 서재로 보내고 지문·키 선택·배치 모드의 의미는 OpenSSH ssh 매뉴얼에서 확인합니다.
따라하기
판정에 사용할 작은 모델 실행
아래 코드는 제공된 고정 입력의 계산만 실행합니다. VM 관측 출력과 구분해 읽습니다.
checks = {'host_key': 'server identity', 'user_key': 'login identity'}
for kind, purpose in checks.items():
print(kind + ': ' + purpose)
실행 결과
host_key: server identity user_key: login identity
실습 전용 키 생성
첫 명령이 성공한 경우에만 다음 명령으로 진행합니다. 암호 문구는 대화형으로 입력하고 .pub만 콘솔을 통해 bcops에 등록합니다. 호스트 공개키 지문은 서버 콘솔에서 별도로 확인합니다.
test ! -e ~/.ssh/bootcamp_m05
ssh-keygen -t ed25519 -f ~/.ssh/bootcamp_m05
chmod 600 ~/.ssh/bootcamp_m05
ssh-keygen -lf ~/.ssh/bootcamp_m05.pubVM 콘솔에서 공개키 등록
공유 폴더로 전달한 공개키 bootcamp_m05.pub만 현재 콘솔 폴더에 둡니다. 개인키는 클라이언트에 남깁니다. 기존 authorized_keys를 보존하며 bcops 홈에 추가합니다. 서버 호스트 키 지문은 클라이언트의 첫 접속 표시와 같은 알고리즘으로 대조합니다.
id bcops
sudo -H -u bcops sh -c 'umask 077; mkdir -p "$HOME/.ssh"; printf "\n" >> "$HOME/.ssh/authorized_keys"; cat >> "$HOME/.ssh/authorized_keys"; chmod 700 "$HOME/.ssh"; chmod 600 "$HOME/.ssh/authorized_keys"' < bootcamp_m05.pub
sudo ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub등록과 실패 비교
정상 요청의 실제 계정을 확인하고 사용자만 바꾼 요청을 비교합니다. 서버의 SSH 유닛 로그를 같은 시각으로 조회합니다. 잘못된 키 비교에는 등록하지 않은 별도 키를 씁니다.
ssh -vv -o IdentitiesOnly=yes -i ~/.ssh/bootcamp_m05 -p 22 bcops@192.168.56.10 'id -un'
ssh -o BatchMode=yes -o IdentitiesOnly=yes -i ~/.ssh/bootcamp_m05 -p 22 bcweb@192.168.56.10 'id -un'경계 사례까지 로컬 검사
호스트 지문·개인키 모드·사용자 인증·연결 실패를 각각 다음 확인으로 연결합니다.
bash check.sh확인 문제
실습
task.py의 next_check를 완성합니다. 지정된 SSH 오류별 다음 확인을 반환하고 빈 로그는 원문 보존으로 처리합니다. 로컬 자동 검사는 고정 입력의 논리만 확인합니다. VM에서의 실제 실행과 기록은 따라하기 및 external 미션으로 확인합니다.
실행 명령
bash check.sh
기대 결과
unittest의 모든 사례 OK, 종료 코드 0
모범 답안
모범 답안 내려받기더 읽기
면접 질문
- SSH 접속이 실패할 때의 확인 순서를 설명합니다.