配置文件

配置文件保存了可以连接的服务器,它可能存在的位置:

  • Linux:/home/<username>/.ssh/config
  • Windows:C:\Users\<username>\.ssh\config

文件结构配置:

Host Hostname
    HostName <IP>
    User <username>
    Port <port>
    IdentityFile ~/.ssh/<id_file>

ssh key 生成

ssh-keygen -t ed25519 -C "you@mail"

systemd 服务开启

sudo systemctl enable ssh
sudo systemctl start ssh

scp

从远程复制文件夹到本地:

scp -r user@ip:path ./

配置登录

在允许密码登录的时候,可以通过

ssh-copy-id -i ~/.ssh/id_ed25519 -p <port> <username>@<hostname>

将自己的公钥传到对面,本质上是将 ~/.ssh/id_ed25519.pub 输入到远程的 ~/.ssh/authorized_keys 中,所以也可以手动添加 authorized_keys。

/etc/ssh/sshd_config
PubkeyAuthentication yes   # 允许公钥登录
PasswordAuthentication yes # 允许密码登录
PasswordAuthentication no  # 禁止密码登录(强烈推荐)

查看 ssh 登录日志

Debian/Ubuntu:

sudo journalctl -u ssh.service

Arch Linux:

sudo journalctl -u sshd.service

查看自从上次启动以来的日志:

sudo journalctl -u ssh.service -b0

端口转发

ssh 提供了三种端口转发,分别是

  • 本地转发 -L
  • 远程转发 -R
  • 动态转发 -D

在端口转发时,我们可以使用 -N -T(或者合并成 -NT),这样只会转发端口,不会开启 shell。

  • 如果开启了 -N 参数,在连接到远程时会使用远程用户的 shell1
  • 如果开启了 -T 参数,会关闭 pty 分配,sshd 将使用一对管道而不是双向 pty 与运行远程命令的进程通信2

举一些比较实际的例子:

  • -D 可以用来搭建 socks 代理,命令格式为:ssh -D <port> username@ip,其中 port 为本地端口,之后就可以通过 socks5 的方式连接代理了,所有的流量都会通过远程服务器。
  • -L 转发指定端口,例如 ssh -NT -L <local_ip>:<local_port>:<target_ip>:<target_port> -p <remote_port> <username>@<remote_ip>
    • 这条指令可以将 <target_ip> 的端口转发到本地端口上,而且不要求 local_iptarget_ip 在一个网段,只需要 remote_ip 能访问到 target_ip 即可。可以用来转发 3389 端口。

端口转发参考资料

将本地端口 7890 转发到远程:

ssh -NT -R 172.18.101.136:7890:127.0.0.1:7890 A6000

将远程端口转发到本地:

ssh -NT -R 127.0.0.1:7890:172.18.101.136:7890 A6000

端口转发示例 1

首先,通过 qemu 启动一个操作系统,例如这样:

qemu-system-i386 \
  -machine 'pc' \
  -cpu 'coreduo' \
  -m 1G \
  -drive file=image.qcow2 \
  -device e1000,netdev=net \
  -netdev user,id=net,hostfwd=tcp::2222-:22 \
  -kernel kernel \
  -initrd initrd \
  -nographic \
  -append "root=LABEL=rootfs console=ttyS0"

它将 qemu 的 22 端口转发到了本地的 2222 端口。

如果我们通过 proxy.py 搭建简单的 http proxy,那怎么让 qemu 使用呢?这时可以使用 -R 参数将本地 8899 端口转发到远程的 8899 端口:

ssh -NT -R 8899:127.0.0.1:8899 -p 2222 [email protected]

接下来就可以使用这个端口了,例如在 apt 时使用 proxy

如果我们想将里面的端口映射到外面该怎么办呢?有一种方法是在启动 qemu 的时候添加多个 hostfwd 参数,例如:

-netdev user,id=net,hostfwd=tcp::2222-:22,hostfwd=tcp::2345-:2345 \

但有时我们还想映射其他端口而不想重启虚拟机,这时还能怎么做呢?这时就可以通过 -L 参数做本地转发,它可以转发多个端口:

ssh -p 2222 [email protected] -NT -L 2355:127.0.0.1:2345 -L 13347:127.0.0.1:13337

这样可以把远程的 2345 端口转发到本地的 2355 端口,远程的 13337 端口转发到本地的 13347 端口。

不过要注意的是,我们需要先执行运行在目标端口的程序再做转发,否则可能出现一些问题。

跳板机

有时需要多个跳板进入目标机器,配置方法也很简单。假设我们的目标是 host2,那么在本地的 ~/.ssh/config 中可以写成如下的配置:

Host host1
    HostName hostname1
    User user1
    Port port1
    IdentityFile ~/.ssh/id_ed25519
    ServerAliveInterval 20
    TCPKeepAlive yes

Host host2
    HostName hostname2
    User user2
    Port port2
    IdentityFile ~/.ssh/id_ed25519
    ServerAliveInterval 20
    TCPKeepAlive yes
    ProxyJump host1

在上面的配置中,host1 是跳板机,我们可以用这种方式一直叠加跳板机。

Footnotes

  1. https://unix.stackexchange.com/a/636172

  2. https://unix.stackexchange.com/a/509162