设为首页 加入收藏

TOP

autossh自动化脚本,快速搭建多服务器SSH动态代理隧道,/v/bin/sshproxy
2021-03-31 17:05:48 来源: 作者: 【 】 浏览:430次 评论:0
#!/bin/bash
SCRIPTPATH=$(realpath $0)
#执行autossh,自动创建SSH动态端口代理隧道

display_usage() {
    echo -e "$SCRIPTPATH\n"
    echo -e "\t执行autossh,自动创建SSH动态端口代理隧道."
    echo -e "\t默认绑定端口:0.0.0.0:8989."
    echo -e "\t参数1目的主机的为必选参数,其余为可选参数."
    echo -e "\nUsage:\n\tsshproxy [*hostname] [local proxy port] [kill exists process] [use http proxy or not(mustbe: nohttp)]"
    echo -e "Example1:\n\tsshproxy racknerd true"
    echo -e "Example2:\n\tsshproxy racknerd nohttp"
    echo -e "Example3:\n\tsshproxy racknerd 7171 true"
    echo -e "Example4:\n\tsshproxy racknerd 7171 nohttp"
    echo -e "Example5:\n\tsshproxy racknerd 7171 true nohttp"
    echo -e "\n附加用法:\n"
    echo -e "\t1.sshproxy kill  检测并杀死所有的代理进程"
    echo -e "\t2.sshproxy list  列出当前活动的所有代理"
    echo -e "\t3.sshproxy test  检测已有代理端口的可用性\n"
}
# if less than two arguments supplied, display usage
if [  $# -lt 1 ]
then
    display_usage
    exit 1
fi

# check whether user had supplied -h or --help . If yes display usage
if [[ ( $* == "--help") ||  $* == "-h" ]]
then
    display_usage
    exit 0
fi

do_KillProcess() {
    #首先尝试查询和保存代理各个端口
    local processPID=$(ps aux|grep 'ssh-for-proxy'|awk '{print $4}'|tr '\n' ' ')
    if [ ! -z "$processPID" ];then
        declare -a proxyPort ## 定义数组,存储找到的多个代理进程本地端口
        for pid in $processPID;
        do
            local port=$(netstat -ano|grep $pid|grep 'LISTENING'|grep 0.0.0.0|awk '{print $2;exit}'|awk -F ':' '{print $NF}')
            #echo "$port"
            proxyPort=(${proxyPort[@]} $port)
        done
    fi
    echo "kill Process..."
    killall autossh &> /dev/null
    killall ssh-for-proxy &> /dev/null
    killall goproxy-for-ssh &> /dev/null
    ## 关闭涉及各端口的TCP连接,以保万全
    echo "kill Connections..."
    for port in ${proxyPort[@]};
        do
            #echo "Close Port connection $port"
            gsudo `cygpath -w /v/bin/cports` /close '*' $port '*' '*'
        done
    return
}

do_ListProxy() {
    local psList=$(ps aux|grep 'ssh-for-proxy')
    local pids=$(echo "$psList"|awk '{print $1}')
    local winpids=$(echo "$psList"|awk '{print $4}')
    declare -a RemoteAddrs
    declare -a ListenAddrs
    declare -a ProxyAddrs
    declare -a HostAlias #查找 ~/.ssh/config以确定主机别名
    for pid in $(echo "$winpids");
    do
        local remoteAddr=$(netstat -ano -P TCP|grep $pid|grep 'ESTABLISHED'|awk '{print $3;exit}') #仅打印一行即退出
        [ -z "$remoteAddr" ] && remoteAddr="Unknown:Unknown\t"
        RemoteAddrs=(${RemoteAddrs[@]} $remoteAddr)
        local remoteIP=$(echo $remoteAddr|cut -d ':' -f 1)
        local hostName=$(python3 /v/bin/sshfindip.py $remoteIP|sed -n '1p')
        if [ ! -z "$hostName" ];then
            local hostName=$(echo "$hostName"|tr -s ' '|tr ' ' ','|sed -r 's/^Host\,//i')
        else
            local hostName="*Unknown*"
        fi
        HostAlias=(${HostAlias[@]} "$hostName")
        local listenAddr=$(netstat -ano -P TCP|grep $pid|grep 'LISTENING'|grep '0.0.0.0'|awk '{print $2;exit}') #仅打印一行即退出
        [ -z "$listenAddr" ] && listenAddr="Unknown:Unknown\t"
        ListenAddrs=(${ListenAddrs[@]} $listenAddr)
        local proxyAddr="socks5://127.0.0.1:"$(echo $listenAddr|awk -F ':' '{print $NF}')
        ProxyAddrs=(${ProxyAddrs[@]} $proxyAddr)
    done
    declare -a unixPids
    declare -a winPids
    local unixPids=($(echo "$pids"|tr '\n' ' '))
    local winPids=($(echo "$winpids"|tr '\n' ' '))
    local proxyIndex=0
    local showType="listen"
    [ ! -z "$2" ] && showType="proxy"
    if [[ $showType == "listen" ]];then
        echo -e "PID\tWINPID\tRemote Address\t\tLocal Address\tHostName\n"
    else
        echo -e "PID\tWINPID\tRemote Address\t\tProxy Address\t\tHostName\n"
    fi
    for proxyNum in ${RemoteAddrs[@]};
    do
        #本地信息显示方式:代理地址 OR 监听地址
        #local showLocal=${ListenAddrs[$proxyIndex]} ##本地监听地址
        #local showLocal=${ProxyAddrs[$proxyIndex]} ##Socks代理地址
        if [[ $showType == "listen" ]];then
            local showLocal=${ListenAddrs[$proxyIndex]}
        else
            local showLocal=${ProxyAddrs[$proxyIndex]}
        fi
        echo -e "${unixPids[$proxyIndex]}\t${winPids[$proxyIndex]}\t$proxyNum\t$showLocal\t${HostAlias[$proxyIndex]}"
        let proxyIndex+=1
    done
}

do_TestProxy() {
    # 当前已适配开启多个Proxy进程的情况
    local processPID=$(ps aux|grep 'ssh-for-proxy'|awk '{print $4}'|tr '\n' ' ')
    if [ ! -z "$processPID" ];then
        #local proxyPort=$(netstat -ano|grep $processPID|grep 'LISTENING'|grep 0.0.0.0|awk '{print $2;exit}'|awk -F ':' '{print $NF}')
        #local proxyPort=$(netstat -ano|grep $processPID|grep 'LISTENING'|grep 0.0.0.0|awk '{print $2}')
        declare -a proxyPort ## 定义数组,存储找到的多个代理进程本地端口
        for pid in $processPID;
        do
            local port=$(netstat -ano|grep $pid|grep 'LISTENING'|grep 0.0.0.0|awk '{print $2;exit}'|awk -F ':' '{print $NF}')
            #echo "$port"
            proxyPort=(${proxyPort[@]} $port)
        done
    fi
    #echo "${proxyPort[@]}" ##数组:存储找到的所有代理的端口
    
    if [ ! -z "$processPID" -a ! -z "$proxyPort" ];then
        for dstport in ${proxyPort[@]};
        do
            echo "proxyPort:$dstport"
            echo "Proxy Address:127.0.0.1:$dstport"
            echo "Full Proxy Address:socks5://127.0.0.1:$dstport"
            nc -w 2 -v 127.0.0.1 $dstport
            curl --connect-timeout 3 -sS -x socks5://127.0.0.1:$dstport 'http://v.ynit.top/ipfull/'
            echo -e "\n"
        done
        return 0
    else
        echo "proxyPort not Found!"
    fi
}

if [[ $* == "kill" ]]
then
    do_KillProcess $@
    exit 0
fi

if [[ $* =~ ^list$ || $* =~ "list " ]]
then
    do_ListProxy $@
    exit 0
fi

if [[ $* == "test" ]]
then
    do_TestProxy $@
    exit 0
fi

proxyPort=8989
targetHost=$1
noHTTP=false

if [ $# -ge 2 ] && [ ! -z "$2" ];then
    #判断第二个参数是否为纯数字,如果是数字,则认定为自定义代理的本地端口
    expr $2 "+" 10 &> /dev/null  
    if [ $? -eq 0 ];then
        proxyPort=$2
        shift
    fi
fi

#proxyProcess=$(netstat -ano -P TCP|grep ':'$proxyPort)
proxyProcess=$(netstat -ano -P TCP|grep ':'$proxyPort|grep 'LISTENING')

if [ $(echo -n "$proxyProcess"|wc -c) -gt 0 ];then
    #echo "有进程..."
    echo "$proxyProcess"
    if [ ! -z "$2" ] && [[ "$2" == "true" ]];then
        ## 不询问用户,直接杀死已有的进程
        do_KillProcess      
    else
        echo "已有代理进程存在,是否杀死进程?"
        read -p "是否终止已有进程?选择否本脚本将退出后续操作。y/n(默认为n)" killProcess
        if [ -z "$killProcess" ];then
            killProcess="no"
        fi
        if [[ "$killProcess" == "y" || "$killProcess" == "yes" ]];then
            do_KillProcess
        else
            exit 0
        fi
    fi
    :;
else
    #echo "无进程..."
    :;
fi

# 如果指定了不询问即终止进程的参数,此处$*参数前移一位
[ $# -ge 3 ] && shift 1

# 是否需要启动HTTP代理,默认均启动socks转http,端口号为socks端口前面加1,$2设为“nohttp”则不启动。
# 下面用tr统一转字符串为小写比较
if [ ! -z "$2" ] && [[ $(tr "[:upper:]" "[:lower:]" <<<"$2") == "nohttp" ]];
then
    noHTTP=true
fi

#从5656端口开始到5700,找到一个未占用的端口作为autossh管理端口
managePort=5656
manageOK=false
while [ !$manageOK -a $managePort -lt 5701 ];
do 
    #echo "循环中"
    #nc -w 2 -v 127.0.0.1 $managePort &> /dev/null
    netstat -ano -P TCP|grep 'LISTENING'|grep '127.0.0.1:'$managePort &> /dev/null
    if [ $? -ne 0 ];then
        manageOK=true
        break
    fi
    #echo "查询下一个端口"
    let managePort+=1
done
if [[ $manageOK == false ]];then
    echo "未找到可用的管理端口,程序罢工退出"
    exit 1
fi
echo "autossh使用管理端口:$managePort"

goProxyPort="1"$proxyPort

AUTOSSH_PATH=/v/bin/ssh-for-proxy autossh -M $managePort -C -N -f -D 0.0.0.0:$proxyPort $targetHost
echo "Proxy Address:127.0.0.1:$proxyPort"
echo "Full Proxy Address:socks5://127.0.0.1:$proxyPort"
echo "sshproxy Execute Done..."
sleep 1
nc -w 2 -v 127.0.0.1 $proxyPort
curl --connect-timeout 3 -sS -x socks5://127.0.0.1:$proxyPort 'http://v.ynit.top/ipfull/'
if [[ $noHTTP == false ]]
then
    echo -e "\nNow goProxy convert SOCKS proxy to HTTP:0.0.0.0:$goProxyPort\t Use:127.0.0.1:$goProxyPort"
    #以下为两种运行goproxy转换代理的方式,由bash接收进程信号会导致效率降低,建议直接cmd形式调用
    # way 1: bash run
    #/v/bin/goproxy-for-ssh http -l 0.0.0.0:$goProxyPort -b 127.0.0.1:$proxyPort &>/dev/null &
    # way 2:cmd run
    cmd /c start "GoProxy: HTTP Proxy for $targetHost" `cygpath -w /v/bin/goproxy-for-ssh` http -l 0.0.0.0:$goProxyPort -b 127.0.0.1:$proxyPort
else
    echo -e "\n"
fi
您看到此篇文章时的感受是:
Tags:autossh sshproxy 责任编辑:administrator
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到QQ空间
分享到: 
上一篇为什么使用shell编程? 下一篇没有了

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

相关栏目

最新文章

图片主题

热门文章

推荐文章

相关文章

广告位