How can I make my own working shell using ssh?
I am creating a custom shell in Python for a very limited user on the server who logs in via ssh with public key authentication. They must be able to run ls
, find -type d
and cat
in certain directories with certain restrictions. This works great if you run something like ssh user@server -i keyfile
, because you see an interactive prompt and can run these commands. However, something like ssh user@server -i keyfile "ls /var/log"
no. ssh
just freezes, no response. Using the switch -v
I found that the connection succeeds, so the problem is in my shell. I'm also pretty sure the script isn't even running since it print sys.argv
doesn't do anything at the beginning of the program. Here's the code:
#!/usr/bin/env python
import subprocess
import re
import os
with open(os.devnull, 'w') as devnull:
proc = lambda x: subprocess.Popen(x, stdout=subprocess.PIPE, stderr=devnull)
while True:
try:
s = raw_input('> ')
except:
break
try:
cmd = re.split(r'\s+', s)
if len(cmd) != 2:
print 'Not permitted.'
continue
if cmd[0].lower() == 'l':
# Snip: verify directory
cmd = proc(['ls', cmd[1]])
print cmd.stdout.read()
elif cmd[0].lower() == 'r':
# Snip: verify directory
cmd = proc(['cat', cmd[1]])
print cmd.stdout.read()
elif cmd[0].lower() == 'll':
# Snip: verify directory
cmd = proc(['find', cmd[1], '-type', 'd'])
print cmd.stdout.read()
else:
print 'Not permitted.'
except OSError:
print 'Unknown error.'
And here's the relevant line from ~ / .ssh / authorized_keys:
command="/path/to/shell $SSH_ORIGINAL_COMMAND" ssh-rsa [base-64-encoded-key] user@host
How can I make a shell script when a command is passed on the command line, so it can be used in scripts without starting an interactive shell?
source to share
The problem with ssh's answer is not because it ssh user@host cmd
doesn't open a terminal for the running command. Try to call ssh user@host -t cmd
.
However, even if you pass in a parameter -t
, you will have another problem with your script: it only runs interactively and completely ignores the $ SSH_ORIGINAL_PROGRAM passed in. A naive solution would be to check sys.argv
, and if there is more than 1, you don't loop forever, but instead only execute the command you have.
source to share