帮助中心

汇集使用技巧,一分钟上手动态IP,赢在大数据时代,从这里开始。

当前位置:帮助中心>最新资讯

内网穿透反向隧道代理技术

  本文的主要目的是利用使ssh服务器(外网)通过客户端(内网)代理上网以及反向控制客户端(内网),不需要网络管理员权限,不需要NAT。即可上网主机A位于内网,不可上网主机B位于外网,A能直接访问B,但B无法访问防火墙内的A,这样B就可以使用SSH隧道访问A主机上的代理服务器上网。(估计有这种变态需求的人只存在于大学中)

内网穿透反向隧道代理技术

  B(210.77.*.*)---->(210.77.*.*)FW(192.168.0.*)|--->(192.168.0.*)A---->(192.168.0.*)FW(123.*.*.*)---->Internet

  B(210.77.*.*)<----(210.77.*.*)FW(192.168.0.*)-----(192.168.0.*)A<----(192.168.0.*)FW(123.*.*.*)<----Internet

  一、代理

  首先在客户端上安装socks代理(HTTP代理可以使用Squid,同理)。socks代理软件使用Dante。Dante的启动以及配置需要手动调整,下面是Dante的配置文件/etc/sockd.conf:

 

  compatibility:reuseaddr

  internal:0.0.0.0 port=1080

  external:eth0

  logoutput:/var/log/sockd/sockd

  clientmethod:none

  method:none

  user.privileged:root

  user.notprivileged:solrex

  connecttimeout:60

  iotimeout:86400

  ##client access rules

  client pass{

  from:127.0.0.1/0 port 1-65535 to:0.0.0.0/0

  log:connect disconnect

  }

  ##server operation access rules

  #allow bind to ports greater than 1023

  pass{

  from:0.0.0.0/0 to:0.0.0.0/0 port gt 1023

  command:bind bindreply udpassociate udpreply

  log:connect disconnect

  }

  pass{

  from:0.0.0.0/0 to:0.0.0.0/0 port 1-65535

  protocol:tcp udp

  log:connect disconnect

  }

  #allow outgoing connections(tcp and udp)

  pass{

  from:127.0.0.1/0 to:0.0.0.0/0

  command:bind bindreply connect udpassociate udpreply

  log:connect disconnect

  }

  #allow replies to bind,and incoming udp packets

  pass{

  from:0.0.0.0/0 to:0.0.0.0/0

  command:bind bindreply connect udpassociate udpreply

  log:connect error

  }

  #log the rest

  block{

  from:0.0.0.0/0 to:0.0.0.0/0

  log:connect error

  }

  下面是Dante的启动脚本/etc/init.d/sockd:

  #!/bin/sh

  set-e

  ./lib/lsb/init-functions

  [-f/usr/local/sbin/sockd]||exit 0

  [!-f/etc/sockd.conf]&&exit 1

  SOCKD_CONF="-f/etc/sockd.conf"

  SOCKD_OPTS="-D"

  case"$1"in

  start)

  #Start daemons.

  log_daemon_msg"Starting Dante socks proxy server""sockd"

  if start-stop-daemon--start--quiet--oknodo--pidfile/var/run/sockd.pid--exec/usr/local/sbin/sockd--$SOCKD_OPTS;then

  log_end_msg 0

  else

  log_end_msg 1

  fi

  ;;

  stop)

  #Stop daemons.

  log_daemon_msg"Stoping Dante socks proxy server""sockd"

  if start-stop-daemon--stop--quiet--oknodo--pidfile/var/run/sockd.pid;then

  log_end_msg 0

  else

  log_end_msg 1

  fi

  ;;

  restart)

  log_daemon_msg"Restarting Dante socks proxy server""sockd"

  start-stop-daemon--stop--quiet--oknodo--retry 30--pidfile/var/run/sockd.pid

  if start-stop-daemon--start--quiet--oknodo--pidfile/var/run/sockd.pid--exec/usr/local/sbin/sockd--$SOCKD_OPTS;then

  log_end_msg 0

  else

  log_end_msg 1

  fi

  ;;

  *)

  log_action_msg"Usage:/etc/init.d/sockd{start|stop|restart}n"

  exit 1

  esac

  exit 0

  二、ssh服务器

  服务器端ssh服务器最好采用Openssh,Windows下应该使用Cygwin运行sshd,FreeSSHd实践证明崩溃比较频繁。同一台机器的Windows和Linux上运行的ssh服务器最好使用相同的host key,将/etc/ssh/下面的文件保持一致即可。最好配置服务器为使用公钥进行登录验证,这样能使用自动脚本进行端口映射。

  三、手动建立隧道(客户端到服务器端口映射)

  用下面命令建立客户端到服务器的端口映射,将客户端的socks代理端口1080映射到服务器的端口8080。这样服务器就可以通过自己的8080端口反向隧道到客户端的socks代理1080端口上网。

  ssh-C-f-N-g-o PreferredAuthentications=publickey-R SERVER:8080:127.0.0.1:1080 USRNAME SERVER

  #参数含义:

  #-C:要求对数据进行压缩

  #-f:要求ssh执行完交互后进入后台运行

  #-N:不用建立一个终端

  #-g:允许远程服务器连接客户端转发端口

  #-R SERVER:8080:127.0.0.1:1080:将客户机(127.0.0.1)的1080端口绑定到服务器(SERVER)的8080端口。

  #USRNAME SERVER:ssh服务器的用户名和密码

  #-p 3022:ssh服务器的端口

  为了方便控制,最好也将客户端的ssh服务器端口映射到服务器端,服务器端就可以通过登录自己的8022端口来登录客户端的ssh服务器:

  ssh-C-f-N-g-o PreferredAuthentications=publickey-R SERVER:8022:127.0.0.1:22 USRNAME SERVER

  这样两台被防火墙隔开的主机就能实现双向控制。

  四、自动建立隧道

  手动建立隧道的缺陷是服务器端必须长期开机,并且连接只能用户在客户端手动发起。可以考虑间接的办法,比如使用两台主机均可访问的服务器作为跳板,或者客户端自动登录聊天软件,利用聊天软件接受指令。下面给出一种使用共享服务器的方法:

    #!/bin/bash

    #{start|stop|restart:username:ipaddress}

    COMMAND="stop"

    SERVER="0.0.0.0"

    USRNAME=""

    PORT="22"

    INFOURL="http://someserver.com/somepage"

    SSHOPTS="-C-f-N-g-oPreferredAuthentications=publickey-oStrictHostKeyChecking=no"

    get_server_info()

    {

    #info=`wget-nv-O-$INFOURL2>/dev/null|iconv-fgbk-tutf8|

    grep-o-e"{.*}"|tr-d'{}'`

    info=`wget-nv-O-$INFOURL2>/dev/null|iconv-fgbk-tutf8|

    sed-n"/{*}/s/.*{\(.*\)}.*/\1/p"`

    COMMAND=${info%%:*}

    SERVER=${info#*:}

    USRNAME=${SERVER%:*}

    SERVER=${SERVER#*:}

    }

    tunneling_status()

    {

    tun_ps=`psaux|grep"ssh-C"|wc-l`

    if[$tun_ps-gt4];then

    echo-n"running"

    else

    echo-n"died"

    fi

    }

    start_tunneling()

    {

    ssh$SSHOPTS-R3128:127.0.0.1:3128${USRNAME}@${SERVER}-p$PORT

    ssh$SSHOPTS-R8022:127.0.0.1:22${USRNAME}@${SERVER}-p$PORT

    }

    failsafe_tunneling()

    {

    ssh$SSHOPTS-R8022:127.0.0.1:22${USRNAME}@${SERVER}-p$PORT

    }

    stop_tunneling()

    {

    killall-essh

    }

    echo-n"[`date+%F\%R`]"

    get_server_info

    case"$COMMAND"in

    start)

    if[$(tunneling_status)="running"];then

    echo"Startingsshtunneling.(started,donothing)"

    else

    echo"Startingsshtunneling."

    start_tunneling

    fi

    ;;

    restart)

    if[$(tunneling_status)="running"];then

    echo"Restartingsshtunneling."

    stop_tunneling

    start_tunneling

    else

    echo"Restartingsshtunneling."

    start_tunneling

    fi

    ;;

    stop)

    if[$(tunneling_status)="running"];then

    echo"Stopingsshtunneling."

    stop_tunneling

    else

    echo"Stopingsshtunneling.(stoped,donothing)"

    fi

    ;;

    failsafe)

    echo"Stargingsshtunneling.(failsafemode)"

    failsafe_tunneling

    ;;

    sleep)

    echo"Sleeping."

    exit0

    ;;

    *)

    echo"Unrecogenizedservercommand($COMMAND)."

    exit1

    ;;

    esac

    exit0



在线咨询
微信号

微信号

回到顶部