SSH 端口转发

简介

ssh 端口转发是建立了一个 ssh 隧道,原来传输的数据通过这个隧道来传输。先来说说大家最熟悉的动态转发。

动态转发

ssh -D <local port> <SSH server>

这种使用方法应该都很熟悉,(能干嘛?:D),它能动态地将各种数据转发到远程的端口上,相当于在本发建立了一个 sock5 的代理。

本地转发

本地端口转发的命令格式是:

ssh -L <local port>:<remote host>:<remote prot> <SSH server>

使用场景:假设我们现在有一台 smtp 服务器 server,但它被监听在 127.0.0.1:25,也就是说只允许来自自己的请求,所以我们不能在远程访问到它的 25 端口。但是 server 允许远程的 ssh 连接。这个时候在本地执行:

ssh -L 2525:localhost:25 server

这个时候我们就能通过访问 localhost:2525 来访问到 server 中的 25 端口了。

还有一种情况:假设现在 local 不能访问到 ser2 的 23 端口,但 local 能访问到 ser1 的 ssh,而且 ser1 也能访问到 ser2 的 23 端口。

这个时候,我们只需要在本地运行:

ssh -L 2323:ser2:23 ser1

这个时候,我们只要访问 localhost:2323 就能通过 ser1 访问 ser2:23 了。

远程转发

它的命令格式是:

ssh -R <local port>:<remote host>:<remote port> <SSH server>

使用场景:假设现在有一台 web 服务器(srv1)处于局域网中,它不能被广域网访问到,另一台服务器(srv2)处于广域网中。srv1 能 ssh 到 srv2,这个时候想让 srv2 访问到 srv1 的 web 服务。在 srv1 中执行

ssh -R 8088:srv1:80 ser2

这个时候就能在 srv2 中访问 localhost:8088 就能访问到 srv1 中的 web 服务器了。

这个时候 srv2 的 8088 只能监听在 127.0.0.1 的,要想允许外部访问,可改写为 -R *:8088:srv1:80,并确保在服务器的 sshd_config 中打开了 GatewayPorts yes 选项。

X 协议转发

ssh -X <SSH Server>

登录完成后,就可以直接在 shell 里执行远程的 X 应用,这里建立的 X 转发会自动设置 DISPLAY 环境变量,通常会被设置成 localhost:10.0,我们无需也不应该在连接之后再进行修改此环境变量。

常用参数

端口转发常与以下参数配合使用:

选项 说明
-f ssh将在后台运行
-N 不执行命令,仅转发端口
-C 压缩传送的数据
-i 使用指定的密钥登录
-g 创建监听 0.0.0.0 的端口

参考资料

  1. SSH端口转发
  2. 实战 SSH 端口转发

ssh 单一用户登录限制

为了防止某一用户重复登陆,也为了防止滥用资源,我们可以用 PAM 来作限制以达到单点登陆的目的。

  1. 确保 /etc/pam.d/sshd 里添加了 “pam_limits.so”,一般情况下 Debian 系的发行版已经添加。
    session required pam_limits.so
  2. 在 “/etc/security/limits.conf” 里添加 “USERNAME – maxlogins 1″,意思是 UERNAME 这个用户的最大登录用户数为1,当然也可以用 * 来代表所有用户。
  3. 重启 ssh 服务 /etc/init.d/ssh restart,超过限制数的 SSH 登录就会提示 Too many logins for 'USERNAME'.