How does one put the ssh-agent socket file in a directory other than /tmp - openssh

I'd like to put the socket file that ssh-agent creates in a directory other than /tmp. If you look at the man page it mentions $TMPDIR so one might conclude that setting that environment variable will allow for this. I tried these:
$ export TMPDIR=$HOME/.ssh
$ ssh-agent
SSH_AUTH_SOCK=/tmp/ssh-gZSxgCXIOMVK/agent.4287; export SSH_AUTH_SOCK;
SSH_AGENT_PID=4288; export SSH_AGENT_PID;
echo Agent pid 4288;
and
$ TMPDIR=$HOME/.ssh ssh-agent
SSH_AUTH_SOCK=/tmp/ssh-cv6U38tey4XQ/agent.5160; export SSH_AUTH_SOCK;
SSH_AGENT_PID=5161; export SSH_AGENT_PID;
echo Agent pid 5161;
As you can see, ssh-agent ignores TMPDIR and puts the socket file in /tmp.
I looked at (I cloned it then ran grep) the ssh-agent source (git#github.com:openssh/openssh-portable.git) and searched for TMPDIR. I had one hit in the function mktemp_proto (misc.c:1401). It looks for the TMPDIR environment variable and uses it if defined, otherwise uses /tmp. The caller of mktemp looks like it calls, then creates the socket's directory, and later creates the socket file. This looks OK.
My next thought was that the version I am using is older than when this feature was added. Looking at the github repo mentioned above I determined that this was added in Version 5.8 on 2011/01/12. Running strings on the executable
$ cat /usr/bin/ssh-agent | strings | grep OpenSSH
outputs several lines, including this one
OpenSSH_6.6.1
So, the executable is at least 6.6.1. Doing a similar grep on TMPDIR finds one hit. So, this executable should be using TMPDIR.
I did this all on Ubuntu 14.04 LTS.
So my question is: How can I get ssh-agent to create a socket file in a directory of my choosing?

Related

Where can I store variables and values for current Unix user so that I can use them in SSH and scripts?

I have some variables I use quite frequently to configure and tweak my Ubuntu LAMP server stack but I'm getting tired of having to copy and paste the export command into my SSH window to register the variable and its value.
Essentially I would like to keep my variables and their values in a file inside the user profiles home directory so when I type a command into a SSH window or execute a bash script the variables can be easily used. I don't want to set any system-wide variables as some of these variables are for setting passwords etc.
What's the easiest way of doing this?
UPDATE 1
So essentially I could store the variables and values in a file and then each time I login into a SSH session I call this file up once to setup the variables?
cat <<"EOF" >> ~/my_variables
export foo='bar'
export hello="world"
EOF
ssh root#example.com
$ source ~/my_variables
$ echo "$foo"
$ bar
and then to call the variable from within a script I place source ~/my_variables at the top of the script?
#!/bin/bash
source ~/my_variables
echo "$hello"
Just add your export commands to a file and then run source <the-file> (or . <the-file> for non-bash shells) in your SSH session.

How to properly do GIT pull in SH?

I need to create script which will do pull request. Currently my code is:
#!/bin/sh
# -*- coding: utf-8 -*-
cd "/var/www/project"
GIT_SSH_COMMAND='ssh -i /var/www/deploy/access-key -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null'
git fetch origin
git reset --hard origin/dev
The thing is that each time I get:
Could not create directory '/var/www/.ssh'. Failed to add the RSA host
key for IP address '104.192.143.1' to the list of known hosts
(/var/www/.ssh/known_hosts). git#bitbucket.org: Permission denied
(publickey). fatal: Could not read from remote repository.
Under my normal user key works fine. Is it possible somehow specify know_hosts file from existing system user?
The line reading:
GIT_SSH_COMMAND='ssh -i ...'
is intended to provide an ssh key and several ssh options to the ssh command when Git—or more specifically, git fetch—uses ssh to call up another Git at an ssh-based URL.
This line is defective (or another line is missing), because as written, it sets the variable without also exporting it into the environment for git fetch. If the variable already exists in the environment, this particular defect is not a problem, since already-exported variables continue to be exported; but, if as is the more typical case, the variable does not exist yet, this just creates the variable locally.
There are two different ways to fix it: either put the variable-setting in front of the command itself, all on one logical line, as in:
GIT_SSH_COMMAND='ssh ...' git fetch
Or, add an export command, either on the line that sets the variable, or shortly afterward:
export GIT_SSH_COMMAND='...'
or:
GIT_SSH_COMMAND='...'
export GIT_SSH_COMMAND
Note that setting the variable on the same line as the command means to set it in the environment of that particular command, but not any longer than that. Setting it with an explicit export means to set it now and keep it set that way until it is changed, or the shell exits, whichever occurs first:
$ USER=hello sh -c 'echo $USER'
hello
$ echo $USER
torek
$ export USER=hello
$ sh -c 'echo $USER'
hello
$ echo $USER
hello

Append to a remote environment variable for a command started via ssh on RO filesystem

I can run a Python script on a remote machine like this:
ssh -t <machine> python <script>
And I can also set environment variables this way:
ssh -t <machine> "PYTHONPATH=/my/special/folder python <script>"
I now want to append to the remote PYTHONPATH and tried
ssh -t <machine> 'PYTHONPATH=$PYTHONPATH:/my/special/folder python <script>'
But that doesn't work because $PYTHONPATH won't get evaluated on the remote machine.
There is a quite similar question on SuperUser and the accepted answer wants me to create an environment file which get interpreted by ssh and another question which can be solved by creating and copying a script file which gets executed instead of python.
This is both awful and requires the target file system to be writable (which is not the case for me)!
Isn't there an elegant way to either pass environment variables via ssh or provide additional module paths to Python?
How about using /bin/sh -c '/usr/bin/env PYTHONPATH=$PYTHONPATH:/.../ python ...' as the remote command?
EDIT (re comments to prove this should do what it's supposed to given correct quoting):
bash-3.2$ export FOO=bar
bash-3.2$ /usr/bin/env FOO=$FOO:quux python -c 'import os;print(os.environ["FOO"])'
bar:quux
WFM here like this:
$ ssh host 'grep ~/.bashrc -e TEST'
export TEST="foo"
$ ssh host 'python -c '\''import os; print os.environ["TEST"]'\'
foo
$ ssh host 'TEST="$TEST:bar" python -c '\''import os; print os.environ["TEST"]'\'
foo:bar
Note the:
single quotes around the entire command, to avoid expanding it locally
embedded single quotes are thus escaped in the signature '\'' pattern (another way is '"'"')
double quotes in assignment (only required if the value has whitespace, but it's good practice to not depend on that, especially if the value is outside your control)
avoiding of $VAR in command: if I typed e.g. echo "$TEST", it would be expanded by shell before replacing the variable
a convenient way around this is to make var replacement a separate command:
$ ssh host 'export TEST="$TEST:bar"; echo "$TEST"'
foo:bar

Phonegap CLI runs from SSH session but not from bash script

I am in the process of setting up a Ubuntu 14.04 server to automate hybrid Android app builds with Phonegap CLI. Having written up all the relevant scripts I ran into a rather strange problem - when I SSH in to my server I can run the script and run all Phonegap commands successfully in my interactive shell session. However, every attempt to run those same commands in an automated script that gets triggered by some other - visitor generated - event fails. To pin down the problem I reduced it down to a simple experiment which I outline below.
Step 1 - write a startup script, pgtest in /etc/init.d
#! /bin/bash
source ~/.nvm/nvm.sh;
nvm use stable;
cd /home;
ls >> /tmp/ls;
which node >> /tmp/node;
which git >> /tmp/git;
which phonegap >> /tmp/pgp;
phonegap -v >> /tmp/pgpv 2>/tmp/pgpe;
Explanations
I use NVM to manage Node so I am making sure that the system knows where to find nvm.sh
I am firing up NVM to use the stable (4.1.1.) version of Node + NPM
I want to make sure that my batch file is actually being executed so I do ls /home and pipe its output to the /tmp/ls file.
I want to be sure that node, git and phonegap are actually available so I do pipe the output from which node|git|phonegap to files in the /tmp folder.
Little point in complicating things so I am issuing the simplest of Phonegap commands, phonegap -v to report the current version number. Any errors that might happen when doing this are being piped into the file /tmp/pgpe.
Step 2 - Make sure that pgtest is run last
ln -s /etc/init.d/pgtest /etc/rc2.d/S04PGTest
Explanation - I only want this script to be run after everything else on my server has had a chance to startup
With all of this in place I rebooted by server and examined the contents of the /tmp folder. My findings
ls - the folder listing for the /home folder present and correct.
node, git and pgp point to the locations of Node, Git and Phonegap
pgpv, which should contain the Phonegap version number, is EMPTY
pgpe is present and NOT empty
That last implies that the system encountered an error whilst attempting to execute phonegap -v. Here are the contents of pgpe.
path.js:8
throw new TypeError('Path must be a string. Received ' +
^
TypeError: Path must be a string. Received undefined
at assertPath (path.js:8:11)
at Object.posix.join (path.js:477:5)
at Object.
(/root/.nvm/versions/node/v4.1.1/lib/node_modules/phonegap/node_modules/phonegap-build/lib/common/config/global.js:17:28)
at Module._compile (module.js:434:26)
at Object.Module._extensions..js (module.js:452:10)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)
at Module.require (module.js:365:17)
at require (module.js:384:17)
at Object.
(/root/.nvm/versions/node/v4.1.1/lib/node_modules/phonegap/node_modules/phonegap-build/lib/common/config.js:9:13)
Now here is the curious thing. If I clear out the /tmp folder and issue a /etc/init.d/pgtest in an interactive shell session I get the following results
/tmp/ls present and populated with the /home folder listing as before
/tmp/node, /tmp/git /tmp/pgp present and correct
/tmp/pgpvreports 5.3.6 - the current Phonegap version number
/tmp/pgpe is EMPTY , i.e, no errors are reported
Clearly, the interactive bash shell environment has something that is not present when I run an automated script - at startup in this case but it also happens when I trigger the process via an automated script in any other way.
With all of this I am moving closer to pinning down the cause of the problem. However, there my knowledge of how these systems work is letting me down. What is the difference between the interactive shell environment and the one that is encountered by my automated script? Just how do I interpret the errors reported in /tmp/pgpe? What do I do to fix them?
I'd be most grateful to anyone who might be able to put me on the right track here.
Edit in light of #Eduardo's suggestions. I grabbed the two sets of environments (interactive & init.d). The results of doing a DIFF (interactive vs init.d) can be found in this fiddle. A somewhat less accessible dump of the DIFF result is shown below
--- /home/env.inter 2015-11-11 08:30:40.314172560 +0000
+++ /home/env.auto 2015-11-11 08:32:55.240906000 +0000
## -1,48 +1,38 ##
BASH=/bin/bash
BASHOPTS=cmdhist:complete_fullquote:extquote:force_fignore:hostcomplete:interactive_comments:login_shell:progcomp:promptvars:sourcepath
BASH_ALIASES=()
-BASH_ARGC=()
-BASH_ARGV=()
+BASH_ARGC=([0]="1")
+BASH_ARGV=([0]="start")
BASH_CMDS=()
BASH_LINENO=([0]="0")
-BASH_SOURCE=([0]="/etc/init.d/pgtest")
+BASH_SOURCE=([0]="/etc/rc2.d/S04pgtest")
BASH_VERSINFO=([0]="4" 1="3" [2]="11" [3]="1" [4]="release" [5]="x86_64-pc-linux-gnu")
BASH_VERSION='4.3.11(1)-release'
DIRSTACK=()
EUID=0
GROUPS=()
-HOME=/root
HOSTNAME=example.com
HOSTTYPE=x86_64
IFS=$' \t\n'
-LANG=en_US.UTF-8
-LESSCLOSE='/usr/bin/lesspipe %s %s'
-LESSOPEN='| /usr/bin/lesspipe %s'
-LOGNAME=root
-LS_COLORS='rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:.tar=01;31:.tgz=01;31:.arj=01;31:.taz=01;31:.lzh=01;31:.lzma=01;31:.tlz=01;31:.txz=01;31:.zip=01;31:.z=01;31:.Z=01;31:.dz=01;31:.gz=01;31:.lz=01;31:.xz=01;31:.bz2=01;31:.bz=01;31:.tbz=01;31:.tbz2=01;31:.tz=01;31:.deb=01;31:.rpm=01;31:.jar=01;31:.war=01;31:.ear=01;31:.sar=01;31:.rar=01;31:.ace=01;31:.zoo=01;31:.cpio=01;31:.7z=01;31:.rz=01;31:.jpg=01;35:.jpeg=01;35:.gif=01;35:.bmp=01;35:.pbm=01;35:.pgm=01;35:.ppm=01;35:.tga=01;35:.xbm=01;35:.xpm=01;35:.tif=01;35:.tiff=01;35:.png=01;35:.svg=01;35:.svgz=01;35:.mng=01;35:.pcx=01;35:.mov=01;35:.mpg=01;35:.mpeg=01;35:.m2v=01;35:.mkv=01;35:.webm=01;35:.ogm=01;35:.mp4=01;35:.m4v=01;35:.mp4v=01;35:.vob=01;35:.qt=01;35:.nuv=01;35:.wmv=01;35:.asf=01;35:.rm=01;35:.rmvb=01;35:.flc=01;35:.avi=01;35:.fli=01;35:.flv=01;35:.gl=01;35:.dl=01;35:.xcf=01;35:.xwd=01;35:.yuv=01;35:.cgm=01;35:.emf=01;35:.axv=01;35:.anx=01;35:.ogv=01;35:.ogx=01;35:.aac=00;36:.au=00;36:.flac=00;36:.mid=00;36:.midi=00;36:.mka=00;36:.mp3=00;36:.mpc=00;36:.ogg=00;36:.ra=00;36:.wav=00;36:.axa=00;36:.oga=00;36:.spx=00;36:.xspf=00;36:'
MACHTYPE=x86_64-pc-linux-gnu
-MAIL=/var/mail/root
-NVM_DIR=/root/.nvm
-NVM_IOJS_ORG_MIRROR=https://iojs.org/dist
-NVM_NODEJS_ORG_MIRROR=https://nodejs.org/dist
-NVM_RC_VERSION=
OPTERR=1
OPTIND=1
OSTYPE=linux-gnu
-PATH=/opt/android/platform-tools:/opt/android/tools:/opt/android:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
+PATH=/sbin:/usr/sbin:/bin:/usr/bin
PIPESTATUS=([0]="0")
-PPID=4801
+PPID=911
+PREVLEVEL=N
PS4='+ '
-PWD=/etc/init.d
+PWD=/
+RUNLEVEL=2
SHELL=/bin/bash
SHELLOPTS=braceexpand:hashall:interactive-comments
-SHLVL=3
-SSH_CLIENT='nn.nn.nn.nn nnnn nnnn'
-SSH_CONNECTION='nn.nn.nn.nn nnnn nn.nn.nn.nn nnnn'
-SSH_TTY=/dev/pts/0
-TERM=xterm
+SHLVL=1
+TERM=linux
UID=0
-USER=root
-XDG_RUNTIME_DIR=/run/user/1000
-XDG_SESSION_ID=5
+UPSTART_EVENTS=runlevel
+UPSTART_INSTANCE=
+UPSTART_JOB=rc
_=n
+previous=N
+runlevel=2
The only things I have changed here - masked the Host name and the SSH client IP address.
I am pretty sure I had tried this in my own experiments prior to posting this question but following #Eduardo's suggestion below I tried sticking in a
EXPORT PATH=/opt/android/platform-tools:/opt/android/tools:/opt/android:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
at the top of the script - just below the source ~/.nvm... line. A reboot later the result was still the same: an empty /tmp/pgpv and the same errors reported in /tmp/pgpe.
Just make sure to set the PATH variable inside your script to the same, longer one, you see on the diff, then retry automated.
I would probably also define the HOME and NVM* variables. As a test I'd create a test.sh script at the same directory of phonegap, with this content:
#!/bin/bash
set > /tmp/env_vars.log
And have your script as:
#!/bin/bash
export TERM=linux
export USER=root
export HOME=/root
export NVM_DIR=/root/.nvm
export NVM_IOJS_ORG_MIRROR=https://iojs.org/dist
export NVM_NODEJS_ORG_MIRROR=https://nodejs.org/dist
export NVM_RC_VERSION=
export PATH=/opt/android/platform-tools:/opt/android/tools:/opt/android:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
source ~/.nvm/nvm.sh
nvm use stable
cd /home
ls > /tmp/ls
which node > /tmp/node
which git > /tmp/git
which phonegap > /tmp/pgp
phonegap -v > /tmp/pgpv 2>/tmp/pgpe;
test.sh

Switch from t-shell to bash and source file in one command line

From my user on my machine, I ssh to a shared user on another machine that runs t-shell by default. I would like to create an alias that logs me in to the other machine as the shared user, cds to my personal folder on that machine, switches shell to bash, and sources a script which defines some additional aliases. How can I achieve this?
This is what I've tried so far. From my machine I run:
ssh -ty <otheruser>#<otherhost> 'cd <myfolder>; source tsh.personal'
On the other machine, I have the file ~/<myfolder>/tsh.personal which looks like
#!/bin/tsh
/bin/bash -c 'source ~/<myfolder>/bash.personal'
However, when I use the option -c for bash, it just runs the command and then exits, and then the connection to other machine closes because all comands passes to the ssh command has finished. I have also tried replacing the last row in ~/<myfolder>/tsh.personal with
/bin/bash -c 'source ~/<myfolder>/bash.personal; /bin/bash'
which tells bash to start another instance of bash, which won't exit. However, when that instance is started, it is like ~/<myfolder>/bash.personal was never sourced. Are all aliases reset whenever a new instance of bash is started, or why are the aliases not passed to the new instance?
Change tsh.personal to
exec /bin/bash --rcfile ~/<myfolder>/bash.personal
The exec isn't strictly necessary, but it cleans up the process table by replacing the tsh instance with a bash instance.

Resources