2014-02-10 128 views
2

是否有可能运行Flask来侦听IPv4和IPv6(即双IP堆栈)?虽然我查远就可以在IPv4中使用可执行:使用Flask应用程序中支持双重IPv4和IPv6

app.run(host='::', port=port, debug=True) 

app.run(host='0.0.0.0', port=port, debug=True) 

或IPv6,但我还没有找到在同一时间在两个运行的方式(它有可能让我的Flask应用程序的一个实例监听IPv4,而另一个实例监听IPv6,但都不能监听同一个端口)。

谢谢!

更新(附加信息):

Followingt桑德Steffann的意见,我也开始了我的应用程序中的IPv6听(谢谢!):

* Running on http://[::]:1028/ 
* Restarting with reloader 

然后用IPv6和IPv4的卷发测试:

分别
curl -g [::1]:1028/notify 
curl 127.0.0.1:1028/notify 

越来越:

::1 - - [10/Feb/2014 12:04:51] "GET /notify HTTP/1.1" 200 - 
::ffff:127.0.0.1 - - [10/Feb/2014 12:05:03] "GET /notify HTTP/1.1" 200 - 

我对第二行的解释是“有人”(操作系统? Flask依赖的底层网络库?)将IPv4请求转换为IPv6请求。不过,据我所知,是不一样的,在一个经典的双堆栈设置支持IPv4“原生地”,即我本来期望的东西临客这个(这是我所得到的,当我跑我的应用程序(Running on http://0.0.0.0:1028/

127.0.0.1 - - [10/Feb/2014 12:05:03] "GET /notify HTTP/1.1" 200 - 
+0

如果他们不能监听同一个端口,那么很可能IPv6实例也接受IPv4连接(即V6ONLY关闭)。你能测试这个吗? –

+0

谢谢@SanderSteffann!我已经完成了这个测试,并因此更新了问题的主体。 – fgalan

+0

我在下面添加了一个答案。它回答你的问题吗? –

回答

4

操作系统会自动将传入的IPv4请求附加到侦听的IPv6套接字上,IPv4地址为mapped,前缀为::ffff:,因此来自127.0.0.1的传入IPv4连接看起来像来自IPv6地址::ffff:127.0.0.1

从客户的角度来看,它正在与IP v4服务器。客户无法分辨差异。从服务器的角度来看,每个人都使用IPv6进行连接。操作系统执行IPv4数据包和IPv6软件之间的映射。

这样做的效果是,您可以开发软件而无需手动处理双栈编程。所有软件都可以为IPv6编写,并将所有地址作为IPv6地址处理。这可以简化代码(无需处理同时拥有侦听IPv4和侦听IPv6套接字等),同时仍然向“外部”提供完整的双栈体验。

因此,您的服务是完全双栈,从系统外部看到。在应用程序本身中,您将看到以IPv6地址表示的整个世界,就像您在日志文件中显示的一样。这通常不会导致任何问题。它可能会影响你处理ACL,记录和其他事情的方式。

+0

使用接受的解决方案,在主机名上运行curl -6时仍然给我提出了问题。它不接受IPv6地址。当我刚使用IPv6时,它工作。 'app.run(host ='::',4060)'在'::'上运行我的应用程序为我处理所有用例(IPv4和IPv6),同时为IPv4地址添加前缀。这可能是更新版本的烧瓶。 – SKipp

0

不幸的是,虽然Linux使用映射的IPv4地址来限定“::”,但这在其他几个IPv6栈上不起作用,例如在Microsoft Windows上。由于安全原因,“::”将绑定到IPv6地址系列,Windows和其他IPv6栈实现者已决定将IPv4地址映射到IPv6地址空间,除非应用程序特别要求这样做。就我理解的讨论而言,此处的基本原理是,否则会出现意想不到的IPv4连接,这可能会破坏ACL或其他应用程序层安全机制。