프로젝트를 진행하며 발견된 도커의 보안 취약점 정리

userland-proxy

Docker에서 컨테이너 포트를 호스트 포트와 연결(-p) 할 때 사용되는 기능 중 하나
이름 그대로 “사용자 영역(userland)”에서 동작하는 프록시(proxy)
즉, 컨테이너의 포트를 호스트가 접근할 수 있도록 Docker 데몬이 사용자 공간에서 TCP 프록시를 띄움으로써 포워딩을 처리

  1. userland-proxy가 활성화된 경우
  • Docker 데몬이 사용자 공간 프로세스로 TCP 프록시를 띄움
  • 호스트 → 프록시 → 컨테이너 포트 순서로 패킷 전달
  • 장점: 운영체제와 상관없이 동일하게 동작
  • 단점: 약간의 오버헤드 발생
  1. userland-proxy 비활성화 (false)
  • iptables를 이용한 커널 레벨 NAT 포워딩으로 처리
  • 성능이 더 좋음
  • 하지만 컨테이너 내부에서 호스트 IP:포트로 접근하는 경우 일부 상황에서 통신이 실패할 수 있음 (특히 사용자 정의 브리지 네트워크)

 

userland-proxy 적용전 테스트

응답서버

docker run -d --name test-nginx -p 8080:80 nginx

ps -ef| grep proxy
root       24598   23864  0 10:50 pts/2    00:00:00 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 8080 -container-ip 172.17.0.2 -container-port 80 -use-listen-fd
root       24606   23864  0 10:50 pts/2    00:00:00 /usr/bin/docker-proxy -proto tcp -host-ip :: -host-port 8080 -container-ip 172.17.0.2 -container-port 80 -use-listen-fd
k          24651   22449  0 10:50 pts/3    00:00:00 grep --color=auto proxy

 

요청서버

docker network create curl-net
docker run --rm --name test-curl --network curl-net curlimages/curl curl http://<wsl IP>:8080
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   615  100   615    0     0  77720      0 --:--:-- --:--:-- --:--:-- 87857
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...
<p><em>Thank you for using nginx.</em></p>
</body>
</html>

 


 

userland-proxy 설정

/etc/docker/daemon.json 수정 후 데몬 리로드 및 도커 재기동

{
  "userland-proxy": false
}

 

 

proxy 확인

docker stop test-nginx ; docker rm test-nginx
docker run -d --name test-nginx -p 8080:80 nginx
ps -ef |grep proxy
k          25280   22449  0 10:55 pts/3    00:00:00 grep --color=auto proxy
k:~$

 

통신 테스트

docker run --rm --name test-curl curlimages/curl curl http://<wsl IP>:8080
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   615  100   615    0     0   443k      0 --:--:-- --:--:-- --:--:--  600k
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...
<p><em>Thank you for using nginx.</em></p>
</body>
</html>

 


 

주의 사항!

만약 두 컨테이너의 네트워크가 다르다면 host를 통한 통신이 불가능해진다.

 

사용자 정의 네트워크를 사용한 nignx

docker network create test-nginx
docker stop test-nginx ; docker rm test-nginx
docker run -d --name test-nginx --network nginx-net -p 8080:80 nginx

 

네트워크를 지정하지 않은 상태로 통신 테스트

docker run --rm --name test-curl curlimages/curl curl http://<wsl IP>:8080
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:--  0:02:09 --:--:--     0
curl: (28) Failed to connect to 172.27.25.244 port 8080 after 129405 ms: Could not connect to server

 

네트워크를 지정한 통신테스트

docker run --rm --name test-curl --network nginx-net curlimages/curl curl http://<wsl IP>:8080
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   615  100   615    0     0   317k      0 --:--:-- --:--:-- --:--:--  600k
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...
<p><em>Thank you for using nginx.</em></p>
</body>
</html>

 

문제 발생 이유

  1. 컨테이너에서 호스트IP:8080으로 접근 시, NAT 루프백 경로 필요
  2. 사용자 정의 브리지는 Docker가 NAT 루프백 규칙을 자동으로 생성하지 않음
  3. 결과: 컨테이너 → 호스트 → 컨테이너 경로가 막혀서 접속 실패

이전 프로젝트에서는 WEB과 WAS가 분리된 서버에서 별도의 도커 네트워크를 구성하여 운영되었다.
하지만 이번 프로젝트에서는 WEB과 WAS가 동일 서버에 배치되면서, 기존 설정대로 호스트 IP를 사용하고 보안조치로 userland-proxy를 false로 설정하면 컨테이너 간 통신이 불가능한 문제가 발생했다.
따라서 이를 해결하기 위해서는 WEB과 WAS 컨테이너를 하나의 네트워크 안에 배치해야 한다.

+ Recent posts