ssh tips
1. 前言
1.1. 更新历史
更新时间 | 更新内容 |
---|---|
2020-09-13 | 初稿 |
2020-09-18 | 启用密钥登录; 使用ssh_config; |
最近新装了一台ubuntu, 照例又是配置各种环境. 在配置ssh的时候遇到很多操作都不记得具体步骤, 又得从网上查怎么操作. 因此觉得有必要记录一下ssh的一些常用操作, 方便下次再配置ssh时进行查阅.
2. 正文
2.1. 生成密钥对
ssh-keygen
私钥路径: ~/.ssh/id_rsa
公钥路径: ~/.ssh/id_rsa.pub
2.2. 添加公钥
cat ./id_rsa.pub >> ~/.ssh/authorized_keys
2.3. 禁用密码登录&&启用密钥登录
参考[2]
# 编辑 sshd_config 文件
vim /etc/ssh/sshd_config
# 禁用密码验证
PasswordAuthentication no
# 启用密钥验证
RSAAuthentication yes
PubkeyAuthentication yes
# 指定公钥数据库文件
AuthorsizedKeysFile .ssh/authorized_keys
2.4. 使用跳板机登录目标服务器
一种方法是使用ProxyCommand
参考[3]. 不过实际使用的话并不推荐, 比较麻烦.
可以结合 ssh -L
端口转发功能. 比如有三台主机: A
, B
, C
. 其对应ip为 ip_A
, ip_B
, ip_C
. A
可以访问B
, B
可以访问C
, 但是A
不能直接访问C
.
我们想要在A
上用ssh
登录C
. 那么可以进行如下操作:
在A
上执行如下命令
ssh -L 2333:ip_C:22 root@ip_B
# 需要配置密钥登录`B`或输入主机``上`root`用户的密码
此时在A
上访问 127.0.0.1:2333
就等价于访问ip_C:22
.
所以在A
上执行如下命令即可登录C
ssh root@127.0.0.1 -p 2333
# 需要配置密钥登录`C`或输入主机`C`上`root`用户的密码
2.5. ssh_config
官方文档参考[4]
说来惭愧, 用了ssh
这么久一直不知道有ssh_config
这个东西. 还是前不久查vscode
的remote-ssh
插件的文档时才无意间知道有这么个东西.
通过配置ssh_config
可以免去每次使用ssh
/sftp
时输入用户名, ip, 端口等操作.
配置文件通常位于 ~/.ssh/ssh_config
, 配置文件具体怎么写我们就用上一节的2.4. 使用跳板机登录目标服务器举个例子.
在配置好代理之后我们连接主机C
需要通过如下命令:
ssh root@127.0.0.1 -p 2333
我们可以在 ~/.ssh/ssh_config
添加如下内容
Host host_C
HostName 127.0.0.1
User root
Port 2333
之后再想要连接主机C
只需要执行如下命令即可
ssh host_C
想要用sftp
传文件的话也可以用类似的命令
sftp host_C
ssh_config
支持配置多个主机.
Host host_C
HostName 127.0.0.1
User root
Port 2333
Host host_B
HostName ip_B
User root
Port 22
ssh_config
甚至还支持域名通配符等操作, 这儿就不再细说, 可以参考官方文档[4].
2.6. 端口转发功能
2.6.1. ssh -L
设有三台主机: A
, B
, C
. 其对应ip为 ip_A
, ip_B
, ip_C
.
如果在主机A
上执行:
ssh -L 1234:ip_C:5678 root@ip_B
那么访问主机A
的1234
端口就等价于访问主机 C
的 5678
端口(两者直接会通过主机B
作为中介建立一个隧道)
这种转发方式的应用场景为: A
可以访问B
, B
可以访问C
, 但是A
不能直接访问C
.
2.6.2. ssh -R
设有两台主机: A
, B
. 其对应ip为 ip_A
, ip_B
.
如果在主机A
上执行:
ssh -R 1234:127.0.0.1:5678 root@ip_B
注意: 这儿一定要是root用户
那么此时在B
上访问 localhost:1234
就等价于访问 A
的 5678
端口.
若想实现可以通过ip_B:1234
访问主机A
的127.0.0.1:5678
还需要配置一层代理, 具体方式后面关于内网穿透的章节会说
这种转发方式的应用场景为: A
是一个内网主机, B
是一个公网主机. 用户想随时随地可以访问A
, 就需要做一个反向代理实现内网穿透, 使得用户可以通过 B
作为中介访问 A
.
2.6.3. ssh -D
设有两台主机: A
, B
. 其对应ip为 ip_A
, ip_B
.
如果在主机A
上执行:
ssh -D 1234 root@ip_B
那么主机A
的 localhost:1234
就会有一个socks
代理, 所有走这个代理的流量都会通过主机B
转发出去.
这种转发方式的应用场景为: 懒得安装/启动socks代理软件客户端.
2.7. autossh + xinetd 实现内网穿透
设有两台主机: A
, B
. 其对应ip为 ip_A
, ip_B
, A
是一个内网主机, B
是一个公网主机. 我们的需求是随时随地可以访问A
上的资源.
我们可以使用前面提到的 ssh -R
转发方式, 在A
上执行:
ssh -R 1234:127.0.0.1:22 root@ip_B
注意: 22是ssh server的端口
此时我们若在B
上执行
ssh root@127.0.0.1 -p 1234
并输入A
上root
用户的密码, 我们就可以成功登录主机A
.
但是B
的127.0.0.1
只有自己能访问, 别的主机想访问B
上的1234
端口只能通过ip_B
进行访问, 所以我们这儿可以在B
上启动一个转发服务: 将ip_B:5678
来的流量转发至127.0.0.1:1234
(两个端口建议不相同, 避免可能的冲突). 我这儿用的是 xinetd
:
$ sudo apt install xinetd
$ cat ./proxy
service http-switch
{
disable = no
type = UNLISTED
socket_type = stream
protocol = tcp
wait = no
redirect = 127.0.0.1 1234
bind = 0.0.0.0
port = 5678
user = nobody
}
$ cp ./proxy /etc/xinetd.d/
$ sudo /etc/init.d/xinetd restart
[ ok ] Restarting xinetd (via systemctl): xinetd.service.
此时我们在任何一台可以访问外网的主机上执行如下命令:
ssh root@ip_B -p 5678
并输入A
上root
用户的密码, 就可以登录上A
了.
autossh
和ssh
功能差不多, 但是多一个自动断线重连功能, 因此搭建内网穿透服务的时候稳定性更好.
使用命令和ssh
类似:
$ sudo apt install autossh
$ autossh -M 7788 -NfR 1234:127.0.0.1:22 root@ip_B
-M
参数声明一个没有被占用的端口, autossh
会使用这个端口检测连接是否存在, 如果断掉的话就需要进行重连操作.
-N
和 -f
参数是让 autossh
不打印信息, 在后台运行. (ssh
同样可以加上这两个参数.)
3. 结语
不会用ssh的网管不是好程序员