Поддержка двух IPv4 и IPv6 в приложениях Flask
Можно ли запустить Flask для прослушивания как IPv4, так и IPv6 (т. Е. Двойной стек IP)? Насколько я проверял, можно запустить либо в IPv4, используя:
app.run(host='0.0.0.0', port=port, debug=True)
или IPv6 используя
app.run(host='::', port=port, debug=True)
но я не нашел способ запуска обоих одновременно (возможно, что один экземпляр моего приложения Flask прослушивает IPv4, а другой - IPv6, но оба не могут прослушивать один и тот же порт).
Спасибо!
Обновление (дополнительная информация):
Следуя комментариям Сандера Штеффана (спасибо!), Я запустил свое приложение, слушающее в 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 -
2 ответа
Что происходит, так это то, что операционная система автоматически подключает входящие запросы IPv4 к прослушивающему сокету IPv6. IPv4-адрес сопоставляется с IPv6-адресом с префиксом ::ffff:
, Поэтому входящее соединение IPv4 от 127.0.0.1
похоже, это исходит от адреса IPv6 ::ffff:127.0.0.1
,
С точки зрения клиента это общение с сервером IPv4. Клиент не может сказать разницу. С точки зрения сервера, все подключаются с помощью IPv6. Операционная система выполняет сопоставление между пакетами IPv4 и программным обеспечением IPv6.
В результате вы можете разрабатывать программное обеспечение, не прибегая к ручному программированию с использованием двух стеков. Все программное обеспечение может быть написано для IPv6 и обрабатывать все адреса как адреса IPv6. Это может упростить код (не нужно иметь дело как с прослушиванием IPv4, так и с прослушиванием сокетов IPv6 и т. Д.), В то же время предоставляя возможность работы с двумя стеками "извне".
Таким образом, ваш сервис является полностью двойным, как видно снаружи вашей системы. В самом приложении вы увидите весь мир, представленный IPv6-адресами, как показано в файле журнала. Это обычно не вызывает никаких проблем. Это может повлиять на то, как вы обрабатываете ACL, ведение журналов и другие подобные вещи.
К сожалению, хотя Linux использует сопоставленные адреса IPv4 для определения "::", это не работает в некоторых других стеках IPv6, например в Microsoft Windows. "::" будет привязан к семейству адресов IPv6, так как по соображениям безопасности Windows и другие разработчики стека IPv6 решили не отображать адреса IPv4 в адресное пространство IPv6, если только приложение специально не сигнализирует об этом. Насколько я понимаю, обоснование здесь заключается в том, что в противном случае могло бы произойти неожиданное подключение к IPv4, которое могло бы подорвать ACL или другие механизмы безопасности прикладного уровня.