SSH反向隧道的搭建过程

by LauCyun Nov 21,2018 13:39:47 6,863 views

现在我有一台内网主机 A,在局域网内是可以访问的,但是如果我现在不处在局域网内,可以选择 VPN 连接,但这样其实并不太方便,所以本节将介绍如何利用 SSH 反向隧道来实现访问内网主机。

0x0 准备

首先需要有一台公网主机作为跳板,这台主机是可以公网访问的,我们将其命名为 B。


图1 SSH反向隧道

所以两台机器网络配置如下:

  • A 内网机器
    • IP:192.168.0.240
    • SSH端口:22
    • 用户名:root
    • 密码:123456
    • 内网配置端口:443
  • B 公网机器
    • IP:47.92.206.111
    • SSH端口:22
    • 用户名:root
    • 密码:123456
    • 公网端口:3443(即用 B 的 3443 端口连到 A 的 3443 端口)

0x1 配置 SSH

首先在主机 A 上执行如下命令生成 SSH 公私密钥:

$ ssh-keygen -t rsa -C "your@email.com"

命令里面的邮箱需要自行更换。


图2 生成SSH公私钥

然后利用如下命令将 A 的 SSH 公钥添加到 B 的authorized_keys里面:

$ scp ~/.ssh/id_rsa.pub root@47.92.206.111:/root/.ssh/authorized_keys

执行后会提示输入主机 B 的密码,执行完毕之后,所以 A 即可通过 SSH 免密登录 B。

0x2 配置主机 B

B 主机需要更改/etc/ssh/sshd_config文件,修改(添加)如下一行:

GatewayPorts yes

这样可以把监听的端口绑定到任意IP 0.0.0.0上,否则只有本机127.0.0.1可以访问。

然后重启sshd服务:

$ sudo service sshd restart

0x3 配置主机 A

主机 A 再安装工具 autossh,以 Ubuntu 为例,命令如下:

$ sudo apt-get install autossh

然后执行如下命令即可完成反向 SSH 配置:

$ autossh -M 65530 -o "ServerAliveInterval 30" -o "ServerAliveCountMax 3" -NCfR 0.0.0.0:3443:127.0.0.1:443 root@47.92.206.111

这样就可以将 A 主机的 443 端口映射到 B 主机的 3443 端口了。。。

ServerAliveInterval and ServerAliveCountMax – they cause the SSH client to send traffic through the encrypted link to the server. This will keep the connection alive when there is no other activity and also when it does not receive any alive data, it will tell AutoSSH that the connection is broken and AutoSSH will then restart the connection.

Reference: https://www.everythingcli.org/ssh-tunnelling-for-fun-and-profit-autossh/

参数:

  • -M port
    autossh参数,任意填写一个可用端口即可。
  • -f
    建立成功后在后台运行,通常和-N连用。
  • -L port:host:hostport
    将本地机(客户机)的某个端口转发到远端指定机器的指定端口。
    工作原理是这样的,本地机器上分配了一个 socket 侦听 port 端口,一旦这个端口上有了连接,该连接就经过安全通道转发出去,同时远程主机和 host 的 hostport 端口建立连接。 可以在配置文件中指定端口的转发。 只有 root 才能转发特权端口。 IPv6 地址用另一种格式说明: port/host/hostport
  • -R port:host:hostport
    将远程主机(服务器)的某个端口转发到本地端指定机器的指定端口。
    工作原理是这样的,远程主机上分配了一个 socket 侦听 port 端口,一旦这个端口上有了连接,该连接就经过安全通道转向出去,同时本地主机和 host 的 hostport 端口建立连接。 可以在配置文件中指定端口的转发。 只有用 root 登录远程主机才能转发特权端口。 IPv6 地址用另一种格式说明: port/host/hostport
  • -D port
    指定一个本地机器 “动态的’’ 应用程序端口转发。
    工作原理是这样的,本地机器上分配了一个 socket 侦听 port 端口,一旦这个端口上有了连接,该连接就经过安全通道转发出去,根据应用程序的协议可以判断出远程主机将和哪里连接。 目前支持 SOCKS4 协议,将充当 SOCKS4 服务器。 只有 root 才能转发特权端口。 可以在配置文件中指定动态端口的转发。
  • -C
    压缩数据传输。
  • -N
    只建立连接,不执行脚本或命令,通常与-f连用。
  • -g
    -L/-R/-D参数中,允许远程主机连接到建立的转发的端口,如果不加这个参数,只允许本地主机建立连接。
    注:这个参数我在实践中似乎始终不起作用。

但是,这样就可以访问吗?答案是不可以,以我的经验来看,好像只有SSH是可以直接访问,所以还需要使用中间件对其进行代理哦,以 Nginx 为例,配置如下:

server
{
    listen 443 ssl;

    ssl_certificate     /etc/nginx/certs/server.crt;
    ssl_certificate_key /etc/nginx/certs/server.key;

    location / {
        proxy_redirect off;
        proxy_pass         https://127.0.0.1:3443;
        proxy_set_header    Host             $host;
        proxy_set_header    X-Real-IP        $remote_addr;
        proxy_set_header    X-Forwarded-For  $proxy_add_x_forwarded_for;
        proxy_set_header    X-Client-Verify  SUCCESS;
        proxy_set_header    X-Client-DN      $ssl_client_s_dn;
        proxy_set_header    X-SSL-Subject    $ssl_client_s_dn;
        proxy_set_header    X-SSL-Issuer     $ssl_client_i_dn;
    }
}

访问 B 主机的 443 端口,就会自动转发到 A 主机的 443 端口了,即可以公网访问了。


图3 AWVS

0x4 参考

Tags