vpn脚本的改进

感谢巨石的验证和建议,之前小看了云梯vpn的规模,以为他们只有那么几台服务器,所以在脚本里把域名写死了;后来发现不同用户的服务域名还是不一样的,改进了一下脚本,不局限于云梯的vpn,适用所有的vpn;代码在这里

安装方式:

$ mkdir -p ~/bin
$ curl -s https://hongjiang.info/vpn.sh > ~/bin/vpn

选项:

$ vpn
Usage: /Users/hongjiang/bin/vpn {list|ping|optimal|conn|close|status}

自动连接:

$ vpn conn
ok, jp3.vpnplease.com connected.

可以指定连接协议:

$ vpn conn L2TP #或PPTP
ok, jp2.vpnplease.com connected.

断开连接:

$ vpn close
ok, jp3.vpnplease.com disconnected.

查看vpn列表(名称:地址):

$ vpn list
VPN (PPTP): jp2.vpnplease.com
jp3.vpnplease.com: jp3.vpnplease.com
us1.vpnplease.com: us1.vpnplease.com
...

查看所有vpn的状态:

$ vpn status

* (Disconnected)   2599A4CB-7D76-4878-8FAF-7496E5F6C58F PPP --> L2TP       "us2.vpnplease.com"              [PPP:L2TP]
* (Disconnected)   57A3276C-505F-4E13-B402-0CB6EC5C9AD7 PPP --> PPTP       "VPN (PPTP)"                     [PPP:PPTP]
* (Connected)      90784ECA-DCFA-4197-B2E5-FBE84AFB9C00 PPP --> L2TP       "jp3.vpnplease.com"              [PPP:L2TP]
...     

获取最优的服务名称(协议参数可选):

$ vpn optimal pptp  #或 l2tp
VPN (PPTP)

测试连接速度:

$ vpn ping
jp2.vpnplease.com  52.190
jp1.vpnplease.com  53.681
sg2.vpnplease.com  171.482
...

选择网速最快的vpn进行连接的脚本

下午github上下载速度只有几K,用了代理也不到10K,后来发现所用的vpn服务器选择了一个慢的。写了这段脚本,用来从可用的vpn选出最快的那个。脚本只适用于mac,并且前提是你已创建好了所有可选的vpn,如图:

脚本内容:

#!/bin/bash

PROG_NAME=$0
ACTION=$1

DOMAIN="vpnplease.com"
declare -a OPTION=("jp" "us" "sg")

usage() {
  echo "Usage: $PROG_NAME {test|conn|close|status}"
  exit 1
}

vpn_test() {

  for c in "${OPTION[@]}";do
    for i in `seq 1 3`; do
      proxy="$c$i.$DOMAIN"
      ping -c3 $proxy 2>/dev/null | tail -1 | cut -d'=' -f2 | cut -d'/' -f2 | xargs -I {} echo "$proxy " {} 2>/dev/null &
    done
  done

  children=$(jobs -p | xargs)
  trap 'kill $children >/dev/null 2>&1' SIGINT SIGTERM
  wait
}

get_fastest() {
  vpn_test 2>/dev/null | sort -nk2 | head -1 | awk '{print $1}'
}

vpn_status() {
  for c in "${OPTION[@]}";do
    for i in `seq 1 3`; do
      proxy="$c$i.$DOMAIN"
      scutil --nc status $proxy 2>/dev/null | head -1 | xargs -I {} echo "$proxy " {}
    done
  done
}

vpn_connect() {
  local name=$1

/usr/bin/env osascript <<-EOF
  tell application "System Events"
    tell current location of network preferences
      set VPN to service "$name" -- your VPN name here
      if exists VPN then connect VPN
      repeat while (current configuration of VPN is not connected)
        delay 1
      end repeat
    end tell
  end tell
EOF
}

vpn_disconnect() {
  local name=$(vpn_status | awk '$2~/Connected/{print $1}')
  [ -z $name ] && return 0

/usr/bin/env osascript <<-EOF
  tell application "System Events"
    tell current location of network preferences
      set VPN to service "$name" -- your VPN name here
      if exists VPN then disconnect VPN
    end tell
  end tell
  return
EOF
}

