Linux Stateless无状态NAT-使用TC来配置

本文涉及的产品
公网NAT网关,每月750个小时 15CU
简介:
如果想在Linux上配置NAT,那么大家众所一言的就是使用iptables的NAT表来配置,iptables提供了灵活丰富的配置来配置SNAT和DNAT,然而我们知道iptables的NAT依赖了ip_conntrack,也就是说,凡是一个命中了NAT表规则的流就会有一条连接追踪生成,由于ip_conntrack追踪了所有的数据包,因此当有大量连接经过了本地设备时,ip_conntrack空间将被撑满,这个在接入区特别容易重现,在骨干网反而不容易重现,然而骨干网却又几乎不可能使用Linux。
        如果Linux支持无状态的NAT就好了,这样就不怕conntrack爆满了,也不会因为conntrack查找而深深影响效率。然而如此的无状态NAT也有自己的缺点,那就是你必须为返回流量显式配置NAT规则,这样配置规则就整整增加了一倍,毕竟是无状态的嘛,NAT工作在无状态的IP层,而IP层是单向的。iptables正是依赖了ip_conntrack才能自动的转换返回包的地址信息的,因为ip_conntrack根据五元素追踪了每一个IP流。
        幸运的是,Linux一直都实现了无状态的NAT,只是其很少被人了解罢了。在Linux 2.4内核上,使用iproute2可以实现无状态NAT,只是在2.6内核上其实现被取消了,这是因为Linux的路由模块是基于目的地址hash或者trie tree的,然而对于同一目的地址而言,其作为负载均衡或者其它目的的多个表项却是线性查找的,NAT的实现就是采用多个这样的表项来完成的,这样在大量NAT规则存在的情况下,就会增加查找时间而影响效率,因此自2.6.24开始,Linux使用TC来实现无状态的NAT,虽然这样的实现有点变态,然而却很好的借助了TC固有的高效的查询匹配方式。
        本文不准备详述Linux的TC机制,仅仅解析其配置NAT的方法。具体来讲,NAT分为SNAT和DNAT,如果应用在网络接口即网卡上而不是应用在协议栈的Netfilter链上的话,SNAT将绑定在egress方向,而DNAT将绑定在ingress方向。需要注意的是,由于基于TC的NAT是无状态的,因此当你配置了ingress的DNAT之后,必须在相反的egress方向显式配置SNAT,你的配置量因此将增加一倍。以下我们先来配置ingress上的DNAT规则,效果是将访问本机的一个网卡上的一个IP装换为该网卡上的另一个IP地址。
        IP地址规划:eth2上的两个IP:192.168.40.249/24  12.12.12.5/24
        和往常一样,首先建立一个规则队列,也就是qdisc:
tc qdisc add dev eth2 ingress handle ffff
然后建立一个filter:
tc filter add dev eth2 parent ffff: protocol ip prio 10 u32 match ip dst 192.168.40.249/32 action nat ingress 192.168.40.249/32 12.12.12.5
这儿不得不说一下这个filter,首先filter并不是对每一种qdisc都管用的,它只对特定的队列管用,比如HTB队列,而对某一些队列则没有作用,这个可以从man tc文档中得到具体详情。另外,我们这里仅仅基于IP地址进行了过滤,如果要涉及到协议以及其源或者目的端口进行过滤,那么请使用fmark,这个可以使用iptables的mangle表来完成,而该表是不依赖ip_conntrack的。最后,针对这个filter,唯一的解释那就是其action子语句,该子语句说的是在ingress方向上将匹配结果的目的地址从192.168.40.249修改为12.12.12.5。
        接下来我们来配置反方向的egress规则:首先建立一个qdisc:
