OpenVPN Streamlitアプリ Python nginx

今回よく使用したLinuxコマンド

指定のサービスが動作しているか

sudo systemctl status <サービス名>

example)
sudo systemctl status nginx

リッスンポートの確認

sudo ss -tuln | grep nginx
sudo ss -tuln | grep 80
sudo ss -tuln | grep 443

エラーログの確認

sudo journalctl -xe

VPNのログの確認

sudo tail -f /var/log/openvpn.log

トラフィックの確認

トラフィックが正しくルーティングされているかを確認するために、iPhoneからVPN接続後、以下のコマンドを使用してトラフィックを監視します。

sudo tcpdump -i tun0

tun0 はOpenVPNの仮想インターフェイスです。トラフィックがこのインターフェイスを通過しているか確認します。

ルーティングテーブルの確認

OpenVPN サーバーでルーティングテーブルを確認して、適切なルートが設定されているか確認。

ip route
以下の出力があるか確認
default via 10.128.0.1 dev ens4 proto dhcp src 10.128.0.4 metric 100 
10.8.0.0/24 via 10.8.0.2 dev tun0 
10.8.0.2 dev tun0 proto kernel scope link src 10.8.0.1 
10.128.0.1 dev ens4 proto dhcp scope link src 10.128.0.4 metric 100

ステップ1: OpenVPNサーバーのセットアップ

  1. 新しいVMインスタンスを作成 Google Cloud Consoleにログインし、「Compute Engine」 > 「VM インスタンス」 > 「インスタンスを作成」を選択します。 インスタンス名を設定し、リージョンとゾーンを選択します。 マシンタイプはe2-mediumを選択し、ブートディスクはUbuntu 20.04 LTSを選択します。 「HTTPトラフィックを許可する」と「HTTPSトラフィックを許可する」のチェックボックスをオンにします。 「作成」をクリックします。

  2. OpenVPNとEasy-RSAのインストール VMインスタンスにSSHで接続し、以下のコマンドを実行してOpenVPNとEasy-RSAをインストールします。

sudo apt-get update
sudo apt-get install openvpn easy-rsa
  1. Easy-RSAの設定と証明書の生成 以下のコマンドを順に実行してEasy-RSAを設定し、証明書を生成します。

make-cadir ~/openvpn-ca
cd ~/openvpn-ca
./easyrsa init-pki
./easyrsa build-ca nopass

./easyrsa gen-req server nopass

### 以下のようなものが出る

Note: using Easy-RSA configuration from: ./vars

Using SSL: openssl OpenSSL 1.1.1f  31 Mar 2020
Generating a RSA private key
............................................................................................................+++++
.........................................+++++
writing new private key to '/home/****/******/*******'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Common Name (eg: your user, host, or server name) [server]

ここで入力を求められている「Common Name (CN)」は、通常はサーバーのホスト名やIPアドレスを入力しますが、 デフォルトで入力されている「server」のままでも問題ありません。 次に、OpenVPNサーバーの証明書に署名する手順に進みます。 ステップ: サーバー証明書の署名 サーバー証明書に署名します。

./easyrsa sign-req server server
./easyrsa gen-dh
./easyrsa gen-req client1 nopass
./easyrsa sign-req client client1

OpenVPNの設定ファイルを作成 生成された証明書とキーを適切なディレクトリに配置し、OpenVPNの設定ファイルを編集します。

# ファイルの場所確認 ~/openvpn-ca/pki/にある。 これまでのコマンドを順に実施していれば現在~/openvpn-ca/にいるはず

sudo cp pki/private/server.key /etc/openvpn/
sudo cp pki/issued/server.crt /etc/openvpn/
sudo cp pki/ca.crt /etc/openvpn/
sudo cp pki/dh.pem /etc/openvpn/dh2048.pem
sudo cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz /etc/openvpn/
sudo gunzip /etc/openvpn/server.conf.gz
sudo vim /etc/openvpn/server.conf

server.confに以下の設定を追加または修正します。

port 1194
proto udp
dev tun
ca ca.crt
cert server.crt
key server.key
dh dh2048.pem
server **.**.*.* 255.255.255.0
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 8.8.8.8"
push "dhcp-option DNS 8.8.4.4"
keepalive 10 120
cipher AES-128-GCM
user nobody
group nogroup
persist-key
persist-tun
status openvpn-status.log
log-append /var/log/openvpn.log
verb 3

