ssh
端口转发
动态端口转发
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
版本信息
使用代理
使用 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
# 启动本地的 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
- 输入命令。可以指定隧道、端口转发等。使用
?
可获得帮助。
显示服务器密钥的指纹
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]而不如此设置会导致得到的数据文件中的换行符被转换。
参见
- sshfs
- ssh-keygen
- sshd
- autossh
- mosh
- pssh
- sshpass: 自动输入密码,然后执行非交互命令
- nobonobo/ssh-p2p: ssh p2p tunneling server and client
外部链接
- 实战 SSH 端口转发
- 通用线程: OpenSSH 密钥管理,第 1 部分 理解 RSA/DSA 认证
- SSH Can Do That? Productivity Tips for Working with Remote Servers | Smylers, 中文翻译:16条技巧让你更高效使用SSH已失效,存档
- how gitolite uses ssh
- 使用ssh_config [Lainme's Blog]
- ssh whoami.filippo.io: 回显客户端提供的 ssh 公钥(以及 roaming bug 检查)
- Having fun with Redis Replication between Amazon and Rackspace. | 3scale Tech Blog (使用 ssh 建立压缩的隧道)
- Endlessh: an SSH Tarpit « null program
- [1]: mmh 跳板机穿透工具
- Managing servers with OpenSSH Certificate Authority - iBug
- 给手机设置只读SFTP服务器 [Lainme's Blog]
参考资料
- ↑ OpenSSH 6.7 will bring socket forwarding and more [LWN.net]
- ↑ http://www.openssh.com/txt/release-6.7
- ↑ SSH using a SOCKS or HTTP proxy | Heiher's Blog
- ↑ SSH agent forwarding 的應用 | ihower { blogging }
- ↑ An Illustrated Guide to SSH Agent Forwarding,从最基本的密码认证到 SSH Agent 转发的详细原理解释。
- ↑ SSH Host Completion – zsh Stylee « Source Guru
- ↑ Get ssh server key fingerprint - Unix & Linux Stack Exchange
- ↑ ssh阻塞与重定向 - SegmentFault
- ↑ Buffers and windows: The mystery of ‘ssh’ and ‘while read’ in excessive detail – Vidar’s Blog
- ↑ remote - Get ssh to forward signals - Unix & Linux Stack Exchange
- ↑ Why is this binary file transfered over "ssh -t" being changed? - Unix & Linux Stack Exchange