SSH 用法进阶 —— 免密登录与端口转发

Posted by icebergu on 08-20,2020

ssh 是一个非常常用的工具,通常用来登录到远程主机上,不过 ssh 不仅仅只能用来登录,还能执行远程命令,或者进行多种的端口转发

基本使用

登录到远程主机

$ ssh <user>@<remote-ip>

ssh 默认连接的端口是 22,如果 ssh server 监听的其他端口的话
那么可以使用 -p <port>来指定端口

如果使用本地当前用户名登录的话,也可以省略 <user>@,只需要 <remote-ip>即可

如何查看 ssh server 监听的地址

# 远程主机上
$ netstat -tlnp | grep sshd

如何免密登录

使用 ssh 登录时,通常会需要输入密码,总会感觉不是很安全,比如让别人协助登录到主机上,就需要把密码告诉他
如果使用公钥认证的话,就只需要登录人提供一下公钥,而不需要告诉他密码了

查看 ssh server 是否支持公钥认证

# 远程主机中
$ cat /etc/ssh/sshd_config | grep Pub
#PubkeyAuthentication yes

默认为开启公钥认证,如果为 no 的话就需要修改为 yes,然后重启 ssh server

查看一下本地主机 ~/.ssh 目录下是否存在 rsa 秘钥(id_rsa.pubid_rsa
没有的话使用 ssh-keygen 生成秘钥,询问输入回车就行

[iceber@localhost ~]$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/iceber/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/iceber/.ssh/id_rsa.
Your public key has been saved in /home/iceber/.ssh/id_rsa.pub.
The key fingerprint is:
e7:af:48:91:e7:61:c4:0b:c2:11:74:0d:1f:56:61:13 iceber@localhost.localdomain
The key's randomart image is:
+--[ RSA 2048]----+
|     .+.ooo.Eo   |
|     . o +.o .   |
|      o . +      |
|       . + .     |
|        S *      |
|         B .     |
|        . o      |
|       . . .     |
|        . ...    |
+-----------------+

使用 ssh-copy-id 将公钥记录到到远程主机上

$ ssh-copy-id <user>@<remote-ip>

一般主机中都会有 ssh-copy-id 命令,如果不存在的话,可以手动将公钥添加到远端主机中

$ ssh <user>@<remote-ip> 'mkdir -p .ssh && cat >> .ssh/authorized_keys' < ~/.ssh/id_rsa.pub

需要注意 ~/.ssh 目录的权限必须是 700~/.ssh/authorized_keys 的权限必须是 600 或者 644 ,否则会出现异常

远程主机信任该公钥后,就不需要输入密码啦

使用其他秘钥

ssh 会默认使用 ~/.ssh/id_rsa~/.ssh/id_rsa.pub,如果想要使用其他的秘钥文件怎么呢

在执行 ssh-keygen 时,会要求选择秘钥的路径,输入新的秘钥路径

Enter file in which to save the key (/home/iceber/.ssh/id_rsa): /home/iceber/.ssh/custom_rsa

~/.ssh 中就会生成私钥custom_rsa 和公钥 custom_rsa.pub

ssh-copy-id -i <公钥路径> <user>@<remote-ip> 将指定的公钥发送给服务端
ssh 使用 -i <私钥路径> 来指定私钥

禁止密码登录

既然公钥可以登录了,有时为了安全考虑,也就不需要密码登陆了
修改 ssh server 配置 /etc/ssh/sshd_config

# /etc/ssh/sshd_config
PasswordAuthentication no # 关闭密码验证

配置远程主机,使用别名登录

虽然可以免密登录的,但是每次登录还是需要配置 userremote-ip,感觉好麻烦

~/.ssh/config 中可以配置远程主机的信息

# ~/.ssh/config
Host iceber
    HostName 10.10.10.100
    User iceber

可以直接使用 ssh iceber 登录了

Host * 相当于全局配置

还可以配置一些其他信息

  • Port <port> 远程主机的 ssh server port
  • ServerAliveInterval <seconds> client 会每隔多少秒向 server 发送一次请求,防止和服务器的连接断开
  • IdentityFile <path> 秘钥路径,rsa 的秘钥地址 (~/.ssh/id_rsa)

端口转发

ssh 不止能用来登录或者执行远程命令,还是用做端口转发
ssh 的端口转发分为三种 本地转发远程转发动态转发

在使用端口转发时,通常会使用到 -N-f 两个 flag

  • -N 表示不需要执行任何命令,用于端口转发
  • -f 表示在后台运行,不需要登录到远端主机上

本地转发

本地转发是指将发送到本地端口的请求发送到远端主机上

ssh -Nf -L <本地地址>:<本地端口>:<远程主机目标地址>:<远程主机目标端口> <user>@<remote-ip>

访问 <本地地址>:<本地端口>,数据会转发到 <remote-ip> 主机的<远程主机目标地址>:<远程主机目标端口>

<本地地址> 可以省略,默认为 127.0.0.1

场景

远端主机(10.10.10.100)中运行一个 http server,但是他只监听了 localhost:8080 地址,但是我想在本地访问这个地址,该怎么办

ssh -Nf -L 8000:127.0.0.1:8080 iceber@10.10.10.100

这时通过本地 127.0.0.1:8000 就可以访问到 10.10.10.100 机器中的本地服务了

有时 MySQL 会限制登录的 ip,这时就可以使用本地端口转发来访问了

远程转发

远程转发是指将发送到远端主机的请求转发到本地的目标端口

ssh -Nf -R <远程主机地址>:<远程主机端口>:<本地目标地址>:<本地目标端口> <user>@<remote-ip>

在本地执行 ssh 远程转发命令,访问 <远程主机地址>:<远程主机端口>时,请求会转发到本地<本地目标地址>:<本地目标端口>

<远程主机地址>: 可以省略,默认为 127.0.0.1,可以设置为 0.0.0.0 在所有网卡上建立转发
转发远程主机的非 localhost ip 时,需要修改 /etc/ssh/sshd_config

# /etc/ssh/sshd_config
GatewayPorts yes
场景

将局域网中的 ssh 通过远程主机暴露给外网
在局域网外,我们无法通过 ssh 连接到局域网中的主机,但是如果把局域网主机中将 ssh 端口和可以外网访问的远程主机端口建立远程转发,那么就可以通过远程主机访问局域网主机了

ssh -Nf R 10022:localhost:22 iceber@<remote-ip>

将远程主机的 localhost:10022 端口接收的请求转发到本地 localhost:22 中

这时在外网登录远程主机,然后 ssh -p 10022 @localhost 就可以登录到局域网中了

不建议局域网中 ssh 端口直接和远程主机的外部 ip 建立端口映射

动态转发

动态转发会在本地监听端口,所有发送到该端口的请求都转发到远程主机中,由远程主机来执行请求

ssh -Nf -D <本地地址>:<本地端口> <user>@<remote-ip>

可以用来做 SOCKS5 代理,如果远程主机可以访问外网,这样通过把浏览器的代理服务器设置为 socks5://127.0.0.1:10080 就可以让远程主机来执行请求,同样可以访问到外网了

$ ssh -Nf -D 10080 iceber@<remote-ip>

其他设置

登录日志可以通过 /var/log/secure 来查看

配置 SSH 登录提醒

# /etc/ssh/sshd_config
Banner <path>

可以在密码输入前会打印 <path> 中的内容

登录后同样会有一些提示内容,这些提示内容再 /etc/update-motd.d中(ubuntu)

ssh server 配置

ssh server 的配置文件时 /etc/ssh/sshd_config
常用的一些配置项:

  • Port <port> 设置ssh server 端口
  • ListenAddress 0.0.0.0 监听地址
  • PasswordAuthentication no 关闭密码验证
  • PubkeyAuthentication yes 可以使用公钥登录
  • RSAAuthentication yes 只允许RSA安全验证
  • PermitRootLogin yes 运行 root 登录
  • PermitEmptyPasswords no 不允许空密码登录
  • LoginGraceTime 2m 用户不能成功登录,2m 后断开连接
  • PrintLastLog yes 登录后打印上次登录信息