IP隧道技术之ipip

IP隧道技术

简介

IP 隧道(IP tunneling):是将一个IP报文封装在另一个IP报文的技术,这可以使得目标为一个IP地址的数据报文能被封装和转发到另一个IP地址。IP隧道技术亦称为IP封装技术(IP encapsulation)。IP隧道主要用于移动主机和虚拟私有网络(Virtual Private Network),在其中隧道都是静态建立的,隧道一端有一个IP地址,另一端也有唯一的IP地址。

Linux系统内核实现的IP隧道技术主要有三种(PPP、PPTP和L2TP等协议或软件不是基于内核模块的):IPIP (IPv4 in IPv4),GRE (IPv4/IPv6 over IPv4) ,SIT (IPv6 over IPv4) 。这三种隧道技术都需要内核模块 tunnel4.ko 的支持。

  • IPIP :需要内核模块ipip.ko,是最简单的一种。它具有最低的开销,但是只能封装IPv4单播流量,因此您将无法设置OSPF,RIP或任何其他基于多播的协议,只能为唯一的隧道端点对设置一个隧道
  • GRE : 需要内核模块ip_gre.ko ,GRE隧道可以封装IPv4 / IPv6单播/多播流量,因此它是动态路由网络的事实上的隧道标准。可以为唯一的隧道端点对最多设置64K隧道
  • SIT :代表"Simple Internet Transition",需要内核模块sit.ko。其主要目的是互连位于全球IPv4 Internet中的隔离的IPv6网络。SIT的工作方式类似于IPIP。内核模块是ipv6,加载后,无法卸载ipv6模块。您可以从隧道代理获取自己的IPv6前缀和SIT隧道 。

内核模块

隧道 内核模块 虚拟网卡
IPIP ipip.ko tunl0
GRE ip_gre.ko gre0
SIT sit.ko sit0

ip tunnel

shell 复制代码
$ ip tunnel help
Usage: ip tunnel { add | change | del | show | prl | 6rd } [ NAME ]
	 [ mode { ipip | gre | sit | isatap | vti } ] [ remote ADDR ] [ local ADDR ]
	 [ [i|o]seq ] [ [i|o]key KEY ] [ [i|o]csum ]
	 [ prl-default ADDR ] [ prl-nodefault ADDR ] [ prl-delete ADDR ]
	 [ 6rd-prefix ADDR ] [ 6rd-relay_prefix ADDR ] [ 6rd-reset ]
	 [ ttl TTL ] [ tos TOS ] [ [no]pmtudisc ] [ dev PHYS_DEV ]

Where:	NAME := STRING
	ADDR := { IP_ADDRESS | any }
	TOS  := { STRING | 00..ff | inherit | inherit/STRING | inherit/00..ff }
	TTL  := { 1..255 | inherit }
	KEY  := { DOTTED_QUAD | NUMBER }

# mode 代表不同的 IPIP 隧道类型

ipip

one to one

A 节点

shell 复制代码
# ip link add name mybr0 type bridge
# ip addr add 10.42.1.1/24 dev mybr0
# ip link set dev mybr0 up

B 节点

shell 复制代码
# ip link add name mybr0 type bridge
# ip addr add 10.42.2.1/24 dev mybr0
# ip link set dev mybr0 up

现在 A 节点的10.42.1.1/24是不通 B 节点的 10.42.2.1/24

A 节点上添加隧道,指定了remote和local,为点对点的隧道

shell 复制代码
# modprobe ipip
# ip tunnel add tunl0 mode ipip remote 172.16.232.194 local 172.16.232.172
# ip addr add 10.42.1.1/24 dev tunl0
# ip link set tunl0 up

A 节点上添加10.42.2.0/24路由,执行点对点的tunl0
# ip route add 10.42.2.0/24 dev tunl0

B 节点上也添加隧道

shell 复制代码
# modprobe ipip
# ip tunnel add tunl0 mode ipip remote 172.16.232.172 local 172.16.232.194
# ip addr add 10.42.2.1/24 dev tunl0
# ip link set tunl0 up

B 节点上添加10.42.1.0/24路由,执行点对点的tunl0
# ip route add 10.42.1.0/24 dev tunl0

现在,A、B节点上的10.42.1.0/24、10.42.2.0/24 就实现了互通

one to many

实际上,在创建 IPIP 隧道的时候完全可以不指定 remote 地址,只要在 TUN 设备上增加对应的路由,IPIP 隧道就知道如何封装新的 IP 数据包并发送到路由指定的目标地址。

shell 复制代码
A: 172.16.165.33   10.42.1.0/24
B: 172.16.165.244  10.42.2.0/24
C: 172.16.168.113  10.42.3.0/24

