Mac OS X client script, simple use

Post your questions about SoftEther VPN software here. Please answer questions if you can afford.
Post Reply
feinir
Posts: 6
Joined: Wed Sep 12, 2018 11:56 am

Mac OS X client script, simple use

Post by feinir » Wed Sep 12, 2018 12:11 pm

暂时只支持Chinese,若需要其他语言的,请联系我。feinir@gmail.com
用法(假设你的脚本文件名为vpn):
vpn start 启动客户端服务
vpn stop 停止客户服务
vpn up 1 连接第一个vpn服务器,参数为2,则连接第二个vpn服务器。参数为空,则默认连接第一个服务器,下同
vpn down 1 断开第一个vpn服务器。
vpn set 重新配置vpn连接的DHCP route dns等
vpn flush 清除vpn连接的DHCP route dns等
vpn downall 断开所有连接

Code: Select all

#!/bin/bash
#string include

type=$1
index=$2

basePath=/usr/local/vpnclient
baseStr="$basePath"

#你的VPN服务器地址和vpnclient里配置好的连接名
#you vpnclient settings
vpnServers=('45.77.***.***' '45.76.***.***')
vpnNames=('VPN-77' 'VPN-76')

#以下值为默认值,程序会自动读取当前网卡的值替换,读取失败时,使用默认值
vpnName="VPN-77"

defaultGW="192.168.9.1"
newGW="192.168.30.1"
defalutIFName="en6"
defalutSPID="F04F0AA7-5C8A-4F18-BEDF-6392C9FFEB9F"
vpnIFName="tap0"

