ssh

来自百合仙子's Wiki
跳转到导航 跳转到搜索

端口转发

动态端口转发

ssh -CqTfnN -D LocalPort remotehost

为隧道而附加的参数意义如下:

-C :- 压缩数据
-q :- be very quite, we are acting only as a tunnel.
-T :- Do not allocate a pseudo tty, we are only acting a tunnel.
-f :- move the ssh process to background, as we don’t want to interact with this ssh session directly.
-N :- Do not execute remote command.
-n :- redirect standard input to /dev/null.

本地端口转发

从本地访问远程主机上的 MongoDB

ssh -L27117:localhost:27017 -Nf host

版本信息

  • openssh 6.7 开始支持 UNIX 域套接字的转发[1][2]

使用代理

使用 netcat

OpenBSD 版的 netcat 可以连接 socks/HTTPS 代理[3]

ssh -oProxyCommand="nc -x 127.0.0.1:8580 %h %p" host

使用 ssh

ProxyCommand ssh -W %h:%p host

使用 socat2

ssh root@talk.archlinuxcn.org -o 'ProxyCommand socat2 stdio "socks5:%h:%p | tcp:127.0.0.1:7119"'

VPN

要使用 ssh 提供的 VPN 功能,远程 sshd 要配置 PermitTunnel = yes | point-to-point | ethernet 。默认是禁用的。

点对点

通过点对点隧道使用 ssh 主机的网络(NAT)。

本地登录:

sudo openvpn --mktun --dev tun1
ssh -w 1 -o Tunnel=point-to-point HOST

远程主机:

ip addr add dev tun0 10.71.0.1/24
ip link set tun0 up
iptables -t nat -A POSTROUTING -s 10.71.0.0/24 -j MASQUERADE

本地配置:

sudo ip link set tun1 up
sudo ip addr add dev tun1 10.71.0.2/24
sudo ip route add HOST/32 via GATEWAY dev mynet1 metric 1
sudo ip route add SUBNET/24 via 10.71.0.1 dev tun1 metric 100

forward agent

[4]

# 启动本地的 ssh-agent
eval $(ssh-agent)
# 加入密钥
ssh-add
# 列一下看看
ssh-add -L
# 登入远程主机
ssh -A host
# 可以在远程主机使用本地的 ssh-agent 了

参数

-L [bind_address:]port:host:hostport
本地端口转发(监听在本地)
-R [bind_address:]port:host:hostport
远程端口转发(监听在远端)。服务器要开启GatewayPorts选项,否则只能在 loopback 上监听
-D port
动态转发(socks5 代理)
-W host:port
将标准输入和标准输出通过 ssh 服务器连接到指定地址(可以配合 systemd.socket 使用)
-X
如果远程服务器支持 X11 forwarding ,那么远程的X应用直接可以在本地X 服务器运行
-Y
受信 X11 forwarding,不受限于 X11 SECURITY 扩展
-e CHAR
指定转义字符,默认为~
-i
指定使用的密钥文件
-A
启用授权代理转发,使得远程主机可使用本地密钥来认证。有潜在的安全隐患。[5]
-C
启用压缩(同默认关闭的Compression选项)

配置文件

位于~/.ssh/config

HashKnownHosts no          #不要 hash 已知主机名
ControlMaster auto
ControlPath ~/.ssh/master-%r@%h:%p
Compression yes
#StrictHostKeyChecking no  #自动接受新主机的hostkey,不每次都提示
#EscapeChar ~              #设定转义字符

Host csslayer.tk           #此域名使用此行以下的配置
IdentityFile ~/.ssh/id_rsa #指定密钥文件
HostName                   #真正的主机名。Host 行上的作为别称

不 hash 已知主机名可方便 zsh 补全,但是引入了安全隐患(入侵者可以获知更多入侵目标)。[6]

启用压缩后传输效率可以提高不少(使用 gzip 算法,对于普通文件大约三倍的样子)。

技巧

关闭 host key 警告

在安全性要求不高的地方,方便使用简单的脚本进行操作。

Host 192.168.1.*
# 不显示添加 key 的警告
LogLevel error
# 接受所有 host key
StrictHostKeyChecking no
# 不记录 host key
UserKnownHostsFile /dev/null

使用 ControlMaster

配置文件里写

Host *
ControlPath ~/.ssh/master-%r@%h:%p
ControlMaster auto

注意,如果要启用 X11 Forwarding,打开连接的进程和交互进程都需要加-X参数。

转义

新行后紧接着的转义字符(默认为~)被识别,重复一次按其本义输入。

以下是常用转义列表(假设转义字符为默认)

~.
断开连接
~^Z
后台
~#
列出forwarded connections
~?
列出转义列表
~C
输入命令。可以指定隧道、端口转发等。使用?可获得帮助。

显示服务器密钥的指纹

[7]

ssh-keyscan host | ssh-keygen -E SHA256 -lf /dev/stdin

reverse ssh

ssh -NTC -o ServerAliveInterval=60 -o ExitOnForwardFailure=yes -o ControlPath=${XDG_RUNTIME_DIR}/ssh/auto_sshd -o ControlPersist=no -R *:RPORT:localhost:LPORT host

需要注意的地方

ssh 等待远程后台进程

当通过 ssh 命令行执行远程命令时,ssh 会等待其标准输出的关闭。重定向远程命令的标准输出可以避免等待。[8]

ssh 无条件读取标准输入

即使 ssh 执行的命令不需要读取标准输入,ssh 也会读取一部分并发送给远端。使用 -n 或者 </dev/null 来避免此问题。[9]

ssh 传递终端信号

当通过 ssh 命令行执行远程命令时,因为其未连接到终端,本地键盘信号(SIGINT 等)不会被发送到远端。使用-t分配终端可解决。如果需要保存远程命令的输出,可以使用 stty 进行一些设置:[10]

ssh -t host "stty -echoctl -echo -onlcr; while true; do work; done" > work.out

但是这样会造成本地终端输出不正常(如同在本地也禁用了 LF -> CR LF 的转换(stty -onlcr)一样)。[11]而不如此设置会导致得到的数据文件中的换行符被转换。

参见

外部链接

参考资料