17

My problem is, that I have to set env variables (like GIT_EXEC_PATH) on a server. I need that variables by every connection (so by bash and by remote commands either). I managed to set those variables by bash with .bash_profile, but I have problems with the remote commands. I found that it's possible to write commands in ~/.ssh/authorized_keys before the actual rsa key, but I don't wan't to write there always, I need a permanent solution... I found that the ~/.ssh/rc file is executed by every ssh login, so I put there my env variable declarations, but it didn't work. The variables are set in the rc file, but after that they disappeared. :S Maybe the rc file runs in a subshell :S Is there any way to define those variables in bash and in remote commands without code duplication?

Edit:

I edited the question, because the server is a godaddy shared host, so it has a unique config. The /etc/ssh/sshd_config and the /etc/ssh/ssh_config files are empty. There are comments in those files, if you are curious I can copy it here.

  1. The ~/.bash_profile is sourced (by bash connections only),
  2. the ~/.bashrc is never sourced,
  3. the ~/.profile is never sourced,
  4. the ~/.ssh/environment is never sourced,
  5. the ~/.ssh/rc is sourced (by bash and remote both), but I think it's called in subshell, because the variables disappearing.
  6. The ~/.ssh/authorized_keys is sourced by every time, but I have to write the commands before every rsa key (so I don't wan't to configure with that).

Summary:

I can configure the bash well (with .bash_profile), but I cannot configure the remote calls. That's the problem. I'm looking for a file which is sourced by both bash and remote commands.

For example:

The git-upload-pack command finds the exe file, because the GIT_EXEC_PATH env variable is set, but with remote: "git clone user@domain.com:myrepo local/myrepo" the server doesn't find that command, because the GIT_EXEC_PATH is not set.

Edit2:

According to this, and my printenv logs: the ~/.ssh/rc is running in normal shell, not in subshell, so it's a riddle why the env variables not sticking...

I created an executable: ~/logenv:

echo "" >> mylog.txt
date >> mylog.txt
printenv >> mylog.txt
echo "" >> mylog.txt

And put this into the ~/.ssh/rc:

export AAA=teszt
source ~/logenv

By bash login & "source logenv" the result was:

Tue May 15 04:21:37 MST 2012
TERM=cygwin
SHELL=/bin/bash
SSH_CLIENT=censored
SSH_TTY=/dev/pts/2
USER=myuser
AAA=teszt
MAIL=/var/mail/myuser
PATH=/usr/local/bin:/bin:/usr/bin
PWD=/home/content/65/7962465
SHLVL=3
HOME=/var/chroot/home/content/65/7962465
LOGNAME=myuser
SSH_CONNECTION=censored
_=/usr/bin/printenv

Tue May 15 04:21:41 MST 2012
HOSTNAME=censored
TERM=cygwin
SHELL=/bin/bash
HISTSIZE=1000
SSH_CLIENT=censored

By remote "ssh myuser@domain.com 'exec ~/logenv'" the result was:

Tue May 15 04:25:52 MST 2012
SHELL=/bin/bash
SSH_CLIENT=censored
USER=myuser
AAA=teszt
MAIL=/var/mail/myuser
PATH=/usr/local/bin:/bin:/usr/bin
PWD=/home/content/65/7962465
SHLVL=3
HOME=/var/chroot/home/content/65/7962465
LOGNAME=myuser
SSH_CONNECTION=censored
_=/usr/bin/printenv

Tue May 15 04:25:52 MST 2012
SHELL=/bin/bash
SSH_CLIENT=censored
USER=myuser
PATH=/usr/local/bin:/bin:/usr/bin
MAIL=/var/mail/myuser
PWD=/home/content/65/7962465
HOME=/var/chroot/home/content/65/7962465

So the rc file is sourced, but after that the variables disappering... :S

inf3rno
  • 408
  • 2
  • 5
  • 17
  • Some options in this thread - http://stackoverflow.com/questions/216202/why-does-an-ssh-remote-command-get-fewer-environment-variables-then-when-run-man – EightBitTony May 14 '12 at 10:25
  • "Unlike /etc/sshrc, which is always processed by the Bourne shell ( /bin/sh), your rc file is processed by your account's normal login shell." - that's strange because it seems like it would not sourced by normal shell :S – inf3rno May 15 '12 at 10:35

8 Answers8

12

Assuming you have UsePAM yes in /etc/ssh/sshd_config, and assuming you want these environment variables set for every user, you can have pam set environment variables for you. If you have the environment variables defined in /etc/gitenv you could add this line to /etc/pam.d/sshd

auth required pam_env.so envfile=/etc/gitenv

Or by inpsecting this file, you might find that there is already a pam_env.so being used, and already a file you can add stuff to. Just be careful, and make sure you have thoroughly tested your changes before ending your ssh session, as when you are messing with pam, you can completely break your ability to login to your server, if you are not careful.

stew
  • 9,388
  • 1
  • 30
  • 43
  • I have a godaddy shared host account, so I can modify the ~ directory only. (It has centos op system.) – inf3rno May 14 '12 at 11:02
  • @inf3rno it does not harm to upvote good answer :) as anyway the solution that will solve your problem can be marked by a different mean. – Huygens May 16 '12 at 07:47
  • Ok. I will, but I'm not the only one who can up vote... :-) – inf3rno May 16 '12 at 18:30
  • On Ubuntu, seems that `/etc/environment` is sourced by `pam_env.so` by default – rcoup Dec 03 '19 at 20:28
5

I'm setting some environment variable for my SSH connections using the ~/.ssh/environment. The file can contain variable in the form VAR=value, no need to explicitly export them.

