I am working on a proxy which can be hosted on a single IP address and dispatch requests to different backends depending on which hostname the client used to connect to this IP address. Currently such a proxy can be build to support HTTP, HTTPS, SMTP, and DNS. However SSH support is impossible due to the ssh client not sending the information such a proxy would need. I am not the first to want such a proxy: http://serverfault.com/q/34552/214507 However my searches only found people talking about it, and nobody doing anything about it. I have attached a tiny patch for the openssh-client, which I believe does everything openssh would need to do in order to support this kind of proxies. What are your thoughts on the attached patch? Rationale behind the design of the patch: A name based SSH proxy will need to accept connections from clients and based on data send by the client choose a backend server to connect to. The proxy will not be able to forward the version identification from the backend to the client until after it has connected to the backend. Thus the proxy will need to extract the hostname from the data send by the client before any version identification has been send in the other direction. This leaves the version identification send from client to server as the only place such a proxy could possibly extract the hostname from. Thus the patch would have to extend the format of the version identification to include a hostname. The version identification contains a comments field which at the moment is a free form field send by client and ignored by server. The intended purpose of this field is to aid in debugging, thus it just needed to be huamn redable. Replacing the comments field with JSON formatted data will allow it to serve both purposes. I picked JSON because it is extensible and very simple. The change amounts to modifying two lines of code in send_client_banner and passing the hostname as function argument where it is now necessary. No server side changes are needed. -- Kasper Dupont -- Rigtige mænd skriver deres egne backupprogrammer #define _(_)"d.%.4s%."_"2s" /* This is my email address */ char*_="@2kaspner"_()"%03"_("4s%.")"t\n";printf(_+11,_+6,_,12,_+2,_+7,_+6);
diff -up openssh-6.6p1/roaming_client.c.original openssh-6.6p1/roaming_client.c --- openssh-6.6p1/roaming_client.c.original 2014-01-10 00:58:53.000000000 +0100 +++ openssh-6.6p1/roaming_client.c 2015-05-23 12:58:12.193450191 +0200 @@ -147,7 +147,7 @@ roaming_resume(void) resume_in_progress = 1; /* Exchange banners */ - ssh_exchange_identification(timeout_ms); + ssh_exchange_identification(timeout_ms, ""); packet_set_nonblocking(); /* Send a kexinit message with resume@xxxxxxxxxxx as only kex algo */ diff -up openssh-6.6p1/sshconnect.c.original openssh-6.6p1/sshconnect.c --- openssh-6.6p1/sshconnect.c.original 2015-05-23 11:56:55.235217137 +0200 +++ openssh-6.6p1/sshconnect.c 2015-05-23 13:43:41.426983727 +0200 @@ -515,12 +515,13 @@ ssh_connect(const char *host, struct add } static void -send_client_banner(int connection_out, int minor1) +send_client_banner(int connection_out, int minor1, const char *host) { /* Send our own protocol version identification. */ if (compat20) { - xasprintf(&client_version_string, "SSH-%d.%d-%.100s\r\n", - PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, SSH_VERSION); + xasprintf(&client_version_string, + "SSH-%d.%d-%.100s {\"SNI\": \"%.133s\"}\r\n", + PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, SSH_VERSION, host); } else { xasprintf(&client_version_string, "SSH-%d.%d-%.100s\n", PROTOCOL_MAJOR_1, minor1, SSH_VERSION); @@ -537,7 +538,7 @@ send_client_banner(int connection_out, i * identification string. */ void -ssh_exchange_identification(int timeout_ms) +ssh_exchange_identification(int timeout_ms, const char *host) { char buf[256], remote_version[256]; /* must be same size! */ int remote_major, remote_minor, mismatch; @@ -559,7 +560,7 @@ ssh_exchange_identification(int timeout_ */ if (options.protocol == SSH_PROTO_2) { enable_compat20(); - send_client_banner(connection_out, 0); + send_client_banner(connection_out, 0, host); client_banner_sent = 1; } @@ -672,7 +673,7 @@ ssh_exchange_identification(int timeout_ logit("Server version \"%.100s\" uses unsafe RSA signature " "scheme; disabling use of RSA keys", remote_version); if (!client_banner_sent) - send_client_banner(connection_out, minor1); + send_client_banner(connection_out, minor1, host); chop(server_version_string); } @@ -1286,7 +1287,7 @@ ssh_login(Sensitive *sensitive, const ch lowercase(host); /* Exchange protocol version identification strings with the server. */ - ssh_exchange_identification(timeout_ms); + ssh_exchange_identification(timeout_ms, host); /* Put the connection into non-blocking mode. */ packet_set_nonblocking(); diff -up openssh-6.6p1/sshconnect.h.original openssh-6.6p1/sshconnect.h --- openssh-6.6p1/sshconnect.h.original 2013-10-17 02:47:24.000000000 +0200 +++ openssh-6.6p1/sshconnect.h 2015-05-23 12:57:16.129172189 +0200 @@ -39,7 +39,7 @@ void ssh_kill_proxy_command(void); void ssh_login(Sensitive *, const char *, struct sockaddr *, u_short, struct passwd *, int); -void ssh_exchange_identification(int); +void ssh_exchange_identification(int, const char *); int verify_host_key(char *, struct sockaddr *, Key *);
_______________________________________________ openssh-unix-dev mailing list openssh-unix-dev@xxxxxxxxxxx https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev