Jim*_*mbo 5 dns openvpn docker docker-swarm traefik
目标:在 docker swarm 上部署一组服务,其中一个服务仅在我连接到 OpenVPN 服务器时才可用,该服务器也已在 docker swarm 上启动。
当我连接到 VPN 时,如何一步一步地只连接到 whoami 示例容器,在浏览器中有一个域?
总体思路是,例如,kibana 和 elasticsearch 在内部运行,只能在 VPN(而不是公司网络)上访问,而其他服务正常公开运行。这些都将位于不同的节点上,因此我使用的是覆盖网络。
我确实在 docker swarm 和whoami容器上运行了 OpenVPN ,我可以连接到 VPN,但是看起来 IP 没有变化,我不知道如何制作它以便 whoami 容器只是在 VPN 上可用,特别是考虑到我使用的是多主机的覆盖网络。我也在使用traefik,这是一个反向代理,它为我提供了一个用于通配符域的几乎自动的 letencrypt 设置(通过 DNS 挑战)。有了这个,我可以得到:
但我也想连接到vpn.mydomain.com(我现在可以这样做),然后能够访问:
......我不能。然而。我已经将我的traefik 配置发布在不同的地方,以防你想看一看,因为如果我把它发布在这里,这个线程会变得太大。
让我们从我现在所处的位置开始。
首先,关于 OpenVPN 和 docker swarm 的有趣之处在于 OpenVPN 需要在特权模式下运行,因为它必须更改网络接口等,而swarm 还没有 CAP_ADD功能。因此,我们的想法是通过一种“代理容器”启动容器,该容器将手动运行容器,并为您添加这些权限。这是目前的一种解决方法,但这意味着您可以使用 swarm 部署服务。
这是我用于 OpenVPN 的 docker-compose:
vpn-udp:
image: ixdotai/swarm-launcher:latest
hostname: mainnode
environment:
LAUNCH_IMAGE: ixdotai/openvpn:latest
LAUNCH_PULL: 'true'
LAUNCH_EXT_NETWORKS: 'app-net'
LAUNCH_PROJECT_NAME: 'vpn'
LAUNCH_SERVICE_NAME: 'vpn-udp'
LAUNCH_CAP_ADD: 'NET_ADMIN'
LAUNCH_PRIVILEGED: 'true'
LAUNCH_ENVIRONMENTS: 'OVPN_NATDEVICE=eth1'
LAUNCH_VOLUMES: '/etc/openvpn:/etc/openvpn:rw'
volumes:
- '/var/run/docker.sock:/var/run/docker.sock:rw'
networks:
- my-net
deploy:
placement:
constraints:
- node.hostname==mainnode
Run Code Online (Sandbox Code Playgroud)
我可以使用以下方法部署上述内容:docker stack deploy --with-registry-auth --compose-file docker/docker-compose.prod.yml my-app-name这就是我用于其余部分的内容。重要的是,我不能只部署它,因为它尚未加载。OpenVPN 配置需要存在于/etc/openvpn节点上,然后安装在容器中,我在配置期间执行此操作:
// Note that you have to create the overlay network with --attachable for standalone containers
docker network create -d overlay app-net --attachable
// Create the config
docker run -v /etc/openvpn:/etc/openvpn --log-driver=none --rm ixdotai/openvpn ovpn_genconfig -u udp://vpn.mydomain.com:1194 -b
// Generate all the vpn files, setup etc
docker run -v /etc/openvpn:/etc/openvpn --log-driver=none --rm ixdotai/openvpn bash -c 'yes yes | EASYRSA_REQ_CN=vpn.mydomain.com ovpn_initpki nopass'
// Setup a client config and grab the .ovpn file used for connecting
docker run -v /etc/openvpn:/etc/openvpn --log-driver=none --rm ixdotai/openvpn easyrsa build-client-full client nopass
docker run -v /etc/openvpn:/etc/openvpn --log-driver=none --rm ixdotai/openvpn ovpn_getclient client > client.ovpn
Run Code Online (Sandbox Code Playgroud)
所以现在,我有一个可连接的覆盖网络,当我部署它时,OpenVPN 在第一个节点上启动并运行。我可以获取一份副本client.ovpn并连接到 VPN。即使我检查了“通过 VPN 发送所有流量”,看起来 IP 没有被更改,而且我仍然无法在其后面隐藏一个容器。
这个简单的容器可以在 docker-compose 中使用以下内容进行部署:
whoami:
image: "containous/whoami"
hostname: mainnode
networks:
- ${DOCKER_NETWORK_NAME}
ports:
- 1337:80
deploy:
placement:
constraints:
- node.hostname==mainnode
Run Code Online (Sandbox Code Playgroud)
我将端口放在1337那里进行测试,因为我可以访问我的 IP:1337 并查看它,但这并不能实现我whoami.mydomain.com仅在连接到 OpenVPN 时进行解析的目标。
192.168连接到 vpn 时我可以 ping 一个地址我在主机节点上运行了以下命令:
ip -4 地址添加 192.168.146.16/24 dev eth0
然后当连接到VPN时,我可以解析这个地址!所以看起来至少有些东西在起作用。
我怎样才能实现上面提到的目标?需要什么?需要存在什么样的 OpenVPN 配置、什么样的网络配置、什么样的容器配置?我是否需要一个自定义的 DNS 解决方案,就像我在下面建议的那样?有什么更好的选择?
一些考虑:
我可以拥有域,包括私有域和whoami.mydomain.com公共域。这意味着我将拥有 https 并轻松为他们获取通配符证书,我想?但我的困惑是 - 我怎样才能在不使用自签名证书的情况下仅在 VPN 上获取这些域,而且还为它们提供 tls 证书?
我也可以运行自己的 DNS 服务器进行解析。我试过这个,但我无法让它工作,可能是因为 VPN 部分还没有正常工作。我为此找到了dnsmasq,我必须添加上述本地 ip 才能resolve.conf在本地进行任何操作。但是域在连接到 VPN 时仍然无法解析,所以看起来 DNS 流量也没有通过 VPN(即使我这样设置 - 我的客户端是粘性的。
有人提到使用桥接网络,但桥接网络不适用于多主机
-一个关于 stackexchange 的完全非解释性的答案,我认为它被其他 Github 线程中的多人引用为基本上没有帮助,并且其中一个链接已失效
小智 1
所以我对这个问题一直在头撞砖墙,然后通过改变你的想法来“解决”它:
基本上我向其主机打开了 VPN 容器的端口。然后启用代理。这意味着我可以通过访问 VPN 所在的 PC(又名 VPN 容器/堆栈的 Docker 主机)的 IP 来访问该代理。
和我一起挂:
我使用了gluetunvpn,但我认为如果您使用 openvpn,这也适用。我只是发现glutun更容易。
另外重要提示:我在本地主机环境中尝试了此操作,但理论上这也应该在多主机情况下工作,因为我正在使用单独的堆栈。也许,在多主机情况下,您需要使用主 docker 主机的公共 IP。
1. 创建网络
因此,首先为此 docker swarm 堆栈创建一个可连接网络:
docker network create --driver overlay --attachable --scope swarm vpn-proxy
Run Code Online (Sandbox Code Playgroud)
顺便说一句,我开始认为这段话是多余的,但需要进行更多测试。
2. 设置VPN堆栈
然后创建你的 VPN 堆栈文件,让我们调用它stack-vpn.yml:
(这里我gluetun通过 swarm-launcher “trick” 使用。这个glutun 服务通过 Wireguard 通过 VPN 连接。它还在端口 8888 启用 http 代理 - 该端口也通过设置映射到其主机LAUNCH_PORTS: '8888:8888/tcp')
docker network create --driver overlay --attachable --scope swarm vpn-proxy
Run Code Online (Sandbox Code Playgroud)
请注意, 和swarm-launcher容器gluetun正在使用先前创建的网络vpn-proxy。
3.设置worker栈
目前我们将在这里设置一个包含 3 个高山图像副本的示例(文件名stack-workers.yml):
version: '3.7'
services:
vpn_launcher:
image: registry.gitlab.com/ix.ai/swarm-launcher
volumes:
- '/var/run/docker.sock:/var/run/docker.sock:rw'
networks:
- vpn-proxy
environment:
LAUNCH_IMAGE: qmcgaw/gluetun
LAUNCH_PULL: 'true'
LAUNCH_EXT_NETWORKS: 'vpn-proxy'
LAUNCH_PROJECT_NAME: 'vpn'
LAUNCH_SERVICE_NAME: 'vpn-gluetun'
LAUNCH_CAP_ADD: 'NET_ADMIN'
LAUNCH_ENVIRONMENTS: 'VPNSP=<your-vpn-service> VPN_TYPE=wireguard WIREGUARD_PRIVATE_KEY=<your-private-key> WIREGUARD_PRESHARED_KEY=<your-preshared-key> WIREGUARD_ADDRESS=<addrs> HTTPPROXY=on HTTPPROXY_LOG=on'
LAUNCH_PORTS: '8888:8888/tcp'
deploy:
placement:
constraints: [ node.role == manager ]
restart_policy:
condition: on-failure
networks:
vpn-proxy:
external: true
Run Code Online (Sandbox Code Playgroud)
他们还使用vpn-proxy覆盖网络。
4.启动我们的堆栈
docker stack deploy -c stack-vpn.yml vpn
docker stack deploy -c stack-workers workers
Run Code Online (Sandbox Code Playgroud)
一旦它们启动,您就可以访问任何工作任务,并尝试使用代理所在的主机 IP 来使用代理。
正如我之前所说,理论上这应该适用于多主机情况,但可能您需要使用主 docker 主机的公共 ip(尽管如果它们共享相同的覆盖网络,它也可以使用内部 ip 地址(192 ...))。
| 归档时间: |
|
| 查看次数: |
1699 次 |
| 最近记录: |