====== ipコマンドでGREトンネルを作成する ====== {{tag>gre centos6 centos7}} ===== GREトンネルとは ===== GREとはGeneric Routing Encapsulationの略で簡単なIPトンネルを構築できる。 他のVPNとは異なり認証や暗号化等のセキュリティ機能はない。 トンネル始端でIPヘッダの前にトンネル用のIPヘッダとGREヘッダを付加してトンネル終端へ転送。 トンネル終端では始端が付加したIPヘッダとGREヘッダを除去してからパケットを処理する。 通常は、トンネルの両端で送信用の設定をすると、その相手先からのGREパケットを受け付けるようになる。 言い換えると、片方向だけトンネルを設定して送信しても受信側で無視される。 ===== GREトンネルの設定 ===== GREトンネルのVPNを構築するには、二つの工程が必要。 一つ目はGREトンネルの作成。 二つ目はGREトンネルへパケットを転送するための設定。 ==== GREトンネルの作成 ==== ip tun add <トンネルデバイス名> mode gre remote <相手のWAN側IP> local <自分のWAN側IP> ip link set dev <トンネルデバイス名> up ''<トンネルデバイス名>''はサーバ内で一意のネットワークデバイス名であればよく、 トンネル両端で合わせる必要はない。 ''<相手のWAN側IP>''と''<自分のWAN側IP>''を入れ替えて、トンネル両端のサーバに設定する。 ==== パケット転送の設定 ==== 設定方法は複数ある。 === トンネル両端のIPアドレスを設定する方法 === トンネル両端のサーバに、''自分のLAN側IP''と対向する''相手のLAN側IP''またはネットワークを設定する。 ip addr add local <自分のLAN側IP> remote <相手のLAN側IP> dev <トンネルデバイス名> 上記のIPアドレス追加コマンドで、トンネルデバイスにIPアドレスを付与すると同時に、 ''相手のLAN側IP''あてのルーティングも追加される。 <相手のLAN側IP> dev <トンネルデバイス名> proto kernel scope link src <自分のLAN側IP> 両端に正しく設定すると、''<自分のLAN側IP>''と''<相手のLAN側IP>''の間で''ping''が通るようになる。 === 個別に設定する方法 === IPアドレスの追加とルーティングを別々に設定することもできる。 ルーティングの設定方法は通常のスタティックルートと同じ。 ip addr add <自分のLAN側IP> dev <トンネルデバイス名> ip route add <相手のLAN側ネットワーク> dev <トンネルデバイス名> ==== トンネルの削除 ==== ip tun del <トンネルデバイス名> トンネルデバイスを削除すると、紐づいているルーティング等も全て削除される。 ===== 設定例1 ===== {{:articles:gre_tunnel_1.png?nolink|GREトンネル構成例1}} WAN側IP''172.31.0.19''と''172.31.0.20''を終端としてGREトンネルを作成。 LAN側IPの''192.168.19.1''と''192.168.20.1''が疎通するようにする。 === 設定例1: サーバA === == GREパケットの受信を許可 CentOS 6の場合 == -A INPUT -p icmp -j ACCEPT # 下の1行を追加 -A INPUT -p gre -j ACCEPT -A INPUT -i lo -j ACCEPT service iptables restart == GREパケットの受信を許可 CentOS 7の場合 == firewall-cmd --add-service=gre --permanent firewall-cmd --reload == GREトンネルの作成 == ip tun add tun_b mode gre local 172.31.0.19 remote 172.31.0.20 ip link set dev tun_b up ip addr add local 192.168.19.1 remote 192.168.20.1 dev tun_b === 設定例1: サーバB === == GREパケットの受信を許可 == サーバAと同じ設定をいれる。 == GREトンネルの作成 == ip tun add tun_b mode gre local 172.31.0.20 remote 172.31.0.19 ip link set dev tun_a up ip addr add local 192.168.20.1 remote 192.168.19.1 dev tun_a === 設定例1: サーバAの状態 === # iptables -S INPUT | grep gre -A INPUT -p gre -j ACCEPT # ip tun show tun_b tun_b: gre/ip remote 172.31.0.20 local 172.31.0.19 ttl inherit # ip addr show tun_b 6: tun_b@NONE: mtu 1476 qdisc noqueue state UNKNOWN link/gre 172.31.0.19 peer 172.31.0.20 inet 192.168.19.1 peer 192.168.20.1/32 scope global tun_b # ip route 192.168.20.1 dev tun_b proto kernel scope link src 192.168.19.1 172.31.0.0/24 dev eth0 proto kernel scope link src 172.31.0.19 ===== 設定例2 ===== {{:articles:gre_tunnel_2.png?nolink|GREトンネル構成例2}} WAN側IPの''172.31.0.19''と''172.31.0.20''を終端としてGREトンネルを作成。 LAN側ネットワークの''192.168.19.0/24''と''192.168.20.0/24''が疎通するようにする。 設定例1との違いは、トンネルデバイスのピアアドレスに相手のLAN側ネットワークをしているすることと、 ''サーバA''と''サーバB''でパケットのフォワーディングを許可すること。 === 設定例2: サーバA === == GREパケットの受信とLANネットワーク間の転送を許可 CentOS 6の場合 == # Controls IP packet forwarding net.ipv4.ip_forward=1 -A INPUT -p icmp -j ACCEPT # 下の1行を追加 -A INPUT -p gre -j ACCEPT -A INPUT -i lo -j ACCEPT # 下の2行を追加 -A FORWARD -s 192.168.19.0/24 -d 192.168.20.0/24 -j ACCEPT -A FORWARD -s 192.168.20.0/24 -d 192.168.19.0/24 -j ACCEPT -A FORWARD -j REJECT --reject-with icmp-host-prohibited sysctl -p service iptables restart == GREパケットの受信とLANネットワーク間の転送を許可 CentOS 7の場合 == # Controls IP packet forwarding net.ipv4.ip_forward=1 sysctl -p firewall-cmd --add-service=gre --permanent firewall-cmd --reload == GREトンネルの作成 == ip tun add tun_b mode gre local 172.31.0.19 remote 172.31.0.20 ip link set dev tun_b up ip addr add local 192.168.19.1 remote 192.168.20.1/24 dev tun_b === 設定例2: サーバB === == GREパケットの受信とLANネットワーク間の転送を許可 == サーバAと同じ設定をいれる。 == GREトンネルの作成 == ip tun add tun_a mode gre local 172.31.0.20 remote 172.31.0.19 ip link set dev tun_a up ip addr add local 192.168.20.1 remote 192.168.19.1/24 dev tun_a === 設定例2: サーバAの状態 === # ip tun show tun_b tun_b: gre/ip remote 172.31.0.20 local 172.31.0.19 ttl inherit # ip addr show tun_b 6: tun_b@NONE: mtu 1476 qdisc noqueue state UNKNOWN link/gre 172.31.0.19 peer 172.31.0.20 inet 192.168.19.1 peer 192.168.20.1/24 scope global tun_b # ip route 192.168.20.0/24 dev tun_b proto kernel scope link src 192.168.19.1 192.168.19.0/24 dev eth1 proto kernel scope link src 192.168.19.1 172.31.0.0/24 dev eth0 proto kernel scope link src 172.31.0.19 # sysctl net.ipv4.ip_forward net.ipv4.ip_forward = 1 # iptables -S INPUT | grep gre -A INPUT -p gre -j ACCEPT # iptables -S FORWARD -P FORWARD ACCEPT -A FORWARD -s 192.168.19.0/24 -d 192.168.20.0/24 -j ACCEPT -A FORWARD -s 192.168.20.0/24 -d 192.168.19.0/24 -j ACCEPT -A FORWARD -j REJECT --reject-with icmp-host-prohibited ===== 設定例3 ===== {{:articles:gre_tunnel_3.png?nolink|GREトンネル構成例3}} 拠点3つをGREトンネルのメッシュでつなぐ。LAN側ネットワークは相互に通信可能。 トンネルデバイスに設定するIPアドレスは、複数のトンネルデバイスで同じIPアドレスを使用できる。 また、物理ネットワークインタフェースのIPアドレスも使用できる。 この構成では''eth1''と2つのトンネルデバイス全てに同じIPアドレスを設定している。 === 設定例3: サーバA === == GREパケットの受信とLANネットワーク間の転送を許可 CentOS 6の場合 == -A INPUT -p icmp -j ACCEPT # 下の1行を追加 -A INPUT -p gre -j ACCEPT -A INPUT -i lo -j ACCEPT # 下の6行を追加 -A FORWARD -s 192.168.19.0/24 -d 192.168.20.0/24 -j ACCEPT -A FORWARD -s 192.168.19.0/24 -d 192.168.21.0/24 -j ACCEPT -A FORWARD -s 192.168.20.0/24 -d 192.168.19.0/24 -j ACCEPT -A FORWARD -s 192.168.20.0/24 -d 192.168.21.0/24 -j ACCEPT -A FORWARD -s 192.168.21.0/24 -d 192.168.19.0/24 -j ACCEPT -A FORWARD -s 192.168.21.0/24 -d 192.168.20.0/24 -j ACCEPT -A FORWARD -j REJECT --reject-with icmp-host-prohibited # Controls IP packet forwarding net.ipv4.ip_forward=1 service iptables restart sysctl -p == GREパケットの受信とLANネットワーク間の転送を許可 CentOS 7の場合 == # Controls IP packet forwarding net.ipv4.ip_forward=1 sysctl -p firewall-cmd --add-service=gre --permanent firewall-cmd --reload == GREトンネルの作成 == ip tun add tun_b mode gre local 172.31.0.19 remote 172.31.0.20 ip tun add tun_c mode gre local 172.31.0.19 remote 172.31.0.21 ip link set dev tun_b up ip link set dev tun_c up ip addr add local 192.168.19.1 remote 192.168.20.1/24 dev tun_b ip addr add local 192.168.19.1 remote 192.168.21.1/24 dev tun_c === 設定例3: サーバB === == GREパケットの受信とLANネットワーク間の転送を許可 == サーバAと同じ設定をいれる。 == GREトンネルの作成 == ip tun add tun_a mode gre local 172.31.0.20 remote 172.31.0.19 ip tun add tun_c mode gre local 172.31.0.20 remote 172.31.0.21 ip link set dev tun_a up ip link set dev tun_c up ip addr add local 192.168.20.1 remote 192.168.19.1/24 dev tun_a ip addr add local 192.168.20.1 remote 192.168.21.1/24 dev tun_c === 設定例3: サーバC === == GREパケットの受信とLANネットワーク間の転送を許可 == サーバAと同じ設定をいれる。 == GREトンネルの作成 == ip tun add tun_a mode gre local 172.31.0.21 remote 172.31.0.19 ip tun add tun_b mode gre local 172.31.0.21 remote 172.31.0.20 ip link set dev tun_a up ip link set dev tun_b up ip addr add local 192.168.21.1 remote 192.168.19.1/24 dev tun_a ip addr add local 192.168.21.1 remote 192.168.20.1/24 dev tun_b === 設定例3: サーバAの状態 === # ip tun show tun_b tun_b: gre/ip remote 172.31.0.20 local 172.31.0.19 ttl inherit # ip tun show tun_c tun_c: gre/ip remote 172.31.0.21 local 172.31.0.19 ttl inherit # ip addr show tun_b 6: tun_b@NONE: mtu 1476 qdisc noqueue state UNKNOWN link/gre 172.31.0.19 peer 172.31.0.20 inet 192.168.19.1 peer 192.168.20.1/24 scope global tun_b # ip addr show tun_c 7: tun_c@NONE: mtu 1476 qdisc noqueue state UNKNOWN link/gre 172.31.0.19 peer 172.31.0.21 inet 192.168.19.1 peer 192.168.21.1/24 scope global tun_c # ip route 192.168.21.0/24 dev tun_c proto kernel scope link src 192.168.19.1 192.168.20.0/24 dev tun_b proto kernel scope link src 192.168.19.1 192.168.19.0/24 dev eth1 proto kernel scope link src 192.168.19.1 172.31.0.0/24 dev eth0 proto kernel scope link src 172.31.0.19 # sysctl net.ipv4.ip_forward net.ipv4.ip_forward = 1 # iptables -S INPUT | grep gre -A INPUT -p gre -j ACCEPT # iptables -S FORWARD -P FORWARD ACCEPT -A FORWARD -s 192.168.19.0/24 -d 192.168.20.0/24 -j ACCEPT -A FORWARD -s 192.168.19.0/24 -d 192.168.21.0/24 -j ACCEPT -A FORWARD -s 192.168.20.0/24 -d 192.168.19.0/24 -j ACCEPT -A FORWARD -s 192.168.20.0/24 -d 192.168.21.0/24 -j ACCEPT -A FORWARD -s 192.168.21.0/24 -d 192.168.19.0/24 -j ACCEPT -A FORWARD -s 192.168.21.0/24 -d 192.168.20.0/24 -j ACCEPT -A FORWARD -j REJECT --reject-with icmp-host-prohibited ===== 設定例4 ===== 設定例3と同じネットワーク構成。 違いはトンネルデバイスにIPアドレスとルーティングを個別に設定していること。 === 設定例4: サーバA === == GREパケットの受信とLANネットワーク間の転送を許可 == 設定例3と同様。 == GREトンネルの作成 == ip tun add tun_b mode gre local 172.31.0.19 remote 172.31.0.20 ip tun add tun_c mode gre local 172.31.0.19 remote 172.31.0.21 ip link set dev tun_b up ip link set dev tun_c up ip addr add 192.168.19.1 dev tun_b ip addr add 192.168.19.1 dev tun_c ip route add 192.168.20.0/24 dev tun_b ip route add 192.168.21.0/24 dev tun_c === 設定例4: サーバB === == GREパケットの受信とLANネットワーク間の転送を許可 == サーバAと同じ設定をいれる。 == GREトンネルの作成 == ip tun add tun_a mode gre local 172.31.0.20 remote 172.31.0.19 ip tun add tun_c mode gre local 172.31.0.20 remote 172.31.0.21 ip link set dev tun_a up ip link set dev tun_c up ip addr add 192.168.20.1 dev tun_a ip addr add 192.168.20.1 dev tun_c ip route add 192.168.19.0/24 dev tun_a ip route add 192.168.21.0/24 dev tun_c === 設定例4: サーバC === == GREパケットの受信とLANネットワーク間の転送を許可 == サーバAと同じ設定をいれる。 == GREトンネルの作成 == ip tun add tun_a mode gre local 172.31.0.21 remote 172.31.0.19 ip tun add tun_b mode gre local 172.31.0.21 remote 172.31.0.20 ip link set dev tun_a up ip link set dev tun_b up ip addr add 192.168.21.1 dev tun_a ip addr add 192.168.21.1 dev tun_b ip route add 192.168.19.1/24 dev tun_a ip route add 192.168.20.1/24 dev tun_b === 設定例4: サーバAの状態 === # ip tun show tun_b tun_b: gre/ip remote 172.31.0.20 local 172.31.0.19 ttl inherit # ip tun show tun_c tun_c: gre/ip remote 172.31.0.21 local 172.31.0.19 ttl inherit # ip addr show tun_b 6: tun_b@NONE: mtu 1476 qdisc noqueue state UNKNOWN link/gre 172.31.0.19 peer 172.31.0.20 inet 192.168.19.1/32 scope global tun_b # ip addr show tun_c 7: tun_c@NONE: mtu 1476 qdisc noqueue state UNKNOWN link/gre 172.31.0.19 peer 172.31.0.21 inet 192.168.19.1/32 scope global tun_c # ip route 192.168.21.0/24 dev tun_c scope link 192.168.20.0/24 dev tun_b scope link 192.168.19.0/24 dev eth1 proto kernel scope link src 192.168.19.1 172.31.0.0/24 dev eth0 proto kernel scope link src 172.31.0.19 # sysctl net.ipv4.ip_forward net.ipv4.ip_forward = 1 # iptables -S INPUT | grep gre -A INPUT -p gre -j ACCEPT # iptables -S FORWARD -P FORWARD ACCEPT -A FORWARD -s 192.168.19.0/24 -d 192.168.20.0/24 -j ACCEPT -A FORWARD -s 192.168.19.0/24 -d 192.168.21.0/24 -j ACCEPT -A FORWARD -s 192.168.20.0/24 -d 192.168.19.0/24 -j ACCEPT -A FORWARD -s 192.168.20.0/24 -d 192.168.21.0/24 -j ACCEPT -A FORWARD -s 192.168.21.0/24 -d 192.168.19.0/24 -j ACCEPT -A FORWARD -s 192.168.21.0/24 -d 192.168.20.0/24 -j ACCEPT -A FORWARD -j REJECT --reject-with icmp-host-prohibited ===== ファイアウォールの設定 ===== === CentOS 6の場合 === iptable -I INPUT -p gre -j ACCEPT ip6table -I INPUT -p gre -j ACCEPT === CentOS 7の場合 その1 === firewalldにgreサービスが登録されているチェックする。 firewall-cmd --info-service=gre コマンドがエラーにならなければ、greサービスが登録されているので、 ファイアウォールの設定はサービスを追加するだけ。 sudo firewall-cmd --add-service=gre 動作を確認した後に ''firewall-cmd --runtime-to-permanent'' で設定を永続化する。 または最初から ''--permanent'' を付けて設定し、''firewall-cmd --reload''で再読み込みする。 === CentOS 7の場合 その2 === CentOS 7のバージョンによっては、firewalldにgreのサービスがない。 ''firewall-cmd --info-service=gre'' がエラーになる場合は、 ''--direct'' を使用して直接iptablesにルールを追加する必要がある。 sudo firewall-cmd --direct --add-rule ipv4 filter INPUT 0 -p gre -j ACCEPT sudo firewall-cmd --direct --add-rule ipv6 filter INPUT 0 -p gre -j ACCEPT 注意点: ''--add-rich-rule'' は使わない事。 rich-ruleで追加するとiptablesには以下のルールが追加される。 -A IN_public_allow -p gre -m conntrack --ctstate NEW -j ACCEPT このルール自体は ''--add-service=gre'' が追加するルールと同じだが、 serviceの方はヘルパーモジュールも一緒にロードしている。 ヘルパーモジュールが無いと上記のルールは正しく動作しない。 ++++ conntrackの確認方法 | nf-ct-list または yum install conntrack-tools conntrack -L -p gre ++++