Python を使用して VPN に接続する

Migel Hewage Nimesha 2023年10月10日
  1. VPNとは
  2. Python を使用して VPN に接続する
  3. まとめ
Python を使用して VPN に接続する

世界では、セキュリティとプライバシーが人々の大きな関心事になっています。 解決策を求めて、開発者は VPN を作成しました。

VPNとは

VPN とも呼ばれる仮想プライベート ネットワークは、オンライン プライバシーを保護するプライベート ネットワークを作成するソフトウェアです。 VPN は私たちに多くの利点をもたらしますが、プライバシーの保護とデータの暗号化がユーザーにとっての主な利点です。

  1. 保護されたプライバシー

    VPN はパブリック ネットワーク内にプライベート ネットワークを作成するため、インターネット上で行っていることを事実上追跡することはできません。 IP アドレスが隠されるため、第三者は私たちの活動を追跡できません。

    IP を非表示にするということは、VPN 経由でアクセスする Web サイトが VPN サーバーをトラフィックの発信元と見なすことを意味します。

    そのため、VPN はユーザーの IP アドレスをマスクし、VPN サーバーの IP が表示されます。 最も重要なことは、このプロセスによって、ユーザーの場所とトラフィックの悪用が防止されることです。 したがって、ユーザーのプライバシーは保護されます。

  2. データの暗号化

    VPN はオンライン データも暗号化します。 VPN は、ハッカーやその他のサード パーティがデータを取得できないように、インターネット全体で送信するデータを暗号化します。

    それらを取得しても、内容を理解することも、データを解読することもできません。

    これで VPN とは何かがよくわかりましたので、接続してみましょう。 この記事では、Python を使用して VPN に接続する方法について説明します。

Python を使用して VPN に接続する

このチュートリアルでは、VPNGate および OpenVPN ソフトウェアの無料の VPN サービスを使用します。 VPNGate は、無料で使用できるパブリック VPN クラウド サービスです。

OpenVPN を使用するには、システムにインストールする必要があります。 Windows OS の場合は、手動でダウンロードしてインストールできます。

Linux または Ubuntu ユーザーの場合は、次のコマンドを使用します。

OpenVPN をインストールします。

$ apt-get install openvpn easy-rsa

インストール後、VPN に接続するための Python スクリプトを作成できます。 ターミナルでこのスクリプトを実行するときは、引数として国を指定する必要があります。

構文は次のとおりです。

Python3 <filename.py> <countryname>

国名を指定する場合、2つのオプションがあります。

  1. 国の長い名前

    $ python3 vpn.py Japan
    
  2. 国の略称

    $ python3 vpn.py JP
    

最初のステップとして、次のライブラリをスクリプトにインポートする必要があります。

import requests
import os
import sys
import tempfile
import subprocess
import base64
import time
import json

スクリプトの実行時に、ユーザーが複数の国を入力する場合があります。 それを防ぐために、以下のコード チャンクを使用できます。

最初のステップとして、以下のライブラリをスクリプトにインポートする必要があります。

if len(sys.argv) != 2:
    print("Enter one country at a time!")
    exit(1)
cntry = sys.argv[1]

この最初の行では、引数の合計が 2 に等しくないかどうかをチェックします。 等しい場合は、指定された国で続行します。 それ以外の場合は、注意して終了します。

次に、ユーザーが国の長い名前または短い名前を指定したかどうかを確認できます。 ユーザーが 1 文字を入力すると、エラー メッセージをスローできます。

if len(cntry) > 2:
    j = 5
elif len(cntry) == 2:
    j = 6
else:
    print("Cannot identify the country. Name is too short.")
    exit(1)

これで、VPNGate Web サイトから利用可能な無料の VPN サーバーのリストを取得できます。 リストに加えて、HostNameIPScorePing などの VPN サーバーのラベルとそれらの値を取得できます。

try:
    vpnServerListData = requests.get("http://www.vpngate.net/api/iphone/").text.replace(
        "\r", ""
    )
    freeServers = [line.split(",") for line in vpnServerListData.split("\n")]
    serverLabels = freeServers[1]
    serverLabels[0] = serverLabels[0][1:]
    freeServers = [srvrs for srvrs in freeServers[2:] if len(srvrs) > 1]
except:
    print("Something is wrong! Cannot load the VPN server's data")
    exit(1)

次に、利用可能なサーバーを取得し、合計数を取得する必要があります。 次に、利用可能なサーバーの数を表示できます。

利用可能なサーバーがない場合は、それについて言及するメッセージをスローして終了できます。 このタスクを達成するために、以下のコード チャンクを使用できます。

availableServers = [srvrs for srvrs in freeServers if cntry.lower() in srvrs[j].lower()]
numOfServers = len(availableServers)
print("We found " + str(numOfServers) + " servers for " + cntry)
if numOfServers == 0:
    exit(1)

これで、OpenVPN ツールをサポートするサーバーの数が表示されます。 このツールを使用して VPN に接続するため、VPN サーバーをサポートすることが不可欠であり、それらを除外できます。

supporteServers = [srvrs for srvrs in availableServers if len(srvrs[-1]) > 0]
print("There are " + str(len(supporteServers)) + " servers that support OpenVPN")

サポートされているサーバーをフィルタリングしたので、その中から ping が最も低く、速度とスコアが最も高い最高のサーバーを選択する必要があります。

次に、for ループを使用してその属性 (ラベル) を表示できます。 最後に、国を表示できます。

bestServer = sorted(
    supporteServers, key=lambda srvrs: float(srvrs[2].replace(",", ".")), reverse=True
)[0]
print("\n------------------Best server------------------")
labelPair = list(zip(serverLabels, bestServer))[:-1]
for (l, d) in labelPair[:4]:
    print(l + ": " + d)
