项目概述
本项目深入探究Linux网络虚拟化核心技术,通过Network Namespace实现网络隔离,结合veth pair和bridge构建虚拟网络拓扑,使用iptables实现精细化流量控制。项目涵盖namespace创建、跨namespace通信、NAT配置、防火墙规则等核心技能,为容器网络(Docker/Kubernetes)和云原生技术奠定坚实基础。
核心目标:
- 掌握Network Namespace的创建与管理
- 理解veth pair和bridge的工作原理与配置
- 熟练使用iptables进行流量过滤与NAT转换
- 能够构建多namespace通信网络
- 理解容器网络底层实现原理
环境信息
| 组件 | 版本 | 说明 |
|---|---|---|
| 操作系统 | CentOS 7 / Ubuntu 20.04 | 内核需支持namespace |
| 内核版本 | 3.10+ | 支持network namespace |
| 工具包 | iproute2 | ip命令工具 |
| 防火墙 | iptables v1.4+ | 流量控制 |
实验拓扑:
- 创建3个namespace:ns1、ns2、ns3
- 通过bridge(br0)实现namespace间二层通信
- 通过veth pair连接namespace与bridge
- 配置iptables实现NAT和流量过滤
实验一:Network Namespace基础操作
实验目的
掌握namespace的创建、查看、进入、删除等基本操作。
Namespace核心概念
Network Namespace:Linux内核提供的网络隔离机制,每个namespace拥有独立的:
- 网络接口(网卡)
- 路由表
- iptables规则
- socket资源
使用场景:
- Docker容器网络隔离
- 网络功能虚拟化(NFV)
- 多租户网络隔离
- 网络协议栈测试
配置步骤
1. 创建namespace
# 创建3个namespace
ip netns add ns1
ip netns add ns2
ip netns add ns3
# 验证创建结果
ip netns list
2. 查看namespace网络状态
# 查看ns1的网络接口
ip netns exec ns1 ip link show
# 查看ns1的路由表
ip netns exec ns1 ip route
# 查看ns1的iptables规则
ip netns exec ns1 iptables -L
3. 在namespace中执行命令
# 在ns1中启动lo接口
ip netns exec ns1 ip link set lo up
# 在ns1中查看接口状态
ip netns exec ns1 ip link show
常用命令速查
| 命令 | 功能 |
|---|---|
ip netns add <name> |
创建namespace |
ip netns del <name> |
删除namespace |
ip netns list |
列出所有namespace |
ip netns exec <name> <cmd> |
在namespace中执行命令 |
ip netns identify <pid> |
查看进程所属的namespace |
常见问题
| 问题 | 原因 | 解决方法 |
|---|---|---|
| namespace创建失败 | 内核不支持 | 升级内核到3.10+ |
| 命令执行无输出 | 接口未启动 | ip link set lo up |
| 权限不足 | 需要root权限 | 使用sudo执行 |
实验二:Veth Pair与Bridge配置
实验目的
掌握veth pair的创建与配置,理解bridge的工作原理,实现namespace间二层通信。
Veth Pair核心概念
Veth Pair:虚拟以太网设备对,成对出现,特点:
- 一端发送的数据包会从另一端接收
- 用于连接不同namespace
- 类似管道,双向通信
Bridge(网桥):
- 工作在数据链路层
- 连接多个网络接口
- 实现二层交换功能
配置步骤
1. 创建bridge
# 创建网桥br0
ip link add br0 type bridge
# 启动网桥
ip link set br0 up
# 查看网桥状态
ip link show br0
2. 创建veth pair连接namespace
# 创建veth pair:veth1-ns1(主机端)和veth1(ns1端)
ip link add veth1-ns1 type veth peer name veth1
# 将veth1移入ns1
ip link set veth1 netns ns1
# 配置ns1端的IP地址
ip netns exec ns1 ip addr add 192.168.100.10/24 dev veth1
ip netns exec ns1 ip link set veth1 up
# 将主机端veth1-ns1连接到br0
ip link set veth1-ns1 master br0
ip link set veth1-ns1 up
3. 为ns2和ns3创建连接
# ns2
ip link add veth2-ns2 type veth peer name veth2
ip link set veth2 netns ns2
ip netns exec ns2 ip addr add 192.168.100.20/24 dev veth2
ip netns exec ns2 ip link set veth2 up
ip link set veth2-ns2 master br0
ip link set veth2-ns2 up
# ns3
ip link add veth3-ns3 type veth peer name veth3
ip link set veth3 netns ns3
ip netns exec ns3 ip addr add 192.168.100.30/24 dev veth3
ip netns exec ns3 ip link set veth3 up
ip link set veth3-ns3 master br0
ip link set veth3-ns3 up
4. 为br0配置IP地址
# 配置br0的IP地址
ip addr add 192.168.100.1/24 dev br0
# 验证配置
ip addr show br0
验证方法
# 在ns1中ping ns2
ip netns exec ns1 ping 192.168.100.20
# 在ns1中ping ns3
ip netns exec ns1 ping 192.168.100.30
# 在ns1中ping br0
ip netns exec ns1 ping 192.168.100.1
常见问题
| 问题 | 原因 | 解决方法 |
|---|---|---|
| ping不通 | 接口未启动 | 检查ip link状态 |
| ping不通 | IP地址配置错误 | 检查ip addr配置 |
| ping不通 | veth未连接到bridge | 检查master配置 |
实验三:Namespace访问外网(NAT配置)
实验目的
配置NAT使namespace能够访问外部网络,理解SNAT和DNAT的工作原理。
配置步骤
1. 开启IP转发
# 临时开启
sysctl -w net.ipv4.ip_forward=1
# 永久开启
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
sysctl -p
2. 配置SNAT(源地址转换)
# 假设主机eth0为外网接口,IP为10.0.0.100
# 将ns1-ns3的源IP转换为eth0的IP
iptables -t nat -A POSTROUTING -s 192.168.100.0/24 -o eth0 -j MASQUERADE
# 说明:
# -t nat: 指定nat表
# -A POSTROUTING: 添加到POSTROUTING链
# -s 192.168.100.0/24: 源地址匹配
# -o eth0: 出接口匹配
# -j MASQUERADE: 动态源地址转换
3. 配置默认路由
# 在ns1中配置默认路由指向br0
ip netns exec ns1 ip route add default via 192.168.100.1
# ns2和ns3同样配置
ip netns exec ns2 ip route add default via 192.168.100.1
ip netns exec ns3 ip route add default via 192.168.100.1
4. 验证外网访问
# 在ns1中ping外网
ip netns exec ns1 ping 8.8.8.8
# 在ns1中curl测试
ip netns exec ns1 curl http://www.example.com
SNAT vs DNAT对比
| 类型 | 全称 | 作用 | 使用场景 |
|---|---|---|---|
| SNAT | Source NAT | 修改源IP地址 | 内网访问外网 |
| DNAT | Destination NAT | 修改目的IP地址 | 外网访问内网服务器 |
| MASQUERADE | 动态SNAT | 自动使用出接口IP | 动态IP场景(拨号) |
常见问题
| 问题 | 原因 | 解决方法 |
|---|---|---|
| 无法访问外网 | IP转发未开启 | sysctl -w net.ipv4.ip_forward=1 |
| 无法访问外网 | NAT规则错误 | 检查iptables规则 |
| 无法访问外网 | 默认路由缺失 | 添加default route |
实验四:iptables防火墙规则配置
实验目的
掌握iptables的基本使用,配置流量过滤规则实现网络安全控制。
iptables四表五链
四表:
| 表名 | 功能 |
|---|---|
| filter | 过滤数据包(默认表) |
| nat | 网络地址转换 |
| mangle | 修改数据包头部 |
| raw | 连接追踪处理 |
五链:
| 链名 | 作用点 |
|---|---|
| PREROUTING | 路由前处理 |
| INPUT | 本机接收处理 |
| FORWARD | 转发处理 |
| OUTPUT | 本机发出处理 |
| POSTROUTING | 路由后处理 |
配置步骤
1. 查看当前规则
# 查看filter表所有规则
iptables -L -n -v
# 查看nat表规则
iptables -t nat -L -n -v
# 查看特定链规则
iptables -L INPUT -n -v
2. 添加基本过滤规则
# 允许已建立连接的数据包
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# 允许本地回环
iptables -A INPUT -i lo -j ACCEPT
# 允许SSH访问(端口22)
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# 允许HTTP访问(端口80)
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
# 允许HTTPS访问(端口443)
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# 默认拒绝其他入站流量
iptables -A INPUT -j DROP
3. 在namespace中配置iptables
# 在ns1中配置防火墙规则
ip netns exec ns1 iptables -A INPUT -p tcp --dport 80 -j ACCEPT
ip netns exec ns1 iptables -A INPUT -j DROP
4. 删除规则
# 查看规则编号
iptables -L --line-numbers
# 删除指定编号的规则
iptables -D INPUT 2
# 清空所有规则
iptables -F
iptables -X
iptables -Z
常用匹配条件
| 条件 | 示例 | 说明 |
|---|---|---|
| -p | -p tcp |
协议匹配 |
| -s | -s 192.168.1.0/24 |
源地址匹配 |
| -d | -d 10.0.0.1 |
目的地址匹配 |
| --dport | --dport 80 |
目的端口匹配 |
| --sport | --sport 1024:65535 |
源端口范围匹配 |
| -i | -i eth0 |
入接口匹配 |
| -o | -o eth0 |
出接口匹配 |
常见问题
| 问题 | 原因 | 解决方法 |
|---|---|---|
| 规则不生效 | 规则顺序错误 | 将ACCEPT规则放在DROP之前 |
| 规则丢失 | 未保存规则 | 使用iptables-save保存 |
| 无法连接 | 规则过于严格 | 检查规则匹配条件 |
知识延伸与总结
考点关联
| 知识点 | 应用场景 |
|---|---|
| Network Namespace | Docker容器网络隔离 |
| Veth Pair | 容器与主机通信 |
| Bridge | 容器间二层通信 |
| iptables NAT | 容器访问外网 |
| iptables Filter | 容器网络安全 |
与Docker网络的关联
| Docker网络模式 | 实现原理 |
|---|---|
| bridge | 创建bridge,veth pair连接容器 |
| host | 容器共享主机network namespace |
| none | 容器只有lo接口 |
| container | 容器共享另一个容器的namespace |
易错点警示
- veth pair成对出现:创建时必须指定peer name
- bridge需要启动:创建后必须
ip link set br0 up - IP转发必须开启:否则NAT不生效
- iptables规则顺序:ACCEPT规则必须在DROP之前
- namespace隔离性:每个namespace有独立的iptables规则
记忆口诀
- namespace操作:"netns add创建,netns exec执行,netns list查看"
- veth pair:"veth成对出,一端给ns,一端给bridge"
- iptables:"四表五链要记牢,filter过滤nat转,ACCEPT接受DROP丢"
今日关键命令速查
Namespace命令
| 命令 | 功能场景 | 记忆口诀 |
|---|---|---|
ip netns add ns1 |
创建namespace | "netns add创建ns" |
ip netns exec ns1 ip a |
在ns中执行命令 | "exec执行,ip a看地址" |
ip netns list |
列出所有ns | "list列出来" |
ip netns del ns1 |
删除namespace | "del删除" |
Veth Pair命令
| 命令 | 功能场景 | 记忆口诀 |
|---|---|---|
ip link add veth0 type veth peer name veth1 |
创建veth pair | "add veth type veth,peer name配对名" |
ip link set veth1 netns ns1 |
移入namespace | "set netns移进去" |
ip link set veth0 master br0 |
连接到bridge | "master br0连网桥" |
Bridge命令
| 命令 | 功能场景 | 记忆口诀 |
|---|---|---|
ip link add br0 type bridge |
创建bridge | "add br0 type bridge" |
ip link set br0 up |
启动bridge | "set up启动它" |
ip addr add 192.168.1.1/24 dev br0 |
配置IP | "addr add配地址" |
iptables命令
| 命令 | 功能场景 | 记忆口诀 |
|---|---|---|
iptables -L -n -v |
查看规则 | "-L列表,-n数字,-v详细" |
iptables -A INPUT -p tcp --dport 80 -j ACCEPT |
允许HTTP | "-A添加,-p协议,--dport目的端口,-j动作" |
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -j MASQUERADE |
SNAT | "-t nat指定表,MASQUERADE动态转换" |
iptables -D INPUT 1 |
删除规则 | "-D删除,INPUT链,1编号" |
iptables -F |
清空规则 | "-F清空,慎用" |
学习感悟
通过本项目学习,我深入理解了Linux网络虚拟化的底层原理。最初接触Docker时,只知道docker run就能启动容器,现在明白了容器网络是如何通过namespace、veth pair、bridge这些底层技术实现的。
在配置veth pair时,我深刻体会到了"成对出现"的设计理念。一端在主机,一端在namespace,通过bridge连接,这种设计非常巧妙。iptables的学习让我认识到网络安全的重要性,每一条规则都可能影响整个网络的可达性。
最让我印象深刻的是NAT配置。通过MASQUERADE,内网的namespace可以访问外网,但外网无法直接访问内网,这种单向访问的控制正是网络安全的基础。
明日计划:继续学习Docker网络模式,将namespace知识与容器技术结合,理解overlay网络、macvlan等高级网络模式。
浙公网安备 33010602011771号