46

I work with several different servers, and it would be useful to be able to set some environment variables such that they are active on all of them when I SSH in. The problem is, the contents of some of the variables contain sensitive information (hashed passwords), and so I don't want to leave it lying around in a .bashrc file -- I'd like to keep it only in memory.

I know that you can use SSH to forward the DISPLAY variable (via ForwardX11) or an SSH Agent process (via ForwardAgent), so I'm wondering if there's a way to automatically forward the contents of arbitrary environment variables across SSH connections. Ideally, something I could set in a .ssh/config file so that it would run automatically when I need it to. Any ideas?

singingwolfboy
  • 5,336
  • 3
  • 27
  • 32

3 Answers3

41

You can, but it requires changing the server configuration.

Read the entries for AcceptEnv in sshd_config(5) and SendEnv in ssh_config(5).

update:

You can also pass them on the command line:

ssh foo@host "FOO=foo BAR=bar doz"

Regarding security, note than anybody with access to the remote machine will be able to see the environment variables passed to any running process.

If you want to keep that information secret it is better to pass it through stdin:

cat secret_info | ssh foo@host remote_program
salva
  • 9,943
  • 4
  • 29
  • 57
  • 2
    It took me a little while before I remembered that I had to restart sshd to get it to re-read its configuration files, but once I did that, `AcceptEnv` and `SendEnv` worked like a charm. Exactly what I was looking for! Thanks! – singingwolfboy Dec 10 '10 at 15:25
14

You can't do it automatically (except for $DISPLAY which you can forward with -X along with your Xauth info so remote programs can actually connect to your display) but you can use a script with a "here document":

ssh ... <<EOF
export FOO="$FOO" BAR="$BAR" PATH="\$HOME/bin:\$PATH"
runRemoteCommand
EOF

The unescaped variables will be expanded locally and the result transmitted to the remote side. So the PATH will be set with the remote value of $HOME.

THIS IS A SECURITY RISK Don't transmit sensitive information like passwords this way because anyone can see environment variables of every process on the same computer.

Aaron Digulla
  • 321,842
  • 108
  • 597
  • 820
  • The `unescaped variables will be expanded locally` part saved my day. This was not explained in other manuals. Thank you! – Kolyunya Mar 04 '18 at 20:51
  • @reinierpost are you sure this is happening and it is a security risk? What about [this question on Security](https://security.stackexchange.com/questions/20282/is-passing-sensitive-data-through-the-process-environment-secure)? – Kamafeather Mar 26 '20 at 18:57
  • 1
    @Kamafeather: indeed, [it seems](https://security.stackexchange.com/questions/14000/environment-variable-accessibility-in-linux) only the user running the process and `root` can see its environment. That makes a big difference. I should delete my comment. – reinierpost Mar 27 '20 at 13:33
0

Something like:

ssh user@host bash -c "set -e; $(env); . thescript.sh"

...might work (untested)

Bit of a hack but if you cannot change the server config for some reason it might work.

  • `ssh # open an ssh connection` `user@host # With user to host` Then, ssh accepts a command, so we run: `bash -c # -c says to run the following args as the command (as opposed to a file)` `set -e; #unneeded, but causes shell to exit on error` `$(env); # env prints all environment variables, which we then set as part of the command we are running` `. thescript.sh # run this script with the environment we just set up.` – josefwells Apr 22 '20 at 21:54