写点什么

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:00879

评论

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

在线上传图片二维码识别解析

入门小站

工具

HarmonyOS(鸿蒙)——单击事件的四种写法

李子捌

28天写作 21天挑战 鸿蒙系统 12月日更

linux动态链接的程序如何在其他系统上运行

SkyFire

动态链接 装载器

kali系统之复现漏洞分析与审计

网络安全学海

黑客 网络安全 安全 信息安全 渗透测试

[架构实战营] 模块三作业

Geek_0ed632

「架构实战营」

Linux 命令 less 全知全会

hedzr

Linux less

Dubbo 框架学习笔记十二

风翱

dubbo 12月日更

儿童教育有感-说话用词不当

wood

28天写作

Spring核心原理之 IoC容器中那些鲜为人知的细节(3)

Tom弹架构

Java spring 源码

webpack-dev-server启动后, localhost:8080返回index.html的原理

汪子熙

JavaScript 前端开发 webpack 28天写作 12月日更

Linux之which命令

入门小站

Linux

模块三-架构文档

撿破爛ぃ

「架构实战营」

100% 展示 MySQL 语句执行的神器-Optimizer Trace

程序员历小冰

MySQL 28天写作 12月日更

从渔夫和游客说到晒太阳的狗狗派

mtfelix

28天写作

Gin-Vue-Admin 使用gin+vue进行极速开发的全栈开发基础平台【gva第一节】

坚果

Go 28天写作 Vue 3 12月日更

注意:字符串substring方法在jkd6,7,8中的差异

CRMEB

模块四-reids存储方案

撿破爛ぃ

「架构实战营」

Netflix系统架构

俞凡

架构 微服务 netflix 大厂实践

Spark-概览

xujiangniao

荐书📚——《剑指Offer》专项突破版

宇宙之一粟

推荐书籍 12月日更

Kubernetes 集群部署 Metrics Server 获取集群 Metric 数据

zuozewei

Kubernetes 性能监控 12月日更

HarmonyOS(鸿蒙)——双击事件

李子捌

28天写作 21天挑战 鸿蒙开发 12月日更

数据管理典范!「山东城商行联盟数据库准实时数据采集系统」入选2021中国大数据应用样板案例

DataPipeline数见科技

大数据 数据同步 数据融合 数据迁移 数据管理

程序员做技术管理需要懂哪些方面?

Seven的代码实验室

程序员 技术管理

【Java 进阶训练营】 JVM 知识总结

wgl

git tips(qbit)

qbit

git #Github

《权力——为什么只为某些人拥有》读书笔记

圣迪

特质 权力 影响力

什么是 AQS 及源码分析

Ayue、

AQS

【安全漏洞】CVE-2021-42287&CVE-2021-42278 域内提权

H

网络安全 信息安全 漏洞

架构实战营模块三课后作业-外包学生管理系统架构文档

Jude

架构实战营

FFmpeg的一些使用实践

为自己带盐

ffmpeg 28天写作 12月日更

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