【Mac向け】コマンドラインからVPNをONにする

記事タイトルとURLをコピーする

こんにちは、技術一課の加藤です。
今日はAWSのお話を離れ、ちょっとした効率化のお話を。

VPNをONにするのめんどくさい問題

PCからVPNを介してサーバーなどにアクセスを行いたい場面はよくあると思います。
その時、いちいちVPNの設定を開いてConnect/Disconnectを切り替えるのがめんどくさかったんですよね。

SSHをするときにVPNをONにすることが多かったため、ならTerminalからVPNをONにできればいいのでは…? と思いついたのが始まり。
それ用のシェルスクリプトを書いてみました。

そもそもコマンドでVPNをONにするには

MacにはデフォルトでVPN設定を切り替えできるコマンドが用意されています。

$ scutil --nc start [name] # nameのVPNに接続
$ scutil --nc stop [name] # nameのVPNから切断
$ scutil --nc status [name] # nameのVPNへの接続状態を取得

※なお[name]にはVPNの設定名を書きます

とはいえいちいちこれを打つのもめんどくさいので、bash_profileへ設定を行い、簡単に呼び出せるようにしていきます。

1. エイリアスを貼る

一番簡単なのはエイリアスを貼ることでしょう。
.bash_profileに以下を追加します

alias vpnstart='scutil --nc start [name]'
alias vpnstop='scutil --nc stop [name]'
alias vpnstatus='scutil --nc status [name]'

これで vpnstart 、vpnstopvpnstatus の各コマンドを使って、VPNへの接続/切断および接続状況確認ができます

2. コマンドを作る

aliasだと物足りない場合はコマンドを作成してしまいましょう。
私はこちらの方法を使いました。

.bash_profileに以下を書き込みます。(ユーザーまたぎで使いたい場合など汎用性を高めたい場合は専用のファイルを作るなど各自工夫をお願いします)

function vpn () {
  OPTIND=1
  if [ -n "$DEFAULT_VPN" ]; then
    local SERVICE="$DEFAULT_VPN"
  fi

  while getopts :n: OPT
  do
    case $OPT in
      "n") SERVICE=$OPTARG;;
      :) echo "[ERROR] option argument is undefined.";return 1;;
      \?) echo "[ERROR] Undefined options.";return 1;;
    esac
  done

  if [ -z "$SERVICE" ]; then
    echo "[ERROR] VPN name is undefined."
    return 1
  fi

  shift $(($OPTIND - 1))

  if [ "$1" = "start" ]; then
    scutil --nc start $SERVICE | head -n 1
    return 0
  fi

  if [ "$1" = "stop" ]; then
    scutil --nc stop $SERVICE | head -n 1
    return 0
  fi

  if [ -n "$1" ]; then
    echo "[ERROR] Invalid argument"
    return 1
  fi

  scutil --nc status $SERVICE | head -n 1
  return 0
}

今回はDEFAULT_VPNという環境変数にセットされた値か、-nオプションで与えた値のどちらかをVPNの設定名として利用します。
普段接続するVPNが決まっている場合は以下のコマンドで設定を.bash_profileに書き込んでください。

$ echo 'export DEFAULT_VPN="VPN_NAME"' >> ~/.bash_profile

使い方は以下になります。

$ vpn # DEFAULT_VPNの状態取得
$ vpn start # DEFAULT_VPNに接続
$ vpn stop # DEFAULT_VPNに接続

$ vpn -n VPN_NAME # VPN_NAMEの状態取得
$ vpn -n VPN_NAME start # VPN_NAMEに接続
$ vpn -n VPN_NAME stop # VPN_NAMEに接続

自分用途に作ったざっくり仕様なので、利用する際はご自身の責任でお願いします。

ちなみに

実は私、普段bashではなくfishを使っているため、上記のコマンドも実はブログ用にbashコマンドに書き起こしたものだったりします。

fish用のコマンドも下記にさらしておきますので、fish使いの人や、ちょっと気になっているという方はぜひご利用ください。(bashコマンドは急いで書き起こしたので、fishのコマンドと出力などにやや違いがありますがご了承ください。使い方は変わりません。)

function vpn
  argparse -n vpn 'n/name=' -- $argv
  set -l service

  # service name
  if set -lq _flag_name
    set service $_flag_name
  else if set -q DEFAULT_VPN
    set service $DEFAULT_VPN
  else
    echo "pls set \$DEFAULT_VPN or give -n/--name option"
    return 1
  end

  # start / stop
  set length (count $argv)
  if test $length -eq 0
    scutil --nc status $service | head -n 1
  else if contains "start" $argv
    networksetup -connectpppoeservice $service
    echo "connect: "$service
  else if contains "stop" $argv
    scutil --nc stop $service
    echo "disconnect: "$service
  else 
    echo "if you wanna connect/disconnect vpn, pls give start/stop"
    return 1
  end


  return 0
end