다음과 같은 설정이 있습니다.
- 도커 서비스를 실행하는 CentOS 호스트
- 사용자 정의 도커 브리지 네트워크
- 해당 사용자 정의 브리지 네트워크에 연결된 2 개의 Docker 컨테이너
- OpenVPN 설치 (현재 호스트에서 실행 중입니다. 도커 컨테이너에서도 실행할 수 있음)
- OpenVPN에 연결된 일부 클라이언트
도커 브리지 네트워크의 도커 컨테이너가 tun0 네트워크의 openvpn 클라이언트와 통신하도록하려면 어떻게해야합니까?
docker1 (10.10.0.3)과 VPN (172.19.0.x 범위)에 연결된 클라이언트간에 투명한 방식으로 TCP 기반 통신을하고 싶습니다.
docker (networking / iptables / …) 측과 호스트 (iptables)에서 무엇을 설정해야합니까?
답변
문맥
Kyle Manna ( https://github.com/kylemanna/docker-openvpn ) 의 매우 우수한 Docker 컨테이너를 사용하고 있습니다. 소위 “파라노이드”문서를 사용하여 OpenVPN 서버를 설정하고 있지만,보기에는 이것이 편집증 방식이 아니라 표준 방식이어야합니다.
구성
선택한 Docker 컨테이너와 VPN 클라이언트간에 양방향 연결을 허용하려면 VPN 클라이언트가 액세스 할 수있는 컨테이너를 연결할 Docker 네트워크를 만들어야합니다. VPN 서버는 이러한 컨테이너 중 하나가 될 것입니다.
VPN 서버가 가져야 client-to-client
, topology subnet
, dev tun0
(또는 다른 툰 장치) 및 push "route <docker net IP> <docker net mask>"
구성한다.
VPN 서버의 호스트는 한 서브넷에서 다른 서브넷으로 IP 패킷을 전달할 수 있도록 구성해야합니다. 이것은 sysctl ip_forward를 1로 설정 함 (Docker를 설치 한 경우에 해당), tun 장치의 패킷이 iptables FORWARD 체인을 통과하고 적절한 라우팅을 설정하도록합니다. 다음 명령으로 요약 할 수 있습니다.
$ sudo sysctl -w net.ipv4.ip_forward=1
$ sudo iptables -A FORWARD -i tun+ -j ACCEPT
$ sudo ip route add 192.168.255.0/24 via <IP address of OpenVPN server container>
어쨌든, 서버 설정에 사용한 옵션은 다음과 같습니다.
$ docker run --rm --net=none -it -v $PWD/files/openvpn:/etc/openvpn kylemanna/openvpn:2.4 ovpn_genconfig -u udp://<FQDN> -N -d -c -p "route <docker net IP> <docker net range>" -e "topology subnet"
다음과 비슷한 서버 구성 파일이 생성됩니다.
server 192.168.255.0 255.255.255.0
verb 3
key /etc/openvpn/pki/private/vpn.example.com.key
ca /etc/openvpn/pki/ca.crt
cert /etc/openvpn/pki/issued/vpn.example.com.crt
dh /etc/openvpn/pki/dh.pem
tls-auth /etc/openvpn/pki/ta.key
key-direction 0
keepalive 10 60
persist-key
persist-tun
proto udp
# Rely on Docker to do port mapping, internally always 1194
port 1194
dev tun0
status /tmp/openvpn-status.log
user nobody
group nogroup
client-to-client
### Push Configurations Below
push "dhcp-option DNS 8.8.8.8"
push "route 172.20.20.0 255.255.255.0"
### Extra Configurations Below
topology subnet
구체적인 예
이제 구체적인 예를 들어 보겠습니다. 이 예에서는 호스트 vpn.example.com의 Docker 내에서 위에서 언급 한 OpenVPN 서버를 실행합니다. 이 컨테이너는 Docker 네트워크 docker-net-vpn에 연결되어 있습니다. 다음은 명령입니다 (이 예제에서는 서버에서 직접 서버 구성을 생성하고 CA 생성을 건너 뜁니다. 대신 위에서 언급 한 프로젝트의 편집증 설명서를 따르십시오).
$ docker network create --attachable=true --driver=bridge --subnet=172.20.20.0/24 --gateway=172.20.20.1 docker-net-vpn
$ docker run --rm --net=none -it -v $PWD/files/openvpn:/etc/openvpn kylemanna/openvpn:2.4 ovpn_genconfig -u udp://vpn.example.com -N -d -c -p "route 172.20.20.0 255.255.255.0" -e "topology subnet"
$ docker run --detach --name openvpn -v $PWD/files/openvpn:/etc/openvpn --net=docker-net-vpn --ip=172.20.20.2 -p 1194:1194/udp --cap-add=NET_ADMIN kylemanna/openvpn:2.4
$ sudo sysctl -w net.ipv4.ip_forward=1
$ sudo iptables -A FORWARD -i tun+ -j ACCEPT
$ sudo ip route add 192.168.255.0/24 via 172.20.20.2
첫 번째 명령은 새로운 서브넷을 정의하는 새로운 전용 Docker 네트워크를 만듭니다. OpenVPN 서버를이 네트워크에 연결합니다.
두 번째는 첫 번째 명령에 정의 된 것과 동일한 서브넷을 사용하여 OpenVPN 구성을 만듭니다.
세 번째는 OpenVPN 서버를 만듭니다. 새로 작성된 Docker 네트워크에 연결되며 수정 IP를 사용합니다.
네 번째 및 다섯 번째 명령은 IP 전달을 구성합니다.
마지막 명령은 OpenVPN 컨테이너 고정 IP를 통해 VPN 클라이언트 구성을 향한 새로운 경로를 추가합니다.
노트
나는 그것을 시도하지 않았지만 iptables에 대한 FORWARD 규칙을 제한 할 수 있어야합니다. Docker 네트워크 생성으로 새로운 브리지 장치가 생성되었습니다. 이 브릿지의 이름 br-<ID>
은 Docker 네트워크 ID의 첫 12자인 ID로 지정됩니다. 이 ID는로 얻을 수 있습니다 docker network inspect -f '{{.Id}}' docker-net-vpn | cut -b-12
. 따라서 다음 명령은 더 제한적일 수 있으므로 (보안 수준이 높음) 여전히 트래픽을 라우팅 할 수 있어야합니다.
$ NET_VPN_BRIDGE="br-$(docker network inspect -f '{{.Id}}' docker-net-vpn | cut -b-12)"
$ sudo iptables -A FORWARD -i tun+ -o ${NET_VPN_BRIDGE} -j ACCEPT