証明書とキーのパーミッションが適切であることを確認します。

cd /etc/openvpn
# 証明書とキーのファイルのリストを表示します。
ls -l
# 以下のようになっているか確認
-rw-r--r-- 1 root root 1704 Jul 22 10:30 ca.crt
-rw------- 1 root root 1448 Jul 22 10:30 server.crt
-rw------- 1 root root 3243 Jul 22 10:30 server.key
-rw------- 1 root root  424 Jul 22 10:30 dh2048.pem

適切なパーミッションの設定

一般的に、以下のパーミッションが設定されていることが望ましいです。

ca.crt: 読み取り可能(644) server.crt: 読み取り可能(644) server.key: 読み取り専用の所有者(600) dh2048.pem: 読み取り専用の所有者(600)

必要に応じて、パーミッションを変更します。 また、これらのファイルの所有者が root であることも確認します。

sudo chmod 644 /etc/openvpn/ca.crt
sudo chmod 644 /etc/openvpn/server.crt
sudo chmod 600 /etc/openvpn/server.key
sudo chmod 600 /etc/openvpn/dh2048.pem
sudo chown root:root /etc/openvpn/ca.crt
sudo chown root:root /etc/openvpn/server.crt
sudo chown root:root /etc/openvpn/server.key
sudo chown root:root /etc/openvpn/dh2048.pem

IPフォワーディングの有効化

OpenVPNサーバーがパケットを転送できるようにするために、IPフォワーディングを有効にします。

sudo sysctl -w net.ipv4.ip_forward=1

永続的に設定するために、/etc/sysctl.conf ファイルの以下の行のコメントアウトを解除する。追記でも良い。 net.ipv4.ip_forward = 1

設定の反映をする

sudo sysctl -p

OpenVPNサーバーを起動

sudo systemctl start openvpn@server

# 成功すると以下のような出力が得られる
******@*******:~/openvpn-ca$ sudo systemctl status openvpn@server.service
● openvpn@server.service - OpenVPN connection to server
     Loaded: loaded (/lib/systemd/system/openvpn@.service; enabled; vendor preset: enabled)
     Active: active (running) since Mon 2024-07-22 12:11:29 UTC; 31ms ago
       Docs: man:openvpn(8)
             https://community.openvpn.net/openvpn/wiki/Openvpn24ManPage
             https://community.openvpn.net/openvpn/wiki/HOWTO
   Main PID: 3312 (openvpn)
     Status: "Pre-connection initialization successful"
      Tasks: 2 (limit: 4680)
     Memory: 1.0M
     CGroup: /system.slice/system-openvpn.slice/openvpn@server.service
             ├─3312 /usr/sbin/openvpn --daemon ovpn-server --status /run/openvpn/server.status 10 --cd /etc/openvpn --script-security 2 --config /etc/openvpn/server.conf --writepid /run/openvpn/server.pid
             └─3320 /sbin/ip addr add dev tun0 local **.*.*.* peer **.*.*.*

Jul 22 12:11:29 openvpn-server systemd[1]: Starting OpenVPN connection to server...
Jul 22 12:11:29 openvpn-server systemd[1]: Started OpenVPN connection to server.



sudo systemctl enable openvpn@server

クライアント証明書とキーの生成

クライアント証明書と設定ファイルをエクスポートし、クライアントに転送します。

cd ~/openvpn-ca
./easyrsa gen-req client1 nopass
./easyrsa sign-req client client1

クライアント設定ファイルの作成

client.ovpnを作成する 以下の内容を client.ovpn に追加します。適切に YOUR_SERVER_IP を置き換えてください。 また以下のファイルの内容を貼り付ける必要があるので頑張る

cd ~/openvpn-ca/pki
cat pki/ca.crt
cat pki/issued/client1.crt
cat pki/private/client1.key

内容を出力したら

sudo vim client.ovpn

client.ovpn に必要事項を記述して最後にさっき出力したものを貼り付け

