web-dev-qa-db-ja.com

LinuxボックスでIPパススルーを実行するにはどうすればよいですか?

2つのネットワークインターフェイスを備えたRaspbian(Debianベース)を実行しているRaspberryPiがあります。

インターフェイスの1つは、衛星モデムからのWANです。もう1つは、Piがインターネットを提供するCustomer Routerです。

問題は、私が扱っているのは/ 30だけであり、衛星モデムにはすでにその/ 30に2つのIPの1つがあるため、残りのIPは1つ(1.1.1.2/30)で、それ(私のRaspberry Piとカスタマールーター)。

私は簡単にNATを実行でき、顧客にLANIPを提供できることを知っています。それは欲しくない。お客様にはパブリックIPが必要です。また、Piを独自のIPを持たない単なるスイッチとして構成することもできますが、Piはインターネットにアクセスできません。私もそれを望んでいません。インターネットを利用するには、Piとお客様のルーターの両方が必要です。

Diagram

私はこれが可能であることを知っています。これは、過去にこれと同じことを行うMicroHardセルモデムを使用したことがあるからです。セルモデムは、セルタワーに接続するときにパブリックIPを取得し、IPパススルーモードを有効にすると、そのセルモデムに接続されているルーターも同じパブリックIPを取得します。

インターネットからポート80、443、または22でそのパブリックIPにアクセスすると、セルモデムと通信しますが、他のポートにアクセスすると、セルモデムの背後にあるルーターと通信します。それがまさに私がやりたいことです。彼らがそれをどのように行うのか、そしてLinuxでそれをどのように複製するのか正確にはわかりません。 MicroHardセルモデムはLinuxベースであるため、Linuxでも可能です。

これまでのところ、これは私の計画です:

  • Raspberry Piのeth0(Sat Modem Interface)の1.1.1.2/30の静的IP
  • Raspberry Piのeth1(カスタマールーターインターフェイス)の静的IP 1.1.1.254/24
  • カスタマールーターを提供するeth1上のDHCPサーバー:
    • 1.1.1.2/24
    • DG:1.1.1.254
  • Net.ipv4.ip_forwardを有効にしました
  • 2つのインターフェイス上の2つのサブネットは明らかに重複しているため、ポリシーベースのルーティングルールを使用して、トラフィックを送信するタイミングと場所をPiに通知します。

これで、次のようになります。

enter image description here

私はこれを機能させるように努めてきましたが、その最後の箇条書きは明らかに難しい部分です。他のすべて(DHCPルーター、静的IP、IP転送)はすべて完了し、機能しています。

私はこれをしました:

# Rules to prevent ARP from going out the wrong interface
$ Sudo arptables -A INPUT -i eth0 --destination-ip ! 1.1.1.2 -j DROP
$ Sudo arptables -A INPUT -i eth1 --destination-ip ! 1.1.1.254 -j DROP

# Create custom routing tables
$ Sudo vim /etc/iproute2/rt_tables
    190 to_sat_modem
    200 to_customer_router

# Add rules to tables
$ Sudo ip route add default dev eth0 table to_sat_modem
$ Sudo ip route add default dev eth1 table to_customer_router

# Add policy based routing rules
$ Sudo ip rule add fwmark 0x1 lookup to_sat_modem
$ Sudo ip rule add fwmark 0x2 lookup to_customer_router

# Add masq rule
$ Sudo iptables -t nat -A POSTROUTING -o eth0 ! -s 1.1.1.2 -j SNAT --to 1.1.1.2

# Add rules for when to use these routing tables

$ Sudo iptables -t mangle -N TO_CUSTOMER_ROUTER
$ Sudo iptables -t mangle -N TO_SAT_MODEM

$ Sudo iptables -t mangle -A OUTPUT -d 1.1.1.2 -j TO_CUSTOMER_ROUTER        # From localhost
$ Sudo iptables -t mangle -A PREROUTING -i eth0 -d 1.1.1.2 -p udp -j TO_CUSTOMER_ROUTER                                         # All UDP ports
$ Sudo iptables -t mangle -A PREROUTING -i eth0 -d 1.1.1.2 -p tcp --match multiport ! --dports 22,80 -j TO_CUSTOMER_ROUTER  # Most TCP ports
$ Sudo iptables -t mangle -A TO_CUSTOMER_ROUTER -j MARK --set-xmark 0x2
$ Sudo iptables -t mangle -A TO_CUSTOMER_ROUTER -j ACCEPT

