Sunday, January 10, 2010

IIS7 Virtual FTP Servers problems and solutions

I know, I know, it's old news. After all IIS7 came out with Vista a couple years back, and with it came the possibility of having multiple virtual FTP servers in the same IIS.

But until now I had no idea of this, because, in all honesty, I skipped Windows Vista altogether. I didn't installed it in my box. Went straight from XP to Windows 7.

As I have some time in my hands, and after a complete reformat of my HD, I made a list of things that needed to be done. One of them is to rewrite the application that I use to update this site.

Part of this site is updated by using Blogger.com, but another part is by a program I made myself. This program was written almost five years ago, so a LOT of things have evolved since then.

I'm currently upgrading it to Visual Studio 2010 Beta2, along with a complete, no old code, rewrite of my ancient FTP Library.

I'm not going into details of this new library (which I will post as it's ready), but during my basic tests I wasn't able to connect to my own local server, because I have set it up as a virtual FTP server, complete, with host name (that I updated the Windows\system32\drivers\etc\hosts file to emulate a live FQDN server) and login users and permissions.

When I tried to connect, I got a "530-Valid hostname is expected." error.

What the heck?!

Because I had never played with the new IIS7 before, I thought it would handle the host name binding behind the scenes (as I have set up just a single FTP server) as the IIS does normally for the HTTP protocol.

And hence the problem. The the FTP protocol, although extensible, does not provide means to infer directly the host name for an specific connection.

For example: let's say we create two virtual FTP servers one for the FQDN ftp.example.com and another for ftp.contoso.com.

Both these virtual servers points to the same IP. And each of these virtual servers points to different location in the same server (it could even be in another server, but let's keep it simple for argument's sake).

Now, let's say that the users allowed to access ftp.example.com DO NOT have access to ftp.contoso.com.

When an FTP client connects to a full qualified domain name (like ftp.example.com) it actually makes a connection to the IP that is represented by that name (your basic DNS service) and, usually, on port 21.

After a connection is established, the FTP server sends a simple reply "220 Connection OK".

At this point the FTP server have NO IDEA of what FQDN the client requested. There's no way to tell. It can't even make a DNS reverse lookup, because the all the server knows at this point is that a client is connected to an specific listening port, bound to an specific address (or not so specific -- as you can set the binding to listen on all server's address).

So there are two approaches:
  • The FTP client sends a "HOST" command to specify which virtual host it's addressing;

  • Or it issues a "USER virtual.host|userName" command

Older FTP clients are not prepared for this kind of situation.

And not all the newer ones are ready for this.

As an workaround Robert McMurray proposed back in '08 to use a "Global Listener FTP Site" which it's nothing more than an unbidden FTP site that routes users to the appropriated paths.

However this approach isn't a solution as it doesn't resolve the problem of a single user that have access to more than one FTP virtual server.

So, to wrap it up, the "virtual.host|userName" approach to connect to an FTP virtual server, is the best fall back solution for older FTP clients that are not aware of the new HOST command, and gives their users a possible mean of connection.

0 Comments:

Post a Comment