client
dev tun
proto udp
remote YOUR_SERVER_IP(OpenVPNの外部IPアドレス) 1194
resolv-retry infinite
nobind
user nobody
group nogroup
persist-key
persist-tun
# ca [inline]  <ca></ca>を使うときはいらない!消す!ChatGPTでは入れるように促されるけど削除でいい
# cert [inline] <cert></cert>を使うときはいらない!消す!ChatGPTでは入れるように促されるけど削除でいい
# key [inline] <key></key>を使うときはいらない!消す!ChatGPTでは入れるように促されるけど削除でいい
cipher AES-128-GCM
verb 3

<ca>
-----BEGIN CERTIFICATE-----
# ca.crtの内容をここに貼り付けます
-----END CERTIFICATE-----
</ca>
<cert>
-----BEGIN CERTIFICATE-----
# client1.crtの内容をここに貼り付けます
-----END CERTIFICATE-----
</cert>
<key>
-----BEGIN PRIVATE KEY-----
# client1.keyの内容をここに貼り付けます
-----END PRIVATE KEY-----
</key>

GoogleCloudのVPCネットワークでファイアウォールルールを新規で作成する

ナビゲーションメニューから「VPCネットワーク」を選択し、「ファイアウォールルール」に移動します。

VPNサーバの1194ポートを許可するルールを作成する

ルールの作成: 画面上部の「ファイアウォールルールを作成」をクリックします。 必要な情報を入力します: 名前: allow-openvpn ターゲット: all instances in the network ソースIP範囲: 0.0.0.0/0 プロトコルとポート: udp:1194 「作成」をクリックします。

NginxのファイアフォールでOpenVPNのIPも許可するように設定する

IP rangesにOpenVPNのIPを追加 **...*/24

DNSトラフィックを許可するファイアウォールルールの追加

  1. DNSトラフィックを許可するファイアウォールルールの追加 まず、DNSトラフィック(UDP 53)を許可するためのファイアウォールルールを追加します。

GCPコンソールにログイン

「VPCネットワーク」 > 「ファイアウォールルール」を選択

「ファイアウォールルールを作成」をクリック

以下の設定でルールを作成

名前: allow-dns ネットワーク: default ターゲット: All instances in the network ソースIP範囲: 0.0.0.0/0 プロトコルとポート: 指定したプロトコルとポート を選択し、udp:53 と入力

NAT (Network Address Translation) の設定

OpenVPNサーバーがクライアントのインターネットトラフィックを転送できるようにするために、NATを設定します。これにはiptablesを使用します。

NATルールを追加

sudo iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE

# eth0 はインターネットに接続されているネットワークインターフェイスの名前です。
# 適切なインターフェイス名に置き換えてください(多くの場合、eth0 ですが、ens4 や enp0s3 など異なる名前である可能性があります)。

ネットワークインターフェースの確認方法
ip a または ip addr:
これにより、すべてのネットワークインターフェースとその詳細情報が表示されます。

例えば
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: ens4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 42:01:0a:80:00:04 brd ff:ff:ff:ff:ff:ff
    inet 10.128.0.4/32 scope global dynamic ens4
       valid_lft 3600sec preferred_lft 3600sec
    inet6 fe80::4001:aff:fe80:4/64 scope link
       valid_lft forever preferred_lft forever


ifconfig (ネットワークツールがインストールされている場合):
これもネットワークインターフェースの情報を表示します。


ip link:
ネットワークインターフェースの状態を表示するためのコマンドです。
sudo apt-get install iptables-persistent
sudo netfilter-persistent save
sudo netfilter-persistent reload

NATルールの確認 先ほど設定したNATルールが正しく動作しているかを確認します。まず、現在のiptablesルールを表示して確認します。

sudo iptables -t nat -L -n -v

