SSH 基本介绍

2016-07-26 linux security ssh

传统的 telnet、rcp ftp、rlogin、rsh 都是极不安全的,并且会使用明文传送密码,OpenSSH 提供了服务端后台程序和客户端工具,用来加密远程控件和文件传输过程中的数据,并由此来代替原来的类似服务。

OpenSSH 是 SSH (Secure SHell) 协议的免费开源实现,SSH 协议族可以用来进行远程控制,或在计算机之间传送文件。这里简单介绍下 SSH 和 OpenSSH 的使用。

OpenSSH logo

简介

SSH 采用的是公私钥加密方式,利用公钥进行加密,通过私钥解密,公钥任何人都可以看到,而私钥是私有的,需要安全保存。目前 ssh 有 V1 和 V2 两个版本, V2 加入了联机检测功能,可以避免联机过程中插入恶意攻击代码。

最常用的是远程登录,除此之外,还支持端口映射、X11 转发、sftp 文件传输等。

工作过程

How SSH Works

  1. 服务器侧私钥文件,安装后会生成 /etc/ssh/ssh_host* 密钥文件,启动时会进行检查。
  2. 客户端将已知服务器的公钥保存在 ~/.ssh/known_hosts 中,如果不存在则提醒用户是否添加。

安装使用

OpenSSH 不仅提供了一个 shell,而且还提供了一个较为安全的 ftp-server 做文本传输。

# dpkg --list | grep ssh                                  # Ubuntu中查看/安装OpenSSH Server
# apt-get install openssh-server

# yum install openssh-server openssh-clients openssh      # CentOS中安装

Ubutnu 中安装之后会包括 /etc/init.d/ssh 文件,可以通过如下方式启动/停止/重启 Openssh Server 。

# /etc/init.d/ssh [start | stop | restart]
# service ssh [start | stop | restart]

通过如下命令可以查看服务是否已经启动,其中 ssh 使用的是 22 号端口,使用 tcp 协议, ftp 同样使用 22 号端口。

# netstat -vatn | grep 22

在 CentOS7 中,可以通过如下命令启动。

# systemctl start sshd.service

客户端使用

正常情况下在安装完服务器后,可以通过如下命令进行简单的登录,如果远程主机的用户名和本地用户名一致可以省略 user,否则需要显示指定。

$ ssh user@host command

关于 ssh 客户端的详细参数可以参考 man 命令,常用的参数有:

  • -p 指定端口号,如果服务端非默认的 22 端口通过该参数指定。
  • -f 不登入主机直接执行一个命令。
  • -v 查看登录时候的详细信息,参数越多显示的详细信息越多,例如 -vv-vvv
  • -i 指定登录用的私钥文件。

另外,最常用的是通过 -o 参数指定选项,例如 ConnectTimeout=10 指定超时时间为 10 秒,如下是常见选项:

  • ConnectTimeout=N 与服务端建立链接时超时等待的时间。
  • StrictHostKeyChecking=[yes|no|ask] 新服务器如何添加到 known_hosts 文件,默认是 ask 由客户决定,或者 yes 直接加入。
  • PreferredAuthentications=publickey 指定登录时权限认证方案,包括publickey、password、keyboard-interactive 等。
  • IdentitiesOnly=yes 只使用指定的鉴权方式,否则通过 -i 指定后还会尝试默认的私钥,通过该参数则只使用指定。

如下简单介绍经常使用的场景。

在服务端执行命令

登入对方主机执行过指令后立刻离开。

$ ssh student@127.0.0.1 find / & > ~/find1.log

此时你会发现怎么画面卡住了,这是因为上头的指令会造成,已经登入远程主机,但是执行的指令尚未跑完,因此会在等待当中。

与上相似,但是让对方主机自己跑该指令,立刻回到本地主机继续工作。

$ ssh -f student@127.0.0.1 find / &> ~/find1.log

此时你会立刻注销 127.0.0.1 ,但 find 指令会自己在远程服务器跑喔!

配置文件

