Safely Remembering Ssh Credentials in Bash Script

Safely remembering ssh credentials in bash script

Use a control socket to share an authenticated connection among multiple processes:

ssh -fNM -S ~/.ssh/sock otheruser@host  # Will prompt for password, then exit
...
ssh -S ~/.ssh/sock otheruser@host command1
ssh -S ~/.ssh/sock otheruser@host command2
...
ssh -S ~/.ssh/sock -O exit otheruser@host # Close the master connection

See man ssh_config, under the ControlPath option, for information on how to create a unique path for the control socket.

Setup and use SSH ControlMaster Session in a Shell Script

Your code looks fine. I haven't tested it, but the first process that tries to use the master connection should probably block until the master connection has actually successfully been established. You can use the -N option to avoid running a spurious shell on the master connection:

ssh -N -o 'ControlMaster=yes' -S "$ssh_control_socket" "$HOST" &

It's perfectly fine to simply kill the ssh process once all the subordinate sessions have completed.

SSH on windows without storing password in clear

You may want to consider using key authentication as opposed to a password.

People will say use a password in addition to the key, but if your alternative is storing the password on your PC in a file anyway, someone with access to your machine owns you in either case.. So you just need to generate the keys. The requirement is: no-one but you has access to that key file.

http://www.linuxproblem.org/art_9.html

I'm in the same boat, have to use Windows, but for me www.mingw.org which gives you a shell, and the basic *nix tools - extremely useful for SSH, connect to remote Linux VPS, etc.. Cygwin, of course which is similar, and has an easier tool (setup.exe if I recall) to install new apps. I actually use git-bash with is mingw with git. No-GUIs. I've found this easy to just drop to the mingw shell when I need to use ssh openssl cut awk etc..

So running any remote command using SSH from the command line without third-party programs like Putty, or those with GUIs, etc.. Using the key authentication and offing password auth completely in ssh on the remote device (at least on devices where you have control) is some additional lockdown for the remote device, especially if you're the only one need access it.

Which leaves, scheduling the script. There should be a way to do that via batch file and Windows or within the command line environment.

Why git can't remember my passphrase under Windows

I realize that this question is coming up on two years old, but I had the same issue and several answers here did not completely answer the question for me. Here are three step-by-step solutions, depending on whether you use TortoiseGit in addition to msysgit or not.

First solution Assumes Windows, msysgit, and PuTTY.

  1. Install msysgit and PuTTY as instructed.

  2. (Optional) Add PuTTY to your path. (If you do not do this, then any references to PuTTY commands below must be prefixed with the full path to the appropriate executable.)

  3. If you have not done so already, then generate a key hash as instructed at GitHub or as instructed by your Git host.

  4. Again, if you have not already done so, convert your key for use with PuTTY's pageant.exe using puttygen.exe. Instructions are in PuTTY's documentation, in this helpful guide, and several other places in cyberspace.

  5. Run PuTTY's pageant.exe, open your .ppk file ("Add Key"), and provide your passphrase for your key.

  6. Access Windows' environment variables dialog (Right-click on "Computer", Click on "Properties", Click on "Advanced system settings" or the "Advanced" tab, click on "Environment Variables"). Add the following environment variable:

    GIT_SSH=C:\full\path\to\plink.exe

    Replace "C:\full\path\to" with the full installation path to PuTTY, where plink.exe is found. It is probably best to add it to the "User variables" section. Also, make sure that the path you use to plink.exe matches the path you use for Pageant (pageant.exe). In some cases, you may have several installations of PuTTY because it might be installed along with other applications. Using plink.exe from one installation and pageant.exe from another will likely cause you trouble.

  7. Open a command prompt.

  8. If you are trying to connect to a git repository hosted at Github.com then run the following command:

    plink.exe git@github.com

    If the git repository you are trying to connect to is hosted somewhere else, then replace git@github.com with an appropriate user name and URL. (Assuming Github) You should be informed that the server's host key is not cached, and asked if you trust it. Answer with a y. This will add the server's host key to PuTTY's list of known hosts. Without this step, git commands will not work properly. After hitting enter, Github informs you that Github does not provide shell access. That's fine...we don't need it. (If you are connecting to some other host, and it gives you shell access, it is probably best to terminate the link without doing anything else.)

  9. All done! Git commands should now work from the command line. You may want to have pageant.exe load your .ppk file automatically at boot time, depending on how often you'll be needing it.

Second solution Assumes Windows, msysgit, and TortoiseGit.