# 以下のような出力が得られればOK
Chain PREROUTING (policy ACCEPT 2 packets, 5314 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain INPUT (policy ACCEPT 2 packets, 5314 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 4 packets, 532 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain POSTROUTING (policy ACCEPT 4 packets, 532 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 MASQUERADE  all  --  *      eth0    *.*.*.*/24          0.0.0.0/0 

iPhoneの設定

クライアント設定ファイルの転送

client.ovpn ファイルを iPhone に転送します。転送方法には以下のようなものがあります。

メールで送信 クラウドストレージ(Google Drive、Dropboxなど)を使用して共有

OpenVPN Connectアプリでインポート

iPhoneに OpenVPN Connect アプリをインストールします。 client.ovpn ファイルをインポートします。 ステップ6: OpenVPNサーバーに接続 OpenVPN Connectアプリを開き、インポートしたプロファイルを選択して接続します。

DNS 設定の確認

iPhoneでVPN接続後に正しくDNS設定が反映されているか確認します。

VPN接続後にiPhoneのWi-Fi設定を開き、現在接続しているWi-Fiネットワークの詳細を表示します。 「DNS」を確認し、VPNサーバーがプッシュするDNSサーバー8.8.8.8と8.8.4.4を設定する。 自動取得されているDNSサーバは削除する。 スクショ忘れずに!!

変更したら

iPhoneの電源を一度落としてDNSキャッシュやネットワーク関連の問題を解消する

その他DNSの設定に関して

手順1: クライアント側の DNS 設定を確認 VPN 接続後にクライアントの DNS 設定が正しく反映されているかを確認します。

cat /etc/resolv.conf

クライアントの /etc/resolv.conf ファイルに 8.8.8.8 および 8.8.4.4 が含まれていることを確認します。

手順2: DNS サーバーの設定を修正 (オプション) systemd-resolved を無効にして、静的な DNS 設定を使用することも可能です。この方法を試す場合は以下の手順を実行してください。

systemd-resolved を無効にします。

sudo systemctl disable systemd-resolved.service
sudo systemctl stop systemd-resolved.service
/etc/resolv.conf を直接編集して、DNS サーバーを設定します。
sudo rm /etc/resolv.conf
echo "nameserver 8.8.8.8" | sudo tee /etc/resolv.conf
echo "nameserver 8.8.4.4" | sudo tee -a /etc/resolv.conf

これにより、DNS クエリが Google の DNS サーバーに送信されるようになります。

OpenVPNの暗号化方式について

OpenVPNの暗号化に関しては、複数の要素が関係しています。暗号化方式(cipher)にはいくつかの種類があり、それぞれに特徴があります。以下に主要な暗号化方式とその違いについて説明します。

主な暗号化方式

  • AES-128-CBC

概要: 128ビットの鍵長を持つAES暗号をCBCモードで使用する方式。 利点: パフォーマンスが高く、セキュリティも十分に確保されている。 使用例: リソースの少ないデバイスや速度が重要な場合に適している。

  • AES-256-CBC

概要: 256ビットの鍵長を持つAES暗号をCBCモードで使用する方式。 利点: 高いセキュリティを提供する。 使用例: セキュリティが最優先される環境に適している。

  • AES-128-GCM

概要: 128ビットの鍵長を持つAES暗号をGCMモードで使用する方式。 利点: 認証付き暗号化を提供し、パフォーマンスが高い。 使用例: モダンなセキュリティ標準に適しており、多くのデバイスでサポートされている。

  • AES-256-GCM

概要: 256ビットの鍵長を持つAES暗号をGCMモードで使用する方式。 利点: 高いセキュリティと認証付き暗号化を提供する。 使用例: 非常に高いセキュリティが求められる場合に適している。 iPhoneでの暗号化設定 iPhoneなどのモバイルデバイスでは、以下の点を考慮して暗号化方式を選ぶと良いでしょう。

互換性: 使用するOpenVPNクライアントアプリがサポートする暗号化方式を確認してください。多くのモダンなクライアントはAES-GCMモードをサポートしています。 パフォーマンス: モバイルデバイスの処理能力に応じて暗号化方式を選びます。AES-128-GCMはパフォーマンスとセキュリティのバランスが良い選択です。 セキュリティ: セキュリティ要件に応じて、AES-256-GCMを選択することで高いセキュリティを確保できます。

フォワーディング設定の確認 IPフォワーディングの確認: sysctlコマンドを使ってIPフォワーディングが有効になっているか確認します。

sudo sysctl net.ipv4.ip_forward

出力が以下のようであることを確認します。

net.ipv4.ip_forward = 1

sysctl.confの設定: /etc/sysctl.confファイルを確認し、以下の行が含まれていることを確認します。

net.ipv4.ip_forward=1
sudo sysctl -p

この記事が気に入ったらサポートをしてみませんか?