if [[ $# -lt 1 ]]
then
	echo "$0 start"
	echo "$0 stop"
	echo "$0 up"
	echo "$0 down"
	echo "$0 flush"
	echo "$0 set"
	echo "$0 get"
	exit 1
fi

function getVpnName()
{
	vpnName=${vpnNames[0]}
	if [[ -z ${index} ]]; then
    	echo "VPN Name为空,使用默认值 $vpnName"
	else
    	let index-=1;
		vpnName=${vpnNames[$index]}
		echo "VPN Name: $vpnName"
	fi
}

function clientStatus()
{
    if [[ `ps -ef | grep vpnclient/vpnclient | grep -c ${baseStr}` -gt 1 ]]; then
		echo "vpn 已经启动"
		#echo "vpnThreadSize: `ps -ef | grep vpnclient/vpnclient | grep -c ${baseStr}`"
		return 1
	fi
    return 0
}

function connectStatus()
{
	status=$( (/usr/local/vpnclient/vpncmd localhost /CLIENT | grep 会话状态)<<EOF
AccountStatusGet $1
EOF
)
	if [[ (${status} =~ "连接完成") ]]; then
		return 1
	fi
	return 0
}

function connectStatusDown()
{
	status=$( (/usr/local/vpnclient/vpncmd localhost /CLIENT | grep 会话状态)<<EOF
AccountStatusGet $1
EOF
)
	if [[ ${status} =~ "连接完成" ]]; then
		return 1
	elif [[ ${status} =~ "开始连接" ]]; then
		return 1
	elif [[ ${status} =~ "重试" ]]; then
		return 1
	fi
	return 0
}

function connectVPN()
{
	echo "开始连接服务器 $1"
	status=$( (/usr/local/vpnclient/vpncmd localhost /CLIENT | grep 完成)<<EOF
AccountConnect $1
EOF
)
	echo ${status}
}

function disConnectVPN()
{
	echo "开始断开服务器 $1"
	status=$( (/usr/local/vpnclient/vpncmd localhost /CLIENT | grep 完成)<<EOF
AccountDisconnect $1
EOF
)
	echo ${status}
}

function setDhcp()
{
	echo "开始从DHCP获得IP..."
	ipconfig set ${vpnIFName} DHCP
	ipconfig waitall
}

function dhcpStatus()
{
	status=$( (ifconfig ${vpnIFName} | grep inet | sed -e 's/.*inet //' | sed -e 's/ netmask.*//') )
	echo "${vpnIFName} DHCP IP value: ${status}"
	if [[ ${status} =~ "192.168" ]]; then
		return 1
	elif [[ ${status} =~ "10." ]]; then
		return 1
	elif [[ ${status} =~ "172." ]]; then
		return 1
	fi
	return 0
}

function setRoute()
{
	echo "开始配置VPN的Route"
	route delete default ${defaultGW}
	route -n flush
	for item in ${vpnServers[@]}; do
        route -n add ${item} ${defaultGW}
    done
	route add default ${newGW}
}

function deleteRoute()
{
	echo "开始删除VPN的Route设定"
    for item in ${vpnServers[@]}; do
        route -n delete ${item}
    done
	route delete default ${newGW}
	route -n flush
	route add default ${defaultGW}
}

function dnsStatus()
{
	status=$( (/usr/sbin/scutil | grep "0 : " | sed -e 's/.*0 : //')<<EOF
show State:/Network/Service/DHCP-${vpnIFName}/DNS
EOF
)
	echo "${vpnIFName} DNS value: ${status}"
	if [[ -n ${status} ]]; then
		return 1
	fi
	return 0
}

function setDNS()
{
	echo "配置VPN的DNS设定,VPN虚拟网卡名:${vpnIFName}"
	/usr/sbin/scutil <<EOF
d.init
get State:/Network/Service/DHCP-${vpnIFName}/DNS
set State:/Network/Global/DNS
EOF

}

function getDefaultIFName()
{
	status=$( (/usr/sbin/scutil | grep PrimaryInterface | sed -e 's/.*PrimaryInterface : //')<<EOF
show State:/Network/Global/IPv4
EOF
)
	#echo ${status}
	if [[ -n ${status} ]]; then
		defalutIFName=${status}
		echo "PrimaryInterface: ${defalutIFName}"
	fi
}

function getDefaultSPID()
{
	status=$( (/usr/sbin/scutil | grep PrimaryService | sed -e 's/.*PrimaryService : //')<<EOF
show State:/Network/Global/IPv4
EOF
)
	#echo ${status}
	if [[ -n ${status} ]]; then
		defalutSPID=${status}
		echo "PrimaryService: ${defalutSPID}"
	fi
}

function getDefaultGW()
{
	status=$( (/usr/sbin/scutil | grep Router | sed -e 's/.*Router : //')<<EOF
show State:/Network/Global/IPv4
EOF
)
	#echo ${status}
	if [[ -n ${status} ]]; then
		defaultGW=${status}
		echo "Router: ${defaultGW}"
	fi
}

function getNewGW()
{
	status=$( (/usr/sbin/scutil | grep "Router : " | sed -e 's/.*Router : //')<<EOF
show State:/Network/Service/DHCP-${vpnIFName}/IPv4
EOF
)
	#echo ${status}
	if [[ -n ${status} ]]; then
		newGW=${status}
		echo "NewRouter: ${newGW}"
	fi
}

function readData(){
	echo "当前主网卡信息:"
	getDefaultIFName
	getDefaultSPID
	getDefaultGW
}

function saveDataFile()
{
	echo "保存主网卡信息"
	rm -rf ${basePath}/save.txt
	if [[ -n ${defalutIFName} ]]; then
		echo "PrimaryInterface : ${defalutIFName}" >> ${basePath}/save.txt
	fi
	if [[ -n ${defalutSPID} ]]; then
		echo "PrimaryService : ${defalutSPID}" >> ${basePath}/save.txt
	fi
	if [[ -n ${defaultGW} ]]; then
		echo "PrimaryRouter : ${defaultGW}" >> ${basePath}/save.txt
	fi
	if [[ -n ${newGW} ]]; then
		echo "NewRouter : ${newGW}" >> ${basePath}/save.txt
	fi
}

function readDataFile()
{
	echo "读取主网卡信息"
	status=$( (cat ${basePath}/save.txt | grep PrimaryInterface | sed -e 's/.*PrimaryInterface : //'))
	if [[ -n ${status} ]]; then
		defalutIFName=${status}
		echo "PrimaryInterface: ${defalutIFName}"
	fi
	status=$( (cat ${basePath}/save.txt | grep PrimaryService | sed -e 's/.*PrimaryService : //'))
	if [[ -n ${status} ]]; then
		defalutSPID=${status}
		echo "PrimaryService: ${defalutSPID}"
	fi
	status=$( (cat ${basePath}/save.txt | grep PrimaryRouter | sed -e 's/.*PrimaryRouter : //'))
	if [[ -n ${status} ]]; then
		defaultGW=${status}
		echo "PrimaryRouter: ${defaultGW}"
	fi
	status=$( (cat ${basePath}/save.txt | grep NewRouter | sed -e 's/.*NewRouter : //'))
	if [[ -n ${status} ]]; then
		newGW=${status}
		echo "NewRouter: ${newGW}"
	fi
}

function deleteDNS()
{
	echo "主网卡信息:"
	echo "PrimaryInterface: ${defalutIFName}"
	echo "PrimaryService: ${defalutSPID}"
	echo "Router: ${defaultGW}"
	echo "删除VPN的DNS设定"
	/usr/sbin/scutil <<EOF
d.init
get State:/Network/Service/${defalutSPID}/DNS
set State:/Network/Global/DNS
EOF

}

function getConnName()
{
	len=${#vpnNames[@]}
	for ((i=0;i<$len;i++));do
		connectStatusDown ${vpnNames[i]}
		if [[ $? == 1 ]]; then
			echo "当前活动连接:${vpnNames[i]}"
			let i+=1;
        	return ${i}
        fi
	done
    return 0;
}

function disConnectVPNAll()
{
	for item in ${vpnNames[@]}; do
		disConnectVPN ${item}
	done
}

function showStatus()
{
	/usr/local/vpnclient/vpncmd localhost /CLIENT <<EOF
AccountList
EOF
    /usr/sbin/scutil <<EOF
show State:/Network/Global/DNS
EOF

}

case "$type" in
	start)
		clientStatus
		if [[ $? == 1 ]]; then exit 1; fi
		echo "开始启动vpn"
		${basePath}/vpnclient start
	;;
	up)
		clientStatus
		if [[ $? == 0 ]]; then exit 1; fi
			
		getVpnName

		connectStatusDown ${vpnName}
		if [[ $? == 1 ]]; then
			echo "当前状态为正在连接,请先down掉这个连接或者等待"
			exit 1;
		fi

		connectVPN ${vpnName}
		connectStatus ${vpnName}
		while [[ $? == 0 ]]; do
			sleep 1
			connectStatus ${vpnName}
		done

		setDhcp
		dhcpStatus
		while [[ $? == 0 ]]; do
			sleep 1
			dhcpStatus
		done

		dnsStatus
		while [[ $? == 0 ]]; do
			sleep 1
			dnsStatus
		done

		readData
		getNewGW
		setDNS
		setRoute				
	;;
	set)
		clientStatus
		if [[ $? == 0 ]]; then exit 1; fi

		setDhcp
		dhcpStatus
		while [[ $? == 0 ]]; do
			sleep 1
			dhcpStatus
		done

		dnsStatus
		while [[ $? == 0 ]]; do
			sleep 1
			dnsStatus
		done

		readData
		getNewGW		
		setDNS
		setRoute
	;;
	get)
		clientStatus
		if [[ $? == 0 ]]; then exit 1; fi
		showStatus
	;;
	stop)
		clientStatus
		if [[ $? == 0 ]]; then exit 1; fi
		echo "开始停止vpn"
		${basePath}/vpnclient stop
		clientStatus
		while [[ $? == 1 ]]; do
			sleep 1
			clientStatus
		done
		readData
		getNewGW
		deleteRoute
		deleteDNS
	;;
	down)
		clientStatus
		if [[ $? == 0 ]]; then exit 1; fi
		getConnName
		index=$?
		if [[ ${index} == 0 ]]; then
			echo "当前没有活动的连接"
		else
			let index-=1;
			vpnName=${vpnNames[$index]};
			disConnectVPN ${vpnName}
			connectStatus ${vpnName}
			while [[ $? == 1 ]]; do
				sleep 1
				connectStatus ${vpnName}
			done
		fi

		readData
		getNewGW
		deleteRoute
		deleteDNS
	;;
	downall)
		clientStatus
		if [[ $? == 0 ]]; then exit 1; fi
		disConnectVPNAll

		readData
		getNewGW
		deleteRoute
		deleteDNS
	;;
	flush)
		clientStatus
		if [[ $? == 0 ]]; then exit 1; fi

		readData
		getNewGW
		deleteRoute
		deleteDNS
	;;
	*)
		echo "$0: invalid type"
		exit 1
	;;
