5
votes

I want to host an embedded FTP server inside an Azure cloud service worker role.

To provide passive access to the FTP server, it uses port range 20000-21000. Inside the ServiceDefinition.csdef I define all needed ports (see screenshot).

ServiceDefinition.cscfg

The main problem is the huge number of ports. If I try to upload the service into the cloud I get the following error.

Validation error: Invalid number of input endpoints - current 1002, max. 25

How can I get this work with cloud service?

2
This repo 's readme says PASV mode does not work. Maybe it is because WorkerRole only supports 25 ports. You can create a VM available set of IIS FTP server with shared storage mounted.CSakura
Yes our product is doing right now. But we explicitly want to switch to worker role with a custom embedded FTP service. I know FTP2Azure but they did not even implement passive connections. So I'm sorry but this is not helping with my problem.Steffen Mangold

2 Answers

0
votes

Here is a solution based on Azure support answer.

You will need to define a public IP in the .cscfg file and upload it the cloud service.

<?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>

More info: https://docs.microsoft.com/en-us/azure/virtual-network/virtual-networks-instance-level-public-ip#manage-an-ilpip-for-a-cloud-services-role-instance

After that you can use nslookup to get the public IP assigned to the instance. If you have multiple instances, you need to change the 0 to 1, 2, 3 etc.

nslookup WebPublicIP.0.<Cloud Service Name>.cloudapp.net

Then you can open the local ports in Windows Firewall of the instance and you will be able to connect the local ports directly from the internet.

You can create a startup task to open the local ports in the cloud service firewall. Following is an example of how to configure firewall rules. The startup task is executed every time the instance is rebooted/reimaged.

https://docs.microsoft.com/en-us/azure/cloud-services/cloud-services-startup-tasks-common#add-firewall-rules

Something like below:

netsh advfirewall firewall add rule name="TCP ports" protocol=TCP dir=in localport=1000-2000 action=allow

-1
votes

When a client connects to an FTP server using passive mode, it will make 2 connections. One using port 21, and another for transferring data.

So it looks like you need to open a single port in ServiceDefinition.csdef and then create a port forwarding rule on the firewall (load balancer) to redirect all of the passive ports to that single port.

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

This is untested, but might help.