$ Sudo iptables -t mangle -A OUTPUT -d 1.1.1.1 -j TO_SAT_MODEM      # From localhost
$ Sudo iptables -t mangle -A PREROUTING -i eth1 -d 1.1.1.1 -j TO_SAT_MODEM
$ Sudo iptables -t mangle -A TO_SAT_MODEM -j MARK --set-xmark 0x1
$ Sudo iptables -t mangle -A TO_SAT_MODEM -j ACCEPT

順調に進んでいるように感じますが、うまくいかないようです。何か案は?

PS。はい、私のルールのほとんどは再起動後も存続しないことを知っています。実用的な解決策ができたら修正します

PPS。これは一方向の透明性を達成しようとしています。 Satモデムは背後にある単一のデバイス(1.1.1.2)のみを認識しますが、カスタマールーターはPi(1.1.1.254)およびSatモデム(1.1.1.1)と通信できます。これは機能するはずですが、実際のパブリックIPの/ 24全体をマスクするという問題があります。効果を減らすために/ 24を/ 29に変更できますが、それでも起こります。最終的には、Piの両端で/ 30 IPを再利用できるように、双方向の透過性が必要になりますが、これは簡単に開始できると考えました

PPPS。この質問に対する明白な答えは次のとおりです。

これをしないでください。他のことをしてください。顧客にLANIPを与えるか、Piを顧客ルーターの後ろに置いてLAN IPを与えるか、piをブリッジモードにするか...

なぜこのようにする必要があるのか​​について10ページの説明を書きたくありませんが、私を信じてください。可能であれば、このようにする必要があります。私がそれを見たので可能です

4
John

私の2 Piソリューションに基づいて、Linuxネットワークの名前空間を使用して、1つのPiで同じものを構成することができました。

Single Pi Solution

初期ステップ:

  • IP転送を有効にする
  • 通常どおりにeth0を1.1.1.2/30静的IPに設定します
    • DHCPクライアントを使用することもできますが、新しいIP用にネットワークを再構成する何らかのフックが必要になります。

ネットワークを構成するスクリプト:

#!/bin/bash

###############
# Global Vars #
###############

# Sat modem IP with subnet
# Ex: 1.1.1.1
SAT_MODEM_IP="1.1.1.1"

# Router IP
# Ex: 1.1.1.2
ROUTER_IP="1.1.1.2"

# Subnet in cidr notation
# Ex: 30
SUBNET_MASK="30"

# Space separated list of ports for the Pi to intercept
PORTS="8081 8082"

#####################
# Calculated Values #
#####################

# Removes the slash, in case the user wrote "/30" instead of "30" above
SUBNET_MASK=$(echo $SUBNET_MASK | tr -d '/')

# Make sure port list is property formatted for iptables
PORTS=$(echo $PORTS | sed 's/ /,/g' | tr -s ',')

##########
# Checks #
##########

# Make sure we are running as root
if ! [ $(id -u) = 0 ]
then
    echo "Error: This script must be run as root" >&2
    exit 1
fi

# Make sure ns2 doesn't already exist
if /sbin/ip netns | grep -q '^ns2'
then
    echo "Error: ns2 already exists"
    exit 1
fi

###################
# Start of Config #
###################

# Create ns2 namespace
ip netns add ns2 

# Move eth1 to ns2 namespace
ip link set eth1 netns ns2

# Configure eth1 in ns2 namespace
ip netns exec ns2 ip address add $SAT_MODEM_IP/$SUBNET_MASK dev eth1
ip netns exec ns2 ip link set eth1 up

# Enable loopback interface in ns2 namespace
ip netns exec ns2 ip link set lo up

# Create virtual interface pair, and move one of the interfaces into
# the ns2 namespace
ip link add veth type veth peer name vpeer
ip link set vpeer netns ns2

# Set ip on virtual interfaces
ip address add 192.168.90.5/24 dev veth
ip netns exec ns2 ip address add 192.168.90.6/24 dev vpeer

# Bring up both virtual interfaces
ip link set veth up
ip netns exec ns2 ip link set vpeer up

# Add DG to ns2 namespace
ip netns exec ns2 ip route add default via 192.168.90.5

