Start ssh-agent on login [closed]

Questions : Start ssh-agent on login [closed]

I have a site as a remote Git repo pulling from using an SSH alias. I can manually start the ssh-agent on my server but I have to do this every time I login via SSH.

I manually start the ssh-agent:

eval ssh-agent $SHELL 

Then I add the agent:

ssh-add ~/.ssh/bitbucket_id 

Then it shows up when I do:

ssh-add -l 

And I’m good to go. Is there any way to automate this process so I don’t have to do it every time I login? The server is running RedHat 6.2 (Santiago).

Total Answers: 12 Answers 12

Popular Answers:

  1. Please go through this article. You may find this very useful:

    Just in case the above link vanishes some day, I am capturing the main piece of the solution below:

    This solution from Joseph M. Reagle by way of Daniel Starin:

    Add this following to your .bash_profile

    SSH_ENV="$HOME/.ssh/agent-environment" function start_agent { echo "Initialising new SSH agent..." /usr/bin/ssh-agent | sed 's/^echo/#echo/' > "${SSH_ENV}" echo succeeded chmod 600 "${SSH_ENV}" . "${SSH_ENV}" > /dev/null /usr/bin/ssh-add; } # Source SSH settings, if applicable if [ -f "${SSH_ENV}" ]; then . "${SSH_ENV}" > /dev/null #ps ${SSH_AGENT_PID} doesn't work under cywgin ps -ef | grep ${SSH_AGENT_PID} | grep ssh-agent$ > /dev/null || { start_agent; } else start_agent; fi 

    This version is especially nice since it will see if you’ve already started ssh-agent and, if it can’t find it, will start it up and store the settings so that they’ll be usable the next time you start up a shell.

  2. Old question, but I did come across a similar situation. Don’t think the above answer fully achieves what is needed. The missing piece is keychain; install it if it isn’t already.

    sudo apt-get install keychain 

    Then add the following line to your ~/.bashrc

    eval $(keychain --eval id_rsa) 

    This will start the ssh-agent if it isn’t running, connect to it if it is, load the ssh-agent environment variables into your shell, and load your ssh key.

    Change id_rsa to whichever private key in ~/.ssh you want to load.

    Some useful options for keychain:

    • -q Quiet mode
    • --noask Don’t ask for the password upon start, but on demand when ssh key is actually used.


  3. The accepted solution have following drawbacks:

    • it is complicated to maintain;
    • it evaluates storage file which may lead to errors or security breach;
    • it starts agent but doesn’t stop it which is close equivalent to leaving the key in ignition.

    If your keys do not require to type password, I suggest following solution. Add the following to your .bash_profile very end (edit key list to your needs):

    exec ssh-agent $BASH -s 10<&0 << EOF ssh-add ~/.ssh/your_key1.rsa  ~/.ssh/your_key2.rsa &> /dev/null exec $BASH <&10- EOF 

    It have following advantages:

    • much simpler solution;
    • agent session ends when bash session ends.

    It have possible disadvantages:

    • interactive ssh-add command will influence only one session, which is in fact an issue only in very untypical circumstances;
    • unusable if typing password is required;
    • started shell becomes non-login (which doesn’t influence anything AFAIK).

    Note that several ssh-agent processes is not a disadvantage, because they don’t take more memory or CPU time.

  4. Tried couple solutions from many sources but all seemed like too much trouble. Finally I found the easiest one 🙂

    If you’re not yet familiar with zsh and oh-my-zsh then install it. You will love it 🙂

    Then edit .zshrc

    vim ~/.zshrc 

    find plugins section and update it to use ssh-agent like so:

    plugins=(ssh-agent git) 

    And that’s all! You’ll have ssh-agent up and running every time you start your shell

  5. So I used to use the approaches described above, but I kind of prefer the agent to die when my last bash session ends. This is a bit longer than the other solutions, but its my preferred approach. The basic idea is that the first bash session starts the ssh-agent. Then each additional bash session checks for the config file (~/.ssh/.agent_env). If that is there and there is a session running then source the environment and create a hardlink to the socket file in /tmp (needs to be on the same filesystem as the original socket file). As bash sessions shut down each deletes its own hardlink. The last session to close will find that the hardlinks have 2 links (the hardlink and the original), removal of the processes own socket and killing of the process will result in 0, leaving a clean environment after the last bash session closes.

    # Start ssh-agent to keep you logged in with keys, use `ssh-add` to log in agent=`pgrep ssh-agent -u $USER` # get only your agents  if [[ "$agent" == "" || ! -e ~/.ssh/.agent_env ]]; then # if no agents or environment file is missing create a new one # remove old agents / environment variable files kill $agent running rm ~/.ssh/.agent_env # restart eval `ssh-agent` echo 'export SSH_AUTH_SOCK'=$SSH_AUTH_SOCK >> ~/.ssh/.agent_env echo 'export SSH_AGENT_PID'=$SSH_AGENT_PID >> ~/.ssh/.agent_env fi # create our own hardlink to the socket (with random name)  source ~/.ssh/.agent_env MYSOCK=/tmp/ssh_agent.${RANDOM}.sock ln -T $SSH_AUTH_SOCK $MYSOCK export SSH_AUTH_SOCK=$MYSOCK end_agent() { # if we are the last holder of a hardlink, then kill the agent nhard=`ls -l $SSH_AUTH_SOCK | awk '{print $2}'` if [[ "$nhard" -eq 2 ]]; then rm ~/.ssh/.agent_env ssh-agent -k fi rm $SSH_AUTH_SOCK } trap end_agent EXIT set +x 
  6. Just to add yet another solution :P, I went with a combination of @spheenik and @collin-anderson ‘s solutions.

     # Ensure that we have an ssh config with AddKeysToAgent set to true if [ ! -f ~/.ssh/config ] || ! cat ~/.ssh/config | grep AddKeysToAgent | grep yes > /dev/null; then echo "AddKeysToAgent yes" >> ~/.ssh/config fi # Ensure a ssh-agent is running so you only have to enter keys once if [ ! -S ~/.ssh/ssh_auth_sock ]; then eval `ssh-agent` ln -sf "$SSH_AUTH_SOCK" ~/.ssh/ssh_auth_sock fi export SSH_AUTH_SOCK=~/.ssh/ssh_auth_sock 

    Could be a little more elegant but its simple and readable. This solution:

    • ensures AddKeysToAgent yes is in your ssh config so keys will be automatically added upon use
    • doesn’t prompt you to enter any passphrases at login (again, one-time passphrase entering occurs on first use)
    • silently starts an ssh-agent if it has not already started one

    Comments welcome 🙂

  7. Users of the fish shell can use this script to do the same thing.

    # content has to be in .config/fish/ # if it does not exist, create the file setenv SSH_ENV $HOME/.ssh/environment function start_agent echo "Initializing new SSH agent ..." ssh-agent -c | sed 's/^echo/#echo/' > $SSH_ENV echo "succeeded" chmod 600 $SSH_ENV . $SSH_ENV > /dev/null ssh-add end function test_identities ssh-add -l | grep "The agent has no identities" > /dev/null if [ $status -eq 0 ] ssh-add if [ $status -eq 2 ] start_agent end end end if [ -n "$SSH_AGENT_PID" ] ps -ef | grep $SSH_AGENT_PID | grep ssh-agent > /dev/null if [ $status -eq 0 ] test_identities end else if [ -f $SSH_ENV ] . $SSH_ENV > /dev/null end ps -ef | grep $SSH_AGENT_PID | grep -v grep | grep ssh-agent > /dev/null if [ $status -eq 0 ] test_identities else start_agent end end 
  8. I solved it by adding this to the /etc/profile – system wide (or to user local .profile, or .bash_profile):

    # SSH-AGENT  #!/usr/bin/env bash SERVICE='ssh-agent' WHOAMI=`whoami |awk '{print $1}'` if pgrep -u $WHOAMI $SERVICE >/dev/null then echo $SERVICE running. else echo $SERVICE not running. echo starting ssh-agent > ~/.ssh/agent_env fi . ~/.ssh/agent_env 

    This starts a new ssh-agent if not running for the current user, or re-sets the ssh-agent env parameter if running.

  9. I use the ssh-ident tool for this.

    From its man-page:

    ssh-ident – Start and use ssh-agent and load identities as necessary.

  10. I like your answers a lot. It made working from cygwin / linux hosts a lot easier. I combined start and end functions to make it secure.

    SSH_ENV="$HOME/.ssh/.agent_env" function start_agent { echo "Initialising new SSH agent..." eval `/usr/bin/ssh-agent` echo 'export SSH_AUTH_SOCK'=$SSH_AUTH_SOCK >> ${SSH_ENV} echo 'export SSH_AGENT_PID'=$SSH_AGENT_PID >> ${SSH_ENV} echo succeeded chmod 600 "${SSH_ENV}" . "${SSH_ENV}" > /dev/null /usr/bin/ssh-add; } # Source SSH settings, if applicable if [ -f "${SSH_ENV}" ]; then . "${SSH_ENV}" > /dev/null #ps ${SSH_AGENT_PID} doesn't work under cywgin ps -ef | grep ${SSH_AGENT_PID} | grep ssh-agent$ > /dev/null || { start_agent; } else start_agent; fi # create our own hardlink to the socket (with random name) MYSOCK=/tmp/ssh_agent.${RANDOM}.sock ln -T $SSH_AUTH_SOCK $MYSOCK export SSH_AUTH_SOCK=$MYSOCK end_agent() { # if we are the last holder of a hardlink, then kill the agent nhard=`ls -l $SSH_AUTH_SOCK | awk '{print $2}'` if [[ "$nhard" -eq 2 ]]; then rm ${SSH_ENV} /usr/bin/ssh-agent -k fi rm $SSH_AUTH_SOCK } trap end_agent EXIT set +x 
  11. Quote from “Eloquent Javascript” 3rd edition by Marijn Haverbeke:

    The difference in meaning between undefined and null is an accident of Javascript’s design, and it doesn’t matter most of the time. In cases where you actually have to concern yourself with these values, I recommend treating them as mostly interchangeable

    Honestly, at first, I am a bit skeptical about this advice. However, in my own interpretation, it is a lazy (vs eager) way to deal with their differences. Maybe, we don’t have to deal with the differences at all. If we have to, we can delay our concern (util we have to) and not hyperactively/defensively worry about it every step of the way as those values (null and undefined) flow through our code.

    PS: This is not a direct answer to your question. This is just a related opinion.

  12. The type of null is Object, while the type of undefined is undefined. Null means ‘no value’, while undefined means ‘not existing’.

    typeof undefined; //undefined typeof null; // Object undefined !== null; //true undefined == null; //true undefined === null; //false var var1; var1; //undefined  var var2 = null; var2; //null 
  13. Generally – don’t use null to avoid confusion.

    1. Standard library methods return undefined, not null
    let a = [10]; console.log(a[1]) //=> undefined console.log(a.find(value => value === 5)) //=> undefined 
    1. I see often in people’s code that some variable was undefined at first, then assigned to some value, then cleared by setting to null. That’s not consistent, better to set back to undefined.

    Still, null makes sense if framework uses it, or for json serialization.

  14. const data = { banners: null } const { banners = [] } = data; console.log(data) // null const data = { banners: undefined } const { banners = [] } = data; console.log(data) // [] 
  15. let a = null; console.log(a); // null let b; console.log(b); // undefined
  16. If a variable is not initialized then it is undefined. undefined is not a object. Example: var MyName; console.log(typeof MyName);

    Check the console log in development tool, it will be printed as undefined.

    null is a a object.If you want some variable to be null then null is used.null variable exists but value is not known.It should be assigned to a variable pro grammatically. null is not automatically initialized.

    Example : var MyName = null; console.log(typeof MyName); Check the csole log in development tool, it will be an object.

  17. Just to add my views –

    A variable that is declared only, and never used anywhere, is removed off by an optimizing compiler in case of compiled languages like C++[or a warning is flagged in the IDE]. It ultimately means that the variable is non-existent because it’s memory is never allocated.

    In case of javascript interpreter, [I guess] a variable is treated as existing only from the point onwards where it is given a value. Before that point, it’s type is “undefined”, and no memory is allocated for it. And, so its type is undefined.

    A null in javascript is a value that represents an address, but that address points to nothing yet[non-existent reference]. Nevertheless, its a value.

  18. Null is ALWAYS an unknown object that exists in memory, whereas undefined is not.

