Golang SSH load LD_PRELOAD and LD_LIBRARY_PATH environment variables - go

I'm trying to connect to a remote server using Golang SSH package, but there's a SOCKS between my workstation and this remote server.
I'm able to connect to the server by simply setting a LD_PRELOAD and LD_LIBRARY_PATH and then running:
$ export LD_PRELOAD="/path/to/lib"
$ export LD_LIBRARY_PATH="/path/to/lib"
$ ssh user#hostname
But when I set these variables within the Go code, it doesn't work:
os.Setenv("LD_PRELOAD", "/path/to/file")
os.Setenv("LD_LIBRARY_PATH", "/path/to/file")
If I set these variables within the Go code and try the following, it works:
ssh := exec.Command("ssh", "hostname")
output, _ := ssh.Output()
fmt.Println(string(output))
The ssh PermitUserEnvironment is set as yes
Is there any way to "force" the Golang SSH to use these environment variables?

(Edit: This answer does not necessarily apply to Go 1.8 and above. See comments for discussion)
LD_PRELOAD and LD_LIBRARY_PATH are environment variables processed by the dynamic linker when a program is starting up. If you set those environment variables inside the program, they don't have an effect on the program itself since the linker didn't see them.
On the other hand, the environment variables will affect external applications that you run (the ssh command for example) from within the program, since the linker is given control to resolve the shared libraries that the application uses.
If you instead set those environment variables before running the Go program, I think you'll have the desired effect. (This is only applicable if the compiled program is linked to the shared standard C library. See #JimB's comments below for more details.)

Related

shell script behaves differently when called using paramiko vs interactive shell [duplicate]

I am trying to run sesu command in Unix server from Python with the help of Paramiko exec_command. However when I am running this command exec_command('sesu test'), I am getting
sh: sesu: not found
When I am running simple ls command it giving me desired output. Only with sesu command it is not working fine.
This is how my code looks like:
import paramiko
host = host
username = username
password = password
port = port
ssh=paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(ip,port,username,password)
stdin,stdout,stderr=ssh.exec_command('sesu test')
stdin.write('Password')
stdin.flush()
outlines=stdout.readlines()
resp=''.join(outlines)
print(resp)
The SSHClient.exec_command by default does not run shell in "login" mode and does not allocate a pseudo terminal for the session. As a consequence a different set of startup scripts is (might be) sourced, than in your regular interactive SSH session (particularly for non-interactive sessions, .bash_profile is not sourced). And/or different branches in the scripts are taken, based on an absence/presence of TERM environment variable.
Possible solutions (in preference order):
Fix the command not to rely on a specific environment. Use a full path to sesu in the command. E.g.:
/bin/sesu test
If you do not know the full path, on common *nix systems, you can use which sesu command in your interactive SSH session.
Fix your startup scripts to set the PATH the same for both interactive and non-interactive sessions.
Try running the script explicitly via login shell (use --login switch with common *nix shells):
bash --login -c "sesu test"
If the command itself relies on a specific environment setup and you cannot fix the startup scripts, you can change the environment in the command itself. Syntax for that depends on the remote system and/or the shell. In common *nix systems, this works:
PATH="$PATH;/path/to/sesu" && sesu test
Another (not recommended) approach is to force the pseudo terminal allocation for the "exec" channel using the get_pty parameter:
stdin,stdout,stderr = ssh.exec_command('sesu test', get_pty=True)
Using the pseudo terminal to automate a command execution can bring you nasty side effects. See for example Is there a simple way to get rid of junk values that come when you SSH using Python's Paramiko library and fetch output from CLI of a remote machine?
You may have a similar problem with LD_LIBRARY_PATH and locating shared objects.
See also:
Environment variable differences when using Paramiko
Certain Unix commands fail with "... not found", when executed through Java using JSch

Where could I find docker-standard environment variables like DOCKER_HOST?

I'm using docker-maven-plugin. And it said -
"By default the plugin will try to connect to docker on localhost:2375. Set the DOCKER_HOST environment variable to connect elsewhere.
DOCKER_HOST=tcp://<host>:2375
Other docker-standard environment variables are honored too such as TLS and certificates.".
After I protect the Docker daemon socket reference to https://docs.docker.com/engine/security/https/. I think I need to set some variables like DOCKER_TLS_VERIFY="1" and also variable which is used to locate ca.pem file. So where could I find these docker-standerd environment variables?
You would find (and set) them on the same user that is running the docker-client.
EG:
nick#primestorage01:~$ set | grep DOCKER
DOCKER_HOST=terrorbyte:2376
DOCKER_TLS_VERIFY=true
You can do that many ways for an interactive login. One way is via a .bashrc file. (assuming you are using bash)
In .bashrc, you can add these lines:
#docker
export DOCKER_HOST=terrorbyte:2376
export DOCKER_TLS_VERIFY=true
If this is some sort of automation, depending on your methodology .bashrc won't be called (Specifically, if it's a non interactive shell such as via ssh host COMMAND. In this case, you'll need to set the environment variables another way.
PS, make sure you also put the certificates in the expected directory to make your life easier. The expected directory is ~/.docker

how to make emacs recognize bash environment variables, including self-defined ones

I have this need to let Emacs recognize all the shell environment variables.
The current setup:
I use VirtualBox and launch Emacs there to remotely access server files via the Tramp mode. When i do c-x c-f, and type
$RESOURCE_HOME/foo.bar
Emacs can't recognize this path, even if this is a valid path on the server -- $RESOURCE_HOME is a self-defined var.
I know this question's been answered there: How do I make Emacs recognize bash environment variables for compilation?
But there are so many self-defined variables that I don't want to write them manually.
I wonder if it's possible to solve it in a better way.
NOTE: i'm using Tramp mode, so please clarify your ideas saying vbox machine vs. server machine. Thanks!
Emacs already lets you use envvars like you suggest above. So your problem is that those vars aren't defined in Emacs's environment. Most likely it's because you define those vars in your shell's init file but that you start Emacs from a context where the shell hasn't been involved so those init files haven't been started yet.
If so, a simple fix is to start Emacs from a shell.

source a script from gdb

Before I debug or execute a program on my system at work, I have to source a file that contains numerous paths and settings that are specific to each project. Is there a way I can do this from gdb? I tried putting it into a .gdbinit file in the working directory, but that doesn't seem to be working. I tried to see if the environmental variable was set by typing
(gdb) shell echo $MY_VAR
and it was blank. Any ideas?
Basically to set the environment variable in the command prompt, you can use the set environment varname [=value]. More information is present here. Since you have noted down there are huge number of paths to be set, you can add them to a file like myGdbSrc and then load them explicitly using source [-s] [-v] filename. You can find details on loading a file here.
I have tried both of them and it works.
HTH.
PS: I have tried it on GNU GDB 6.6 version on SUSE Linux. However, it must work across all version since it seems to be basic command.
How about writing a wrapper script which sources your settings before loading gdb?
E.g. some trivial example:
#!/bin/sh
source my-script-which-sets-up-the-environment
gdb $*
This can of course also add arguments to the gdb invocation to setup paths, load a gdb script, etc.

View windows environment variables in Cygwin

Is there a way to sync windows environment variables with Cygwin?
For example, in CMD echo %inetroot% gives the path to a project build. Is it possible to transfer this env variable to Cygwin such that echo $inetroot provides the same path?
Thanks!
Use the env program to so that ... or echo "$inetroot". I think the variable names are case-sensitive, though (in Bash and thus MinGW).
Those variables are all available in MinGW from Windows (user profile and global). Again, use env to list them or for example env|grep -i inetroot to find the properly capitalized version of the variable name.

Resources