0 votes
by (160 points)

I am using a trial version of Rebex File Server. When a client connects to the server, I would like to get the host address that they used (e.g. "xyz.company.com"). I tried to do this in the FileServer.Authentication event like this:

var endpoint = args.ClientEndPoint as DnsEndPoint;

However, I am getting null results even though the client is connecting using a host address and not an IP address.

Am I doing something wrong? Thanks.

Applies to: File Server

1 Answer

+1 vote
by (148k points)
selected by
 
Best answer

DnsEndPoint is just a .NET class that makes it possible to pass hostname/port endpoints to APIs that accept EndPoint on input. It doesn't actually reflect how things work at the TCP protocol level.

A TCP connection is identified by a 5-tuple - a tuple with five elements:
- Protocol (TCP)
- Source IP address
- Source port
- Target IP address
- Target port

In order to establish a TCP connection, the target DnsEndPoint is resolved into an IP address. The host name is not transmitted to the target at all.

This can be observed with .NET's System.Net.Sockets.Socket class as well:

var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.Connect(new DnsEndPoint("test.rebex.net", 22));
Console.WriteLine(socket.RemoteEndPoint);
socket.Close();

The socket.RemoteEndPoint returns an instance of IPEndPoint even though the socket has been connected with DnsEndPoint.

However, you can resolve an IP address into a hostname using DNS:

var ep = (IPEndPoint)args.ClientEndPoint;
IPHostEntry entry = Dns.GetHostEntry(ep.Address);
string hostName = (entry != null) ? entry.HostName : null;

But please note that:

  • This actually involves querying the Domain Name System and might cause a noticeable delay.
  • An IP address might not resolve into any hostname at all.
by (160 points)
Thanks for the explanation! However, it does not really address the problem that I'm trying to solve. The service that I'm implementing has multiple DNS addresses associated to the same IP address. Each DNS address represents a different "virtual host" and that information provides context for authentication and the file system that needs to be presented to the client. So the information that I am trying to gather is the actual host address that the client used to establish this connection (reverse DNS would return all the address associated with the IP, but would not tell me which one was used by the client...). The HTTP protocol solves this problem through the "Host" header, and the FTP protocol has a "HOST" command to solve this problem (see https://tools.ietf.org/html/rfc7151). I don't know if this information is transmitted in the connection in a way that would be available to the SFTP server.
by (148k points)
Thanks for the clarification, I understand now. This would indeed be a very useful, but unfortunately, there is no such feature in the SSH protocol - the host name is not transmitted to the server. It might be possible to add a custom extension for it, but that would only work if both the SSH client and SSH server supported it, which is a showstopper for almost all scenarios.
There was a discussion about adding such feature to OpenSSH few years ago (see https://lists.gt.net/openssh/dev/55943), but it got nowhere (and the suggested workarounds are not really suitable, I'm afraid).
by (160 points)
Ok, thanks for the link! This answers my question.
...