Python: откройте порт прослушивания за маршрутизатором (upnp?)

Я разработал приложение, которое по сути представляет собой небольшой ftp-сервер с возможностью указать, какой каталог вы хотите открыть при запуске. Я использую ftplib для сервера, потому что это очень просто. Единственная проблема, с которой я сталкиваюсь, заключается в том, что если вы находитесь за маршрутизатором, вам нужно вручную перенаправить порты на вашем маршрутизаторе, и я считаю, что это слишком сложно для моих пользователей (также известных как коллеги / клиенты).

Итак, я искал простое решение для открытия портов, но обнаружил, что большинство API-интерфейсов слишком широкие и непосильные для меня. Кто-нибудь знает решение, которое было бы относительно просто реализовать?

Примечание. На самом деле он будет использоваться только в Windows, хотя приветствуется кроссплатформенная совместимость. Если есть более простое решение только для Windows, я бы выбрал его.

Спасибо!


person Boona    schedule 08.12.2010    source источник
comment
@Falmarri: Вы можете сделать это с помощью UPnP, который является стандартом (помимо прочего) для динамического открытия дыр в брандмауэре;) Так что это не зависит от маршрутизатора / производителя.   -  person ZeissS    schedule 10.12.2010


Ответы (5)


Простой пример для miniupnp. На обнаруженном шлюзе создается сопоставление внешнего порта 43210 с интерфейсом, подключенным к порту 43210 на интерфейсе, подключенном к обнаруженному шлюзу.

import miniupnpc

upnp = miniupnpc.UPnP()

upnp.discoverdelay = 10
upnp.discover()

upnp.selectigd()

port = 43210

# addportmapping(external-port, protocol, internal-host, internal-port, description, remote-host)
upnp.addportmapping(port, 'TCP', upnp.lanaddr, port, 'testing', '')
person datashaman    schedule 27.02.2016
comment
Спасибо, @lionello, хороший улов! Я немного отредактировал ваше редактирование. - person datashaman; 05.04.2018

Протокол, который вам нужен, называется IGD (от Internet Gateway Device) и основан на UPNP. Это позволяет клиентской программе (вашей) обнаруживать маршрутизатор в сети (используя UPNP), а затем просить его перенаправить определенный порт.

Это поддерживается большинством домашних маршрутизаторов, и этот метод используется во многих сервисах, таких как BitTorrent или многопользовательские игры, но его немного сложно использовать или реализовать. Существует несколько библиотек с открытым исходным кодом, поддерживающих IGD, и одна из самых простых (также кроссплатформенная) — «miniupnp»: см. http://miniupnp.free.fr»./

person GregD    schedule 03.05.2012

Похоже, есть несколько вариантов, один из которых miniupnp. Существуют также привязки Python для GNUPnP здесь. Для Windows будет работать minupnp, или вы можете использовать чистый python с miranda-upnp.

Есть хороший пример привязки Python GNUPnP, используемой для открытия портов на маршрутизаторе здесь. В этом примере время аренды установлено равным 0, что является неограниченным. См. определение здесь. из add_port.

Простым примером может быть:

#! /usr/bin/python
import gupnp.igd
import glib
from sys import stderr

my_ip = YOUR_IP

igd = gupnp.igd.Simple()
igd.external_ip = None

main = glib.MainLoop()

def mep(igd, proto, eip, erip, port, localip, lport, msg):
    if port == 80:
        igd.external_ip = eip
        main.quit()

def emp(igd, err, proto, ep, lip, lp, msg):
    print >> stderr, "ERR"
    print >> stderr, err, proto, ep, lip, lp, msg
    main.quit()

igd.connect("mapped-external-port", mep)
igd.connect("error-mapping-port", emp)

#igd.add_port("PROTO", EXTERNAL_PORT, INTERNAL_IP, INTERNAL_PORT, LEASE_DURATION_IN_SECONDS, "NAME")
igd.add_port("TCP", 80, my_ip, 8080, 86400, "web")

main.run()
person KernelSanders    schedule 21.02.2015

Существует статья, объясняющая, как использовать COM-объект Windows IGD с win32com.

person Martin v. Löwis    schedule 08.12.2010

Я искал это много дней. Мне не удалось установить miniupnpc с помощью pip для python 3.

Я решил эту проблему с помощью реализации, найденной здесь, которая будет работать для Python 2.

Я разветвил его и внес изменения для использования в Python 3, вы можете найти его здесь

Эта реализация, безусловно, самая простая из тех, что я видел, и работает хорошо.

person Jaime    schedule 01.05.2018