目标:在 docker swarm 上部署一组服务,其中一个服务只有当我连接到也在 docker swarm 上启动的 OpenVPN 服务器时才可用。
背景
一般的想法是,比如说,kibana 和 elasticsearch 在内部运行,只能在 VPN 上访问(就像企业网络一样),其他服务在公开场合正常运行。这些都将位于单独的节点上,因此我使用覆盖网络。
我确实在 docker swarm 上运行了 OpenVPN,以及我是谁容器,我可以连接到 VPN,但是 IP 似乎没有改变,我不知道如何让 whoami 容器仅在 VPN 上可用,尤其是考虑到我使用的是覆盖网络这是多主机。我还在使用特雷菲克,一个反向代理,它为我提供了一个几乎自动的 letsencrypt 设置(通过 DNS 质询),用于通配符域。通过它我可以获得:
但我还想连接到vpn.mydomain.com
(我现在就可以做到),然后能够访问:
...我不能。但是。我已经发布了我的traefik 配置在不同的地方,以防您想看一下,因为如果我将它发布在这里,这个线程会变得太大。
让我们从我现在所在的地方开始吧。
OpenVPN
首先,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
我可以使用以下命令部署上述内容: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
现在,我有一个可连接的覆盖网络,当我部署它时,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
我将端口放在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 部分还没有正常工作。我发现域名系统为此,我必须添加上述本地 IP 才能
resolve.conf
在本地运行。但连接到 VPN 时域名仍然无法解析,因此 DNS 流量似乎也没有通过 VPN(尽管我已将其设置为这样 - 我的客户端是粘度。有人提到使用桥接网络,但桥接网络不适用于多主机
迄今为止的资源(我将更新更多)
-Stackexchange 上一个完全没有解释的答案在其他 Github 帖子中,我看到很多人提到这一点,认为它基本上没有帮助,而且其中一个链接已经失效