A 节点上创建隧道,并把B、C的路由指向tunl0

shell 复制代码
# modprobe ipip
# ip tunnel add tunl0 mode ipip
# ip link set tunl0 up
# ip addr add 10.42.1.0/32 dev tunl0
# ip route add 10.42.2.0/24 via 172.16.165.244 dev tunl0 onlink
# ip route add 10.42.3.0/24 via 172.16.168.113 dev tunl0 onlink

B 节点、 C节点同理

shell 复制代码
B 节点
# modprobe ipip
# ip tunnel add tunl0 mode ipip
# ip link set tunl0 up
# ip addr add 10.42.2.0/32 dev tunl0
# ip route add 10.42.1.0/24 via 172.16.165.33 dev tunl0 onlink
# ip route add 10.42.3.0/24 via 172.16.168.113 dev tunl0 onlink
C 节点
# modprobe ipip
# ip tunnel add tunl0 mode ipip
# ip link set tunl0 up
# ip addr add 10.42.3.0/32 dev tunl0
# ip route add 10.42.1.0/24 via 172.16.165.33 dev tunl0 onlink
# ip route add 10.42.2.0/24 via 172.16.165.244 dev tunl0 onlink

现在,A、B、C节点上的10.42.1.0/24、10.42.2.0/24、10.42.3.0/24 就实现了互通

使用ipip实现三层软网关

客户端

bash 复制代码
# 加载ipip模块,实现基于三层的软网关
$ sudo /usr/sbin/modprobe ipip
# 添加default路由,并测试到114的联通性
$ sudo ip link set tunl0 up
$ sudp ip r add default via $gw dev tunl0 onlink

# /etc/network/interfaces固化tunl0的软网关配置
$ vi /etc/network/interfaces
auto bond0
  ......
  post-up ip link set tunl0 up
  post-up ip r add default via 10.122.43.252 dev tunl0 onlink

服务端

bash 复制代码
$ echo 1 > /proc/sys/net/ipv4/ip_forward
$ sudo vi /etc/network/interfaces # 启动tunl口
auto tunl0
iface tunl0 inet manual
  up ip link set tunl0 up
down ip link set tunl0 down
$ sudo ifup tunl0
$ cat /etc/shorewall/masq # nat的地址
bond1.564 10.122.40.0/22
bond1.564 10.239.81.0/26
bond1.564 10.239.83.64/26
bond1.564 10.239.83.128/26
bond1.564 10.239.83.192/26

$ sudo iptables -L -n -t nat
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination

Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination
bond1.564_masq  all  --  0.0.0.0/0            0.0.0.0/0

Chain bond1.564_masq (1 references)
target     prot opt source               destination
MASQUERADE  all  --  10.122.40.0/22       0.0.0.0/0
MASQUERADE  all  --  10.239.81.0/26       0.0.0.0/0
MASQUERADE  all  --  10.239.83.64/26      0.0.0.0/0
MASQUERADE  all  --  10.239.83.128/26     0.0.0.0/0 # snat的ip段
MASQUERADE  all  --  10.239.83.192/26     0.0.0.0/0

如果做了2层snat,例如装机、容器里,将源ip不是本机的转换为本机ip

bash 复制代码
iptables -t nat -A POSTROUTING ! -s `hostname -I` -o tunl0 -j SNAT --to `hostname -I`

异常可以通过抓包分析

bash 复制代码
sudo tcpdump -eni any net $需要nat的地址
相关推荐
腾昵猫34 分钟前
Linux从网卡接收到内核软中断处理整体流程
linux·运维·windows
ImangoCloud37 分钟前
Git的windows开发与linux开发配置
linux·windows·git
带鱼工作室44 分钟前
conda更换清华源
linux·运维·conda
鹏大师运维1 小时前
中科方德鸳鸯火锅平台使用教程:轻松运行Windows应用!
linux·windows·国产操作系统·统信uos·中科方德·麒麟2503·鸳鸯火锅
shylyly_2 小时前
Linux环境基础开发工具->vim
linux·运维·编辑器·vim·centos 7·vim配置·底行模式
Johny_Zhao3 小时前
centos8安装部署RADIUS+MySQLPGSQL高可用架构实现
linux·网络·网络安全·信息安全·云计算·shell·cisco·yum源·radius·huawei·系统运维·华三
DisonTangor3 小时前
微软的 Windows Linux 子系统现已开源
linux·运维·microsoft·开源
渡梦酒3 小时前
Linux查 ssh端口号和服务状态
linux·运维·ssh
2302_799525743 小时前
【Linux】第二十五章 运行容器
linux·运维·服务器
fengchengwu20124 小时前
mongodb部署Shard Cluster
linux·mongodb·分片集群·shard cluster