1

I will send a string from a local machine to a remote ssh server.

The user is in a simple jail, so he can't execute commands, login, do something on the remote bash or what ever, he can only send a string/value/variable and execute the script run on the ssh server not more.

This is the simple jail for the user

This is are the default settings for the USER to login and run a shell:

chsh -s /bin/bash [USER]

But i change the settings to this for the simple jail:

chsh -s /home/[USER]/./run [USER]

The ssh server receive the string and change the string to a new result.

I save this new result on my local machine in a file called OUTPUT.

After trying i found this solution, call it a hack or a bug, but i don't know if this is the correct way!

  1. With this command i ssh to the remote server, with a ssh-key without a password.

MY SSH COMMAND ON THE LOCAL MACHINE TO CONNECT TO THE SERVER:

ssh -i [KEY] -p [XXXX] [USER]@[HOST] '123' <<< "$VALUE" > OUTPUT
  1. The script run receive the string 123 from the variable $VALUE

MY SCRIPT WITH NAME run ON THE SSH SERVER

#!/bin/bash
echo "WELCOME TO SSH"
read VALUE
echo $VALUE

This is only an example to See what i mean, the real Script generate a Hash.

  1. On my local machine i store/save the result in my file OUTPUT from the script run of the remote ssh server.

MY LOCAL FILE OUTPUT WITH THE RESULT FROM THE SERVER

WELCOME TO SSH
123

The read VALUE command saves the value 123 in the variable $VALUE without a prompt and save the result on my local machine.

THE EXECUTION STEPS:

  1. Connect to ssh server
  2. Send a string from my local machine to the remote ssh server
  3. The remote server change this string to a new result
  4. Save the new result on my local machine in a file

When i start the ssh command it opens connection,

the script works, i see WELCOME TO SSH on my terminal and

i receive the result on my local machine and the connection close.

You can easy test this example on your machine to see what i mean.

This is exactly what i need but i wonder:

Why i need the read

Why i get not a prompt.

What is an other solution for this example.

How can i send a string to a script on a server over ssh with a jailed user and save the result from the server on my local machine in a file?

UPDATE FOR SOLUTION

From @ilkkachu answer i can run this commands and send:

String and Variable:

ssh -i [KEY] -p [XXXX] [USER]@[HOST] "123" "$VALUE" > OUTPUT

String:

ssh -i [KEY] -p [XXXX] [USER]@[HOST] "123"> OUTPUT

Variable:

ssh -i [KEY] -p [XXXX] [USER]@[HOST] "$VALUE" > OUTPUT

Nothing:

ssh -i [KEY] -p [XXXX] [USER]@[HOST] > OUTPUT

#!/bin/bash

value=     # empty by default
if [ "$1" = -c ]; then
    value="$2"
fi
if [ -z "$value" ]; then
    echo "value is empty" >&2
    exit 1
fi
# do something with the value
echo "$value" | rev 

SSH authorized_keys command option

From this post:

SSH authorized_keys command option: multiple commands?

No. It is not "allowed" command, but "forced" command (as ForceCommand option). The only possibility is to use different keys for different command or read parameters from stdin.

It is a good tip but for a single command, like a backup or output some informations.

I have to do more config stuff if i run a command like rsync, if i don't wanna receive errors.

So i will stay with a simple jailed user and a given script.

0

2 Answers 2

4

Using ssh user@somehost <<< "$value" is pretty much the same as echo "$value" | ssh user@somehost: the contents of the variable are sent to the standard input of the SSH client process. SSH transfers that to the remote end, and it's available there for the remote process to read, again on stdin. For example using the shell's read, as you did there. That's one way of passing data over the SSH connection.

Another way is using command line arguments. If you run

ssh user@somehost "some string here"

then SSH asks the remote side to run the remote user's shell with the two arguments -c and some string here. With a normal shell, that would have the shell interpret "some string here" as a shell command line, so indeed something like ssh user@somehost "ls /tmp" would work to run ls. (ssh user@somehost ls /tmp does the same, the SSH client joins the args with spaces before sending them to the remote.)

But you have changed the user's shell to limit what they can do, so the -c option will not do what SSH assumes it does. For the same reason, there's no prompt: your script doesn't print one like a normal shell would.

