# SSH
SSH(Secure Shell 的缩写)是一种网络协议,用于加密两台计算机之间的通信,并且支持各种身份验证机制。
实务中,它主要用于保证远程登录和远程通信的安全,任何网络服务都可以用这个协议来加密。
SSH 也是 Linux 系统的登录工具,现在广泛用于服务器登录和各种加密通信。
# SSH 是什么
历史上,网络主机之间的通信是不加密的,属于明文通信。这使得通信很不安全,一个典型的例子就是服务器登录。登录远程服务器的时候,需要将用户输入的密码传给服务器,如果这个过程是明文通信,就意味着传递过程中,线路经过的中间计算机都能看到密码,这是很可怕的。
SSH 就是为了解决这个问题而诞生的,它能够加密计算机之间的通信,保证不被窃听或篡改。它还能对操作者进行认证(authentication)和授权(authorization)。明文的网络协议可以套用在它里面,从而实现加密。
# SSH 历史
1995 年,芬兰赫尔辛基工业大学的研究员 Tatu Ylönen 设计了 SSH 协议的第一个版本。
SSH 1 协议存在一些安全漏洞,所以 1996 年又提出了 SSH 2 协议,但是,官方的 SSH2 软件是一个专有软件,不能免费使用。
1999 年,OpenBSD 的开发人员决定写一个 SSH 2 协议的开源实现,这就是 OpenSSH 项目。
现在,SSH-2 有多种实现,既有免费的,也有收费的。本书的内容主要是针对 OpenSSH。
# SSH 架构
SSH 的软件架构是服务器-客户端模式(Server - Client)。
向服务器发出请求的部分,称为客户端(client),OpenSSH 的实现为 ssh;
接收客户端发出的请求的部分,称为服务器(server),OpenSSH 的实现为 sshd。
# SSH 服务器
SSH 的架构是服务器/客户端模式,两端运行的软件是不一样的。OpenSSH 的客户端软件是 ssh,服务器软件是 sshd。
如果没有安装 sshd,可以用下面的命令安装。
# Debian
sudo apt install openssh-server
# 启动
sshd
# 自启
sudo systemctl enable sshd.service
# 重启
sudo systemctl restart sshd.service
# SSH 客户端
OpenSSH 的客户端是二进制程序 ssh。它在 Linux/Unix 系统的位置是/usr/local/bin/ssh
Linux 系统一般都自带 ssh,如果没有就需要安装。
# Ubuntu 和 Debian
sudo apt install openssh-client
# SSH 配置
ssh 公钥生成和上传到服务器
# 生成密钥
ssh-keygen -C "[email protected]"
# 生成公司 SSH-key
ssh-keygen -t rsa -C "[email protected]" -f ~/.ssh/id-rsa
# 生成Github SSH-key
ssh-keygen -t rsa -C "[email protected]" -f ~/.ssh/github-rsa
# 上传密钥
ssh-copy-id -i id-rsa user@hostname
ssh-copy-id -i github-rsa user@hostname
# 测试
ssh -T [email protected]
ssh -T git@yougitserver
# 基本用法
ssh 登录服务器的命令如下。
# 不指定用户名的情况下,将使用客户端的当前用户名
ssh hostname
ssh user@hostname
ssh -l username host
ssh 默认连接服务器的 22 端口,-p 参数可以指定其他端口。
ssh -p 8821 foo.com
ssh foo.com:8821
# 主机设置
用户个人的配置文件~/.ssh/config
,可以按照不同服务器,列出各自的连接参数,从而不必每一次登录都输入重复的参数。下面是一个例子。
Host remoteserver
HostName remote.example.com
User neo
Port 2112
ssh remoteserver
# 等同于
ssh -p 2112 [email protected]
# SSH 密钥登录
SSH 默认采用密码登录,这种方法有很多缺点,简单的密码不安全,复杂的密码不容易记忆,每次手动输入也很麻烦。密钥登录是比密码登录更好的解决方案。
# 生成密钥
密钥登录时,首先需要生成公钥和私钥。OpenSSH 提供了一个工具程序 ssh-keygen 命令,用来生成密钥。
ssh-keygen
# 指定密钥的加密算法
ssh-keygen -t rsa
# 指定密钥的二进制位数
ssh-keygen -t rsa -b 1024
# 添加注释
ssh-keygen -C username#@host
# 手动上传公钥
生成密钥以后,公钥必须上传到服务器,才能使用公钥登录。
OpenSSH 规定,用户公钥保存在服务器的~/.ssh/authorized_keys 文件。
注意,authorized_keys 文件的权限要设为 644,即只有文件所有者才能写。
chmod 644 ~/.ssh/authorized_keys
# 自动上传公钥
OpenSSH 自带一个 ssh-copy-id 命令,可以自动将公钥拷贝到远程服务器
ssh-copy-id -i key_file user@host
#
ssh-copy-id -i id_rsa user@host
# 关闭密码登录
为了安全性,启用密钥登录之后,最好关闭服务器的密码登录。
对于 OpenSSH,具体方法就是打开服务器 sshd
的配置文件 /etc/ssh/sshd_config
,将 PasswordAuthentication
这一项设为 no
。
PasswordAuthentication no
修改配置文件以后,不要忘了重新启动 sshd,否则不会生效。
service sshd restart
# SCP 命令
scp 是 secure copy
的缩写,相当于 cp 命令 + SSH。它的底层是 SSH 协议,默认端口是 22,相当于先使用 ssh 命令登录远程主机,然后再执行拷贝操作。
使用 scp 传输数据时,文件和密码都是加密的,不会泄漏敏感信息。
# 本地文件复制到远程
复制本机文件到远程系统的用法如下。
# 语法
$ scp SourceFile user@host:directory/TargetFile
# 示例
$ scp file.txt [email protected]:/remote/directory
# 将本机整个目录拷贝到远程目录下
$ scp -r localmachine/path_to_the_directory username@server_ip:/path_to_remote_directory/
# 远程文件复制到本地
# 语法
$ scp user@host:directory/SourceFile TargetFile
# 示例
$ scp [email protected]:/remote/file.txt /local/directory
# 两个远程系统之间的复制
本机发出指令,从远程主机 A 拷贝到远程主机 B 的用法如下。
# 示例
$ scp [email protected]:/files/file.txt [email protected]:/files