Как подключить устройство TAP к оверлейной сети?
Я хотел бы разрешить пользователям OpenVPN получать доступ ко всем контейнерам Docker, которые являются частью сети Overlay, как если бы они находились в одной локальной сети. Самый простой пример: 3 контейнера распределены на 2 хостах, хосты соединены через оверлейную сеть, и все 3 контейнера являются частью этой оверлейной сети.
Для этого я подготовил один контейнер OpenVPN (OpenVPN в режиме моста с адаптером TAP), в этом контейнере я создал мост br0 и соединил интерфейсы eth0 и Tap0 с br0. При этом я бы сказал, что я подключил свой TAP и всех клиентов OpenVPN к оверлейной сети (я не уверен, что это утверждение верно).
До сих пор, когда мои пользователи OpenVPN подключаются к OpenVPN и пытаются пинговать фиктивный контейнер 1 (который находится на том же хосте, что и контейнер OpenVPN), пользователи могут пинговать фиктивный контейнер 1 (и, конечно же, могут пинговать контейнер OpenVPN). также). Все идет нормально!
Однако пользователи не могут выполнить проверку связи с фиктивным контейнером 2, который существует на другом хосте (но является частью того же оверлея с контейнером OpenVPN, как упоминалось выше).
Короче говоря, пользователи VPN, которые подключены к контейнеру OpenVPN (подключенному к оверлейной сети Docker) и пытаются пинговать другие контейнеры, могут пинговать контейнеры только на том же хосте, а не на другом хосте, как если бы мост работал только на локальном компьютере. мост, а не с оверлейной сетью.
Важно также сказать, что изнутри самого контейнера OpenVPN я могу пропинговать фиктивный контейнер 2 (и, конечно же, фиктивный контейнер 1).
Эта цифра самаритизирует всю историю, которую я рассказал выше. Обратите внимание на красную стрелку, обозначающую соединение, которое я хотел бы установить, но в данный момент оно не работает (пользователь VPN подключается к хосту 1 через OpenVPN, а затем пытается выполнить проверку связи с фиктивным контейнером 2).
Немного подробной технической информации
OpenVPN-контейнер
/etc/openvpn # ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
2: tap0: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc fq_codel master br0 state UP group default qlen 1000
link/ether 06:9b:33:89:85:81 brd ff:ff:ff:ff:ff:ff
3: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UP group default qlen 1000
link/ether 02:42:0a:08:00:04 brd ff:ff:ff:ff:ff:ff
inet 10.8.0.4/24 scope global br0
valid_lft forever preferred_lft forever
74: eth0@if75: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue master br0 state UP group default
link/ether 02:42:0a:08:00:04 brd ff:ff:ff:ff:ff:ff link-netnsid 0
76: eth1@if77: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:12:00:04 brd ff:ff:ff:ff:ff:ff link-netnsid 1
inet 172.18.0.4/16 brd 172.18.255.255 scope global eth1
valid_lft forever preferred_lft forever
/etc/openvpn # ip route
default via 172.18.0.1 dev eth1
10.8.0.0/24 dev br0 proto kernel scope link src 10.8.0.4
172.18.0.0/16 dev eth1 proto kernel scope link src 172.18.0.4
Конфигурация OpenVPN-сервера:
port 1194
proto udp
dev tap0
ca ca.crt
cert server.crt
key server.key # This file should be kept secret
dh dh.pem
ifconfig-pool-persist ipp.txt
client-to-client
keepalive 10 120
cipher AES-256-GCM
compress lz4-v2
push "compress lz4-v2"
persist-key
persist-tun
status /var/log/openvpn-status.log
verb 3
explicit-exit-notify 1
##### Authentication #####
# A client certificate is not required. The client need to authenticate using username/password only.
verify-client-cert none
# Disables keys renegotiation. The default value is one hour, which disconnects the user every hour and causes the end user to be challenged to reauthorize using a new OTP.
reneg-sec 0
# Loads and uses LDAP plugin config.
plugin /usr/lib/openvpn/plugins/openvpn-auth-ldap.so /etc/openvpn/auth-ldap.conf
# Loads and uses PAM-auth plugin (mainly for 2FA).
plugin /usr/lib/openvpn/plugins/openvpn-plugin-auth-pam.so "openvpn login USERNAME password PASSWORD pin OTP"
Свадьба делается так:
openvpn --mktun --dev tap0
ip link set tap0 promisc on up
ip link add name br0 type bridge
ip link set dev br0 up
ip link set dev tap0 master br0
ip link set dev eth0 master br0
ip addr flush dev eth0
ip addr add 10.8.0.4/24 dev br0
OpenVPN запускается командой
VPN_SERVER_HOST_IP_ADDRESS=10.8.0.254
VPN_NETMASK=255.255.255.0
VPN_POOL_START_IP_ADDRESS=10.8.0.50
VPN_POOL_END_IP_ADDRESS=10.8.0.100
openvpn \
--config server.conf \
--server-bridge $VPN_SERVER_HOST_IP_ADDRESS $VPN_NETMASK $VPN_POOL_START_IP_ADDRESS $VPN_POOL_END_IP_ADDRESS
Мой фиктивный контейнер 2 (очень похож на фиктивный контейнер 1, но с другими IP-адресами):
/ # ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
35: eth0@if36: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1450 qdisc noqueue state UP
link/ether 02:42:0a:08:00:05 brd ff:ff:ff:ff:ff:ff
inet 10.8.0.5/24 brd 10.8.0.255 scope global eth0
valid_lft forever preferred_lft forever
37: eth1@if38: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP
link/ether 02:42:ac:12:00:03 brd ff:ff:ff:ff:ff:ff
inet 172.18.0.3/16 brd 172.18.255.255 scope global eth1
valid_lft forever preferred_lft forever
/ # ip route
default via 172.18.0.1 dev eth1
10.8.0.0/24 dev eth0 scope link src 10.8.0.5
172.18.0.0/16 dev eth1 scope link src 172.18.0.3