# Add root namespace iptables rules
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
iptables -t nat -A POSTROUTING -o veth -s $SAT_MODEM_IP -j MASQUERADE
iptables -t nat -A PREROUTING -i eth0 -p udp -j DNAT --to-destination 192.168.90.6
iptables -t nat -A PREROUTING -i eth0 -p tcp -m multiport ! --dport $PORTS -j DNAT --to-destination 192.168.90.6
iptables -t nat -A PREROUTING -i eth0 -p ICMP -j DNAT --to-destination 192.168.90.6
iptables -t nat -A PREROUTING -i veth -p udp -d 192.168.90.5 -j DNAT --to-destination $SAT_MODEM_IP
iptables -t nat -A PREROUTING -i veth -p tcp -m multiport ! --dport $PORTS -d 192.168.90.5 -j DNAT --to-destination $SAT_MODEM_IP
iptables -t nat -A PREROUTING -i veth -p ICMP -d 192.168.90.5 -j DNAT --to-destination $SAT_MODEM_IP

# Add ns2 namespace iptables rules
ip netns exec ns2 iptables -t nat -A POSTROUTING -o vpeer -j MASQUERADE
ip netns exec ns2 iptables -t nat -A POSTROUTING -o eth1 -s 192.168.90.5 -j MASQUERADE
ip netns exec ns2 iptables -t nat -A PREROUTING -i vpeer -j DNAT --to-destination $ROUTER_IP
ip netns exec ns2 iptables -t nat -A PREROUTING -i eth1 -d $SAT_MODEM_IP -j DNAT --to-destination 192.168.90.5

# Add ICMP blocking
# Note: This just prevents customers from seeing LAN IPs in a
# traceroute from site, and duplicate WAN IPs in a traceroute to
# site
iptables -A OUTPUT -p ICMP -j DROP
ip netns exec ns2 iptables -A OUTPUT -p ICMP -j DROP

注:私はこれまでネットワーク名前空間を使用したことがありませんでしたが、最終的には理解しやすく、使いやすいものになりました。参照: https://blogs.igalia.com/dpino/2016/04/10/network-namespaces/

注:静的に設定しなくても、eth1でDHCPサーバーをセットアップして顧客ルーターにIPを与えることもできますが、ns2名前空間のeth1でDHCPサーバーを実行する必要があります。これはこの質問の範囲外ですが、NetworkNamespacePath systemdオプションを探し、パッケージマネージャーと戦わずに systemdユニットファイルを適切に編集する 方法を知っていることを確認してください。

0
John

私の最終的な目標は双方向の透明性であるという事実にもかかわらず、質問では、一方向の透明性を実現しようとする道を歩み始めました。

一方向の透明性とは、モデムはその背後にある1つのデバイス(1.1.1.2)しか認識できないが、カスタマールーターはPi(1.1.1.254)と1.1.1.1のモデムの両方を認識できることを意味します。

一方向の透明性の問題は、少なくとも私がやろうとしていた方法では、正当なパブリックIPをマスクすることになるということです。これは明らかに理想的ではありません。

以下は、双方向の透明性を機能させる1つの方法ですが、2つのRaspberry Piを使用します。これは機能し、他の誰かを助けるかもしれませんが、私はこれが単一のPiで機能することを必要とするので、Linuxネットワーク名前空間を使用して単一のPiでこれを実行することを検討します。誰かが単一のPiで実用的な解決策を持っているなら、私に知らせてください。

2 Piソリューション:

enter image description here

一般的な手順:

  • 両方のPiで静的IPを構成する
  • 両方のPiでルーティングを有効にします(エコー1>/proc/sys/net/ipv4/ip_forward)

Pi 1:

ip route add default via 1.1.1.1

iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
iptables -t nat -A POSTROUTING -o eth1 -s 1.1.1.1 -j MASQUERADE

# All UDP Ports
iptables -t nat -A PREROUTING -i eth0 -p udp -j DNAT --to-destination 192.168.90.6

# Some TCP Ports
iptables -t nat -A PREROUTING -i eth0 -p tcp -m multiport ! --dport 8081,8082 -j DNAT --to-destination 192.168.90.6

Pi 2:

ip route add default via 192.168.90.5

iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
iptables -t nat -A POSTROUTING -o eth1 -s 192.168.90.5 -j MASQUERADE

# Forwards EVERYTHING to Customer Router
iptables -t nat -A PREROUTING -i eth0 -j DNAT --to-destination 192.168.90.6

注:私はこの2-piソリューションからsingle-piソリューションにかなり迅速に移行したため、これは受け入れられているsingle-piソリューションほどうまくいきません。誰かがこれを使用する予定がある場合は、いくつかの改善を使用できます。これは、単一piソリューションよりも理解しやすいので、主に参照用ですが、基本的に同じことを行います

0
John