진행 중인 PoC에서 SSH 접속 방식을 테스트해야 했다. 그런데 공식 ubuntu Docker 이미지에는 SSH 서버(openssh-server)가 들어 있지 않다. 컨테이너는 bash 하나만 띄운 채로 시작하니 22번 포트에서 기다리는 프로세스가 없다.
이 글에서는 컨테이너에 SSH 서버를 직접 깔고 로컬에서 ssh로 들어가기까지를 정리한다.
테스트용으로 보안은 일부러 낮췄다
먼저 범위를 분명히 해 둔다. 여기서는 root 계정에 비밀번호를 걸고 그 비밀번호로 접속한다. 접속 방식이 되는지만 확인하려는 테스트라서 그렇다. 실제로 쓸 환경이라면 별도 계정을 만들고 공개키 인증을 쓰는 게 맞다.
접속 주소도 컨테이너 IP가 아니라 localhost다. 컨테이너 IP로는 SSH 접속이 되지 않는다. 왜 안 되는지는 「Mac에서 컨테이너 IP로 접속이 안 되는 이유」에서 따로 다뤘다.
링크: https://jaylab.blog/docker-container-network-arch/
컨테이너를 띄울 때 22번 포트를 미리 연다
Ubuntu 컨테이너를 실행하면서 바로 bash로 들어간다.
docker run -it --name {컨테이너 이름} -p 2222:22 ubuntu:latest bash
-p 2222:22: 로컬 포트 2222를 컨테이너의 22번(SSH) 포트로 포트포워딩
포트 매핑은 컨테이너를 만들 때만 정할 수 있다. 나중에 SSH를 쓸 생각이라면 이 단계에서 열어 둬야 한다.
컨테이너 안에서 sshd를 깔고 root 로그인을 연다
컨테이너 안에서 SSH 서버를 설치한다.
apt update
apt install -y openssh-server
설치만 해서는 비밀번호로 root에 들어갈 수 없다. sshd_config의 기본값인 PermitRootLogin prohibit-password가 root 로그인 자체는 허용하되 비밀번호 방식은 막아 두기 때문이다. 이 줄을 yes로 바꾸고 root 비밀번호를 정한 뒤 SSH 서버를 띄운다.
echo "root:DockerPass123" | chpasswd # root 비밀번호 설정
# SSH 설정파일에서 root 비밀번호 로그인 금지 → 허용으로 바꾸는 설정
sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config
service ssh start # SSH 서버 구동
로컬에서 2222번으로 붙는다
컨테이너 쉘은 그대로 두고 새 터미널을 열어 로컬에서 접속한다.
ssh root@localhost -p 2222
비밀번호는 앞에서 정한 DockerPass123이다. 로컬 2222번으로 들어온 연결이 컨테이너 22번으로 넘어가고, 거기서 기다리던 sshd가 받는다.
매번 sshd를 켜기 싫으면 Dockerfile로 굳힌다
위 방식대로면 컨테이너를 다시 띄울 때마다 service ssh start를 또 쳐야 한다. 컨테이너가 뜰 때마다 sshd가 돌게 하려면 Dockerfile에 CMD ["/usr/sbin/sshd", "-D"]를 적는다. -D 옵션을 주면 sshd가 데몬으로 떨어져 나가지 않고 포그라운드에 남아 컨테이너의 메인 프로세스 역할을 한다.
# Dockerfile 예시
FROM ubuntu:latest
RUN mkdir /run/sshd
RUN apt update && apt install -y openssh-server
RUN echo "root:DockerPass123" | chpasswd
RUN sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config
CMD ["/usr/sbin/sshd", "-D"]
공식 Ubuntu 이미지 대신 SSH가 이미 들어 있는 이미지를 쓰는 방법도 있다.
정리
컨테이너는 서버가 아니라 프로세스 하나라서, SSH가 필요하면 sshd를 직접 깔고 띄워야 한다. 포트는 컨테이너를 만들 때 열고, root 비밀번호 로그인은 테스트에서만 쓴다.
참고자료
docker container run: Publish or expose port (-p) —
-p 호스트포트:컨테이너포트포트 게시 옵션sshd_config(5) —
PermitRootLogin의prohibit-password,yes값 설명sshd(8) —
-D옵션(데몬으로 분리하지 않음)