print(labelPair[4][0] + ": " + str(float(labelPair[4][1]) / 10 ** 6) + " MBps")
print("Country: " + labelPair[5][1])

出力:

最高のサーバー

VPN を起動する前に、resolveconf を DNS 設定で更新する必要があります。 また、文字列形式にする必要があります。

デフォルトでは、バイナリ形式で提供されます。 base64 デコード を使用して、それらを文字列に変換できます。

次に、VPN を起動できます。

print("\nLaunching VPN...")
_, path = tempfile.mkstemp()
file = open(path, "wb")
file.write(base64.b64decode(bestServer[-1]))
file.write(
    b"\nscript-security 2\nup /etc/openvpn/update-resolv-conf\ndown /etc/openvpn/update-resolv-conf"
)
file.close()
vpnR = subprocess.Popen(["sudo", "openvpn", "--config", path])

起動すると、次の出力が得られます。

vpn を起動

Initialization Sequence Competed のようなメッセージが表示されたら、接続は成功です。

Initialization Sequence Competed

これで、VPN に正常に接続できました。 以下に、接続が成功した後に表示される VPNGate サーバー情報を示します。

また、OpenVPN を VPN サーバーに接続するのに必要な時間を設定することもできます。 以下のコードチャンクを通じて、それを達成できます。

try:
    # time required to connect the openvpn to connect the vpn server
    time.sleep(60)
    start_time = time.time()
    nUrl = "http://bot.whatismyipaddress.com/"
    nRet = requests.get(nUrl)
    if nRet.status_code == 200:
        with open('resp', "wb") as txtFile:
            txtFile.write(nRet.text)
            print('Time took to check Ip address  ',
                  (time.time() - start_time))
    vpnR.kill()

VPN 接続を終了するには、Ctrl+C を使用します。 その後、接続が終了し、システムはメッセージをスローしてユーザーに通知します。

except Exception as ex:
    try:
        vpnR.kill()
    except:
        pass
    while vpnR.poll() != 0:
        time.sleep(1)
    print('\nVPN has terminated')

出力:

vpn 終了

完全なコード:

import requests
import os
import sys
import tempfile
import subprocess
import base64
import time
import json

if len(sys.argv) != 2:
    print("Enter one country at a time!")
    exit(1)
cntry = sys.argv[1]

if len(cntry) > 2:
    j = 5
elif len(cntry) == 2:
    j = 6
else:
    print("Cannot identify the country. Name is too short.")
    exit(1)

try:
    vpnServerListData = requests.get("http://www.vpngate.net/api/iphone/").text.replace(
        "\r", ""
    )
    freeServers = [line.split(",") for line in vpnServerListData.split("\n")]
    serverLabels = freeServers[1]
    serverLabels[0] = serverLabels[0][1:]
    freeServers = [srvrs for srvrs in freeServers[2:] if len(srvrs) > 1]
except:
    print("Something is wrong! Cannot load the VPN server's data")
    exit(1)

    availableServers = [
        srvrs for srvrs in freeServers if cntry.lower() in srvrs[j].lower()
    ]
    numOfServers = len(availableServers)
    print("We found " + str(numOfServers) + " servers for " + cntry)
    if numOfServers == 0:
        exit(1)

    supporteServers = [srvrs for srvrs in availableServers if len(srvrs[-1]) > 0]
    print(str(len(supporteServers)) + " of these servers support OpenVPN")

    bestServer = sorted(
        supporteServers,
        key=lambda srvrs: float(srvrs[2].replace(",", ".")),
        reverse=True,
    )[0]
    print("\n== Best server ==")
    labelPair = list(zip(serverLabels, bestServer))[:-1]
    for (l, d) in labelPair[:4]:
        print(l + ": " + d)
    print(labelPair[4][0] + ": " + str(float(labelPair[4][1]) / 10 ** 6) + " MBps")
    print("Country: " + labelPair[5][1])

    print("\nLaunching VPN...")
    _, path = tempfile.mkstemp()
    file = open(path, "wb")
    file.write(base64.b64decode(bestServer[-1]))
    file.write(
        b"\nscript-security 2\nup /etc/openvpn/update-resolv-conf\ndown /etc/openvpn/update-resolv-conf"
    )
    file.close()
    vpnR = subprocess.Popen(["sudo", "openvpn", "--config", path])

try:
    # time required to connect the openvpn to connect the vpn server
    time.sleep(60)
    timeS = time.time()
    nUrl = "http://bot.whatismyipaddress.com/"
    nRet = requests.get(nUrl)
    if nRet.status_code == 200:
        with open("resp", "wb") as txtFile:
            txtFile.write(nRet.text)
    print("Time took to check Ip address  ", (time.time() - timeS))
    vpnR.kill()

except Exception as ex:
    try:
        vpnR.kill()
    except:
        pass
    while vpnR.poll() != 0:
        time.sleep(1)
    print("\nVPN has terminated")

出力 (終了なし):

終了せずに

まとめ

この記事では、VPN とその利点について説明しました。 次に、Python を使用して無料の VPN サービスに接続します。

目標を達成する方法は他にもありますが、この方法で VPN に接続する基本的な概念を簡単に理解できます。

Migel Hewage Nimesha avatar Migel Hewage Nimesha avatar

Nimesha is a Full-stack Software Engineer for more than five years, he loves technology, as technology has the power to solve our many problems within just a minute. He have been contributing to various projects over the last 5+ years and working with almost all the so-called 03 tiers(DB, M-Tier, and Client). Recently, he has started working with DevOps technologies such as Azure administration, Kubernetes, Terraform automation, and Bash scripting as well.