😽

Nordvpn proxyが突然機能しなくなった話

2024/09/21に公開

背景

NordvpnをDocker上で動かしてproxyにするという記事を書いた後に再度試したら全部ipアドレスがそのままになっていた

発見した経緯

スクレイピング開始前に下記の様なエラーチェックを入れていた

# デフォルトのIPアドレスを取得
response = requests.get('https://ifconfig.me')
pure_ip = response.text

# プロキシ経由でIPアドレスを取得
temp_proxy_address = f"http://localhost:8118"
temp_proxies = {
    'http': temp_proxy_address,
    'https': temp_proxy_address,
}
response = requests.get('https://ifconfig.me', proxies=temp_proxies)
vpn_ip = response.text

assert pure_ip != vpn_ip, "VPNが機能してないよ!"

エラーメッセージ

IPが取得できる時点でproxyとしては動作している。しかしproxyがnordvpnに接続できていないのでとりあえずDockerのエラーログを見に行ってみた

実行コマンド

docker run -d --cap-add=NET_ADMIN --name=vpn --dns=103.86.96.100 --dns=103.86.99.100 --restart=always -e "COUNTRY=JP" -e "USERNAME=**" -e "PASSWORD=**" -e "LOCAL_NETWORK=192.168.1.0/24" -v /etc/localtime:/etc/localtime:ro -v ovpn-data:/app/ovpn/config -p 8118:8118 jeroenslot/nordvpn-proxy:latest
2024-08-26 12:23:55 2024-08-26 03:23:55 INFO: Removing current cronfile
2024-08-26 12:23:55 2024-08-26 03:23:55 INFO: Skipping downloading OVPN files - as they are not older than 120 minute(s).
2024-08-26 12:23:55 2024-08-26 03:23:55 INFO: SERVER has not been set, choosing best for you.
2024-08-26 12:23:55 2024-08-26 03:23:55 INFO: Creating new cronfile
2024-08-26 12:23:55 2024-08-26 03:23:55 INFO: Your country setting will be used. This is set to: JP
2024-08-26 12:23:55 2024-08-26 03:23:55 INFO: Your cron settings (*/15 * * * *) will be applied!
2024-08-26 12:23:55 2024-08-26 03:23:55 INFO: The country codes are unknown, getting country codes from API
2024-08-26 12:23:55 parse error: Invalid numeric literal at line 1, column 7
2024-08-26 12:23:56 2024-08-26 03:23:56 INFO: Skipping downloading OVPN files - as they are not older than 120 minute(s).
2024-08-26 12:23:56 2024-08-26 03:23:56 INFO: SERVER has not been set, choosing best for you.
2024-08-26 12:23:56 2024-08-26 03:23:56 INFO: Your country setting will be used. This is set to: JP
2024-08-26 12:23:56 2024-08-26 03:23:56 INFO: The country codes are known, skipping
2024-08-26 12:23:57 parse error: Invalid numeric literal at line 1, column 7

というわけでどうやら Invalid numeric literal at line 1, column 7 が問題な模様。

ファイルを見る

/app/ovpn/run を見ると

#!/bin/bash
set -e -u -o pipefail

source /app/ovpn/get-ovpn-files.sh
source /app/ovpn/servers_recommendations.sh

. /app/date.sh --source-only
# (続く)

とあるので、とりあえず get-ovpn-files.sh を見に行く

# check if the file exists
if [ -f ${OVPN_CONFIG_DIR}/ovpn.zip ]; then
  #the file exists continue checking if its older than two hours.
  if test `find ${OVPN_CONFIG_DIR}/ovpn.zip -mmin +${REFRESH_TIME}`; then
    download_files
  else
    echo "$(adddate) INFO: Skipping downloading OVPN files - as they are not older than ${REFRESH_TIME} minute(s)."
  fi
else
  #the files don't exists continue to download and extract them.
  download_files
fi

つまりどうやら ovpn.zipは存在する。ovpn.zipは120分以内に更新されてるのでスキップされているらしい
Skipping downloading OVPN files - as they are not older than 120 minute(s).

問題無さそう。

続いて
servers_recommendations.sh を見る。そこそこ長いのでエラーから考えてみる
parse errorなので、そもそもそれが発生しうる箇所に絞ってみると

# 1. 国コードを取得
curl -s https://nordvpn.com/wp-admin/admin-ajax.php?action=servers_countries -o /tmp/servers_countries
export COUNTRY_CODE=$(cat $JSON_FILE_SERVER_COUNTRIES | jq '.[]  | select(.code == "'${COUNTRY^^}'") | .id')

# 2. nordvpnのAPIを叩いて、推奨サーバーを取得
# つまりはコレ https://api.nordvpn.com/v1/servers/recommendations?limit=10&filters=JP=106
curl -s $SERVER_RECOMMENDATIONS_URL$QUERY_PARAM -o $JSON_FILE
NUMBER_OF_SERVERS="$(jq length $JSON_FILE)"

## 特定のサーバーに設定
DESIRED_SERVER_NUMBER="$(shuf -i 0-$(($NUMBER_OF_SERVERS - 1)) -n 1)"
export SERVER="$(jq -r '.['$DESIRED_SERVER_NUMBER'].hostname' $JSON_FILE)"
export SERVERNAME="$(jq -r '.['$DESIRED_SERVER_NUMBER'].name' $JSON_FILE)"
export LOAD="$(jq -r '.['$DESIRED_SERVER_NUMBER'].load' $JSON_FILE)"
export UPDATED_AT="$(jq -r '.['$DESIRED_SERVER_NUMBER'].updated_at' $JSON_FILE)"
export IP="$(jq -r '.['$DESIRED_SERVER_NUMBER'].station' $JSON_FILE)"
echo "$(jq -r '.['$DESIRED_SERVER_NUMBER'].hostname' $JSON_FILE)"
echo "$(jq -r '.['$DESIRED_SERVER_NUMBER'].hostname' $JSON_FILE)" > /tmp/nordvpn_hostname

ログ的にこの2つ。

ログを仕込んでみると
https://api.nordvpn.com/v1/servers/recommendations?limit=10&filters=JP=106 を叩いた際にjsonではなく、下記のレスポンスが帰ってきてparseに失敗した模様。

<html>
    <head><title>429 Too Many Requests</title></head>
    <body>
        <center><h1>429 Too Many Requests</h1></center>
        <hr><center>nginx</center>
    </body>
</html>

nordvpnに接続した状態でこのdockerを動かしていたが、別のサーバーに接続し直すと動作しました。

つまり
VPNに相乗りしてた誰かがnordvpnのAPI叩きまくって429出てた

が真相だったみたいです。

エラートレースしやすくするためにjsonを変換する前にエラーチェックした方が良いと思いました。

学んだ事

宣伝(招待リンク)

お友達紹介リンク を使用した登録は下記の特典が付くので、もし検討している方はご一考ください。

- 1年または2年プランを選ぶと3か月分の無料期間
- 1か月プランを選ぶと1か月分の無料期間
がもらえます。

書いていて思いましたが、結構紹介特典がしょぼいのでハピタス経由でダウンロードしてポイント貰った方がお得かもしれません。

Discussion