web-dev-qa-db-ja.com

openvpnクライアントを介してLANIPトラフィックをルーティングする

VPNクライアントをLAN上の他のノードと共有しようとしています。 LAN上でopenvpnクライアントを実行しているubuntuサーバーがあります。以下は私のネットワーク図です。

enter image description here

サーバーは、WANでアクセス可能である必要があるいくつかのWebサービスも実行しています-VPNをオンにすると、このセットアップは機能しますが、サービスはアクセスできなくなります。これに従って 質問 、openvpn設定に以下を追加しました:

route-nopull
route 192.168.4.50 255.255.255.255

ip route listを実行すると:

default via 192.168.4.1 dev enp1s0 proto static metric 100
10.175.0.69 dev tun0 proto kernel scope link src 10.175.0.70
169.254.0.0/16 dev enp1s0 scope link metric 1000
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 linkdown
172.18.0.0/16 dev br-616f4053c28b proto kernel scope link src 172.18.0.1
192.168.4.0/24 dev enp1s0 proto kernel scope link src 192.168.4.199 metric 100
192.168.4.50 via 10.175.0.69 dev tun0

route-nopullを使用すると、ノードはインターネットにアクセスできますが、VPN経由ではアクセスできません

完全なopenvpn構成(キーなし):

dev tun
fast-io
persist-key
persist-tun
nobind
remote XXXXXXX 1195
#script-security 2
#up /etc/openvpn/up.sh

remote-random
pull
comp-lzo no
tls-client
verify-x509-name Server name-prefix
ns-cert-type server
key-direction 1
route-method exe
route-delay 2
tun-mtu 1500
fragment 1300
mssfix 1200
verb 3
cipher AES-256-CBC
keysize 256
auth SHA512
sndbuf 524288
rcvbuf 524288
auth-user-pass /etc/openvpn/login

route-nopull
route 192.168.4.50 255.255.255.255

[〜#〜] update [〜#〜]:このスクリプトは、VPNが有効になっているときに実行されます。最後の2行で、特定のポートのデータがVPNをバイパスできるようにしようとしていますが、これで問題が発生します。

#!/bin/sh
INTIF=enp1s0  # internal interface (your LAN)
EXTIF=tun0    # external interface (WAN via OpenVPN)

#iptables -t nat -A POSTROUTING -o $EXTIF -j MASQUERADE

iptables -A FORWARD -i $EXTIF -o $INTIF -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -i $INTIF -o $EXTIF -j ACCEPT

iptables -A FORWARD -i $EXTIF -o $EXTIF -p tcp --sport 7878 --dport 7878 -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -i $EXTIF -o $EXTIF -p tcp --sport 7878 --dport 7878 -j ACCEPT
1
Gabrielus

まず、試したオプションを見てみましょう。 routeは、OpenVPN接続が確立された後、OpenVPN接続を介して192.168.4.50/32へのルートを追加するようにOpenVPNに指示するだけです。 route-nopullは、サーバーから取得したルートを無視するようにOpenVPNに指示します。それがあなたが得る理由です

192.168.4.50 via 10.175.0.69 dev tun0

したがって、サーバーでは、to192.168.4.50へのパケットはすべてVPNを通過します。それはあなたが望むものではありません。 OTOH、

default via 192.168.4.1 dev enp1s0 proto static metric 100

インターネットにパケットを送信するように指示します(たとえば、from192.168.4.0)からルーターに送信します。また、インターネットからの応答はすべて、ルーターを介して直接クライアントに送信されます。

これが、クライアントがインターネットアクセスを取得する理由です(送信パケットは最初にサーバーに到達し、次にルーターに到達します。着信パケットはルーターからクライアントに直接送信され、サーバーに設定したルートは表示されません)が、OpenVPN経由ではありません。


本当に必要なのは、サーバーからのルートをnot無視しないことです(これらのルートは、通常、0.0.0.0/1128.0.0.0/1defaultルートを維持できる)は、サーバーに、もう一方の端にあるOpenVPNサーバー経由でインターネットにアクセスするように指示します。したがって、ゲートウェイは静的IPアドレスではないため、OpenVPNにこれらのルートを設定させる必要があります。

これらのルートを取得すると、クライアントからのパケットはOpenVPN接続に正常に送信されます。

しかし、答えはどうですか?もう一方の端のExpressVPNサーバーはマルチクライアントモードで実行され、パケットの送信先となる単一のIPアドレス(サーバー)があることを前提としています。そのアドレスの背後にサブネット全体があることをサーバーに通知するには(回答が必要なクライアントを含む)、--irouteオプションが必要です。 ここ これが必要な理由の説明を読むことができます。 ここ は正確に何をすべきかについてのOpenVPNの指示です。ご覧のとおり、irouteオプションを設定するにはクライアント構成ディレクトリが必要です。

しかし、あなたはサーバーを制御していないので、それを行うことはできません。そのため、OpenVPN経由のルーティングは終了しています。


したがって、ExpressVPNを使用したセットアップ全体は、ユーザー側の単一のIPアドレスに対してのみ機能します。ただし、この単一のIPアドレスを使用しているふりをする方法があります:ネットワークアドレス変換(NAT)。

インターネット上にはNAT)に関する情報がたくさんあります。必要なものの非常に凝縮されたバージョンは

INTIF=enp1s0  # internal interface (your LAN)
EXTIF=tun0    # external interface (WAN via OpenVPN)

iptables -t nat -A POSTROUTING -o $EXTIF -j MASQUERADE

このルールは、外部OpenVPNインターフェースから送信されるすべてのパケットが、送信元アドレスをこのインターフェース上のアドレスに書き換えることによって「マスカレード」されることを示しています。接続トラッカーはこれを記憶し、答えが反対の方法で書き直されることを確認します。

さらに、発信接続(または応答)のみが次のようなルールによって転送されるようにすることができます

iptables -A FORWARD -i $EXTIF -o $INTIF -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -i $INTIF -o $EXTIF -j ACCEPT

WAN)に公開されているサービスのみがサーバー上にあると想定します。

これを永続化するにはさまざまな方法がありますが、Dockerには通常多くのiptablesルールもあるため、Dockerのインストールではこれが少し複雑になり、誤って破棄しないように注意する必要があります。また、理想的には、これはOpenVPN接続が確立されたときにのみ発生し、終了時に切断される必要があるため、OpenVPN構成ファイルに設定された適切なスクリプトがおそらく最善の方法です。

--up--down、および OpenVPNドキュメント の他のスクリプトをご覧ください。

1
dirkt