esac


feinir
Posts: 6
Joined: Wed Sep 12, 2018 11:56 am

Re: Mac OS X client script, simple use

Post by feinir » Thu Sep 13, 2018 5:14 am

修改了DNS配置方式

Code: Select all

#!/bin/bash
#string include

type=$1
index=$2

basePath=/usr/local/vpnclient
baseStr="$basePath"

#you IPs
vpnServers=('1.2.*.*' '3.4.*.*' '5.6.*.*')
vpnNames=('VPN-77' 'VPN-94' 'VPN-Home')

#以下值为默认值,程序会自动读取当前网卡的值替换,读取失败时,使用默认值
vpnName="VPN-77"

defaultGW="192.168.9.1"
newGW="192.168.30.1"
defaultIFName="en6"
defaultSPID="F04F0AA7-5C8A-4F18-BEDF-6392C9FFEB9F"
defaultDNS="114.114.115.115 68.105.28.11"

vpnIFName="tap0"

if [[ $# -lt 1 ]]
then
	echo "$0 start"
	echo "$0 stop"
	echo "$0 up"
	echo "$0 down"
	echo "$0 downall"
	echo "$0 flush"
	echo "$0 set"
	echo "$0 get"
	exit 1
fi

function getVpnName()
{
	vpnName=${vpnNames[0]}
	if [[ -z ${index} ]]; then
    	echo "VPN Name为空,使用默认值 $vpnName"
	else
    	let index-=1;
		vpnName=${vpnNames[$index]}
		echo "VPN Name: $vpnName"
	fi
}

function clientStatus()
{
    if [[ `ps -ef | grep vpnclient/vpnclient | grep -c ${baseStr}` -gt 1 ]]; then
		echo "vpn 已经启动"
		#echo "vpnThreadSize: `ps -ef | grep vpnclient/vpnclient | grep -c ${baseStr}`"
		return 1
	fi
    return 0
}

function connectStatusOK()
{
	status=$( (/usr/local/vpnclient/vpncmd localhost /CLIENT | grep 会话状态)<<EOF
AccountStatusGet $1
EOF
)
	if [[ (${status} =~ "连接完成") ]]; then
		return 1
	fi
	return 0
}

function connectStatusConn()
{
	status=$( (/usr/local/vpnclient/vpncmd localhost /CLIENT | grep 会话状态)<<EOF
AccountStatusGet $1
EOF
)
	if [[ ${status} =~ "连接完成" ]]; then
		return 1
	elif [[ ${status} =~ "开始连接" ]]; then
		return 1
	elif [[ ${status} =~ "重试" ]]; then
		return 1
	fi
	return 0
}

function connectVPN()
{
	echo "开始连接服务器 $1"
	status=$( (/usr/local/vpnclient/vpncmd localhost /CLIENT | grep 完成)<<EOF
AccountConnect $1
EOF
)
	echo ${status}
}

function disConnectVPN()
{
	echo "开始断开服务器 $1"
	status=$( (/usr/local/vpnclient/vpncmd localhost /CLIENT | grep 完成)<<EOF
AccountDisconnect $1
EOF
)
	echo ${status}
}

function setDhcp()
{
	echo "开始从DHCP获得IP..."
	ipconfig set ${vpnIFName} DHCP
	ipconfig waitall
}

function dhcpStatus()
{
	status=$( (ifconfig ${vpnIFName} | grep inet | sed -e 's/.*inet //' | sed -e 's/ netmask.*//') )
	echo "${vpnIFName} DHCP IP value: ${status}"
	if [[ ${status} =~ "192.168" ]]; then
		return 1
	elif [[ ${status} =~ "10." ]]; then
		return 1
	elif [[ ${status} =~ "172." ]]; then
		return 1
	fi
	return 0
}

function setRoute()
{
	echo "开始配置VPN的Route"	
	route delete default ${defaultGW}
	#route -n flush
	for item in ${vpnServers[@]}; do
        route -n add ${item} ${defaultGW}
    done
	route add default ${newGW}
}

function deleteRoute()
{
	echo "开始删除VPN的Route设定"
    for item in ${vpnServers[@]}; do
        route -n delete ${item}
    done
	route delete default ${newGW}
	#route -n flush
	route add default ${defaultGW}
}

function dnsStatus()
{
	status=$( (/usr/sbin/scutil | grep "0 : " | sed -e 's/.*0 : //')<<EOF
show State:/Network/Service/DHCP-${vpnIFName}/DNS
EOF
)
	echo "${vpnIFName} DNS value: ${status}"
	if [[ -n ${status} ]]; then
		return 1
	fi
	return 0
}

function setDNS()
{
	echo "配置VPN的DNS设定,VPN虚拟网卡名:${vpnIFName}"
	/usr/sbin/scutil <<EOF
d.init
get State:/Network/Service/DHCP-${vpnIFName}/DNS
set State:/Network/Global/DNS
set State:/Network/Service/${defaultSPID}/DNS
set Setup:/Network/Service/${defaultSPID}/DNS
EOF

}

function deleteDNS()
{
	echo "清除VPN的DNS设定。主网卡:"
	echo "PrimaryInterface: ${defaultIFName}"
	echo "PrimaryService: ${defaultSPID}"
	/usr/sbin/scutil <<EOF
d.init
d.add ServerAddresses * ${defaultDNS}
set State:/Network/Global/DNS
set State:/Network/Service/${defaultSPID}/DNS
set Setup:/Network/Service/${defaultSPID}/DNS
EOF

}

function getDefaultIFName()
{
	status=$( (/usr/sbin/scutil | grep PrimaryInterface | sed -e 's/.*PrimaryInterface : //')<<EOF
show State:/Network/Global/IPv4
EOF
)
	#echo ${status}
	if [[ -n ${status} ]]; then
		defaultIFName=${status}
		#echo "PrimaryInterface: ${defaultIFName}"
	fi
}

function getDefaultSPID()
{
	status=$( (/usr/sbin/scutil | grep PrimaryService | sed -e 's/.*PrimaryService : //')<<EOF
show State:/Network/Global/IPv4
EOF
)
	#echo ${status}
	if [[ -n ${status} ]]; then
		defaultSPID=${status}
		#echo "PrimaryService: ${defaultSPID}"
	fi
}

function getDefaultDNS()
{
	status=$( (cat /etc/resolv.conf | grep -v '#' | sed -e 's/nameserver //' | paste -s -d' ' -))
	#echo ${status}
	if [[ -n ${status} ]]; then
		defaultDNS=${status}
		#echo "DefaultDNS: ${defaultDNS}"
	fi
}

function getDefaultGW()
{
	status=$( (/usr/sbin/scutil | grep "Router : " | sed -e 's/.*Router : //')<<EOF
show State:/Network/Service/${defaultSPID}/IPv4
EOF
)
	#echo ${status}
	if [[ -n ${status} ]]; then
		defaultGW=${status}
		#echo "DefaultRouter: ${defaultGW}"
	fi
}

function getNewGW()
{
	newGWStatus
	if [[ $? == 1 ]]; then
		status=$( (/usr/sbin/scutil | grep "Router : " | sed -e 's/.*Router : //')<<EOF
show State:/Network/Service/DHCP-${vpnIFName}/IPv4
EOF
)
		#echo ${status}
		if [[ -n ${status} ]]; then
			newGW=${status}
			echo "NewRouter: ${newGW}"
		fi
	fi
}

function newGWStatus()
{
	status=$( (/usr/sbin/scutil | grep "Router : " | sed -e 's/.*Router : //')<<EOF
show State:/Network/Service/DHCP-${vpnIFName}/IPv4
EOF
)
	#echo ${status}
	if [[ -n ${status} ]]; then
		return 1
	fi
	return 0
}

function readData(){
	echo "从内存中读取当前主网卡信息:"
	getDefaultIFName
	getDefaultSPID
	getDefaultDNS
	getDefaultGW
	
	echo "PrimaryInterface: ${defaultIFName}"
	echo "PrimaryService : ${defaultSPID}"
	echo "DefaultDNS : ${defaultDNS}"
	echo "DefaultGW : ${defaultGW}"

}


function saveDataFile()
{
	echo "保存主网卡信息"
	echo "PrimaryInterface: ${defaultIFName}"
	echo "PrimaryService : ${defaultSPID}"
	echo "DefaultDNS : ${defaultDNS}"

	rm -rf ${basePath}/save.txt
	if [[ -n ${defaultIFName} ]]; then
		echo "PrimaryInterface : ${defaultIFName}" >> ${basePath}/save.txt
	fi
	if [[ -n ${defaultSPID} ]]; then
		echo "PrimaryService : ${defaultSPID}" >> ${basePath}/save.txt
	fi
	if [[ -n ${defaultDNS} ]]; then
		echo "DefaultDNS : ${defaultDNS}" >> ${basePath}/save.txt
	fi
}

function readDataFile()
{
	echo "从文件中读取主网卡信息"
	status=$( (cat ${basePath}/save.txt | grep PrimaryInterface | sed -e 's/.*PrimaryInterface : //'))
	if [[ -n ${status} ]]; then
		defaultIFName=${status}
		echo "PrimaryInterface: ${defaultIFName}"
	fi
	status=$( (cat ${basePath}/save.txt | grep PrimaryService | sed -e 's/.*PrimaryService : //'))
	if [[ -n ${status} ]]; then
		defaultSPID=${status}
		echo "PrimaryService: ${defaultSPID}"
	fi
	status=$( (cat ${basePath}/save.txt | grep DefaultDNS | sed -e 's/.*DefaultDNS : //'))
	if [[ -n ${status} ]]; then
		defaultDNS=${status}
		echo "DefaultDNS: ${defaultDNS}"
	fi

	getDefaultGW
}


function getConnName()
{
	len=${#vpnNames[@]}
	for ((i=0;i<$len;i++));do
		connectStatusConn ${vpnNames[i]}
		if [[ $? == 1 ]]; then
			echo "当前活动连接:${vpnNames[i]}"
			let i+=1;
        	return ${i}
        fi
	done
    return 0;
}

function disConnectVPNAll()
{
	for item in ${vpnNames[@]}; do
		disConnectVPN ${item}
	done
}

function showStatus()
{
	echo "连接信息:"
	(/usr/local/vpnclient/vpncmd localhost /CLIENT <<EOF
AccountList
EOF
) | grep '\|'
	echo " "

	echo "当前网络配置(State:/Network/Global/VPv4):"
    (/usr/sbin/scutil <<EOF
show State:/Network/Global/IPv4
EOF
) | grep -v '<dictionary>' | grep -v '}'

	echo "当前DNS(State:/Network/Global/DNS):"
	(/usr/sbin/scutil <<EOF
show State:/Network/Global/DNS
EOF
) | grep -v '<dictionary>' | grep -v '^}'

	echo "当前DNS(State:/Network/Service/${defaultSPID}/DNS):"
	(/usr/sbin/scutil <<EOF
show State:/Network/Service/${defaultSPID}/DNS
EOF
) | grep -v '<dictionary>' | grep -v '^}'
	echo "当前DNS(Setup:/Network/Service/${defaultSPID}/DNS):"
	(/usr/sbin/scutil <<EOF
show Setup:/Network/Service/${defaultSPID}/DNS
EOF
) | grep -v '<dictionary>' | grep -v '^}'
	echo ""
	echo "/etc/resolv.conf文件内容:"
	cat /etc/resolv.conf | grep -v '#'
}

case "$type" in
	start)
		clientStatus
		if [[ $? == 1 ]]; then exit 1; fi
		echo "开始启动vpn"
		${basePath}/vpnclient start
	;;
	up)
		clientStatus
		if [[ $? == 0 ]]; then exit 1; fi
			
		getVpnName

		connectStatusConn ${vpnName}
		if [[ $? == 1 ]]; then
			echo "当前状态为正在连接,请先down掉这个连接或者等待"
			exit 1;
		fi

		readData
		saveDataFile

		connectVPN ${vpnName}
		connectStatusOK ${vpnName}
		while [[ $? == 0 ]]; do
			sleep 1
			connectStatusOK ${vpnName}
		done

		setDhcp
		dhcpStatus
		while [[ $? == 0 ]]; do
			sleep 1
			dhcpStatus
		done

		dnsStatus
		while [[ $? == 0 ]]; do
			sleep 1
			dnsStatus
		done
		getNewGW

		setDNS
		setRoute				
	;;
	set)
		clientStatus
		if [[ $? == 0 ]]; then exit 1; fi

		setDhcp
		dhcpStatus
		while [[ $? == 0 ]]; do
			sleep 1
			dhcpStatus
		done

		dnsStatus
		while [[ $? == 0 ]]; do
			sleep 1
			dnsStatus
		done

		readDataFile

		getNewGW	
		setDNS
		setRoute
	;;
	get)
		clientStatus
		if [[ $? == 0 ]]; then exit 1; fi
		readData
		readDataFile
		showStatus
	;;
	stop)
		clientStatus
		if [[ $? == 0 ]]; then exit 1; fi

		readDataFile

		echo "开始停止vpn"
		${basePath}/vpnclient stop
		clientStatus
		while [[ $? == 1 ]]; do
			sleep 1
			clientStatus
		done		
		
		getNewGW
		deleteRoute
		deleteDNS
	;;
	down)
		clientStatus
		if [[ $? == 0 ]]; then exit 1; fi

		readDataFile

		getConnName
		index=$?
		if [[ ${index} == 0 ]]; then
			echo "当前没有活动的连接"
		else
			let index-=1;
			vpnName=${vpnNames[$index]};
			disConnectVPN ${vpnName}
			connectStatusOK ${vpnName}
			while [[ $? == 1 ]]; do
				sleep 1
				connectStatusOK ${vpnName}
			done
		fi

		getNewGW
		deleteRoute
		deleteDNS
	;;
	downall)
		clientStatus
		if [[ $? == 0 ]]; then exit 1; fi

		readDataFile

		disConnectVPNAll

		deleteRoute
		deleteDNS
	;;
	flush)
		clientStatus
		if [[ $? == 0 ]]; then exit 1; fi

		readDataFile
		
		getNewGW
		deleteRoute
		deleteDNS
	;;
	*)
		echo "$0: invalid type"
		exit 1
	;;