Tasg: git, ssh

Answer Link
  • Unable to run NoraUI mvn verify goal
  • Unable to run my app on emulator in VS Code
  • Unable to run multiple instances of libVLC(MobileVLCKit) in IOS via flutter framework
  • Unable to run make on griddb source on ubuntu 20.04 (building from source)
  • Unable to run latexindent macOS Monterey 12.0.1
  • Unable to run kotlinc-native command
  • Unable to run JUnit Test… Java.lang.ExceptionInInitializerError (Android Studio)
  • Unable to run java with -Xmx > 966m
  • Unable to run ionic cap run android from wsl2 inorder to start android emulator
  • Unable to run Intel HAXM installer: Cannot start process, the working directory does not exist
  • fs
  • Unable to run Google Analytics sample code
  • unable to run flutter run after upgarding to flutter 2.8.0 from 2.5.3
  • Unable to run Django with PostgreSQL in Docker
  • Unable to Run Container Using testcontainers
  • Unable to run ClojureScript Hello World program, Error building classpath. Error reading edn.
  • unable to run client command for apache karaf 4.3.3 through remote server
  • Unable to run c program 2nd time using eclipse
  • unable to run c++ in visual studio code on m1 chipset
  • Unable to run Android Instrumented Tests
  • Unable to run adb, check your Android SDK installation and ANDROID_SDK_ROOT environment variable: …AndroidSdkplatform-toolsadb.exe
  • Unable to run a singlespecific .spec.ts file through angular cli using ng test –include option
  • Unable to run a Mango query
  • Unable to return response back to view in laravel from package
  • Unable to return object reference in std::optional
  • Unable to return NULL in a function that expects an integer return type
  • Unable to return correct change in JavaScript Cash Register
  • Unable to retrieve version information from Elasticsearch nodes. Request timed out
  • Unable to retrieve values from Axios Response data
  • Unable to retrieve dotenv JWT secret Error: secretOrPrivateKey must have a value
  • Unable to resolve your shell environment
  • Unable to resolve token for FCM while implementing Push notification for Xamarin
  • Unable to resolve the request yii
  • Unable to resolve service for type Swashbuckle.AspNetCore.Swagger.ISwaggerProvider
  • Unable to resolve service for type Microsoft.EntityFrameworkCore.Diagnostics.IDiagnosticsLogger