Contents

使用ssh的反向和正向代理让内网网站通过外部服务器访问

用法

1. 反向代理

A能连B,在A运行, 把【外部访问B的端口】转到【A的端口】

1
ssh -fCNR *:B_port:127.0.0.1:A_port B_user@B_ip # [bind_address:]remote_port:localhost:localhost_port  

注:一定要开/etc/ssh/sshd_config中的GatewayPorts yes。这样才能让任意外部来源的地址访问B的端口(加上星号*)。否则,只能接收B的loopback访问(B上面用localhost或127.0.0.1才行,在B上面用B的ip都不行)。

2. 正向代理

B能连A,在B运行, 把【外部访问B端口】转到【A的端口】

1
ssh -fCNL *:B_port:127.0.0.1:A_port A_user@A_ip # [bind_address:]local_port:remotehost:remotehost_port

或,在没有开GatewayPorts的情况下,用这个让任意外部来源地址可以通过port2访问port1(类似本地的端口映射)

1
ssh -fCNL *:local_port2:127.0.0.1:local_port1 localhost

3. 创建socks代理

B能连A,在B运行并启动一个socks5代理,把【socks访问B端口】全部转到A

1
ssh -D B_port A_user@A_ip # [bind_address:]local_port

4. 其他技巧

通过ps aux | grep ssh查看有没有运行成功

反向代理详细说明

  • 内网的服务器1上有网站,但是端口不开放,网站无法在公网上被访问。同时,此内网服务器1本身可以访问外网,于是可以通过ssh反向代理,让内网服务器1首先连接另一台端口可以在公网被访问的服务器2,通过服务器2来访问服务器1上的网站。

  • ssh 反向代理转发的操作:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    
    # 服务器2上
    首先ssh登录到公网主机,修改sshd的配置文件/etc/ssh/sshd_config
    GatewayPorts yes #(这一句是精髓)
    重启sshd,如下
    service sshd restart
    # 服务器1上:
    ssh -p {服务器2ssh端口} -i {登陆的公钥} -qTfNn -R {服务器2端口}:localhost:{服务器1端口} root@服务器2的ip
    -q, Quiet mode. Causes most warning and diagnostic messages to be suppressed
    -T, Disable pseudo-tty allocation. 
    -f, 后台执行
    -N, 不执行命令
    -n, Redirects stdin from /dev/null (actually, prevents reading from stdin) his must be used when ssh is run in the background.
    -R, 远程端口转发
    

    当然为了保持服务稳定,还要在内网主机上设置心跳信号来保持连接,修改内网主机的~/.ssh/config文件,增加

    1
    2
    
    ServerAliveInterval 60
    ServerAliveCountMax 9999999999
    
      第一个参数表示如果服务器(外网)没数据发来则过60秒客户端(内网)会发送一个空包到服务器,以保持tcp长连接,默认值为0,表示不会发心跳包,所以这里设置为60秒。
      第二个参数表示,如果服务器(内网)没有收到心跳包指定次数,就中断连接。
    

于是就这样运行了半个月,服务一直都有

参考

ssh的文档最重要

ssh反向代理

ssh转发实战

ssh三种端口转发

iptables本地端口映射