case "$ACTION" in
    test)
        vpn_test
    ;;
    conn)
        vpn_connect $(get_fastest)
    ;;
    close)
        vpn_disconnect
    ;;
    status)
        vpn_status
    ;;
    *)
        usage
    ;;
esac

使用方式:

1) 自动选择最优的vpn进行连接

$ vpn conn

2) 查看连接状态

$ vpn status

jp1.vpnplease.com  Connected
jp2.vpnplease.com  Disconnected
jp3.vpnplease.com  Disconnected
us1.vpnplease.com  Disconnected
us2.vpnplease.com  Disconnected
us3.vpnplease.com  Disconnected
sg1.vpnplease.com  Disconnected
sg2.vpnplease.com  Disconnected

3) 测试网速,时间最小的最优

$ vpn test

jp2.vpnplease.com  76.314
jp1.vpnplease.com  75.793
jp3.vpnplease.com  136.161
sg1.vpnplease.com  169.494
us3.vpnplease.com  242.685
us2.vpnplease.com  249.032
us1.vpnplease.com  266.427
sg2.vpnplease.com  168.750

4) 断开连接

$ vpn close 

mac上通过ssh连接docker的container

下午尝试了一下在mac上通过ssh的方式连接到container,因为之前采用交互方式启动container,一个实例只有一个交互终端,有时需要多个终端只能通过screen一类的工具,而screen有个不爽的地方是它的屏幕缓冲,不能方便的通过滚屏的方式看之前输出内容。还是通过多个终端ssh到container上比较方便。

在mac上docker依赖virtualbox,想要与container之间通讯,需要两层端口映射,一层是在mac与virtualbox之间,另一层是在宿主机与container之间。

在宿主与container之间的端口映射,docker命令中就有参数支持,使用-p参数:

$ docker run -d -p 2222:22 ubuntu /usr/sbin/sshd -D

上面以daemon的方式启动一个ubuntu的container实例,在启动时运行了sshd,并把container的22端口映射到了宿主的2222端口。

现在需要再把mac与宿主的2222端口打通,需要通过virtualbox的命令来设置(需要先boot2docker stop):

$ VBoxManage modifyvm "boot2docker-vm" --natpf1 "containerssh,tcp,,2222,,2222"

上面的命令把virtualbox里的宿主机2222端口映射到了本地的2222,现在可以通过访问mac本地的2222端口来连接container实例了:

$ ssh root@localhost -p2222

注意,Ubuntu和CentOS的openssh-server默认配置都是禁止root用户通过ssh访问的,需要的话可以去修改ssh-server的配置。

如果想要修改virtualbox的映射,可以删除之前的映射规则,不记得映射规则名称的话,可以通过showvminfo的信息grep一下

$ VBoxManage showvminfo boot2docker-vm  | grep 2222
NIC 1 Rule(0):   name = containerssh, protocol = tcp, host ip = , host port = 2222, guest ip = , guest port = 2222

然后通过name删除这条规则:

$ VBoxManage controlvm boot2docker-vm natpf1 delete "containerssh"

查询ip来源的脚本

查询ip地址的方式很多,linux里有一个geoip的工具,我通过homebrew安装过并不work(可能是网络的问题无法更新这个地址库),所以实现了一个通过ip138.com来查询的. 只在mac上测试过,mac自带的sed很不好用,我用的gnu-sed,可以通过homebrew安装:

#!/bin/sh

if [ $# -lt 1 ]; then
    echo "input ip address" && exit -1;
fi

URL="http://ip138.com/ips138.asp?ip="$1
result=`curl -s $URL | iconv -f GBK -t UTF-8 | grep "td align=\"center\"" | awk 'NR==2||NR==3'`
echo $result | gsed 's/[<|>]/\n/g' | gsed '/ul\|li\|h1\|td/d' | awk NF

测试效果:

$ ip138 8.8.8.8
您查询的IP:8.8.8.8

本站主数据:美国 Google免费DNS
参考数据一:美国
网友提交的IP:美国 Google免费DNS