概念知识
参考: https://codecharms.me/posts/security-ssh
SSH
SSH (Secure Shell)是一种连接加密机制,能够保证我们在传送数据时,会先进行加密,并且只有通过认证的才能解密。使用的是公钥加密技术
属于client-server模型,要建立一个ssh连接的条件:
- 远端服务器要跑一个SSH daemon,默认监听端口22的连接
- 本地要用一个SSH client程序,使用SSH protocol来传送数据
SSH使用形式:
- 最基本的ssh连接远端
- tunneling 隧道
- SFTP
- SCP
SSH具体使用公钥加密的运行机制:
公钥(用于认证和让别人加密)和私钥(用于电子签名和解密)。举个例子:A要使用SSH传数据给B,此时他们都拥有了对方的公钥。过程包含5个步骤:
- A用自己的私钥给信息签名
- A用B的公钥给信息加密
- 信息传送给B
- B用自己的私钥解密
- B用A的公钥来确认签名来自A
其实SSH登陆有这三种方式:
- 密钥
- 密码
- 证书
OpenSSH
OpenSSH 是一個 SSH 協定的開源實作,也可以說是遵守 SSH 的一組工具。
sshd是 OpenSSH 的 server component,當出現一個連線請求,sshd會根據 client 來建立對應的連線
主要包括几个部分:ssh(客户端)、sshd(主程序)、scp、sftp、ssh-keygen、ssh-agent、ssh-add等
SSL/TLS
HTTPS的核心技术(SSL/TLS):握手,以及使用CA进行身份认证。与SSH作用有些相似,都是为了保证安全连接。但前者主要用户资料传输,后者用于执行指令。
一个实例
来自 https://codecharms.me/posts/security-ssh 的关于github的一个ssh例子:
每當我們要送訊息(指令)給 GitHub (remote server) 時,我們就可以
- 用我們的私鑰加密指令。
- 用 Github 的公鑰加密指令。
- 傳送指令到 GitHub server。
- GitHub server 用它自己的私鑰解密。
- GitHub server 用我們的公鑰來驗證我們的身份。
SSH常用命令
登陆
|
|
远程执行命令
|
|
服务器指纹
当ssh首次连接某个远程服务器时,会有这个确认提示:
|
|
这里的sha256就是所谓的服务器指纹,也就是该远程服务器的公钥的哈希值。
这是因为首次连接时,对于本机来说远程服务器是陌生的,所以需要额外确认下服务器指纹。输入yes,就会将该指纹写入本机的~/.ssh/known_hosts中。每次连接时,服务器会判断欲连接的远程主机是否已在此known_hosts文件中,如果在,就不弹出确认提示。
此外,查看公钥的指纹命令:
|
|
当远程服务器变更了公钥(比如重装SSH;或是通过虚拟地址可连接主备机中的主机,当主备切换时,连接实际主机的公钥信息也不同),此时需要会有这样的警告:
|
|
在确认新的公钥可信任的情况下,可将原先的公钥指纹从~/.ssh/known_hosts中删掉,或直接vi进入文件删除对应行:
ssh-keygen -R hostname
此后,再次尝试连接,并将新的公钥指纹添加进来即可。
参考:https://ronpad.com/docs/ssh/client-3.html
配置文件
sshd配置文件(服务端配置文件)
路径:/etc/ssh/sshd_config
格式:
- 每个命令占据一行,大小写不敏感
- 中间用空格或等号连接,如
port 2034或port = 2034 #开头的行表示注释,但是#只能放在开头
修改完配置文件后:
|
|
配置项
sshd配置文件中支持很多配置项,这里就先了解一些我认为常用的吧!
- AllowGroups 允许登陆的用户组
- AllowUsers 允许登陆的用户(也可用user@address的形式),用空格或多行指定(如果不指定,默认所有用户可登陆)
- AllowTCPForwarding 是否允许端口转发,默认yes。local表示只允许本地转发,remote表示只允许远程端口转发
- ClientAliveInterval 允许客户不输入的间隔时间,超过这段时间,用户没发任何信号的话会自动关闭SSH连接
- DenyGroups 指定不允许登陆的用户组
- DenyUsers 指定不允许登陆的用户
- PermitRootLogin 是否允许root用户登陆,默认yes,建议改为no
- Port 指定sshd监听的端口(默认22),可以通过配置多行来同时监听多个端口
- PubKeyAuthentication 是否允许公钥登陆,默认yes
- X11Forwarding 指定是否打开X window的转发,默认no
参考:https://ronpad.com/docs/ssh/server-2.html
ssh配置文件(客户端配置文件)
路径:/etc/ssh/ssh_config,用户个人的配置文件在~/.ssh/config,优先级高于全局的
个人连接配置文件设置
可以在~/.ssh/config中设置连接各个远程主机的默认连接参数,例如:
|
|
上面代码中,
Host *表示对所有主机生效,后面的Port 2222表示所有主机的默认连接端口都是2222,这样就不用在登录时特别指定端口了。这里的缩进并不是必需的,只是为了视觉上,易于识别针对不同主机的设置。
配置项
同理,就先列举出一些我认为常用的吧!
- checkHostIP 检查SSH服务器的IP地址是否和公钥数据库吻合
- Port 指定客户端连接的SSH服务器端口
- PubKeyAuthentication 是否支持密钥登陆,还需要在服务端配置
- StrictHostKeyChecking
yes表示严格检查,服务器公钥为未知或发生变化,则拒绝连接。no表示如果服务器公钥未知,则加入客户端公钥数据库,如果公钥发生变化,不改变客户端公钥数据库,输出一条警告,依然允许连接继续进行。ask(默认值)表示询问用户是否继续进行。(详细分析见下面会单独给出)
端口转发
SSH除了作为登陆远程服务器的作用,还可以作为加密通信的中介。比如在两台无加密的服务器之间的充当加密通信的跳板。这个功能称为端口转发(port forwarding),也称为SSH 隧道(tunnel)。
- 动态转发
- 本地转发
- 远程转发
StrictHostKeyChecking
用于ssh连接时指定是否要进行远程主机的公钥确认,可以有这三种取值:
- no:如果key在本地不存在,则直接添加到known_hosts中,只给出警告,并不会停下来
- ask:默认的级别,如果连接时判断到远程key不匹配,则给出交互式提示,不会直接登陆
- yes:如果不匹配,拒绝连接,不会提示详细信息
该参数的配置在:
- ssh客户端配置文件 /etc/ssh/ssh_config
- 当前用户的ssh配置文件 ~/.ssh/config
- 直接在ssh命令中指定:
ssh -o StrictHostKeyChecking=no ....
参考:https://www.cnblogs.com/aspirant/p/10654041.html