However, this user configuration file is ignored by default by the SSH server process unless the option PermitUserEnvironment is set to yes. Therefore you need to make sure to edit /etc/sshd_config on the SSH server to add or update this parameter:

PermitUserEnvironment yes

You need to reload the SSH server configuration. On RHEL or Suse Linux you do (as root)

/sbin/service sshd reload

(Possibly replace sshd by ssh if it does not work)

On Ubuntu (using upstart) you do

sudo reload ssh

On any other Linux, you could try (as root)

/etc/init.d/sshd reload

(Replace sshd by ssh or openssh or whatever that would correspond to the SSH server init script)

Huygens
  • 1,708
  • 3
  • 20
  • 36
2

I have no longer a godaddy shared host, so I cannot check whether the proposed solutions are valid. This will stay the accepted answer, since it worked by me when I asked the question. The other answers might work as well. I let the community decide that with upvotes.

Ok. The solution is that there is no solution on a godaddy shared host. I tried everything, but nothing works, so I decided that I stay with the ~/.ssh/authorized_keys:

command="~/connect.sh" ssh-rsa AAAAB3NzaC...

In the ~/connect.sh:

#!/bin/bash
if [ -f "${HOME}/.env_profile" ]; then
        source ~/.env_profile
fi;

if [ "x${SSH_ORIGINAL_COMMAND}x" == "xx" ]; then
        $SHELL --login
else
        eval "${SSH_ORIGINAL_COMMAND}"
fi;

And in the ~/.env_profile:

export PATH=$PATH:$HOME/bin:$HOME/git/libexec/git-core
export LD_LIBRARY_PATH=$HOME/git/lib
export GIT_EXEC_PATH=~/git/libexec/git-core
export GIT_TEMPLATE_DIR=~/git/share/git-core/templates

So I have to copy the command="..." to every rsa key in the authorized_keys. This is code duplication, but I don't think there is another solution on a godaddy shared hosts.

inf3rno
  • 408
  • 2
  • 5
  • 17
1

If you are using bash as your shell, try adding the environment settings to .bashrc.

Check first that this does get run upon login, it may not as the standard files often have something like:

# If not running interactively, don't do anything
[ -z "$PS1" ] && return

at the start of them. any change that you want to have made even for non-interactive logins will need to go above such a statement.

.profile is a more general place to put configuration like this and is respected by most shells (on a default Debian setup it is ~/.profile that calls ~/.bashrc in the first place). You may need to be more careful editing .profile in case it is ever interpreted by other shells - i.e. try to avoid using bash specific extensions.

Edit

If you have a .bash_profile edit that instead of .profile: bash will use it in favour of the more general file, and you can safely use bash specific things in there.

David Spillett
  • 22,754
  • 45
  • 67
1

You can use the command for all users/key without adding the command part in the authorized_keys by adding this line to the sshd_config file :

ForceCommand ~/connect.sh

In this case I suggest that you use an absolute path for the script

GARCIN David
  • 111
  • 5
0

I'm proposing you another approach.

You set up a file with the declaration of your environment variable and then you source it each time you call a remote command.

Example: you put the necessary variables in ~/.my_var.rc and then for each remote command you do ssh user@remote bash -c "source ~/.my_var.rc; <your command>"

If this suits you, you can then refine this concept and script it for convenience. If you need it only for git commands, then I would create a git.sh scripts that would do this:

#!/bin/bash

source ~/.my_var.rc

git $@

Assuming this script would be in your home directory, you would call it: ssh user@remote git.sh pull origin master

Note: it's a simple starting point. For instance, it does not support parameters with spaces.

Huygens
  • 1,708
  • 3
  • 20
  • 36
  • 1
    I can do that ofc, but that config is not for me alone, and it should work with git gui where the commands are automatically generated... – inf3rno May 15 '12 at 10:28
  • Do you connect to the ssh remote using the same user? If yes, then the file ~/.my_var.rc would be user specific and the git.sh common for all. If no, then you could add an extra parameter to git.sh that could help you differentiate which .rc file to source (or it using fixed IP, you could use the SSH_CLIENT env info to differentiate your users). The command should work with git gui, call `ssh -Y user@remote git.sh gui` – Huygens May 15 '12 at 11:09
  • I need the same env settings for every user. I won't add extra part to the commands, it's absurd... – inf3rno May 15 '12 at 11:34
  • Well then if the settings are the same for all users then the answer is complete and you can disregard my previous comment. You would probably need to put the .rc and .sh files in a directory that is common to/accessible by all users. – Huygens May 15 '12 at 12:32
  • @inf3rno if you want more answers, you should thanks already those that proposed good answers, even if not applicable to your case because information were missing in the original question. Or people won't bother trying. – Huygens May 16 '12 at 07:50
  • I can solve my problem with git by configuring my local git repo, but I think the location of the binarys should be somewhere in the server config, not in the config files on another computer... You should see, that this is a configuration problem, and configuration must be automatically, and cannot be dependent on the commands... So I think there is no such case your solution is acceptable in. Btw, thanks, that you attempted solve my problem! – inf3rno May 16 '12 at 18:39
0

This doesn't answer the general question about PATHS, but it does allow you to use a git repository on a remote server which does not have git in its path, and which you do not have root access to. This solution comes from this page.

git clone -u relative/path/to/bin/git-upload-pack username@host.com:relative/path/to/remote_repository.git

To also push and fetch:

git config remote.origin.receivepack relative/path/to/bin/git-receive-pack
git config remote.origin.uploadpack relative/path/to/bin/git-upload-pack
Ben
  • 1
0

/etc/profile will be sourced on each connection with ssh-client.