ipコマンドでGREトンネルを作成する
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
WAN側IP172.31.0.19
と172.31.0.20
を終端としてGREトンネルを作成。
LAN側IPの192.168.19.1
と192.168.20.1
が疎通するようにする。
設定例1: サーバA
GREパケットの受信を許可 CentOS 6の場合
- /etc/sysconfig/iptables
-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: <POINTOTPOINT,NOARP,UP,LOWER_UP> 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
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の場合
- /etc/sysctl.conf
# Controls IP packet forwarding net.ipv4.ip_forward=1
- /etc/sysconfig/iptables
-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の場合
- /etc/sysctl.conf
# 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: <POINTOTPOINT,NOARP,UP,LOWER_UP> 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
拠点3つをGREトンネルのメッシュでつなぐ。LAN側ネットワークは相互に通信可能。
トンネルデバイスに設定するIPアドレスは、複数のトンネルデバイスで同じIPアドレスを使用できる。
また、物理ネットワークインタフェースのIPアドレスも使用できる。
この構成ではeth1
と2つのトンネルデバイス全てに同じIPアドレスを設定している。
設定例3: サーバA
GREパケットの受信とLANネットワーク間の転送を許可 CentOS 6の場合
- /etc/sysconfig/iptables
-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
- /etc/sysctl.conf
# Controls IP packet forwarding net.ipv4.ip_forward=1
service iptables restart
sysctl -p
GREパケットの受信とLANネットワーク間の転送を許可 CentOS 7の場合
- /etc/sysctl.conf
# 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: <POINTOTPOINT,NOARP,UP,LOWER_UP> 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: <POINTOTPOINT,NOARP,UP,LOWER_UP> 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: <POINTOTPOINT,NOARP,UP,LOWER_UP> 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: <POINTOTPOINT,NOARP,UP,LOWER_UP> 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の方はヘルパーモジュールも一緒にロードしている。
ヘルパーモジュールが無いと上記のルールは正しく動作しない。