SSH妙用

最近方才了解到,原来可以通过SSH以配置SOCKS代理的方式,不用开VPN便能够科学上网,于是便搜集了一些SSH的用法,以供未来参考。

无密码登录

只要把自己的公钥保存在远程主机上就可以了,如果本机尚未生成公私钥对(可以通过ls ~/.ssh查看是否存在以pub为扩展名的文件),可以通过ssh-keygen生成一个。之后把这个pub文件的内容全部复制到远程主机上的~/.ssh/authorized_keys中就能够实现无密码登录了。复制的过程也可以用以下命令实现:

1
ssh-copy-id user@remote.host.name

Mac上默认没有ssh-copy-id,可以通过以下命令安装:

1
brew install ssh-copy-id

远程执行命令

配置完无密码登录后,在远程主机上执行命令很简单,只要在最后面加一个字符串即可:

1
ssh remote.host.name "hostname"

如果命令很长,是个脚本,那就这么搞:

1
2
3
4
5
6
7
8
9
10
echo -e "ls\necho ggg" > cmd.txt

ssh remote.host.name "`cat cmd.txt`"
ssh remote.host.name SSH隧道

### 配置SOCKS代理
超级简单:

```sh
ssh -D 9999 remote.host.name

这样便可以通过如下系统设置通过远程主机上网了(以mac为例):

浏览器代理也是一样(以chrome插件SwitchyOmega为例):

本地端口转发

如果你想让本地经由remote1访问remote2,可以这么做:

1
ssh -L 9999:remote2.host.name:80 remote1.host.name

-L后面的参数,表示本地端口:目标主机:目标主机端口,也就是说,往本地9999端口发出去的请求,会经由remote1传给remote2的80端口。为什么我们会需要这样的东东呢?原因可能有几种:

  • 本地访问不了remote2(或remote2的指定端口),但是本地可以访问remote1,并且remote1可以访问remote2。如果公司的网络分为几块,互相之间操作有限制,可能就需要一些remote1作为跳板/堡垒机(bastion)来做这样的脏活儿。
  • 被邪恶的防火墙挡住了去路的时候。
  • 希望能够比较安全的时候。
  • 有时候目标机器由于安全原因或其它原因,某个端口只能开放给自己。这时候就可以将remote1和remote2合而为一。例如,当Java调试所用的5050端口不对外开放时,就可以用以下命令让IDE在localhost的5050端口进行调试:
1
ssh -L 5050:localhost:5050 remote.host.name

中间的localhost是相对remote.host.name而言的,也就是它自己。

远程端口转发

在你的本地可以连通远程主机remote1和另一台远程主机remote2,而它们俩不能相互访问的情况下,如果你想让remote1能够访问remote2,就可以这么做:

1
ssh -R 9999:remote2.host.name:80 remote1.host.name

这样的话,remote1的本地用户便可以便可以通过你的9999端口,访问remote2的80端口了。相当于你把自己变成了一台堡垒机!如果你有权限在其它机器上运行远程端口转发的命令,那你也可以把它变成堡垒机,把你自己的客户机变成remote1了。

复制文件

SSH当然是可以用来复制文件的:

1
cat file | ssh -e none remote-host "cat > file"

其中的参数-e none,表示不转义任何字符。SSH默认会通过~来转义一些控制语句。

但是既然我们有scp,还用ssh图个什么,用专业工具吧。

文件系统

可以用sshfs来将远程的文件系统通过SFTP加载到本地。对于mac而言,可以用FUSE for macOS来实现。我还没有那样的需求,没试过,据说比较简单。有兴趣的读者可以自行尝试。

其它环境

Windows

Windows的话,你可以就得试试Putty了。

Android

用手机和平板来运维?你值得拥有!
JuiceSSH的基本功能时免费的,但是要想端口转发什么的就得收费了。用户体验很不错。
ConnectBot是完全免费的。

iOS

Prompt都说好,收费。

参考资料

SSH: More than secure shell
SSH原理与运用(二):远程操作与端口转发
25 Best SSH Commands / Tricks