Linux-ssh安全隧道:动态端口转发(SOCKS代理)


SYNOPSIS

ssh [-46AaCfGgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec]
  [-D [bind_address:]port] [-E log_file] [-e escape_char]
  [-F configfile] [-I pkcs11] [-i identity_file]
  [-J [user@]host[:port]] [-L address] [-l login_name] [-m mac_spec]
  [-O ctl_cmd] [-o option] [-p port] [-Q query_option] [-R address]
  [-S ctl_path] [-W host:port] [-w local_tun[:remote_tun]]
  [user@]hostname [command]

ssh支持动态端口转发,由ssh来判断发起请求的工具使用的是什么应用层协议,然后根据判断出的协议结果决定目标端口。

以下图为例进行说明,host1处在办公内网,能和host3互相通信,但它无法直接和互联网和host2通信,而host3则可以和host2以及互联网通信

 

要让host1访问互联网,又能和host2的22端口即ssh服务通信,显然在host1上仅设置一个本地端口转发是不够的。使用动态端口转发即可

语法格式为:

ssh -D [bind_addr:]port hostname

以上图为例,在host1上执行:

[root@xuexi ~]# ssh -Nfg -D 2222 host3 

执行完上面的命令,host1将在本地开启SOCKS4或SOCKS5服务来监听2222端口。只要客户端程序工具(隐含了使用的应用层协议类型)将其自身的代理设置为host1:2222,则该程序所有产生的数据都将转发到host1:2222,再由host1:2222将数据通过隧道转发给host3,最后由host3和互联网或host2上对应客户端工具的应用层协议的端口进行通信。

Refence:  https://www.cnblogs.com/f-ck-need-u/p/10482832.html

 

使用ssh动态端口转发实现FQ脚本如下:

shell脚本如下:

vim sockstunnel.sh

#!/bin/bash

if [ -z $1 ];then
  echo "No SSH host specified"
  exit 1;
fi

SSHCMD="ssh -qCTfnN -D $INTERNEL_IP:$INTERNEL_PORT $1"

CODE=`curl -o -I --connect-timeout 10 -s -w "%{http_code}" https://www.google.com --socks5-host $INTERNEL_IP:$INTERNEL_PORT`

PID=`ps -A -o pid,cmd|grep "$SSHCMD" | grep -v grep |head -n 1 | awk '{print $1}'`

function sshHK() {
  echo "`date +%F" "%H:%M:%S` Status: $CODE."
  if [ $CODE -ne 200 -a $CODE -ne 302 ];then
    if [ -n $PID ];then
      kill -9 $PID
      echo "`date +%F" "%H:%M:%S` Killed PID: $PID."
    fi
    echo "`date +%F" "%H:%M:%S` Try to reconnect."
    $SSHCMD
    return 1
  else
    return 1
  fi
}

sshHK

bash  sockstunnel.sh hk   #执行脚本需要传入一个参数(传入的参数hk,其实对应的是要连接远程主机ssh hk。在.ssh/config配置中hk对于的就是一台远程主机),这个参数对应的是要连接远程主机hostname(本地需要连接这个远程主机即代理主机,通过这个代理主机连上国外的主机),这个国外的主机是能够访问google的。

python脚本如下:

vim ssh_socks_tunnel.py

import sys
import os
import time

if(len(sys.argv) != 2):
print("命令行参数不符合,必须是这样的",sys.argv[0]+" ""参数1")
exit()

ip="hostname -I | awk '{print $1}'"
internet_ip=os.popen(ip).read().split("\n")[0]

internet_port=6060
cmd_args1=sys.argv[1]


ssh_cmd=f"ssh -qCTfnN -D {internet_ip}:{internet_port} {cmd_args1}"
print("0000",ssh_cmd)


http_code="%{http_code}"
code=f"curl -o -I --connect-timeout 10 -s -w {http_code} https://www.google.com --socks5-host {internet_ip}:{internet_port}"
result_code=os.popen(code).read().split("\n")[0]
print(result_code,type(result_code),"1212")