默认包括了如下的配置文件:

  • /etc/ssh/sshd_config 服务器配置文件。
  • ~/.ssh/authorized_keys 服务端保存的用户公钥,在登录用户主目录下,需手动设置,常用于“无密码登录”。
  • /etc/ssh/ssh_config ~/.ssh/ssh_config 客户端全局、用户配置文件。
  • ~/.ssh/known_hosts 客户端记录已通过验证的服务器,第一次登录时会提示是否将服务器添加到该文件中,以后再登录时,会利用该文件检测是否是之前的服务器,从而防止中间人攻击。

如下介绍服务端的详细介绍。

整体配置

Protocol 2,1    # SSH协议版本,1可能会有中间人攻击,建议只配置为2

登入设定部分

PermitRootLogin yes                      # 是否允许root登入
StrictModes yes                          # 严格检查目录权限,权限设置出错则不允许登陆
PubkeyAuthentication yes                 # 允许公钥登陆
AuthorizedKeysFile .ssh/authorized_keys  # 公钥保存文件
HostbasedAuthentication no               # 取消基于host的授权
PasswordAuthentication yes               # 使用密码验证
PermitEmptyPasswords no                  # 是否允许以空的密码登入
AllowUsers list                          # 允许登陆的用户,用空格分开,可以用*?通配符
DenyUsers foobar                         # 禁止某一个用户登入
AllowGroups nosh                         # 允许某一个组登入
DenyGroups nosh                          # 禁止某一个组登入

登入后设置

ClientAliveInterval 300        # 若300秒内没有收到客户端消息,则发送心跳报文
ClientAliveCountMax 0          # 客户端断开连接之前,能发送保活信息的条数,此时踢出用户

安全设置

IgnoreRhosts yes              # 取消使用~/.ssh/.rhosts来做为认证

其它

UseDNS yes                    # 关闭DNS验证,详见后面的介绍

杂项

整理一些常见的配置、注意事项、使用技巧。

目录权限设置

ssh 对目录的权限有要求,主要是为了防止一些加密信息泄漏,使用时要设置好新生成的 config 文件权限才行,包括 ~ 目录权限是 750,~/.ssh 的是 700,~/.ssh/* 的是 600,~/.ssh/config 是 700 。

客户端心跳报文

主要是为了防止长时间没有交互导致链接断开,不同客户端设置略有区别。

SecureCRT:
   Properties->Terminal->Anti-dile
   设置每隔80秒发送一个字符串或是NO-OP协议包
Putty:
   Properties->Connection->Seconds between keepalives(0 to turn off)
   默认为0,改为80
Xshell:
   File->Properties->Connection->Keep Alive
   设置为80s
Linux:
   在/etc/ssh/ssh_config添加ServerAliveInterval 80

关闭DNS检查

OpenSSH 服务器有一个 DNS 查找选项 UseDNS 默认是打开的。

当客户端试图登录 OpenSSH 服务器时,服务器端先根据客户端的 IP 地址进行 DNS PTR 反向查询,查询出客户端的 host name,然后根据查询出的客户端 host name 进行 DNS 正向 A 记录查询,验证与其原始 IP 地址是否一致。

这是防止客户端欺骗的一种手段,但一般 IP 是动态的,不会有 PTR 记录的,打开这个选项不过是在浪费时间。

减少延迟

如果每次连接服务器都意味着你需要等待几十秒而无所事事,那么你或许应该试试在你的 SSH 配置中加入下面这条,这一配置可以在客户端或者服务端配置,或者在 ssh 登录时加上 -o GSSAPIAuthentication=no

GSSAPIAuthentication no

GSSAPI 是 Generic Security Services Application Program Interface (通用安全服务应用程序接口) 是 ITEF 的一个标准,允许不同的安全算法使用一个标准化的 API 来为网络产品提供加密认证。

OpenSSH 使用这个 API 并且底层的 kerberos 5 协议代码提供除了 ssh_keys 的另一种 ssh 认证方式。

参考