restrict ssh reverse portforwarding per user [duplicate]
Solution 1:
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.
Solution 2:
My suggestion is using SELinux for this. You'll have to configure user profiles that allow which ports to be open. The sshd
process forks and drops to the user's privileges before opening a port to forward, so anything applied to the user's processes will be enforced on sshd
. Be mindful that you'll need to restrict to all user processes since once could use netcat
to forward another port. I'll try to sort out proper syntax for you later (or any other user is welcome to edit it in for me).
Alternatively, you could try using iptables
.
iptables -m owner --add-owner $user -p tcp --sport 8000 -j ACCEPT
iptables -m owner --add-owner $user -p tcp --tcp-flags SYN,ACK SYN,ACK -j REJECT
That won't prevent them from opening the port and denying another user, however.