p1='{print $1}'
pid=f"ps -A -o pid,cmd|grep {internet_port} | grep -v grep |head -n 1 | awk '{p1}'"
result_pid=os.popen(pid).read().split("\n")[0]
print(result_pid,type(result_pid),"1212")

kill_cmd = f"kill -9 {result_pid}"



'''
ubuntu_name="root"
ip_ubuntu="192.168.1.120"
#ssh_cmd="ssh %s@%s 'hostname'"%(ubuntu_name,ip_ubuntu)
ssh_cmd=f"ssh {ubuntu_name}@{ip_ubuntu} 'hostname'"
print(ssh_cmd)
'''

def sshHK():
current_fromt=time.strftime("%Y-%m-%d %H:%M:%S")
print(current_fromt,result_code)
time.sleep(2)
if result_code != 200 and result_code != 302:
print(current_fromt,result_pid)
if len(result_pid) > 0:
os.popen(kill_cmd).read().split("\n")[0]
os.popen(ssh_cmd).read().split("\n")[0]
return
print(current_fromt,result_pid)
os.popen(ssh_cmd).read().split("\n")[0]
else:
return

sshHK()

 

python3.6 ssh_socks_tunnel.py hk

 

vim ssh_socks_tunnel1.py

import sys
import subprocess
import time

if(len(sys.argv) != 2):
print("命令行参数不符合,必须是这样的",sys.argv[0]+" ""参数1")
exit()

def subprocess_Popne(cmd_args):
obj=subprocess.Popen(cmd_args,shell=True,universal_newlines=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
result=obj.stdout.read().split("\n")[0]

return result

def defin_time_front():
current_time=time.strftime("%Y-%m-%d %H:%M:%S")
return current_time

ip="hostname -I | awk '{print $1}'"
internet_ip=subprocess_Popne(ip)
internet_port=6060
cmd_args1=sys.argv[1]


ssh_cmd=f"ssh -qCTfnN -D {internet_ip}:{internet_port} {cmd_args1}"
print("0000",ssh_cmd)

http_code="%{http_code}"
code=f"curl -o -I --connect-timeout 10 -s -w {http_code} https://www.google.com --socks5-host {internet_ip}:{internet_port}"
result_code=subprocess_Popne(code)

print(result_code,type(result_code),"1212")


p1='{print $1}'
pid=f"ps -A -o pid,cmd|grep {internet_port} | grep -v grep |head -n 1 | awk '{p1}'"
result_pid=subprocess_Popne(pid)
print(result_pid,type(result_pid),"1212")

kill_cmd = f"kill -9 {result_pid}"


'''
ubuntu_name="root"
ip_ubuntu="192.168.1.120"
#ssh_cmd="ssh %s@%s 'hostname'"%(ubuntu_name,ip_ubuntu)
ssh_cmd=f"ssh {ubuntu_name}@{ip_ubuntu} 'hostname'"
print(ssh_cmd)
'''

def sshHK():
t=defin_time_front()
print(t,result_code)
if result_code != "200" and result_code != "302":
print(defin_time_front(),result_pid)
if len(result_pid) > 0:
print("进程号!")
#subprocess.call(kill_cmd,shell=True)
subprocess_Popne(kill_cmd)
subprocess_Popne(ssh_cmd)
#subprocess.call(ssh_cmd,shell=True)
return
print(t,result_pid)
subprocess_Popne(ssh_cmd)
#subprocess.call(ssh_cmd,shell=True)
else:
t=defin_time_front()
print(t,"current code:",result_code)
sshHK()

python3.6 ssh_socks_tunnel1.py hk

 

 

A 192.168.1.102 客户端
hk 114.67.xxx.xx 跳板机     #远程主机即代理主机
C 8.210.x.x 服务器                #国外服务器

以下在客户端配置ssh别名即通过代理机制实现连接

vim .ssh/config
Host C
HostName 8.210.x.x
User root


Host hk
HostName 114.67.x.x
User root

#代理机制
#proxycommand ssh -W %h:%p C 
proxycommand ssh -W 114.67.x.x:22 C

 

 

 

 

 

 

 

 

 

 

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM