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