tc qdisc add dev eth2 root handle 10: htb
然而配置一个和上面类似的filter:
tc filter add dev eth2 parent 10: protocol ip prio 10 u32 match ip src 12.12.12.5/32 action nat egress 12.12.12.5/32 192.168.40.249
该语句说的是,在egress方向上,将源地址从12.12.12.5装换为192.168.40.249这个地址。可以看出,该egress规则和上述的ingress规则是相反的。
        需要指出的是,使用TC配置的无状态NAT,它和iptables是完全不同的理念,它基于网卡接口以及其方向,而不是基于协议栈实现的N个HOOK点,因此使用TC配置的无状态NAT并没有本机发出包和Forward包之间的区别,一切都需要你自己在接口上显式的进行配置才可以。比如虽然在ingress上将目的地址配置成了12.12.12.5,TC并看不到这个地址到底是谁的,是本机的?还是其它网络的?TC并不知道,一切都由最终的路由来决定。反过来在配置egress的返回规则时,为何要在eth2这个设备上进行配置,这完全取决于你的路由,这是和iptables一致的,也就是说,SNAT必须在路由后完成,而DNAT则必须在路有前来完成。和iptables不同的是,TC配置的无状态NAT并没有区分OUTPUT和PREROUTING(这并不是一种模式,而是Linux协议栈的实现理念-一切都由callback来决定来决定的),而是统一于ingress和egress,这对于习惯于Cisco IOS或者VRP平台的家伙来讲,无疑更加习惯一些。
        测试一下上述配置的正确性十分简单,但是千万别用tcpdump来抓包确认,因为tcpdump基于pcap,而它只是抓取混杂模式下的“未DNAT转换前的目的IP地址以及已经SNAT之后的源IP地址”,想了解这一点,那就看看Linux的PACKET_ALL的实现,它在数据从网卡读出还未做任何处理则进入了pcap,而对于外发包则是在数据马上就进入网卡的时候才进入pcap。

        本文主要介绍了使用TC配置NAT的一般原理和步骤,如果习惯了这个配置,你可以就会抛弃一些被你抱怨已久的iptables nat方案了。



 本文转自 dog250 51CTO博客,原文链接:http://blog.51cto.com/dog250/1269008

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
相关文章
|
15天前
|
Ubuntu Unix Linux
Linux网络文件系统NFS:配置与管理指南
NFS 是 Linux 系统中常用的网络文件系统协议,通过配置和管理 NFS,可以实现跨网络的文件共享。本文详细介绍了 NFS 的安装、配置、管理和常见问题的解决方法,希望对您的工作有所帮助。通过正确配置和优化 NFS,可以显著提高文件共享的效率和安全性。
113 7
|
2月前
|
数据库连接 Linux Shell
Linux下ODBC与 南大通用GBase 8s数据库的无缝连接配置指南
本文详细介绍在Linux系统下配置GBase 8s数据库ODBC的过程,涵盖环境变量设置、ODBC配置文件编辑及连接测试等步骤。首先配置数据库环境变量如GBASEDBTDIR、PATH等,接着修改odbcinst.ini和odbc.ini文件,指定驱动路径、数据库名称等信息,最后通过catalog.c工具或isql命令验证ODBC连接是否成功。
|
2月前
|
缓存 资源调度 安全
深入探索Linux操作系统的心脏——内核配置与优化####
本文作为一篇技术性深度解析文章,旨在引领读者踏上一场揭秘Linux内核配置与优化的奇妙之旅。不同于传统的摘要概述,本文将以实战为导向,直接跳入核心内容,探讨如何通过精细调整内核参数来提升系统性能、增强安全性及实现资源高效利用。从基础概念到高级技巧,逐步揭示那些隐藏在命令行背后的强大功能,为系统管理员和高级用户打开一扇通往极致性能与定制化体验的大门。 --- ###
83 9
|
2月前
|
存储 安全 数据管理
如何在 Rocky Linux 8 上安装和配置 Elasticsearch
本文详细介绍了在 Rocky Linux 8 上安装和配置 Elasticsearch 的步骤,包括添加仓库、安装 Elasticsearch、配置文件修改、设置内存和文件描述符、启动和验证 Elasticsearch,以及常见问题的解决方法。通过这些步骤,你可以快速搭建起这个强大的分布式搜索和分析引擎。
71 5
|
3月前
|
Java Linux 网络安全
NIFI在Linux服务区上的部署配置过程是什么?
【10月更文挑战第21天】NIFI在Linux服务区上的部署配置过程是什么?
93 2
|
3月前
|
Ubuntu Linux 编译器
Linux/Ubuntu下使用VS Code配置C/C++项目环境调用OpenCV
通过以上步骤,您已经成功在Ubuntu系统下的VS Code中配置了C/C++项目环境,并能够调用OpenCV库进行开发。请确保每一步都按照您的系统实际情况进行适当调整。
783 3
|
3月前
|
网络协议 安全 网络安全
Cisco-网络端口地址转换NAPT配置
Cisco-网络端口地址转换NAPT配置
|
3月前
|
监控 安全 网络协议
快速配置Linux云服务器
【10月更文挑战第3天】快速配置Linux云服务器
|
4月前
|
Oracle Java 关系型数据库
Linux下JDK环境的配置及 bash: /usr/local/java/bin/java: cannot execute binary file: exec format error问题的解决
如果遇到"exec format error"问题,文章建议先检查Linux操作系统是32位还是64位,并确保安装了与系统匹配的JDK版本。如果系统是64位的,但出现了错误,可能是因为下载了错误的JDK版本。文章提供了一个链接,指向Oracle官网上的JDK 17 Linux版本下载页面,并附有截图说明。
Linux下JDK环境的配置及 bash: /usr/local/java/bin/java: cannot execute binary file: exec format error问题的解决
|
3月前
|
应用服务中间件 Linux Shell
Linux 配置 Nginx 服务的详细步骤,绝对干货
Linux 配置 Nginx 服务的详细步骤,绝对干货
116 0