TortoiseGit comes with PuTTY executables and a specially modified version of plink (called TortoisePlink.exe) that will make things easier.

  1. Install msysgit and TortoiseGit as instructed.

  2. If you have not done so already, then generate a key hash as instructed at GitHub or as instructed by your Git host.

  3. Again, if you have not already done so, convert your key for use with TortoiseGit's pageant.exe using TortoiseGit's puttygen.exe. Instructions are in PuTTY's documentation, in the helpful guide linked to in the first solution, and in several other places in cyberspace.

  4. Run TortoiseGit's pageant.exe, open your .ppk file ("Add Key") and provide your passphrase for your key.

  5. Access Windows' environment variables dialog (Right-click on "Computer", Click on "Properties", Click on "Advanced system settings" or the "Advanced" tab, click on "Environment Variables"). Add the following environment variable:

    GIT_SSH=C:\full\path\to\TortoisePlink.exe

    Replace "C:\full\path\to" with the full installation path to TortoiseGit, where TortoisePlink.exe is found. It is probably best to add it to the "User variables" section. Also, make sure that the path you use to TortoisePlink.exe matches the path you use for Pageant (pageant.exe). In some cases, you may have several installations of PuTTY because it might be installed along with other applications. Using TortoisePlink.exe from the TortoiseGit installation and pageant.exe from another installation of a different application (or from a standalone PuTTY installation) will likely cause you trouble.

  6. All done! Git commands should now work from the command line. The first time you try to connect to your git repository you will probably be informed that the server's host key is not cached, and asks if you trust the server. Click on "Yes". (This is TortoisePlink.exe in action.)

    You may want to have pageant.exe load your .ppk file automatically at boot time, depending on how often you'll be needing it.

Third solution Assumes Windows, msysgit, and the native command prompt.

  1. Install msysgit
  2. Make sure to allow git to be used on the MS-DOS command prompt
  3. Run start-ssh-agent
  4. Enter SSH passphrases
  5. All done! Git commands should now work in the native command prompt.

Save password between bash script execution

Depending on what the "multiple invocations" of the script are doing, you could do this using 2 scripts, a server and a client, using a named pipe to communicate. Warning: this may be unportable.

Script 1 "server":

#!/bin/bash

trigger_file=/tmp/trigger
read -s -p "Enter password: " password
echo
echo "Starting service"
mknod $trigger_file p
cmd=
while [ "$cmd" != "exit" ]; do
read cmd < $trigger_file
echo "received command: $cmd"
curl -u username:$password http://www.example.com/
done
rm $trigger_file

Script 2 "client":

#!/bin/bash

trigger_file=/tmp/trigger
cmd=$1
echo "sending command: $cmd"
echo $cmd > $trigger_file

Running:

$ ./server
Enter password: .....
Starting service
received command: go

other window:

$ ./client go
sending command: go

EDIT:

Here is a unified self-starting server/client version.

#!/bin/bash

trigger_file=/tmp/trigger
cmd=$1

if [ -z "$cmd" ]; then
echo "usage: $0 cmd"
exit 1
fi

if [ "$cmd" = "server" ]; then
read -s password
echo "Starting service"
mknod $trigger_file p
cmd=
while [ "$cmd" != "exit" ]; do
read cmd < $trigger_file
echo "($$) received command $cmd (pass: $password)"
curl -u username:$password http://www.example.com/
done
echo exiting
rm $trigger_file
exit
elif [ ! -e $trigger_file ]; then
read -s -p "Enter password: " password
echo
echo $password | $0 server &
while [ ! -e $trigger_file ]; do
sleep 1
done
fi

echo "sending command: $cmd"
echo $cmd > $trigger_file

How can I save username and password in Git?

Attention: This method saves the credentials in plaintext on your PC's disk. Everyone on your computer can access it, e.g. malicious NPM modules.

Run

git config --global credential.helper store

then

git pull

provide a username and password and those details will then be remembered later. The credentials are stored in a file on the disk, with the disk permissions of "just user readable/writable" but still in plaintext.

If you want to change the password later

git pull

Will fail, because the password is incorrect, git then removes the offending user+password from the ~/.git-credentials file, so now re-run

git pull

to provide a new password so it works as earlier.

I need to securely store a username and password in Python, what are my options?

I recommend a strategy similar to ssh-agent. If you can't use ssh-agent directly you could implement something like it, so that your password is only kept in RAM. The cron job could have configured credentials to get the actual password from the agent each time it runs, use it once, and de-reference it immediately using the del statement.

The administrator still has to enter the password to start ssh-agent, at boot-time or whatever, but this is a reasonable compromise that avoids having a plain-text password stored anywhere on disk.

ssh-agent does not remember identities when running inside a docker container in DC/OS

Docker Version

Check that your local version of Docker matches the version installed on the DC/OS agents. By default, the DC/OS 1.9.3 AWS CloudFormation templates uses CoreOS 1235.12.0, which comes with Docker 1.12.6. It's possible that the entrypoint behavior has changed since then.

Docker Command

Check the Mesos task logs for the Marathon app in question and see what docker run command was executed. You might be passing it slightly different arguments when testing locally.

Script Errors

As mentioned in another answer, the script you provided has several errors that may or may not be related to the failure.

  1. echo $PRIVATE_KEY should be echo "$PRIVATE_KEY" to preserve line breaks. Otherwise key decryption will fail with Bad passphrase, try again for /root/.ssh/id_rsa:.
  2. expect -c "spawn ssh-add /root/.ssh/id_rsa; expect \"Enter passphrase for /root/.ssh/id_rsa:\" send \"\"; interact " should be expect -c "spawn ssh-add /root/.ssh/id_rsa; expect \"Enter passphrase for /root/.ssh/id_rsa:\"; send \"\n\"; interact ". It's missing a semi-colon and a line break. Otherwise the expect command fails without executing.

File Based Secrets

Enterprise DC/OS 1.10 (1.10.0-rc1 out now) has a new feature named File Based Secrets which allows for injecting files (like id_rsa files) without including their contents in the Marathon app definition, storing them securely in Vault using DC/OS Secrets.

  • Creation: https://docs.mesosphere.com/1.10/security/secrets/create-secrets/
  • Usage: https://docs.mesosphere.com/1.10/security/secrets/use-secrets/

File based secrets wont do the ssh-add for you, but it should make it easier and more secure to get the file into the container.

Mesos Bug

Mesos 1.2.0 switched to using Docker --env_file instead of -e to pass in environment variables. This triggers a Docker env_file bug that it doesn't support line breaks. A workaround was put into Mesos and DC/OS, but the fix may not be in the minor version you are using.

A manual workaround is to convert the rsa_id to base64 for the Marathon definition and back in your entrypoint script.

Jenkins pipeline - ssh to different machine and where to store credentials (using ssh/SSHAgent plugin/etc...)

So unfortunately, you're right.

It looks like the ssh-agent-plugin only supports stored user,passphrase,public key credentials added through the Credentials Management area in Jenkins. See this unit test that verifies that ssh-agent is working correctly based around a public key. It's unlikely that there is untested functionality in the plugin to support user+password auth.

If you can, make the switch to Public Key based authentication. If for some reason you can't switch ... you COULD install sshpass on your Jenkins box, but this is generally considered bad practice.

node {
stage 'Does sshpass work?'
sh 'sshpass -p \'password\' ssh user@host "ls; hostname; whois google.com;"'
}

Is there a way to cache https credentials for pushing commits?

Since Git 1.7.9 (released 2012), there is a neat mechanism in Git to avoid having to type your password all the time for HTTP / HTTPS, called credential helpers.

You can just use one of the following credential helpers:

git config --global credential.helper cache

The credential.helper cache value tells Git to keep your password cached in memory for a particular amount of minutes. The default is 15 minutes, you can set a longer timeout with:

# Cache for 1 hour
git config --global credential.helper "cache --timeout=3600"

# Cache for 1 day
git config --global credential.helper "cache --timeout=86400"

# Cache for 1 week
git config --global credential.helper "cache --timeout=604800"

You can also store your credentials permanently if so desired, see the other answers below.

GitHub's help also suggests that if you're on Mac OS X and used Homebrew to install Git, you can use the native Mac OS X keystore with:

git config --global credential.helper osxkeychain

For Windows, there is a helper called Git Credential Manager for Windows or wincred in msysgit.

git config --global credential.helper wincred # obsolete

With Git for Windows 2.7.3+ (March 2016):

git config --global credential.helper manager

For Linux, you would use (in 2011) gnome-keyring(or other keyring implementation such as KWallet).

Nowadays (2020), that would be (on Linux)

Fedora

sudo dnf install git-credential-libsecret
git config --global credential.helper /usr/libexec/git-core/git-credential-libsecret

Ubuntu

sudo apt-get install libsecret-1-0 libsecret-1-dev
cd /usr/share/doc/git/contrib/credential/libsecret
sudo make
git config --global credential.helper /usr/share/doc/git/contrib/credential/libsecret/git-credential-libsecret


Related Topics



Leave a reply



Submit