Linux – How to limit reverse SSH tunelling ports

linuxsshssh-tunnel

We have a public server which accepts SSH connections from multiple clients behind firewalls.

Each of these clients create a Reverse SSH tunnel by using the ssh -R command from their web servers at port 80 to our public server.

The destination port(at the client side) of the Reverse SSH Tunnel is 80 and the source port(at public server side) depends on the user. We are planning on maintaining a map of port addresses for each user.

For example, client A would tunnel their web server at port 80 to our port 8000; client B from 80 to 8001; client C from 80 to 8002.

Client A: ssh -R 8000:internal.webserver:80 clienta@publicserver

Client B: ssh -R 8001:internal.webserver:80 clientb@publicserver

Client C: ssh -R 8002:internal.webserver:80 clientc@publicserver

Basically, what we are trying to do is bind each user with a port and not allow them to tunnel to any other ports.

If we were using the forward tunneling feature of SSH with ssh -L, we could permit which port to be tunneled by using the permitopen=host:port configuration. However, there is no equivalent for reverse SSH tunnel.

Is there a way of restricting reverse tunneling ports per user?

Best Answer

Since you've placed not allow in bold, I assume you want some kind of run-time rejection at the SSH client side that prevents the port bind. So, I've had a dig of the source code for you:

serverloop.c:

/* check permissions */
if (!options.allow_tcp_forwarding ||
    no_port_forwarding_flag ||
    (!want_reply && listen_port == 0)
#ifndef NO_IPPORT_RESERVED_CONCEPT
    || (listen_port != 0 && listen_port < IPPORT_RESERVED &&
    pw->pw_uid != 0)
#endif
    ) {
        success = 0;
        packet_send_debug("Server has disabled port forwarding.");
} else {
        /* Start listening on the port */
        success = channel_setup_remote_fwd_listener(
            listen_address, listen_port,
            &allocated_listen_port, options.gateway_ports);
}

Unfortunately, as you can see, there aren't many conditions that appear to prevent port forwarding aside from the standard ones.

I was about to recommend the same suggestion for using mod_owner within iptables, but Jeff has beaten me to it.

Your cleanest solution would just to modify this file (for example, you can use pw->pw_uid to get the uid of the user connecting, and map that to the correct port) and recompile your SSH server, but that would depend on how comfortable you are with this.