UPDATED ON 2018.01.01
基础使用
# basic usage
ssh username@XXX.XXX.XXX.XXX -p port
ssh username@example.com -p port
# If ignore port: using 22. If ignore username: using local username.
配置文件
编辑 .ssh/config
可以在登录时使用主机缩写,而非 IP 地址。一个主机名设置例子如下,可以在 config
文件中设置多个主机。
host ws
hostname XXX.XXX.XXX.XXX
port 22
user plus
而后就可以使用缩写登陆:
ssh ws
通过 SSH 使用的文件传输工具
SSH 的强大之处远远不止是远程登录。有很多工具在 SSH 之上工作,如简单文件拷贝 scp
和文件夹同步 rsync
。 这里只记录了最基本的用法。这两个工具都会读取 ssh
的配置文件,可以使用配置文件中配置好的主机名。
# copy file
scp from_file ws:to_file
scp -r ws:from_dir to_dir
# sync folder, -v: print the rate of prograss
# -r: --recursive
rsync -av from_dir to_dir
注意,有个坑是
zsh
中使用scp
时,如果要使用通配符,需要把通配符转义,否则zsh
似乎尝试在本地处理通配符导致通配符没有效果:
# bash:
scp -r ws:~/hello* ./
# zsh:
scp -r ws~/hello\* ./
SSH Key 密钥登录设置
使用密码验证每次都需要重复输入,而且有安全问题。因此建议配置密钥对验证。
任意 *UIX 环境通常支持 ssh-keygen
命令生成密钥对。默认配置下(一路按回车),会在 ~/.ssh
目录下生成两个文件:id_rsa, id_rsa.pub
. 其中 .pub
文件是公钥,另一个是私钥。将公钥复制到要登陆的服务器的 .ssh/authorized_keys
文件中(写到这个文件里,这不是一个文件夹。如果文件不存在则直接把公钥复制过去重命名成这个文件),私钥留在本地(运行 ssh
客户端的电脑上),保持在 .ssh/id_rsa
这个位置就可以。之后就可以不用密码远程登录了。
注意检查文件权限:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
密钥验证的安全性非常高。私钥不泄漏、算法是最新算法时可以认为是不可能攻破的。可以查一下非对称密钥体系的工作原理,会对一系列加密技术如 https
等有更好的理解。
SSH 代理设置
可以通过 SSH 进行各种的端口转发、代理设置等,因此所有利用网络的程序,如 Jupyter Notebook 等可以配合 SSH 使用。
本地分享服务器网络环境
用于服务器有更广的网络访问权限,或者从本地访问服务器上的资源(如 Jupyter Notebook)的情况。有两种方式:
- SSH tunneling: Dynamic port forwarding (SOCKS proxy on localhost:9999):
ssh -D 9999 -C username@remote_host
- SSH tunneling: Forward a specific port (localhost:9999 to slashdot.org:80):
ssh -L 9999:slashdot.org:80 username@remote_host
第一条会在本地 9999 端口开一个 socks 代理,本地浏览器将代理指向这个端口 (localhost:9999) 时,本地的网络环境就会相当于远程主机的网络环境。
第二条会将本地的 9999 端口映射到指定的网址,访问这个网址时使用的是服务器端的网络环境。
注意,这些代理(前向代理)需要在 /etc/ssh/sshd_config
中允许 TCP 前向代理:AllowTcpForwarding yes
. (Ubuntu 默认开启)
服务器分享本地网络环境
只映射一个端口较为容易:
ssh -R 8888:localhost:1080 username@remote_host
此时访问服务器 8888 端口相当于访问本地 8888 端口。
有时候服务器不允许访问网络,但是可以被 ssh 连接,此时可以通过 ssh 分享本地整个网络环境给服务器。如果要将本地的网络环境完整映射到远程则比较麻烦,需要打开一个本地 HTTP 代理,然后把这个代理端口映射到远端。你本地很可能有一个 HTTP 或 HTTPS 代理 —— 科学上网工具一般会在本地开一个 HTTP 代理。如果需要架设本地 HTTP 代理服务器,可以使用 proxy2. 如果本地代理端口为 8888,则之前的命令即可讲该端口映射到服务器的 1080 端口。在服务器上运行:
export HTTP_PROXY=localhost:1080
export HTTPS_PROXY=localhost:1080
即可为 wget, git 等程序设置代理。可以把这两行命令写入 .ssh/authorized_keys
或 .bashrc
中。
另一种方式不需要本地开启 HTTP 代理,但需要本地主机打开 SSHD 服务。避免麻烦,把本地和远程主机分别称为 A 和 B,从 A 运行:
ssh -R 2222:localhost:22 username_B@host_B
这将 A 的 SSH 登录端口 22 映射到了 B 的 2222 端口。在 B 运行:
ssh -D 9876 username_A@localhost -p 2222
这样能在 B 得到一个位于 9876 端口的 socks 代理,但问题是 socks 代理不如 HTTP 代理好用,因此不推荐这种方式。
MOSH
mosh
是一款“稳定”的 ssh
替代品。在网络中断时 ssh
连接会中断,但 mosh
能够保持连接,同时在网络连接不稳定时表现较好。但 mosh
没有 ssh
的丰富功能,如各种端口重定向等。在只进行交互式使用时是个不错的替代品。
使用时需要在服务器、本地进行安装:apt install mosh
. 而后基本用法与 ssh
相同,可以自动使用 ssh
的配置文件。
Exit SSH
SSH 不像 Screen 那样对特定的快捷键有反应,而是对特定的按键序列有反应。有时候因为失去网络连接等,SSH 远程主机不再有反应,此时退出 SSH 的方法是,依次按下以下三个键:
Enter, ~, .