Having the script as the shell doesn't matter, though, as it can just detect and ignore the -c option and use what comes after it.

E.g. you could have a script like this on the remote:

#!/bin/bash

value=     # empty by default
if [ "$1" = -c ]; then
    value="$2"
fi
if [ -z "$value" ]; then
    echo "value is empty" >&2
    exit 1
fi
# do something with the value
echo "$value" | rev 

The mock example would pass the value through rev, reversing the string.

Hence, running ssh user@somehost "hello there" would give back the string ereht olleh.

Running just ssh user@somehost, without a "command" at the end, would trigger the error message in the script, but it also would have SSH act like it was starting an interactive session. It would reserve pseudo-terminal (pty) on the remote, and might run some extra stuff usually done during login, like run PAM session modules on Linux. Those do stuff like printing the "Message of the day" or checking if the account had unread email. Same with ssh user@somehost "", so you can't really pass an empty argument and expect it to behave exactly the same as a non-empty one.


In addition to restricting the shell of the remote user, another alternative for locking the commands that can be run through SSH would be to use SSH keys, and to use the command=... in authorized_keys. Doing that would also allow disabling pty allocation with the no-pty keyword. (And the mere fact of running a forced command related to the key might affect running those PAM session modules.) See the sshd man page.

1

I think you are getting confused.

What you were Originally asking:
When you have a local value (eg VALUE="XXXXXXXX" on the local machine), you can save it to a local file OUTPUT without going to the remote machine.

What you Actually want to ask:
Possibility 1 : I think, you want a remote value (eg VALUE="XXXXXXXX" on the remote machine), which you want to save to a local file OUTPUT.

Solution 1:

ssh -i [KEY] -p [XXXX] [USER]@[HOST] 'echo ${VALUE}' > OUTPUT

Note: Single Quotes, not Double Quotes!

Here, the Single Quotes ensure that VALUE is not evaluated in local machine but will get evaluated on remote machine.

What you Actually want to ask:
Possibility 2 : "I want to send a value VALUE to a script running on remote machine which will output some new value ; I want that new value in the local file OUTPUT"

Solution 2:

ssh -i [KEY] -p [XXXX] [USER]@[HOST] /path/to/myscript "${VALUE}" > OUTPUT

Note: Double Quotes, not Single Quotes!

Here we are Passing the VALUE to your script via command-line arguments. In /path/to/myscript , you can access that value via $1, Eg :

VALUE=$1  
echo " I got $1 which I am storing in the variable VALUE which now contains $VALUE "  
#### Process VALUE & Compute new value and echo it  

What you Actually want to ask:
Possibility 3 : "I have a remote machine where USER can only login , execute a Pre-Defined Script (/home/[USER]/./run) and Exit. I want to send a value VALUE to that script running on remote machine which will output some new value ; I want that new value in the local file OUTPUT"

Solution 3:

ssh -i [KEY] -p [XXXX] [USER]@[HOST] MYVALUE "${VALUE}" > OUTPUT

Note: Double Quotes, not Single Quotes!

Here we are Passing the String "MYVALUE" & the value of the variable VALUE to your script via command-line arguments. In your Script /home/[USER]/./run , you can access those Command-line Parameter values via $1, $2, $2, Etc. :

#!/bin/bash
echo "WELCOME TO SSH"
echo " I got \$1 which $1 "  
echo " I got \$2 which $2 "  
echo " I got \$3 which $3 "  
echo " I got \$4 which $4 "  
echo " I got \$5 which $5 "  
echo " I got \$6 which $6 "  
echo " I got \$7 which $7 "  
echo " I got \$8 which $8 "  
echo " I got \$9 which $9 "  
#### echo " I got STRING MYVALUE in ${N} and the value VALUE in ${M} which I am storing in the remote variable VALUE "  
#### VALUE=${M}  
#### echo $($VALUE + $VALUE)  

Here I am echoing all Command-line Parameter values $1, $2, $3, $4, $5, $6, $7, $8, $9, to check which has the STRING MYVALUE and which has the value of the variable VALUE.
When you figure out that eg, $3 has the correct value, remove all the unwanted echo lines, uncomment the last 3 lines , update the N & M , and check ; It should work !

0

You must log in to answer this question.

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