Implementation of Docker VPN

Network integration based on OpenVPN

도커 네트워크 개요 및 제약사항

  • 도커 네트워크는 도커들 간의 사설 네트워크가 구축되고, 호스트 머신과 bridge 인터페이스를 통해서 통신

    • Mac OS의 도커는 가상 머신(virtual machine) 에서 구동되는 것이기 때문에, bridge 가 없음.
    • 따라서, Mac OS 에서는 호스트 머신과 도커 컨테이너들이 직접적으로 통신할 수 없음.
  • Mac OS 에서 호스트 머신이 컨테이너에 접근하기 위해서, -p 옵션을 통해 포트 바인딩이 필요함.

    • 많은 포트가 바인딩되는 경우 이에 대한 관리가 어려움

VPN을 이용한 호스트 머신과 도커 네트워크 터널링

  • 호스트 머신을 도커 네트워크에 virtual private network(VPN)으로 연결하여 라우팅 수행
    • VPN 의 개념은 네트워크 섹션을 참고
    • VPN 터널링을 통해서 Creating a docker network 에서 생성된 주소는 해당 VPN 으로 라우팅되도록 설정
  • VPN 터널링 및 라우팅 설정이 된 이후에는 도커 컨테이너에 접속할 때 별도 포트바인딩이 필요없음.

VPN 터널링 및 라우팅 설정 절차

  • 본 섹션에서는 Open VPN 을 통해서 설정하는 방법에 대해서 설명

Open VPN 설정

Open VPN 사전 설정

  • 사전 설정 단계에서는 컨테이너가 구동되기 전에 필요한 설정 작업을 미리 수행
    • Open VPN 으로 발급된 인증서에 기술할 도메인 이름 등을 설정

도커 볼륨 생성

  • 도커 볼륨 크게 두가지 방법을 사용할 수 있음.
    • docker volume 으로 생성하는 실제 도커의 볼륨
    • 호스트 경로 를 도커 볼륨으로 사용
## 도커 볼륨 사용시
export OVPN_DATA=ovpn-data
docker volume create --name $OVPN_DATA

## 호스트 경로 사용시
export OVPN_DATA=$(pwd)/openvpn # 호스트 머신에서 설정파일을 저장하고자 하는 경로

PKI 구조 초기화

  • PKI 구조는 인증서를 발급/검증하기 위한 구조로 Open VPN 에서 인증서 발급 구조로 사용
    • 상세 설명은 네트워크 섹션 참고
  • PKI 구조를 만들기 위해서 아래와 같은 절차를 거침.
    1. PKI 구조를 위한 설정 파일 생성
    2. PKI 구조 생성
  • 아래의 명령어를 수행하기 전에 도커 볼륨 생성은 이미 완료되어야 함.
docker run -v $OVPN_DATA:/etc/openvpn --rm kylemanna/openvpn:2.4 ovpn_genconfig -u udp://localhost
docker run -v $OVPN_DATA:/etc/openvpn --rm -it kylemanna/openvpn:2.4 ovpn_initpki

Open VPN 컨테이너 설정

  • 아래와 같이 도커 컴포즈 설정 파일을 작성
    • Creating a docker network에서 생성된 네트워크를 사용
      • 해당 네트워크를 사용해야지 개발용 도커와 연계할 수 있음.
    • 호스트 경로가 아닌 도커 볼륨을 사용하는 경우에는 코멘트 삭제
version: "3.9"

networks:
  default:
    external:
      name: devnet

services:
  vpn.docker:
    restart: always
    container_name: vpn.docker
    image: kylemanna/openvpn:2.4
    ports:
       - 1194:1194/udp
    volumes:
      - $OVPN_DATA:/etc/openvpn
    cap_add:
      - NET_ADMIN

# volumes:
#   ovpn-data:
#     external: true

Open VPN 컨테이너 실행

docker-compose -p infra up -d

OVPN 인증서 설정

OVPN 인증서 발급

  • VPN에 접속할 때, 사용할 인증서 발급
  • 인증서 발급이 완료되고 나면 $NAME.ovpn 파일이 생성됨.
export NAME=hackartist
docker run -v $OVPN_DATA:/etc/openvpn --rm -it kylemanna/openvpn easyrsa build-client-full $NAME nopass
docker run -v $OVPN_DATA:/etc/openvpn --rm kylemanna/openvpn ovpn_getclient $NAME > $NAME.ovpn

인증서 수정

  • 생성된 인증서를 텍스트 에디터로 열기
    • 아래와 같은 형태의 인증서가 나온것을 확인할 수 있음.
client
nobind
dev tun
remote-cert-tls server

remote localhost 1194 udp

<key>
-----BEGIN PRIVATE KEY-----
... 생략 ...
-----END PRIVATE KEY-----
</key>
<cert>
-----BEGIN CERTIFICATE-----
... 생략 ...
-----END CERTIFICATE-----
</cert>
<ca>
-----BEGIN CERTIFICATE-----
... 생략 ...
-----END CERTIFICATE-----
</ca>
key-direction 1
<tls-auth>
#
# 2048 bit OpenVPN static key
#
-----BEGIN OpenVPN Static key V1-----
... 생략 ...
-----END OpenVPN Static key V1-----
</tls-auth>

redirect-gateway def1

Open VPN 연결

  • Mac OS 에서는 tunnel blick 을 사용
    • 설치를 위해서는 아래의 스크립트 실행
brew cask install tunnelblick

라우팅 정보 확인

  • netstat 을 이용하여 라우팅 정보 확인
    • tun 인터페이스와 일부 라우터가 추가된 것을 확인
netstat -nr
Destination Gateway Genmask Flags MSS Window irtt Iface
128.0.0.0 192.168.255.5 128.0.0.0 UG 0 0 0 tun0
192.168.255.1 192.168.255.5 255.255.255.255 UGH 0 0 0 tun0
192.168.255.5 0.0.0.0 255.255.255.255 UH 0 0 0 tun0

라우팅 정보 수정

  • Creating a docker network에서 192.168.100.0/24 로 네트워크를 생성하였고, 해당 트래픽을 tun0 인터페이스로 라우팅을 수행
    • 라우팅 테이블을 수정하는 작업인데, 간단하게는 route 명령어를 통해서 수행할 수 있음.
    • 본 섹션에서는 ovpn 파일을 수정하는 방법에 대해서 설명
client
nobind
dev tun
remote-cert-tls server

remote localhost 1194 udp

<key>
-----BEGIN PRIVATE KEY-----
... 생략 ...
-----END PRIVATE KEY-----
</key>
<cert>
-----BEGIN CERTIFICATE-----
... 생략 ...
-----END CERTIFICATE-----
</cert>
<ca>
-----BEGIN CERTIFICATE-----
... 생략 ...
-----END CERTIFICATE-----
</ca>
key-direction 1
<tls-auth>
#
# 2048 bit OpenVPN static key
#
-----BEGIN OpenVPN Static key V1-----
... 생략 ...
-----END OpenVPN Static key V1-----
</tls-auth>

route 192.168.100.0 255.255.255.0
  • 라우팅 테이블 확인

    • 해당 대역에 대한 라우팅 정보가 추가된 것을 확인
    Destination Gateway Genmask Flags MSS Window irtt Iface
    192.168.100.0 192.168.255.5 255.255.255.0 UG 0 0 0 tun0
    192.168.255.1 192.168.255.5 255.255.255.255 UGH 0 0 0 tun0
    192.168.255.5 0.0.0.0 255.255.255.255 UH 0 0 0 tun0