クラウドVM(EC2インスタンス)でOpenVPNをクライアントモードで実行して、VMを出るトラフィックが一般的にVPNを通過するようにしたいと思います。ただし、既存のIPアドレスをSSH接続で使用できるようにしたいのです(そのため、現在マシンに接続しているSSH接続が切断されません)。

これ.ovpnが私が使用している現在の設定ファイルです:

client
dev tun
proto udp
remote xxx.yyy.com 1198
resolv-retry infinite
nobind
persist-key
persist-tun
cipher aes-128-cbc
auth sha1
tls-client
remote-cert-tls server
auth-user-pass
comp-lzo
verb 1
reneg-sec 0
crl-verify crl.rsa.2048.pem
ca ca.rsa.2048.crt
disable-occ

編集:この質問は、サーバーマシンでVPNにログインした後にSSH接続が失われるのを防ぐのと重複している可能性があります...しかし、そこにも受け入れられた答えはありません。

answer

高度なルーティングを使用して、プライマリインターフェイスに着信するパッケージを同じインターフェイス経由でルーティングできます。このようにして、サーバーから発信されたトラフィックはVPN経由でルーティングされますが、サーバーのプライマリインターフェイスは引き続き接続に使用できます。ここでの考え方は、パケットがプライマリインターフェイスを経由する場合、「vpn」という名前の別のルーティングテーブルを使用するため、VPNクライアントのルーティング設定の影響を受けないということです。

これを実現するには、次のようにします。

/etc/iproute2/rt_tablesファイルを編集します。次のようなものが含まれている必要があります。

#
# reserved values
#
255     local
254     main
253     default
0       unspec
#
# local 
#

次の行をファイルの最後に追加します。

1        vpn

/etc/network/interfacesファイル、あなたのメインインターフェイス(またはで適切なファイルへの設定の下/etc/network/interfaces.d/)、次の行を追加します。

up ip route add 0.0.0.0/0 via def.ault.gw table vpn
up ip rule add from the.primary.ip.addr table vpn
down ip route del 0.0.0.0/0 table vpn
down ip rule del from the.primary.ip.addr

the.primary.ip.addrプライマリインターフェイスのIPアドレス(つまり、サーバーを利用できるようにするIP)def.ault.gwと、デフォルトゲートウェイアドレスに置き換えます。

'--up'および '--down'オプションを使用して、必要に応じてVM上のファイアウォールとルーティングテーブルを操作するシェルスクリプトを実行することをお勧めします。これにより、VPNを介してトラフィックをトンネリングし(openvpnがまだ実行していない場合)、sshトラフィックの例外を作成できます。iptablesルールはトップダウン方式で適用されるため、トンネリングルールの前に例外ルールが適用されていることを確認してください。ルーティングテーブルとファイアウォールルールを管理する方法の例として使用できる他の質問があります。

iptables-パケットを特定のインターフェースにルーティングするターゲット?

あなたが直面している問題は、デフォルトルートがVPN上にあり、送信元へのルートがないインターフェイスから送信されるパケットを除外しているルートがあることだと思います。これはRPフィルターと呼ばれます

sshdのデフォルトルートを他のプロセスとは異なる2つのソリューションがあります。ネットワーク名前空間を使用することも、cgroupsを使用することもできます。私はそれらについてあまり知りませんが、あなたはの答えでもっと読むことができます:https
//superuser.com/questions/271915/route-the-traffic-over-specific-interface-for-a-process-in- Linux

提案されているように高度なルーティングによってそれを行うことができますが、それはそれほど単純ではありません。

目標を達成するための最も簡単な解決策は、(ホーム)IPアドレスを別の方法でアドレス指定するパッケージをルーティングすることです。sshアクセスをいくつかの安全なIPアドレスに制限することは常に良い考えです。たとえば、次のことができます。

ip route add 1.1.1.1 via 9.9.9.9

ここで、1.1.1.1はホームIPアドレスであり、9.9.9.9はルーティングテーブルですでに到達可能なデフォルトゲートウェイですこれで、マシンから外部IPへのすべてのパッケージが同じ方法で返されます。他のすべては通常どおりVPN経由でルーティングできます。このルートをopenvpn設定ファイルに追加することもできます。すべてが素晴らしいです。

ただし、ホームIPが変更されている場合(動的アドレスとも呼ばれます)、またはランダムなアドレスからマシンに到達する必要がある場合(複数のユーザー、旅行中)はそれほど優れていません。その場合、あなたは困難な道を歩まなければなりません。

何もしなければ、sshパッケージは外部インターフェース(およびIP)に到着しますが、VPN経由でルーティングすると、戻る方法を見つけることができません(実際に、VPN設定によって可能ですが、ソースIPは異なり、パッケージはドロップされます)。あなたの目標は、いくつかの発信パッケージを外部インターフェースにリダイレクトし、いくつかをVPNにリダイレクトすることです。これが問題です。

代替ルーティングテーブルを作成します。

echo "100 secure" >> /etc/iproute2/rt_tables

ルーティングの設定と制御:

# route ssh over external iface eth0 to router 9.9.9.9 
ip route add default via 9.9.9.9 dev eth0 table secure

# send all packages with fwmark 1 to the secondary routing table
ip rule add fwmark 0x1 table secure

# Mark outgoing ssh packages with the mark 1
iptables -t mangle -A OUTPUT -p tcp --sport 22 -j MARK --set-mark 1

ここでは、すべての発信sshパッケージにマークを付けてから、マークされたすべてのパッケージを代替ルーティングにリダイレクトします。もちろん、すべての回答が別のインターフェースにリダイレクトされるため、VPNをSSHで接続することはできなくなります。重要なのは、任意に複雑なiptablesルールを作成し、set-markを使用してそれらを異なる方法でルーティングできるということです。

幸い、CONNMARKと呼ばれるものがあり、(カーネルの接続追跡機能を利用して)接続全体を前後にマークできます(xt_connmarkモジュールが必要になります)。

# mark incoming ssh *connection* with 1. Here eth0 is your external interface
iptables -A INPUT -m state --state NEW -i eth0 -p tcp --dport 22 -t mangle -j CONNMARK --set-mark 1

# restore connection mark (e.g. mark the packages) 
iptables -A OUTPUT -t mangle -j CONNMARK --restore-mark 

# send all packages with fwmark 1 to the secondary routing table as before..
ip rule add fwmark 0x1 table secure

単にコピー&ペーストするのではなく、概念を理解した後、現在の設定に従って上記を使用してください。


編集:クライアントの観点から

ssh接続が確立されているのと同じマシンからVPNを使用している場合、追加の問題が発生します。

デフォルトでは、VPNピアがデフォルトゲートウェイになります。sshパッケージはVPNチャネルを介してルーティングされるため、既存の接続が簡単に切断される可能性があります(サーバーは、物理ethインターフェイスからではなくtunまたはtapインターフェイスからそれらを取得します)。簡単な解決策は、クライアント側の構成にdefault-gatewayオプションを含めないことです(またはプッシュしないでください)。優先サブネットのルートのみをプッシュします。警告:(自宅の)パブリックアドレスを非表示にするようにVPNを作成した場合、これは希望どおりではない可能性があります。