드림핵 워게임 풀 때마다 바보같지만 이러한 과정을 반복하고 있었다.
매번 파일을 호스트↔게스트로 왔다갔다 옮기는 게 너무 번거로웠다. 하지만 VSCode에 Remote-SSH라는 기능을 쓰면 한방에 해결된다길래 시도해봤는데 생각보다 오래걸렸지만 성공했다!
여담으로 SSH는 정보기 공부할 때 많이 나오는 개념중에 하나였지만 실제로 사용해본적은 없었기 때문에 막연한 기능이라고 생각하고 넘어갔었다.(부끄러운일이다..)
HostName, User, IdentityFile 정도만 적으면 바로 연결될 줄 알았다.드림핵에서 알려준 포트 포워딩 방식:
이름: SSH
프로토콜: TCP
호스트 포트: 22
게스트 포트: 22
근데 여기 게스트 IP 입력하는 칸이 없다. VirtualBox NAT 엔진이 알아서 게스트를 찾아서 연결해주는 구조라서 그렇다.
하지만 VMware는 달랐다. 포트 포워딩 규칙에 게스트(가상머신) IP를 직접 입력해야만 규칙이 성립하는 것이었다. 이 차이를 모르고 드림핵 가이드 그대로 따라가려다가 한참 헤맸었다..

VM 설정 창(Network Adapter → Advanced)에는 NAT Settings 관련 버튼 자체가 없었다. 알고 보니 Virtual Machine Settings 창이 아니라 Edit → Virtual Network Editor로 들어가야 하는 메뉴였다.

Virtual Network Editor → VMnet8(NAT) → NAT Settings → Port Forwarding까지는 들어갔는데 이번엔 Add... 버튼이 아예 비활성화돼있었다.
원인은 관리자 권한이었다. VMware를 일반 권한으로 켜면 네트워크 설정 파일에 쓰기 권한이 없어서 편집 자체가 막히기 때문에, 우클릭 → "관리자 권한으로 실행"으로 다시 켜니까 바로 해결되었다.
Add로 규칙(Host Port 22 → 칼리 IP:22) 넣고 OK 눌렀는데, 창 다시 열어보니까 테이블이 텅 비어있다. 이것도 결국 관리자 권한 문제였다. — 입력은 되는 것처럼 보이는데 실제 저장은 조용히 실패하고 있었던 것! 관리자 권한으로 재실행하고 다시 넣으니까 이번엔 사라지지 않았다.
포트 포워딩 규칙에 넣은 게스트 IP가 칼리가 DHCP로 받은 값이었다. ip a 를 입력해보니 dynamic, valid_lft 1477sec처럼 임대 시간이 붙어있는 임시 주소였다. — 재부팅하면 바뀔 수 있는 상태였던 것
포트 포워딩 규칙은 특정 IP 하나를 딱 박아두는 방식이라 칼리 IP가 바뀌면 그 규칙 자체가 의미 없어진다.
키를 등록하려고 이 명령어 쳤는데 (Windows PowerShell)
type $env:USERPROFILE\.ssh\id_ed25519.pub | ssh ojun@127.0.0.1 -p 22 "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"
"내 윈도우 공개키를 칼리로 전송해서 거기 authorized_keys 파일 끝에 추가해라" 라는 명령어이다.
ssh: connect to host 127.0.0.1 port 22: Connection refused
Connection refused는 타임아웃이랑 다르게 요청은 도착했는데 응답하는 게 없다는 뜻이라서 포트 포워딩 규칙이 진짜 적용됐는지부터 다시 확인해야 했다. 확인해보니 역시나 4번이랑 똑같은 이유로 규칙이 저장 안 된 상태였다.
정리하면 결국 원인은 두 가지로 좁혀짐.
추가로 칼리 IP가 DHCP라 유동적이라는 것까지 겹쳐서 포트 포워딩 규칙을 잘 넣어도 재부팅하면 다시 깨질 수 있는 상태였다.
최신 칼리는 /etc/network/interfaces 방식이 아니라 NetworkManager로 관리된다. nmcli로 고정함(클로드의 힘을 빌렸다^^)
nmcli connection show
# → "Wired connection 1" 확인
sudo nmcli connection modify "Wired connection 1" ipv4.addresses 192.168.xxx.xxx/24
sudo nmcli connection modify "Wired connection 1" ipv4.gateway 192.168.xxx.x
sudo nmcli connection modify "Wired connection 1" ipv4.dns "8.8.8.8 1.1.1.1"
sudo nmcli connection modify "Wired connection 1" ipv4.method manual
sudo systemctl restart NetworkManager
ip a로 다시 확인했을 때 dynamic 표시가 사라지고 valid_lft forever로 바뀐 것을 보고 고정되었음을 알 수 있었다.
Host Port: 22
Type: TCP
Virtual Machine IP Address: 192.168.xxx.xxx
Virtual Machine Port: 22
Description: SSH to Kali
이번엔 창을 닫았다 열어도 규칙이 사라지지 않는것을 확인
sudo systemctl enable --now ssh
sudo systemctl status ssh
active (running), Server listening on 0.0.0.0 port 22 로그 확인!
ssh-keygen -t ed25519
type $env:USERPROFILE\.ssh\id_ed25519.pub | ssh ojun@127.0.0.1 -p 22 "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"
Host linuxvm
HostName 127.0.0.1
Port 22
User ojun
IdentityFile ~/.ssh/id_ed25519

Remote - SSH 확장 설치 → Ctrl+Shift+P → Remote-SSH: Connect to Host → linuxvm 선택 → 왼쪽 아래에 SSH: linuxvm 뜨면 성공
VSCode 터미널에 칼리 프롬프트(ojun@kali:~$)가 떠서 신기했다. ~/Dreamhack 폴더를 Open Folder로 열어서 파일을 직접 편집하고 저장해봤는데 저장한 내용이 칼리 파일시스템에 그대로 반영되는 것까지 확인함. 이제 다운로드 → 복붙 → 편집 → 재복붙으로 이어지던 과정이 칼리 안에서 한 번에 끝나게 된 것이다.
SSH가 0.0.0.0(모든 인터페이스)에서 리스닝 중인 게 좀 걸려서 클로드에게 물어보니, 결론적으로는 VMware NAT(vmnet8) 네트워크가 호스트 밖에서는 아예 접근 불가능한 사설 네트워크라 실질적 위험은 없지만 그래도 방어적으로 비밀번호 인증은 꺼두라고 하였다.
# /etc/ssh/sshd_config
PasswordAuthentication no
sudo systemctl restart ssh
이러면 SSH 키 없이는 접속 자체가 불가능해져서 무차별 대입 공격 걱정을 덜 수 있다.
VirtualBox 기준 가이드를 VMware에 그대로 적용하려다 많이 고생했다. 두 가상화 프로그램의 NAT 구현 방식 차이(게스트 IP 자동 추론 여부)를 미리 알았으면 훨씬 빨리 끝났을 것이다. 또한 GUI 설정 창이 에러 없이 조용히 실패하는 경우(관리자 권한 문제)는 디버깅이 까다롭다는 것을 느꼈다. — 다음부턴 이런 종류의 문제를 만나면 권한 문제부터 먼저 의심해봐야겠다.
보안공부를 하는 입장에서 이제야 SSH를 직접 사용해보는 것이 부끄러운 일이지만 그래도 이번일을 통해서 SSH가 어떻게 동작하고 어떤 설정을 해야하는지 조금은 와닿는 계기가 되었다.