幽谷奇峰 | 燕雀鸣幽谷,鸿鹄掠奇峰

使用ssh和ssh-agent实现“无密码”登录远程机器


我们经常有从本地连接登录到远程机器的必要,例如,使用版本控制工具进行push操作时。每次push时都要求输入用户名和密码,这不仅不方便,也不安全。使用SSH密钥就可以轻松的解决这个问题。

本文目标

通过使用ssh和ssh-agent两种工具,加密安全地连接到远程机器,而又不用手工输入密码。

基本流程

  1. 在本地机器上创建密钥对
  2. 将公共密钥放到要连接的远程机器上
  3. 使用ssh-agent来缓存解密的私有密钥,实现后续的“无密码”连接

具体实现方法

以从基于Ubuntu系统的本地机器连接到GitHub.com为例进行说明。如果本地操作系统为Windows,请使用Cygwin或者msysgit。

步骤1:检查本地是否已存在密钥对

打开终端,运行:

1
$ cd ~/.ssh

如果提示"No such file or directory",就请直接跳到步骤3,否则继续步骤2.

步骤2:备份和删除本地已存在密钥对

1
2
3
4
$ ls
$ mkdir key_backup
$ cp id_rsa* key_backup
$ rm id_rsa*

步骤3:生成新的密钥对

1
$ ssh-keygen -t rsa -f ~/.ssh/github_rsa -C "github"

-t rsa表示密钥类型是rsa,-C选项用于添加comment,可以设置成自己的Email地址。

会提示你输入和确认密码。

然后,私有密钥会保存在/home/you/.ssh/github_rsa,公共密钥会保存在/home/you/.ssh/github_rsa.pub.

想修改密钥的解密密码,请使用以下命令:

1
$ ssh-keygen -p

在 SSH 用户配置文件 ~/.ssh/config 中指定证书名称,如果没有 config 文件的话就新建一个 (Linux 平台的话需使用该命令 chmod 644 ~/.ssh/config 来改变 config 文件权限),并输入以下内容:

1
2
3
Host github.com
    HostName github.com
    IdentityFile ~/.ssh/github_rsa

步骤4:添加公共密钥到远程机器(GitHub)

运行以下命令,复制公共密钥到剪切板。

1
2
$ sudo apt-get install xclip
$ xclip -sel clip < ~/.ssh/github_rsa.pub

说明:复制密钥时,不能增加额外的空格和新行,因此这里借助了工具xclip

然后,按照以下步骤添加公共密钥到GitHub:

  1. 打开github.com网站,登入自己的帐号
  2. 进入“Account Settings”
  3. 点击左边的“Add SSH key”
  4. 将刚才复制的公共密钥内容粘贴到“Key”文本框
  5. 点击“Add key”
  6. 输入GitHub帐号密码,确认操作

如果你所要连接的远程机器支持shell登入,就可以运行以下命令来添加公共密钥:

1
$ cat ~/.ssh/id_rsa.pub | ssh you@other-host 'cat - >> ~/.ssh/authorized_keys'

Note: 1. 如果远程机器运行的是一个较旧版的ssh,你可能要使用~/.ssh/authorized_keys2文件。 1. 如果远程机器运行的是Windows系统,你可能要用"type"代替"cat""$HOME"代替"~"

步骤5:测试密钥工作是否正常

1
$ ssh -T git@github.com

会提示你输入密钥密码,就是在步骤3里设置的密码。第一次你会看到以下警告:

1
2
3
The authenticity of host 'github.com (207.97.227.239)' can't be established.
RSA key fingerprint is 16:27:ac:a5:76:28:2d:36:63:1b:56:4d:eb:df:a6:48.
Are you sure you want to continue connecting (yes/no)?

输入“yes”,回车。如果看到以下消息,且“username”是正确的,就说明密钥已设置成功。

1
2
Hi username! You've successfully authenticated, but GitHub does not
provide shell access.

