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