42

Is it possible to configure ssh (on linux) to allow access for tunneling only? Ie user can setup tunnels but cannot get a shell/access files?

0

6 Answers 6

57

Yes, just use /bin/false as shell and instruct the user to start the tunneling SSH process without executing any remote command (i.e. the -N flag for OpenSSH):

ssh -N -L 1234:target-host:5678 ssh-host
3
  • Um, if the user doesn't use -N, they have shell access. This really doesn't solve the problem and is dangerous.
    – mlissner
    Mar 29, 2017 at 18:46
  • 15
    @mlissner: No, if you have /bin/false as shell, you won't have shell access, as every login session will terminate immediately.
    – Sven
    Mar 30, 2017 at 16:26
  • But will this prevent scp from working?
    – Rémi
    Jun 25, 2021 at 17:25
11

In the user's .ssh/authorized_keys file, put something like the following:

permitopen="192.168.1.10:3306",permitopen="10.0.0.16:80",no-pty ssh-rsa AAAAB3N...

So, basically, you the controls would be in front of the user's ssh public key separated by a space. In the example, connections using the specific public key will be allowed to do SSH port forwarding only to 192.168.1.10's MySQL server and 10.0.0.16's web server, and will not be assigned a shell (no-pty). You're specifically asking about the "no-pty" option, but the others may also be useful if the user is only supposed to tunnel to specific servers.

Look at the man page for sshd for more options for the authorized_keys file.

Note that the user's experience may look a little odd: when they ssh in, it will look like the session is hanging (as they are not getting a pty). That's OK. If the user has specified port forwarding with, for example, "-L3306:192.168.1.10:3306", the port forwarding will still be in effect.

In any case, give it a try.

2
  • 7
    This is dangerous advice; no-pty doesn't prevent shell access, it just doesn't give the shell a pty. It doesn't display the prompt (ie. "appears to hang"), but you can still give commands just fine. You need the command="..." option in .ssh/authorized_keys if you want to restrict shell access from there. Jan 1, 2015 at 19:58
  • 2
    @AleksiTorhamo is correct, but this is a start; you also must set shell to /usr/sbin/nologin or /bin/false in /etc/passwd to fully restrict the shell. I edited the above entry to reflect that, along with Aleksi's advice. Dec 10, 2018 at 16:37
3

Give the user a shell that only allows them to log out such as /bin/press_to_exit.sh

#!/bin/bash
read -n 1 -p "Press any key to exit" key

This way he can stay logged in as long as he wants, with tunnels active, but not run any commands. Ctrl-c closes the connection.

1
  • 5
    I think that at least in theory, the user will be able to hit CTRL+C at the right moment (between lines 1 and 2) and end up with a full bash shell.
    – andreas-h
    Jan 21, 2013 at 9:03
2

Assign a shell that doesn't let the user log in.

e.g.

#!/bin/sh
echo "No interactive login available."
sleep 60
exit 0

would prevent them from getting a shell prompt, and give them a time-out of 60 seconds - if there's no connection active for 60 seconds then it will exit and thereby disconnect them completely (increase the number according to requirements).

They can't execute a remote command, either, because that shell won't let them.

6
  • 5
    Most linux installs already come with something for that. /sbin/nologin, or /bin/false or similar. Aug 20, 2009 at 11:27
  • 1
    What would Ctrl-C do in the above example?
    – Arjan
    Aug 20, 2009 at 12:00
  • 2
    I actually like earl's response, with the "-N" option, but if you want to give your user a helpful, friendly, informative message - and stop them leaving SSH connections all over the place - then a custom script is nice and clear about what it's doing.
    – jrg
    Aug 20, 2009 at 17:06
  • 3
    @jrg This discussion is old and you might have changed your mind :) but IMHO it's dangerous to come out with handmade shell scripts. There is already /sbin/nologin, which you can customize with an user-friendly message in /etc/nologin.txt.
    – dr_
    Aug 23, 2018 at 8:00
  • 1
    There are some things that are dangerous in shell scripts, but this isn’t one of them (The original implementation of nologin - in BSD 4.4 - being a script is quite telling.) The main reason for my custom script suggestion was to support a tunnel being added after connection, not the message, hence why I personally still like Earl’s -N approach. These days I’d probably use a container with nothing else in it, as well.
    – jrg
    Aug 26, 2018 at 19:51
1
​##Create a new user

sudo useradd -m [user]

##Edit /etc/ssh/sshd_config

Match User [user]
   #AllowTcpForwarding yes
   #X11Forwarding no
   #PermitTunnel no
   GatewayPorts yes ##Enable listening on 0.0.0.0
   AllowAgentForwarding no
   PermitOpen localhost:2888 ##specify port
   ForceCommand echo 'This account can only be used for Tunneling'
0

My solution is to provide the user who only may be tunneling, without an interactive shell, to set that shell in /etc/passwd to /usr/bin/tunnel_shell.

Just create the executable file /usr/bin/tunnel_shell with an infinite loop.

Additionally make use of the AllowGroups and Match Group option.

Fully explained here: http://blog.flowl.info/2011/ssh-tunnel-group-only-and-no-shell-please/

2
  • 2
    The user might be able to exit the executable somehow and escape a shell. Are you perfectly confident that your executable won't allow to do this?
    – dr_
    Aug 23, 2018 at 7:56
  • 2
    @dr01 To be honest, I am not sure if this is 100% secure. I guess when you exit the executable, the SSH session is quit, too. I will research this more and might comment again here.
    – Daniel W.
    Aug 24, 2018 at 7:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.