====== 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
++++