2

I have written a simple application that runs in console mode. I want to allow people from the Internet to SSH to this host and use the application in question.

Each time someone SSH's to the server, I want to be able to allow an instance of the application to run in their SSH session. They will work with the program, and then after it has completed (i.e. it exits) the SSH session should be closed.

The caveats are:

  1. I don't want to use a shell script like .bash_profile. Too many opportunities for this to be hacked!
  2. Preferably I don't even want the user account to be assigned a valid "shell". In other words I want the user shell to be something like /bin/false, so that FTP, SFTP, etc. all of the rest will not be permitted. The ONLY thing I want allowed from the account is access to this one specific console application, running in unprivileged mode as this user.
  3. I may want to offer more than one of these applications on different usernames. So for example, "search" will present one console app, while "browse" will present another, depending on how the user logs in.
  4. Requiring a password for the SSH session is not required. It'd be nice if it just ignored authentication altogether, but having to give the end users the SSH password is not a deal-breaker. The only thing here is of course being secure - I do NOT want the account to be allowed to do anything else.
  5. The user shouldn't have to do anything special on their end. They should be able to just "ssh [email protected]" and get the service.
  6. The program that executes may need command line arguments. I am fine with writing a wrapper to do this, but does that create an insecurity? e.g. If the command is "/usr/local/bin/myapp --mode=search", and I write a script like:

    !/bin/bash

    /usr/local/bin/myapp --mode=search

...does this create an insecure situation? Assume all file permissions are set properly - the user cannot modify the file.

Is this possible to do? If so, how can it be done, and importantly, how can it be done securely?

The server already offers SSH to the outside for remote login, which is fine. I still want that to work, obviously. So for instance if I login as my own user, I want to be asked for a password like usual and then presented a shell.

Thanks!

F

2
  • If you set the shell of the user to the program, then Linux will execute that binary as the 'shell', which could be your search program. Have you tried that ?
    – Lawrence
    Commented May 1, 2014 at 1:50
  • There might be some value in researching "sshrc". It gets called when someone successfully logs in (but not necessarily gets a shell).
    – joatd
    Commented Oct 25, 2022 at 4:26

4 Answers 4

0

There are three options:

  1. Set the application (or suitable wrapper for it) as the shell for the account.

    This way the account does not have a shell. When the user passes command, it will be passed as command line argument to the "shell" preceded by the -c flag. Do anything you want with it.

  2. Use public key authentication and define what each user can run using the command option in .ssh/authorized_keys.

    This allows running different commands for different keys and allows revoking permissions of individual users. It however needs each user to send you their public key (the private keys should never leave the machine on which they are generated, so users should generate keys and send the public parts to you).

    The command gets the command passed on ssh command line in SSH_ORIGINAL_COMMAND environment variable, so you can use it if you want.

    In this case the account does need a valid shell, because ssh uses it to run the configured command.

  3. Does it really have to be ssh? You mention it does not have to be authenticated, in which case perhaps directly starting it from inetd could do. Or telnet if you need terminal rather than just stdin/stdout. Note, that the option 1 will work with telnet too.

A wrapper script is safe if you take due care writing it. If it does not accept any input, it should be OK. If you do want to use the input (command-line arguments in 1., SSH_ORIGINAL_COMMAND envvar in 2.), you have to carefully sanitize it and properly quote it.

Of course depending on how much you trust the application itself you still may want to put it in chroot or separate namespace.

3
  • This is a great start. I had already considered setting the shell, and it looks like that may be the quickest way to get it to work right. As long as this disables use of SFTP and any other services it should be secure. Also, SSH is still best because I eventually plan to expand this to a system where people can login to a service via SSH, but the user accounts would be stored in a database - great example of this being done is text-based MUDs. You would want security available so people don't have to send their passwords in the clear (the app, not Linux itself, would be authenticating).
    – fdmillion
    Commented May 2, 2014 at 7:06
  • I also should have been clearer - public/private key pairs wouldn't be appropriate because in theory an untrusted random Internet user may have cause to login. (Again, for an example, think MUD.) You could do something where you have a website and people have to upload their key, but that ends up being confusing to people who don't already "understand" how SSH manages keys. Basically, I'm not as worried about host authentication as I am about transport security i.e. no sniffing packets of the session and getting cleartext. Not highly sensitive stuff, just don't want it to be too easy.
    – fdmillion
    Commented May 2, 2014 at 7:08
  • @fdmillion: Ssh uses the shell to do everything, including starting the sftp server. So restricting the shell disables it.
    – Jan Hudec
    Commented May 2, 2014 at 8:29
0

Yes....use a public/private key pair. On the authorized_key file, if you do your research you will note that you can restrict a private key to a specific key and even protect it from being allowed from only certain IP number.

0

What you want is to use ChrootDirectory in your sshd_config file. Here's a nice tutorial on the process.

0

Nowadays there is a framework that does just this: run golang applications through the ssh protocol.

https://github.com/charmbracelet/wish

(I know it does not exactly answer the question)

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .