10 月 23 - 25 日,QCon 上海站即将召开,现在购票,享9折优惠 了解详情
写点什么

VPC 中 NAT 的那点事

  • 2019-11-20
  • 本文字数:3485 字

    阅读完需:约 11 分钟

VPC中NAT的那点事
### NAT就在那里


下图 是EC2实例通过IGW(Internet网关) 接入到Internet的示意图。熟悉AWS的读者会知道,这里EC2实例和Internet通信的两个方向上,实际上发生了如下的转换:
* 从EC2实例发出的前往Internet的IP包,其源地址10.0.0.10在经过IGW时,会被转换为与实例关联的公网地址 54.232.0.1;* 从Internet发给54.232.0.1的IP包,经过IGW时其目的地址会转换为ENI对应的内网地址10.0.0.10并被送到 EC2实例;
可以看到,这里Internet网关就是起到实例的内网地址和公网地址一对一的基本 NAT(网络地址转换)的功能。
![](https://s3.cn-north-1.amazonaws.com.cn/images-bjs/1017-01.png)
相比于没有NAT的场景,大部分的应用、软件不需要任何改变就能在基本NAT的场景下继续工作,例如基于HTTP协议的Web应用等;但是对于某些应用,例如FTP、VoIP等,网络地址转换会给应用带来一些意想不到的挑战。今天我们以历史悠久的FTP协议为例,来和大家探讨一下NAT给FTP这样的应用带来什么样的挑战,以及FTP应用和协议又是如何演进去适应它。
### 被动模式下的FTP
我们重温一下FTP的工作过程。客户端连接服务端TCP 21端口建立命令通道后,输入用户名密码完成登录;随后的每一次数据传输都需要另外建立数据通道进行; 如果数据通道由客户端发起,服务端接受,我们称之为被动模式;反之,如果数据通道由服务端发起,客户端接受,则称之为主动模式。
为简化讨论,我们以被动模式为例。
**同一个私网内**
我们在EC2实例10.0.0.10上搭建了一台FTP服务器,它监听在21端口。现在我们从同一个VPC里的另外一台EC2上运行FTP客户端;那么整个过程会很顺利。 ![](https://s3.cn-north-1.amazonaws.com.cn/images-bjs/1017-2.PNG)
**从Internet访问**
现在我们从位于Internet某处的一台PC上运行FTP客户端。 ![](https://s3.cn-north-1.amazonaws.com.cn/images-bjs/1017-3.PNG)
这里连接超时的原因显而易见,FTP服务端发送给客户端的IP地址是服务端的私有地址。位于Internet上的客户端无法建立与位于VPC内部的私有地址10.0.0.10直接通讯。
解决这个问题有多种方法,我们由简单到复杂分别叙述。
### 增强协议适配NAT
FTP协议针对NAT和其他因素,对协议进行了增强,提供了增强版的被动模式EPSV命令[1]。
下面的例子里,服务端不再显式指定IP地址,只提供数据通道的端口号。客户端默认与控制通道相同的IP地址建立数据通道。
![](https://s3.cn-north-1.amazonaws.com.cn/images-bjs/1017-4.PNG)
可以看到,解决方案很优雅。实际上如果你在阅读本文的时候,绝大部分FTP服务端和客户端都已经实现了EPSV,而且优先使用它,所以FTP应用目前在EC2上是可以称之为开箱即用的。当然这需要客户端和服务端都支持增强的协议才能达成;如果我们不修改协议,能否解决这个问题呢。
### 放开那协议!我来!
有些时候,修改协议和实现需要多方协调和很长的时间才能完成。在RFC2428标准化之前,一些FTP实现就已经通过修改实现来适配基本NAT,而非修改协议。
以vsftpd为例,它允许通过配置文件vsftpd.conf中的配置项 pasv_address=54.232.0.1 告知服务端,在PASV被动模式下,应当指示客户端连接到配置项指定的IP(而不是服务端的私有IP)来适配基本NAT。
其他的一些常见应用例如VoIP类应用,也有类似的机制去适配基本NAT;例如引入STUN/TURN/ICE等方式[2]适配各种更加复杂的NAT穿越场景;但是针对部署在EC2上的基本NAT环境,也有通过实现上的简单调整,例如开源VoIP应用Asterisk就支持通过在配置文件/etc/asterisk/sip.conf里指定本机的公网地址和本地网段的方式来适配基本NAT。
nat=yes
externaddr=54.223.0.1
localnet=10.0.0.0/16
### 协议和实现我都不想动!
作为一枚任性的读者,如果您既不想动协议也不想动实现,这里笔者给读者介绍一种剑走偏锋的方式,读者若有兴趣,可以轻松愉快的在AWS上试一试,看看能否解决你的应用适配基本NAT。下面是一段shell脚本,当然是运行在Linux操作系统上的。
_\#从EC2 实例元数据服务获取本实例的公网IP(如有)、私网IP_
_public_ipv4=`curl -s http://169.254.169.254/latest/meta-data/public-ipv4`_
_local_ipv4=`curl -s http://169.254.169.254/latest/meta-data/local-ipv4`_
_\#配置私网地址段,这里应为EC2实例所在VPC的地址范围_
_local_net=10.0.0.0/16_
_if [ “x${public_ipv4}” == “x” ]_
_then_
_echo “No public IPv4 address available for this instance, abort.”_
_exit 1_
_else_
_\#如果EC2实例的公网IP不为空,则将该公网地址添加到eth0上_
_ip address add ${public_ipv4}/32 dev eth0_
_\#本地接受的连接,如果来源不是本VPC,那么将IP包的目的地址改写为公网IP_
_iptables -t nat -A PREROUTING ! -s ${local_net} -d ${local_ipv4} -i eth0 -j DNAT –to ${public_ipv4}_
_\#本地发起的连接,如果出方向流量的源IP地址是公网地址,那么需要改写为私网IP_
_iptables -t nat -A POSTROUTING -s ${public_ipv4} -o eth0 -j SNAT –to ${local_ipv4}_
_fi_
正常情况下,脚本执行完毕后,可以通过如下方式验证效果。
### 首先检查本实例的公网IP是否已经正确配置到eth0上。
~ # ip addr show dev eth0
eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc pfifo_fast state UP group default qlen 1000
link/ether 02:c7:6b:9b:d2:b6 brd ff:ff:ff:ff:ff:ff
inet 10.0.0.10/24 brd 10.0.0.255 scope global eth0
valid_lft forever preferred_lft forever
inet 54.232.0.1/32 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::c7:6bff:fe9b:d2b6/64 scope link
valid_lft forever preferred_lft forever
可以看到,公有IP地址(54.232.0.1/32)已经成功添加到eth0接口。
### 然后检查iptables的NAT规则是否正确配置
~ # iptables -t nat -nvL


Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 DNAT all — eth0 * ! 10.0.0.0/16 10.0.0.10 to:54.223.74.106
Chain INPUT (policy ACCEPT 1 packets, 64 bytes)
pkts bytes target prot opt in out source destination


Chain OUTPUT (policy ACCEPT 3 packets, 222 bytes)
pkts bytes target prot opt in out source destination


Chain POSTROUTING (policy ACCEPT 3 packets, 222 bytes)
pkts bytes target prot opt in out source destination
0 0 SNAT all — * eth0 54.223.74.106 0.0.0.0/0 to:10.0.0.1
从上面可以看到传入、传出数据包的数量以及IP地址在传入前,传出后的地址改写情况。
### 最后分别从VPC内部和Internet连接到服务,验证结果
~ $ ss -nt
State Recv-Q Send-Q Local Address:Port Peer Address:Port
ESTAB 0 72 54.223.74.106:21 119.xx.x.xx:52425
ESTAB 0 1272 54.223.74.106:12081 119.xx.x.xx:23710
ESTAB 0 72 10.0.0.10:21 10.xx.x.xx:48361
ESTAB 0 1272 10.0.0.10:12090 10.xx.x.xx:32115
笔者在没有修改任何vsftpd的配置文件的前提下,通过上述脚本的运行和配置,同一个VPC内部的客户端和Internet客户端都能完成FTP被动模式的文件传输全流程。
值得一提的是,本方法仅供参考,不建议在生产环境中大规模使用,推荐的解决方案请参考前文关于协议适配和实现适配。
[1] FTP Extensions for IPv6 and NATs https://tools.ietf.org/html/rfc2428 [2] NAT Traversal Practices for Client-Server https://tools.ietf.org/html/rfc6314 **作者介绍:**
![](https://s3.cn-north-1.amazonaws.com.cn/images-bjs/Ding+Chandler.jpg)
丁成银
AWS 解决方案架构师,获得AWS解决方案架构师专业级认证和DevOps工程师专业级认证。负责基于AWS的云计算方案架构的咨询和设计,同时致力于AWS云 服务在国内的应用和推广,在数字媒体、电信、互联网和游戏、企业混合IT等方面有着丰富的实践和设计经验。在加入AWS之前,历任数字媒体娱乐系统工程 师、宽带业务架构师、云解决方案架构师,负责数字媒体娱乐系统、云计算解决方案等服务的咨询和架构设计工作。
复制代码


TAGS:


Amazon VPC


,


大咖专栏


,


网络和内容发布


2019-11-20 08:00866

评论

发布
暂无评论
发现更多内容

保姆级SpringBoot+Vue图片上传到阿里云OSS教程

沉默王二

Spring Boot

如何理解基础服务和通用服务

Im胡子

基础服务 通用服务 基础服务边界

信通院推出数字化赋能者新标准天翼云获评数字化转型赋能服务集体

天翼云开发者社区

2022年最热门的招聘技术技能是什么,您绝对想不到

禅道项目管理

项目管理 开发技能

两会“数字经济”高频出位,博睿数据为企业数字转型提供有力引擎

博睿数据

天翼云成为首个加入openGauss社区的运营商云

天翼云开发者社区

Docker Build时的安全问题

火线安全

Docker 云原生 云安全 docker build

以太坊的扩容革命:ETH2.0

不登山的小鲁

以太坊 扩容 Ethereum eth eth2.0

融云互联网通信安全揭秘之链路安全

融云 RongCloud

网络安全

电路模型和电路定律 (Ⅲ)

謓泽

3月月更

限量独家!濒危动物数字藏品免费发放!

百度开发者中心

一文来了解关于分布式锁的那些事儿

Linux服务器开发

redis 分布式 分布式锁 Linux服务器开发 Linux后台开发

VuePress 博客之 SEO 优化(六)站长工具

冴羽

Vue 前端 vuepress SEO 博客搭建

DevOps落地思考

火线安全

DevOps 云原生 云安全 DevOps认证

跑马灯带你深入浅出TextView的源码世界

vivo互联网技术

android 源码分析 TextView

百度希壤元宇宙平台上线首个汽车数字展厅,领克探索汽车营销新方式

百度开发者中心

Gartner发布中国IaaS PaaS市场服务报告,天翼云强势入选

天翼云开发者社区

中台和多云管理是伪问题?运维要集体下岗了吗?

火线安全

DevOps 云原生 云安全

雄安新区设立四周年,看天翼云以数字底座托起未来之城

天翼云开发者社区

Rust 用于移动开发的几种方式

非凸科技

Java c++ Python rust 量化

QoS 设计:车联网平台消息传输质量保障|车联网平台搭建从入门到精通 04

EMQ映云科技

物联网 IoT mqtt coap emq

译文《Java并发编程之volatile》

潘大壮

并发编程 volatile 后端 Java EE

多场景推进 服务网格在联通的落地实践(下)

百度开发者中心

开学季 | 飞桨AI Studio课程学习,小白也可以成为一名优秀的算法工程师!

百度开发者中心

内存之旅——如何提升CMA利用率?

OpenHarmony开发者

内存 OpenHarmony

阿里巴巴云原生大数据运维平台 SREWorks 正式开源

阿里云大数据AI技术

大数据 自动化运维 大规模网络运维

公有云市场百舸争流!天翼云稳居第一梯队,进入领导者象限

天翼云开发者社区

融云直播 SDK 升级,让直播「PK」起来

融云 RongCloud

直播 IM 场景化

长连接网关技术专题(七):小米小爱单机120万长连接接入层的架构演进

JackJiang

网络编程 websocket 即时通讯 网关 长连接

春分耕种时,AI“现身”田间地头

百度开发者中心

企业在线产品宣传册应该如何设计?

小炮

产品宣传手册

VPC中NAT的那点事_其他_亚马逊云科技 (Amazon Web Services)_InfoQ精选文章