步骤6:运行ssh-agent

大多数linux发行版,在登入系统时便会自动启动一个ssh-agent进程。如果你的系统没有这个功能,请在~/.xsession文件中加入:

1
ssh-agent gnome-session

Note:请使用你自己的窗口管理器取代gnome-session

查看ssh-agent是否在运行:

1
$ ps -e | grep ssh-agent

但是,如果你使用的是Cygwin或者msysgit环境,请将以下代码添加进你的~/.profile或者~/.bashrc或者~/.bash_profile中。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
SSH_ENV="$HOME/.ssh/environment"

# start the ssh-agent
function start_agent {
    echo "Initializing new SSH agent..."
    # spawn ssh-agent
    ssh-agent | sed 's/^echo/#echo/' > "$SSH_ENV"
    echo succeeded
    chmod 600 "$SSH_ENV"
    . "$SSH_ENV" > /dev/null
    ssh-add
}

# test for identities
function test_identities {
    # test whether standard identities have been added to the agent already
    ssh-add -l | grep "The agent has no identities" > /dev/null
    if [ $? -eq 0 ]; then
        ssh-add
        # $SSH_AUTH_SOCK broken so we start a new proper agent
        if [ $? -eq 2 ];then
            start_agent
        fi
    fi
}

# check for running ssh-agent with proper $SSH_AGENT_PID
if [ -n "$SSH_AGENT_PID" ]; then
    ps -ef | grep "$SSH_AGENT_PID" | grep ssh-agent > /dev/null
    if [ $? -eq 0 ]; then
        test_identities
    fi
# if $SSH_AGENT_PID is not properly set, we might be able to load one from
# $SSH_ENV
else
    if [ -f "$SSH_ENV" ]; then
        . "$SSH_ENV" > /dev/null
    fi
    ps -ef | grep "$SSH_AGENT_PID" | grep ssh-agent > /dev/null
    if [ $? -eq 0 ]; then
        test_identities
    else
        start_agent
    fi
fi

这样,你每次启动Cygwin或者msysgit的shell时,都会自动运行ssh-agent,并添加私有密钥,提示你输入私有密钥的解密密码,然后你可以跳过步骤7了。

步骤7:将私有密钥添加到ssh-agent的缓存中

运行以下命令:

1
$ ssh-add ~/.ssh/github_rsa

会提示你输入私有密钥的解密密码(步骤3中设置的密码)

查看ssh-agent正在管理的密钥:

1
$ ssh-add -l

步骤8:测试ssh-agent

再次连接GitHub:

1
$ ssh -T git@github.com

不会再让你输入密码了。你再进行多少次git push操作,都不会要你输入密码了。爽吧:)

步骤9:更改repo的协议

要使用ssh-agent,就要求repo使用的协议是ssh,而不是https。查看repo所使用的协议:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
$head -n 10 .git/config
[core]
    repositoryformatversion = 0
    filemode = true
    bare = false
    logallrefupdates = true
[remote "origin"]
    url = https://github.com/yys294/vimfiles.git
    fetch = +refs/heads/*:refs/remotes/origin/*
[credential]
    helper = cache

将url的值改为ssh协议的模式即可

1
2
3
[remote "origin"]
    url = git@github.com:yys294/vimfiles.git
    fetch = +refs/heads/*:refs/remotes/origin/*

参考资料

  1. Generating SSH Keys
  2. Using ssh-agent with ssh
  3. Working with SSH key passphrases
  4. Set up SSH for Git and Mercurial on Mac OSX/Linux

本作品由 Yysfire 创作,采用知识共享许可协议进行许可。转载时请在显著位置标明本文永久链接:
http://yysfire.github.io/linux/using-ssh-agent-with-ssh.html


相关文章


最后修改
2012-10-30 22:16
发表时间
2012-10-25 21:06
本文标签
git 2 Linux 18 SSH 2 ssh-agent 2
关注我

侧栏导航