Я хочу разместить встроенный FTP-сервер в рабочей роли облачной службы Azure.
Для обеспечения пассивного доступа к FTP-серверу он использует диапазон портов 20000-21000.
Внутри ServiceDefinition.csdef я определяю все необходимые порты (см. Снимок экрана).
Основная проблема - огромное количество портов. Если я попытаюсь загрузить сервис в облако, я получаю следующую ошибку.
Validation error: Invalid number of input endpoints - current 1002, max. 25
Как я могу получить эту работу с облачным сервисом?
Да наш продукт делает прямо сейчас. Но мы явно хотим переключиться на рабочую роль с настраиваемой встроенной службой FTP. Я знаю FTP2Azure, но они даже не реализовали пассивные соединения. Мне очень жаль, но это не помогает решить мою проблему.





Когда клиент подключается к FTP-серверу в пассивном режиме, он устанавливает 2 подключения. Один использует порт 21, а другой - для передачи данных.
Похоже, вам нужно открыть один порт в ServiceDefinition.csdef, а затем создать правило переадресации портов на брандмауэре (балансировщике нагрузки), чтобы перенаправить все пассивные порты на этот единственный порт.
<Endpoints>
<InputEndpoint name = "FTP2Azure.Command" protocol = "tcp" port = "21" localPort = "9003" />
<InstanceInputEndpoint name = "FTP2Azure.Passive" protocol = "tcp" localPort = "9002">
<AllocatePublicPortFrom>
<FixedPortRange max = "21000" min = "20000" />
</AllocatePublicPortFrom>
</InstanceInputEndpoint>
</Endpoints>
Это не проверено, но может помочь.
Это роль сотрудника облачной службы, нет ничего лучше брандмауэра.
Я обновил свой ответ примером и пояснением того, что я имею в виду под брандмауэром.
Значит, моему FTP-серверу нужно прослушивать порт 9002 в пассивном режиме?
Да, тогда, когда клиент пытается подключиться, балансировщик нагрузки перенаправляет все порты 20000-21000 на порт 9002. Вот как это работает теоретически. Я не могу проверить, но могу подтвердить, что InstanceInputEndpoint действительно работает с рабочими ролями.
Проблема в том, что вы можете привязать только один порт один раз. Поэтому, если у меня есть несколько параллельных пассивных подключений к данным, это не сработает.
Хорошо, тогда пересылка должна быть на стороне клиента.
Вот решение, основанное на ответе службы поддержки Azure.
Вам нужно будет определить общедоступный IP-адрес в файле .cscfg и загрузить его в облачную службу.
<?xml version = "1.0" encoding = "utf-8"?>
<ServiceConfiguration serviceName = "ILPIPSample" xmlns = "http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration" osFamily = "4" osVersion = "*" schemaVersion = "2014-01.2.3">
<Role name = "WebRole1">
<Instances count = "1" />
<ConfigurationSettings>
<Setting name = "Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString" value = "UseDevelopmentStorage=true" />
</ConfigurationSettings>
</Role>
<NetworkConfiguration>
<AddressAssignments>
<InstanceAddress roleName = "WebRole1">
<PublicIPs>
<PublicIP name = "MyPublicIP" domainNameLabel = "WebPublicIP" />
</PublicIPs>
</InstanceAddress>
</AddressAssignments>
</NetworkConfiguration>
</ServiceConfiguration>
После этого вы можете использовать nslookup, чтобы получить публичный IP-адрес, назначенный экземпляру. Если у вас несколько экземпляров, вам нужно изменить 0 на 1, 2, 3 и т. д.
nslookup WebPublicIP.0.<Cloud Service Name>.cloudapp.net
Затем вы можете открыть локальные порты в брандмауэре Windows экземпляра, и вы сможете подключать локальные порты непосредственно из Интернета.
Вы можете создать задачу запуска, чтобы открыть локальные порты в брандмауэре облачной службы. Ниже приведен пример настройки правил брандмауэра. Задача запуска выполняется каждый раз при перезагрузке / обновлении образа экземпляра.
Что-то вроде ниже:
netsh advfirewall firewall add rule name = "TCP ports" protocol=TCP dir=in localport=1000-2000 action=allow
В файле readme репо говорится, что режим PASV не работает. Может это потому, что WorkerRole поддерживает только 25 портов. Вы можете создать доступный набор виртуальных машин для FTP-сервера IIS с подключенным общим хранилищем.