某VPNの設定を半自動化する小汚い小スクリプト群

何をしているのかわからない人はやらないほうがいいです

俺もわからん.

VPNはセットアップが楽ちん

さらに楽にするために半自動化します. その場しのぎで書いただけで何も考えてません. 使用, 参考にする場合は要注意.

筆者の環境はArch Linuxだが, 執筆時にちょっと書き換えて動作確認はしていない.

はい

連番振りたいが行をあけると無理?

1.こちらを導入:

GitHub - flamusdiu/python-pia: Commandline tool to auto configure PIA services

ポート番号でアルゴリズムを設定してくれるのでこことか参考(特に気にしないのであればUDP 1197でよいと思う):

What's the difference between the OVPN files? - Knowledgebase / Technical / OVPN Files - PIA Support Portal

2. vpn-hosts.txtのリストにプレフィクスを付けるスクリプト:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

def main():
    path = '/etc/private-internet-access/'
    hosts_file = path + 'vpn-hosts.txt'
    with open(hosts_file) as f:
        lines = f.readlines()
    newlines = ['PIA ' + line for line in lines]
    print(*newlines, sep='')
    yn = input('write to file?[y/N]: ')
    if yn == 'y':
        with open(hosts_file, 'w') as f:
            f.writelines(newlines)

if __name__ == '__main__':
    main()

3. pia.confvpn-hosts.txtを全部突っ込むスクリプト:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

def main():
    path = '/etc/private-internet-access/'
    hosts_file = path + 'vpn-hosts.txt'
    conf_file = path + 'pia.conf'

    with open(hosts_file, 'r') as f:
        countries = [line.strip().split(',')[0] for line in f.readlines()]
    with open(conf_file, 'r') as f:
        conf_lines = f.readlines()

    for i, line in enumerate(conf_lines):
        if line.startswith('hosts'):
            conf_lines[i] = 'hosts = {}\n'.format(', '.join(countries))
            break

    print(*conf_lines, sep='')

    yn = input('write to file?[y/N]: ')
    if yn == 'y':
        with open(conf_file, 'w') as f:
            f.writelines(conf_lines)

if __name__ == '__main__':
    main()

4. /etc/openvpn/client/以下にOpenVPN設定ファイルを展開:

# pia -a

5. 公開鍵証明書ファイル名にプレフィクス付ける(俺の環境では動いてるが初回は自分で調整して):

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import os

def main():
    path = '/etc/openvpn/client/'
    pia_confs = [fname for fname in os.listdir(path) if os.path.isfile(path + fname) and fname.startswith('PIA')]

    conf = pia_confs[0]
    with open(path + conf) as f:
        lines = f.readlines()
    names = dict()
    targets = ('ca', 'crl-verify')
    for i, line in enumerate(lines):
        l = line.split(' ')
        if l[0] in targets:
            names[l[0]] = l[1].rstrip()
            if len(names) >= len(targets):
                break
    for tgt, name in names.items():
        pathname, basename = os.path.split(name)
        newname = '{}/pia_{}'.format(pathname, basename)
        if os.path.exists(name):
            os.rename(name, newname)
        names[tgt] = newname

    for cnf in pia_confs:
        with open(path + cnf) as f:
            lines = f.readlines()
        for i, line in enumerate(lines):
            l = line.split(' ')
            for tgt, name in names.items():
                if l[0] == tgt:
                    lines[i] = '{} {}\n'.format(tgt, name)
                    break
        with open(path + cnf, 'w') as f:
            f.writelines(lines)

if __name__ == '__main__':
    main()

6. キルスイッチ

キルスイッチについてはこちらを参照(固定化のデメリットがある):

Internet Kill Switch by Firewall (OpenVPN + iptables) - vanaestea’s blog

DNS

そのままだと/etc/resolv.confVPNサービス側のDNSに書き換えられたと記憶しているが, それが嫌なら, たとえば, resolv.conf

nameserver 1.1.1.1
nameserver 1.0.0.1

のように好きに設定したあと,

# chattr +i /etc/resolv.conf

でイミュータブル属性を付加するとよい(参考: Private Internet Access - ArchWiki).