Contents

SSH Tunnel 端口转发详解

前言

SSH(Secure Shell)不仅仅是用来远程登录服务器的工具,它还提供了强大的端口转发(Port Forwarding)功能,也叫 SSH Tunnel。通过 SSH Tunnel,我们可以加密传输数据、绕过防火墙限制、访问远程内网服务等。本文介绍 SSH 端口转发的常用参数及一些实用技巧。

SSH 常用参数

除了基本的远程登录,SSH 还有一些别的参数值得介绍。

-N 和 -T 参数

-N 参数表示只连接远程主机,不打开远程 shell;-T 参数表示不为这个连接分配 TTY。这两个参数可以放在一起用,代表这个 SSH 连接只用来传数据,不执行远程操作。

1
$ ssh -NT -D 8080 host

-f 参数

-f 参数表示 SSH 连接成功后,转入后台运行。这样一来,你就可以在不中断 SSH 连接的情况下,在本地 shell 中执行其他操作。

1
$ ssh -f -D 8080 host

要关闭这个后台连接,就只有用 kill 命令去杀掉进程。

SSH Tunnel 端口转发类型

SSH Tunnel 主要分为三种类型:本地端口转发、远程端口转发和动态端口转发。

本地端口转发(Local Port Forwarding)

将本地机器的某个端口转发到远程服务器的指定端口。

1
2
3
4
5
6
7
8
# 语法
$ ssh -L [本地绑定地址:]本地端口:目标主机:目标端口 用户名@远程服务器

# 示例:将本地 8080 端口转发到远程服务器的 80 端口
$ ssh -L 8080:localhost:80 user@remote_host

# 示例:将本地 3306 端口转发到远程内网的数据库服务器
$ ssh -L 3306:db_server:3306 user@jump_host

远程端口转发(Remote Port Forwarding)

将远程服务器的某个端口转发到本地机器的指定端口。

1
2
3
4
5
# 语法
$ ssh -R [远程绑定地址:]远程端口:目标主机:目标端口 用户名@远程服务器

# 示例:将远程服务器的 8080 端口转发到本地的 80 端口
$ ssh -R 8080:localhost:80 user@remote_host

动态端口转发(Dynamic Port Forwarding)

动态端口转发相当于创建了一个 SOCKS 代理,可以代理所有端口的流量。

1
2
3
4
5
6
7
8
# 语法
$ ssh -D [本地绑定地址:]本地端口 用户名@远程服务器

# 示例:在本地 1080 端口创建 SOCKS 代理
$ ssh -D 1080 user@remote_host

# 结合 -N、-T、-f 参数在后台运行
$ ssh -fNT -D 1080 user@remote_host

SSH Tunnel 专用帐号配置

如果你正好有一台已经装了 sshd 的 Linux 系统,你可以很方便地 useradd 一个账户就能开始 SSH 了,当然也可以 Tunnel 了。

但是,这样子留下了一个可以登录 shell 的用户,有一定的安全隐患,怎么避免呢?

方案一:限制 Shell 登录

最简单的增加 SSH Tunnel 专用帐号的办法:

1
useradd -M -s /usr/sbin/nologin tussh

这样的用户如果使用 Putty 等工具登录,输入密码后会看到这样一句话,然后 SSH 就会断开:

1
This account is currently not available

但是 SSH Tunnel 功能并不受影响。

方案二:允许用户自行修改密码

方案一还不够完美。对于 SSH Tunnel 用户,通常只有一个需求,那就是修改密码。由于不能登录 shell,用户不能自己更改密码,只能求助管理员,这样既不安全,也不方便。

完美的解决方案是用这样的 useradd 参数:

1
useradd -M -s /usr/bin/passwd tussh

这样的用户登录的时候,会直接进入修改密码状态,用户就可以收到管理员设置的一个简单密码后,自己设置自己的密码,甚至定期更换自己的密码。

方便,安全!

记得用 passwd 为新用户设置初始密码。

常用组合命令

实际使用中,我们通常会将多个参数组合使用:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 后台运行本地端口转发
$ ssh -fNL 8080:localhost:80 user@remote_host

# 后台运行远程端口转发
$ ssh -fNR 8080:localhost:80 user@remote_host

# 后台运行动态端口转发(SOCKS 代理)
$ ssh -fNT -D 1080 user@remote_host

# 指定本地绑定地址(允许外部访问)
$ ssh -fNL 0.0.0.0:8080:localhost:80 user@remote_host

总结

SSH Tunnel 是一个强大而灵活的网络工具,掌握端口转发可以解决很多实际问题:

  • 本地端口转发:访问远程内网服务
  • 远程端口转发:将本地服务暴露给外网
  • 动态端口转发:搭建 SOCKS 代理

配合专用帐号配置,既能满足转发需求,又能保证系统安全。

参考链接:

  1. SSH 端口转发
  2. OpenSSH 官方文档