articles:gre_with_ip_command

ipコマンドでGREトンネルを作成する

GREとはGeneric Routing Encapsulationの略で簡単なIPトンネルを構築できる。 他のVPNとは異なり認証や暗号化等のセキュリティ機能はない。

トンネル始端でIPヘッダの前にトンネル用のIPヘッダとGREヘッダを付加してトンネル終端へ転送。 トンネル終端では始端が付加したIPヘッダとGREヘッダを除去してからパケットを処理する。

通常は、トンネルの両端で送信用の設定をすると、その相手先からのGREパケットを受け付けるようになる。 言い換えると、片方向だけトンネルを設定して送信しても受信側で無視される。

GREトンネルのVPNを構築するには、二つの工程が必要。 一つ目は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 <トンネルデバイス名>

トンネルデバイスを削除すると、紐づいているルーティング等も全て削除される。

GREトンネル構成例1

WAN側IP172.31.0.19172.31.0.20を終端としてGREトンネルを作成。 LAN側IPの192.168.19.1192.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

GREトンネル構成例2

WAN側IPの172.31.0.19172.31.0.20を終端としてGREトンネルを作成。 LAN側ネットワークの192.168.19.0/24192.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

GREトンネル構成例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

設定例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の方はヘルパーモジュールも一緒にロードしている。 ヘルパーモジュールが無いと上記のルールは正しく動作しない。

conntrackの確認方法

  • 最終更新: 2023-04-06 01:07
  • by nabium