Ssh

Published: by Creative Commons Licence

  • Tags:

1.简介

Secure Shell(安全外壳协议,简称SSH)是一种加密的网络传输协议,可在不安全的网络中为网络服务提供安全的传输环境。SSH通过在网络中创建安全隧道来实现SSH客户端与服务器之间的连接。虽然任何网络服务都可以通过SSH实现安全传输,SSH最常见的用途是远程登录系统,人们通常利用SSH来传输命令行界面和远程执行命令。

2.SSH用途

2.1.登录远程主机

SSH的主要用途就是登录远程主机。假设你有一台ip或域名为host的主机,那么利用

ssh user@host

就可以登录到host上的user用户上。如果本地用户名和远程用户名一致,则也可以缩略用户名,即以

ssh host

就可以登录到host上的同名用户。由于SSH的默认端口为22,如果你修改了远程主机的SSH端口,则需要显式指定端口号。

ssh user@host -p port

其中port即为host主机上的SSH端口,如果希望修改ssh端口,可以借助下面步骤:

  1. 打开文件/etc/ssh/sshd_config
  2. 修改Port的对应值为新端口号

在登录的时候,被登录主机将会把自己的公钥发送过来。如果是一次登录,那么就会提示下面内容

The authenticity of host '[xxx.xx.xx.xx]:xxxx ([xxx.xx.xx.xx]:xxxx)' can't be established.
RSA key fingerprint is SHA256:Ge6fw6ZJDJP0V5RT5kdP7jfFeZIfLSDJJc/8oOBKra4.
Are you sure you want to continue connecting (yes/no)?

你必须判断登录主机发送来的公钥签名是否正确,如果正确就输入yes否则输入no。一旦输入yes后,该ssh公钥就会被加入到~/.ssh/known_hosts中,之后的登录如果发送来的公钥存储在known_hosts中则将不再需要验证。

2.1.1.口令验证

仅仅ssh连接了主机,还是不够的。要作为某个特定用户登录,必须键入密码。这是一般的登录方式。

2.1.2.密钥登录

假如你已经厌倦了每次登录都需要键入密码,那么你可以试试密钥的方式。其原理是本地生成私钥和公钥对,将公钥发布到远程主机上,这样之后登录就可以通过密钥对验证身份。

SSH 密钥对总是成双出现的,一把公钥,一把私钥。公钥可以自由的放在您所需要连接的 SSH 服务器上,而私钥必须稳妥的保管好。 所谓"公钥登录",原理很简单,就是用户将自己的公钥储存在远程主机上。登录的时候,远程主机会向用户发送一段随机字符串,用户用自己的私钥加密后,再发回来。远程主机用事先储存的公钥进行解密,如果成功,就证明用户是可信的,直接允许登录 shell,不再要求密码。这样子,我们即可保证了整个登录过程的安全,也不会受到中间人攻击。

下面是具体操作步骤:

  1. 如果已经有自己的公私钥对,可以跳过这一步。否则先利用下面命令生成rsa密钥对:
    ssh-keygen
    

    中间会提示输入密钥密码,可以留空,否则之后使用密钥需要先键入密码。 生成密钥id_rsa后,需要修改访问权限为600,即只有当前用户有读写权限。

    chmod 600 id_rsa
    
  2. 登录远程主机,将之前生成的公钥(.pub文件内容)拷贝到~/.ssh/authorized_keys文件尾部(另起一行),如果文件或目录不存在,需要手动创建。

  3. 打开远程主机上的/etc/ssh/sshd_config,修改下面几项的值,以允许使用密钥登录:
    RSAAuthentication yes
    PubkeyAuthentication yes
    AuthorizedKeysFile .ssh/authorized_keys
    

    之后重启远程主机上的sshd服务

    service sshd restart
    

    顺便一提,sshd表示ssh deamon,表示ssh的连接接收方,而ssh则用于发起ssh连接。

  4. 修改本地文件~/.ssh/config文件,追加下面内容:
    Host xxx #远程主机别名
     HostName xx.xx.xx.xx #远程主机地址
     User xx #登录用户名
     IdentityFile /root/.ssh/id_rsa #密钥文件
     Port xx #远程ssh端口
    

    config中可以配置多个主机信息,通过Host作为分隔符,分隔不同的主机。

  5. 现在就可以直接登录,利用下面的命令:
    ssh xxx #xxx是Host别名
    

2.1.3 ssh-agent管理密钥密码

如果你在2.1.2步骤中生成的密钥时指定了密码,那么每次使用该密钥都需要键入密码。这样依旧很麻烦(当然你也可以使用空密码,但是这样一旦私钥被他人获取将非常危险)。

ssh agent程序可以将你已经解密的私钥缓存起来,并在需要的时候提供给SSH。这样子在ssh agent的生命周期中每个私钥你只需要输入一次私钥密码即可。

OpenSSH自带了一个ssh agent名为ssh-agent。之后我们执行下面命令

echo 'eval $(ssh-agent)' >> ~/.bash_profile #每次登录用户shell时都会自动运行ssh-agent

之后我们逐一将自己的密钥加入ssh agent中。

ssh-add 密钥路径

2.2.内容转发

ssh不仅可以用于登录远程主机,还能用于端口转发。

ssh -D [options] port user@host #将所有发送向本地port端口的数据转发到远程主机host的ssh端口。
ssh -L [options] localPort:destHost:destPort agentHost #本机将所有传输到localPort的数据发送到agentHost,并要求agentHost将这些数据转发到destHost主机的destPort端口
ssh -R [options] sourcePort:targetHost:targetPort sourceHost #要求sourceHost监听自己的端口sourcePort,并利用ssh转发到本机,并由本机将数据转发到targetHost:targetPort上

options可以取下面值:

  • -N: 仅连接远程主机,不打开远程shell
  • -p port: 指定远程主机的端口
  • -f: 要求在执行命令前退至后台,该选项隐含-n。
  • -g: 允许远端主机连接本地转发的端口
  • -n: 把stdin重定向到/dev/null
  • -q: 安静模式,消除所有警告和诊断信息
  • -t: 强制分配伪终端
  • -T: 禁止分配伪终端
  • -v: 冗余模式
  • -c: 要求进行数据压缩

2.3 在远端执行命令

ssh也可以用于在远端直接执行命令。格式如下:

ssh [options] <remote host> <command> #在remotehost主机上执行命令command