esac


feinir
Posts: 6
Joined: Wed Sep 12, 2018 11:56 am

Re: Mac OS X client script, simple use

Post by feinir » Thu Sep 13, 2018 5:22 am

Code: Select all

#!/bin/bash
#string include

type=$1
index=$2

basePath=/usr/local/vpnclient
baseStr="$basePath"

#you vpnclient settings
vpnServers=('45.77.***.***' '45.76.***.***')
vpnNames=('VPN-77' 'VPN-76')

#以下值为默认值,程序会自动读取当前网卡的值替换,读取失败时,使用默认值
vpnName="VPN-77"

defaultGW="192.168.9.1"
newGW="192.168.30.1"
defaultIFName="en6"
defaultSPID="F04F0AA7-5C8A-4F18-BEDF-6392C9FFEB9F"
defaultDNS="114.114.115.115 68.105.28.11"

vpnIFName="tap0"

if [[ $# -lt 1 ]]
then
	echo "$0 start"
	echo "$0 stop"
	echo "$0 up"
	echo "$0 down"
	echo "$0 downall"
	echo "$0 flush"
	echo "$0 set"
	echo "$0 get"
	exit 1
fi

function getVpnName()
{
	vpnName=${vpnNames[0]}
	if [[ -z ${index} ]]; then
    	echo "VPN Name为空,使用默认值 $vpnName"
	else
    	let index-=1;
		vpnName=${vpnNames[$index]}
		echo "VPN Name: $vpnName"
	fi
}

function clientStatus()
{
    if [[ `ps -ef | grep vpnclient/vpnclient | grep -c ${baseStr}` -gt 1 ]]; then
		echo "vpn 已经启动"
		#echo "vpnThreadSize: `ps -ef | grep vpnclient/vpnclient | grep -c ${baseStr}`"
		return 1
	fi
    return 0
}

function connectStatusOK()
{
	status=$( (/usr/local/vpnclient/vpncmd localhost /CLIENT | grep 会话状态)<<EOF
AccountStatusGet $1
EOF
)
	if [[ (${status} =~ "连接完成") ]]; then
		return 1
	fi
	return 0
}

function connectStatusConn()
{
	status=$( (/usr/local/vpnclient/vpncmd localhost /CLIENT | grep 会话状态)<<EOF
AccountStatusGet $1
EOF
)
	if [[ ${status} =~ "连接完成" ]]; then
		return 1
	elif [[ ${status} =~ "开始连接" ]]; then
		return 1
	elif [[ ${status} =~ "重试" ]]; then
		return 1
	fi
	return 0
}

function connectVPN()
{
	echo "开始连接服务器 $1"
	status=$( (/usr/local/vpnclient/vpncmd localhost /CLIENT | grep 完成)<<EOF
AccountConnect $1
EOF
)
	echo ${status}
}

function disConnectVPN()
{
	echo "开始断开服务器 $1"
	status=$( (/usr/local/vpnclient/vpncmd localhost /CLIENT | grep 完成)<<EOF
AccountDisconnect $1
EOF
)
	echo ${status}
}

function setDhcp()
{
	echo "开始从DHCP获得IP..."
	ipconfig set ${vpnIFName} DHCP
	ipconfig waitall
}

function dhcpStatus()
{
	status=$( (ifconfig ${vpnIFName} | grep inet | sed -e 's/.*inet //' | sed -e 's/ netmask.*//') )
	echo "${vpnIFName} DHCP IP value: ${status}"
	if [[ ${status} =~ "192.168" ]]; then
		return 1
	elif [[ ${status} =~ "10." ]]; then
		return 1
	elif [[ ${status} =~ "172." ]]; then
		return 1
	fi
	return 0
}

function setRoute()
{
	echo "开始配置VPN的Route"	
	route delete default ${defaultGW}
	#route -n flush
	for item in ${vpnServers[@]}; do
        route -n add ${item} ${defaultGW}
    done
	route add default ${newGW}
}

function deleteRoute()
{
	echo "开始删除VPN的Route设定"
    for item in ${vpnServers[@]}; do
        route -n delete ${item}
    done
	route delete default ${newGW}
	#route -n flush
	route add default ${defaultGW}
}

function dnsStatus()
{
	status=$( (/usr/sbin/scutil | grep "0 : " | sed -e 's/.*0 : //')<<EOF
show State:/Network/Service/DHCP-${vpnIFName}/DNS
EOF
)
	echo "${vpnIFName} DNS value: ${status}"
	if [[ -n ${status} ]]; then
		return 1
	fi
	return 0
}

function setDNS()
{
	echo "配置VPN的DNS设定,VPN虚拟网卡名:${vpnIFName}"
	/usr/sbin/scutil <<EOF
d.init
get State:/Network/Service/DHCP-${vpnIFName}/DNS
set State:/Network/Global/DNS
set State:/Network/Service/${defaultSPID}/DNS
set Setup:/Network/Service/${defaultSPID}/DNS
EOF

}

function deleteDNS()
{
	echo "清除VPN的DNS设定。主网卡:"
	echo "PrimaryInterface: ${defaultIFName}"
	echo "PrimaryService: ${defaultSPID}"
	/usr/sbin/scutil <<EOF
d.init
d.add ServerAddresses * ${defaultDNS}
set State:/Network/Global/DNS
set State:/Network/Service/${defaultSPID}/DNS
set Setup:/Network/Service/${defaultSPID}/DNS
EOF

}

function getDefaultIFName()
{
	status=$( (/usr/sbin/scutil | grep PrimaryInterface | sed -e 's/.*PrimaryInterface : //')<<EOF
show State:/Network/Global/IPv4
EOF
)
	#echo ${status}
	if [[ -n ${status} ]]; then
		defaultIFName=${status}
		#echo "PrimaryInterface: ${defaultIFName}"
	fi
}

function getDefaultSPID()
{
	status=$( (/usr/sbin/scutil | grep PrimaryService | sed -e 's/.*PrimaryService : //')<<EOF
show State:/Network/Global/IPv4
EOF
)
	#echo ${status}
	if [[ -n ${status} ]]; then
		defaultSPID=${status}
		#echo "PrimaryService: ${defaultSPID}"
	fi
}

function getDefaultDNS()
{
	status=$( (cat /etc/resolv.conf | grep -v '#' | sed -e 's/nameserver //' | paste -s -d' ' -))
	#echo ${status}
	if [[ -n ${status} ]]; then
		defaultDNS=${status}
		#echo "DefaultDNS: ${defaultDNS}"
	fi
}

function getDefaultGW()
{
	status=$( (/usr/sbin/scutil | grep "Router : " | sed -e 's/.*Router : //')<<EOF
show State:/Network/Service/${defaultSPID}/IPv4
EOF
)
	#echo ${status}
	if [[ -n ${status} ]]; then
		defaultGW=${status}
		#echo "DefaultRouter: ${defaultGW}"
	fi
}

function getNewGW()
{
	newGWStatus
	if [[ $? == 1 ]]; then
		status=$( (/usr/sbin/scutil | grep "Router : " | sed -e 's/.*Router : //')<<EOF
show State:/Network/Service/DHCP-${vpnIFName}/IPv4
EOF
)
		#echo ${status}
		if [[ -n ${status} ]]; then
			newGW=${status}
			echo "NewRouter: ${newGW}"
		fi
	fi
}

function newGWStatus()
{
	status=$( (/usr/sbin/scutil | grep "Router : " | sed -e 's/.*Router : //')<<EOF
show State:/Network/Service/DHCP-${vpnIFName}/IPv4
EOF
)
	#echo ${status}
	if [[ -n ${status} ]]; then
		return 1
	fi
	return 0
}

function readData(){
	echo "从内存中读取当前主网卡信息:"
	getDefaultIFName
	getDefaultSPID
	getDefaultDNS
	getDefaultGW
	
	echo "PrimaryInterface: ${defaultIFName}"
	echo "PrimaryService : ${defaultSPID}"
	echo "DefaultDNS : ${defaultDNS}"
	echo "DefaultGW : ${defaultGW}"

}


function saveDataFile()
{
	echo "保存主网卡信息"
	echo "PrimaryInterface: ${defaultIFName}"
	echo "PrimaryService : ${defaultSPID}"
	echo "DefaultDNS : ${defaultDNS}"

	rm -rf ${basePath}/save.txt
	if [[ -n ${defaultIFName} ]]; then
		echo "PrimaryInterface : ${defaultIFName}" >> ${basePath}/save.txt
	fi
	if [[ -n ${defaultSPID} ]]; then
		echo "PrimaryService : ${defaultSPID}" >> ${basePath}/save.txt
	fi
	if [[ -n ${defaultDNS} ]]; then
		echo "DefaultDNS : ${defaultDNS}" >> ${basePath}/save.txt
	fi
}

function readDataFile()
{
	echo "从文件中读取主网卡信息"
	status=$( (cat ${basePath}/save.txt | grep PrimaryInterface | sed -e 's/.*PrimaryInterface : //'))
	if [[ -n ${status} ]]; then
		defaultIFName=${status}
		echo "PrimaryInterface: ${defaultIFName}"
	fi
	status=$( (cat ${basePath}/save.txt | grep PrimaryService | sed -e 's/.*PrimaryService : //'))
	if [[ -n ${status} ]]; then
		defaultSPID=${status}
		echo "PrimaryService: ${defaultSPID}"
	fi
	status=$( (cat ${basePath}/save.txt | grep DefaultDNS | sed -e 's/.*DefaultDNS : //'))
	if [[ -n ${status} ]]; then
		defaultDNS=${status}
		echo "DefaultDNS: ${defaultDNS}"
	fi

	getDefaultGW
}


function getConnName()
{
	len=${#vpnNames[@]}
	for ((i=0;i<$len;i++));do
		connectStatusConn ${vpnNames[i]}
		if [[ $? == 1 ]]; then
			echo "当前活动连接:${vpnNames[i]}"
			let i+=1;
        	return ${i}
        fi
	done
    return 0;
}

function disConnectVPNAll()
{
	for item in ${vpnNames[@]}; do
		disConnectVPN ${item}
	done
}

function showStatus()
{
	echo "连接信息:"
	(/usr/local/vpnclient/vpncmd localhost /CLIENT <<EOF
AccountList
EOF
) | grep '\|'
	echo " "

	echo "当前网络配置(State:/Network/Global/VPv4):"
    (/usr/sbin/scutil <<EOF
show State:/Network/Global/IPv4
EOF
) | grep -v '<dictionary>' | grep -v '}'

	echo "当前DNS(State:/Network/Global/DNS):"
	(/usr/sbin/scutil <<EOF
show State:/Network/Global/DNS
EOF
) | grep -v '<dictionary>' | grep -v '^}'

	echo "当前DNS(State:/Network/Service/${defaultSPID}/DNS):"
	(/usr/sbin/scutil <<EOF
show State:/Network/Service/${defaultSPID}/DNS
EOF
) | grep -v '<dictionary>' | grep -v '^}'
	echo "当前DNS(Setup:/Network/Service/${defaultSPID}/DNS):"
	(/usr/sbin/scutil <<EOF
show Setup:/Network/Service/${defaultSPID}/DNS
EOF
) | grep -v '<dictionary>' | grep -v '^}'
	echo ""
	echo "/etc/resolv.conf文件内容:"
	cat /etc/resolv.conf | grep -v '#'
}

case "$type" in
	start)
		clientStatus
		if [[ $? == 1 ]]; then exit 1; fi
		echo "开始启动vpn"
		${basePath}/vpnclient start
	;;
	up)
		clientStatus
		if [[ $? == 0 ]]; then exit 1; fi
			
		getVpnName

		connectStatusConn ${vpnName}
		if [[ $? == 1 ]]; then
			echo "当前状态为正在连接,请先down掉这个连接或者等待"
			exit 1;
		fi

		readData
		saveDataFile

		connectVPN ${vpnName}
		connectStatusOK ${vpnName}
		while [[ $? == 0 ]]; do
			sleep 1
			connectStatusOK ${vpnName}
		done

		setDhcp
		dhcpStatus
		while [[ $? == 0 ]]; do
			sleep 1
			dhcpStatus
		done

		dnsStatus
		while [[ $? == 0 ]]; do
			sleep 1
			dnsStatus
		done
		getNewGW

		setDNS
		setRoute				
	;;
	set)
		clientStatus
		if [[ $? == 0 ]]; then exit 1; fi

		setDhcp
		dhcpStatus
		while [[ $? == 0 ]]; do
			sleep 1
			dhcpStatus
		done

		dnsStatus
		while [[ $? == 0 ]]; do
			sleep 1
			dnsStatus
		done

		readDataFile

		getNewGW	
		setDNS
		setRoute
	;;
	get)
		clientStatus
		if [[ $? == 0 ]]; then exit 1; fi
		readData
		readDataFile
		showStatus
	;;
	stop)
		clientStatus
		if [[ $? == 0 ]]; then exit 1; fi

		readDataFile

		echo "开始停止vpn"
		${basePath}/vpnclient stop
		clientStatus
		while [[ $? == 1 ]]; do
			sleep 1
			clientStatus
		done		
		
		getNewGW
		deleteRoute
		deleteDNS
	;;
	down)
		clientStatus
		if [[ $? == 0 ]]; then exit 1; fi

		readDataFile

		getConnName
		index=$?
		if [[ ${index} == 0 ]]; then
			echo "当前没有活动的连接"
		else
			let index-=1;
			vpnName=${vpnNames[$index]};
			disConnectVPN ${vpnName}
			connectStatusOK ${vpnName}
			while [[ $? == 1 ]]; do
				sleep 1
				connectStatusOK ${vpnName}
			done
		fi

		getNewGW
		deleteRoute
		deleteDNS
	;;
	downall)
		clientStatus
		if [[ $? == 0 ]]; then exit 1; fi

		readDataFile

		disConnectVPNAll

		deleteRoute
		deleteDNS
	;;
	flush)
		clientStatus
		if [[ $? == 0 ]]; then exit 1; fi

		readDataFile
		
		getNewGW
		deleteRoute
		deleteDNS
	;;
	*)
		echo "$0: invalid type"
		exit 1
	;;
esac


Post Reply