前の前の記事はこちら → 1 : Easy-RSA による証明書等の準備
前の記事はこちら → 2 : サーバの設定
3 : クライアントの設定
以上で、サーバのほうは完成しました。
あとは、クライアントの設定ファイルなど、クライアントの構築です。
クライアントのホストで作業します。
3-1 OpenVPNクライアントの設定ファイルを作成
クライアントの基本的な 設定ファイル client.conf
(/etc/openvpn/client.conf
)を作ります。
実際には、 /etc/openvpn/client/
に ファイル client.conf
を作って保持し、それへのシンボリックリンクを /etc/openvpn/
に置きました。
user<clienthost~> % sudo -s
root<clienthost~> % cd /etc/openvpn/client/
root<clienthost/etc/openvpn/client> % cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf .
root<clienthost/etc/openvpn/client> % vim client.conf
最終的な設定内容だけを示します。
なお、 my.domain
は名前解決してグローバルアドレスが得られるようになっているドメイン名です。
client
dev tap0
proto udp
remote my.domain 1194
resolv-retry infinite
nobind
user nobody
group nogroup
persist-key
persist-tun
ca /etc/openvpn/ca.crt
cert /etc/openvpn/clienthost.crt
key /etc/openvpn/clienthost.key
remote-cert-tls server
tls-auth /etc/openvpn/ta.key 1
verb 3
mssfix 1280
ファイルを保存したらシンボリックリンクを作ります。
root<clienthost/etc/openvpn/client> % cd ..
root<clienthost/etc/openvpn> % ln -s client/client.conf
client.conf
の内容に関するメモ
参考 : man openvpn
参考 : Deprecated Options in OpenVPN
参考 : OpenVPNに接続したときに、接続が不安定になる問題を解消する
参考 : OpenVPN TIPS - UDP使用時にVPN通信が不安定になる場合
設定内容 | メモ |
---|---|
client |
pull tls-client の2つを指定するのと同等とのこと。 |
dev tap0 |
dev tap でも大丈夫ですが、ここでは、 tap0 と指定しました。 |
proto udp |
サーバの設定と合わせます。 |
remote my.domain 1194 |
接続先です。 ポート 1194 はサーバの設定と合わせます。 |
remote-cert-tls server |
悪意を持ったクライアントがサーバになりすます攻撃を防ぐためのオプションです。昔は ns-cert-type server というオプションだったようですね。それがこれに置き換わったようです。 |
cipher AES-256-CBC | いまのバージョンの OpenVPN では、サーバとクライアントが相談して利用可能な中から最適なサイファを決めるようになっているそうで、オプションでの指定は必要ないようです。 バージョン 2.3 以前のサーバと通信する場合は互換性のために入れてもよいとの情報がありますが、しないので省きました。 |
data-ciphers AES-256-GCM:AES-128-GCM:?CHACHA20-POLY1305:AES-256-CBC | 上と同じ。省きました。 |
comp lzo | サーバの設定と合わせなければなりません。サーバの設定で入れなかったので、クライアントの設定からも除かなくてはいけません。 |
mssfix 1280 |
よくわかっていないのですが、送信する UDPパケット の大きさの上限を決める、みたいな意味のようです(でいいですか?)。場合により、ある大きさを超えるパケットが経路途中のルータで破棄されるというケースがあるみたいで、それが起こると通信できなくなったり遅延したりします。いろいろ試す中でそのようなことがあったので、参考サイトの説明に従ってこの値を定めてみました。いちおう、これで順調に動作しています。 |
3-2 証明書や鍵のファイルを適切な場所に置く
1 : Easy-RSA による証明書等の準備 で用意した証明書や鍵のファイルのうち OpenVPN のクライアントに必要なものを、コピーしてきて適切な場所(/etc/openvpn/
)に置きます。
OpenVPN のクライアントが必要とするファイルは以下です。
必要なもの | ファイル名 |
---|---|
クライアントの証明書 | clienthost.crt |
クライアントの秘密鍵 | clienthost.key |
CAの証明書 | ca.crt |
TLS認証鍵 | ta.key |
(1) 適切な場所にコピーする
上の4つのファイルを、サーバのホストにある Easy-RSA のディレクトリからクライアントのホストに送り、 /etc/openvpn/
に置きます。
実際には、 clienthost.crt
と clienthost.key
の2つのファイルは、 /etc/openvpn/client/
に保持し、それらへのシンボリックリンクを /etc/openvpn/
に置きました。
(2) 秘密鍵からパスフレーズを取り除く
サーバの秘密鍵 に対してしたのと同じように、 クライアントの秘密鍵 からパスフレーズを取り除いておきます。
openssl
コマンドで行います。 openssl rsa -in 元の秘密鍵ファイル -out パスフレーズの取り除かれた秘密鍵を格納するファイル名
とします。
Enter pass phrase for clienthost.key.BACKUP:
でそのパスフレーズを入力します。
root<clienthost/etc/openvpn> % cd client/
root<clienthost/etc/openvpn/client> % mv clienthost.key clienthost.key.BACKUP
root<clienthost/etc/openvpn/client> % openssl rsa -in clienthost.key.BACKUP -out clienthost.key
Enter pass phrase for clienthost.key.BACKUP:
writing RSA key
サーバの秘密鍵 のところで述べたのと同じように、 クライアントの秘密鍵 についても、このファイルが盗まれたら(パスフレーズがあれば秘密鍵は漏洩しない可能性があったところ、パスフレーズを取り除いてしまったので)一巻の終わり、と考え、ファイルとディレクトリのパーミッションに細心の注意を払っておく必要があります。
このファイルのオーナーは root:root にし、パーミッションは 600 にしました。
3-3 systemd で サービス openvpn
を有効化
クライアントのホストにおいて、 systemd で サービス openvpn
を有効化します。
(実際には、最初から有効化されているようなので、この作業は必要ないかと思います。)
root<clienthost/etc/openvpn> % cd
root<clienthost~> % sudo systemctl enable openvpn
Synchronizing state of openvpn.service with SysV service script with /usr/lib/systemd/systemd-sysv-install.
Executing: /usr/lib/systemd/systemd-sysv-install enable openvpn
3-4 OpenVPN の tap接続 に関わる route の設定
Ubuntu の NetworkManager には OpenVPN と連携するモジュールのパッケージがあり、 openvpn
のパッケージとともにインストールされていますので、ここまでの作業で、システムに tap接続 の設定が認識され、接続できる状態になっています。
しかし、実際に接続テストをしてみると、接続しているものの通信できないという状態になります。
その問題を解決します。
tap接続 を起動する前の状態
まず、 tap接続 を起動する前のインタフェースの状態は
root<clienthost~> % exit
exit
user<clienthost~> % ifconfig
enp175s0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
ether 06:e0:4c:6a:02:13 txqueuelen 1000 (イーサネット)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (ローカルループバック)
RX packets 183 bytes 15273 (15.2 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 183 bytes 15273 (15.2 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
wlp174s0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.201.13 netmask 255.255.255.0 broadcast 192.168.201.255
inet6 2001:268:981b:8d89:aace:3896:a11e:e49a prefixlen 64 scopeid 0x0<global>
inet6 2001:268:981b:8d89:3eaa:e15b:e724:379 prefixlen 64 scopeid 0x0<global>
inet6 fe80::d82f:f558:99e1:f584 prefixlen 64 scopeid 0x20<link>
ether f4:7b:09:99:fb:01 txqueuelen 1000 (イーサネット)
RX packets 153 bytes 48685 (48.6 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 157 bytes 26905 (26.9 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
です。 enp175s0
は有線インタフェース、 wlp174s0
は無線インタフェースです。
現在、有線は接続されていなくて無線で接続されており、無線インタフェースが アドレス 192.168.201.13/24
を持っていることがわかります。
route は
user<clienthost~> % route
カーネルIP経路テーブル
受信先サイト ゲートウェイ ネットマスク フラグ Metric Ref 使用数 インタフェース
default _gateway 0.0.0.0 UG 600 0 0 wlp174s0
link-local 0.0.0.0 255.255.0.0 U 1000 0 0 wlp174s0
192.168.201.0 0.0.0.0 255.255.255.0 U 600 0 0 wlp174s0
となっています。
NetworkManager での接続の確認
ここで、NetworkManager が認識している接続のリストを表示させると
user<clienthost~> % nmcli connection
NAME UUID TYPE DEVICE
wifi1 0d9603b3-9124-4437-b970-0d23815e573e wifi wlp174s0
wifi2 b2c1560d-6305-4f1d-a2f9-488ccc6884bf wifi --
tap0 b9b087c3-d3d6-4b20-a101-bb45a60cdbe1 tun --
有線接続 1 1be4e9ec-3c65-31ae-980c-106c59275d19 ethernet --
と表示されます。
tap0
がちゃんと含まれていますね。
では、 tap0
を起動してみます。
user<clienthost~> % nmcli connection up tap0
接続が正常にアクティベートされました (D-Bus アクティブパス: /org/freedesktop/NetworkManager/ActiveConnection/2)
user<clienthost~> % nmcli connection
NAME UUID TYPE DEVICE
wifi1 0d9603b3-9124-4437-b970-0d23815e573e wifi wlp174s0
tap0 b9b087c3-d3d6-4b20-a101-bb45a60cdbe1 tun tap0
wifi2 b2c1560d-6305-4f1d-a2f9-488ccc6884bf wifi --
有線接続 1 1be4e9ec-3c65-31ae-980c-106c59275d19 ethernet --
うまくいきました。
ところが、この状態で、 VPN でつないだローカルネットワーク内のホストへ ping
を打っても、返事が返ってきません。
それどころか、 wifi1
を通した VPN とは無関係な外部への通信もできなくなってしまっています。
通信できない原因
その原因は、 route にあります。
この状態で route を表示させると
user<clienthost~> % route
カーネルIP経路テーブル
受信先サイト ゲートウェイ ネットマスク フラグ Metric Ref 使用数 インタフェース
default 192.168.0.1 0.0.0.0 UG 450 0 0 tap0
default _gateway 0.0.0.0 UG 600 0 0 wlp174s0
link-local 0.0.0.0 255.255.0.0 U 1000 0 0 wlp174s0
192.168.0.0 0.0.0.0 255.255.255.0 U 450 0 0 tap0
192.168.201.0 0.0.0.0 255.255.255.0 U 600 0 0 wlp174s0
となります。 _gateway
(192.168.201.0/24
のゲートウェイ)と 192.168.0.1
(192.168.0.0/24
のゲートウェイ)の2つが default
になっています。
これが原因のようです。
tap接続 を default route にしないよう NetworkManager に指示
この問題は、 tap0
を default
とする設定を取り除けば解決します。
それは
user<clienthost~> % sudo route del default tap0
でできますが、 NetworkManager に覚えてもらうには、次のようにします。
user<clienthost~> % nmcli connection modify tap0 ipv4.never-default yes
このようにすると、再起動後も永続する設定になります。
問題の解決を確認
一旦、 tap0
を停止して、ふたたび起動します。
user<clienthost~> % nmcli connection down tap0
接続 'tap0' が正常に非アクティブ化されました (D-Bus アクティブパス: /org/freedesktop/NetworkManager/ActiveConnection/2)
user<clienthost~> % nmcli connection up tap0
接続が正常にアクティベートされました (D-Bus アクティブパス: /org/freedesktop/NetworkManager/ActiveConnection/3)
すると、 route は
user<clienthost~> % route
カーネルIP経路テーブル
受信先サイト ゲートウェイ ネットマスク フラグ Metric Ref 使用数 インタフェース
default _gateway 0.0.0.0 UG 600 0 0 wlp174s0
link-local 0.0.0.0 255.255.0.0 U 1000 0 0 wlp174s0
192.168.0.0 0.0.0.0 255.255.255.0 U 450 0 0 tap0
192.168.201.0 0.0.0.0 255.255.255.0 U 600 0 0 wlp174s0
ちゃんと default
が1個になりました。
通信も無事にできるようになりました。 VPN で繋いだローカルネットワーク内のすべてのホストと自由に通信することができます。もちろん外部との通信もできます。
NetworkManager での tap接続 の設定の内容
NetworkManager での tap0
の設定を一覧表示させるとこうなります。
user<clienthost~> % nmcli connection show tap0
connection.metered: 不明
connection.lldp: default
connection.mdns: -1 (default)
connection.llmnr: -1 (default)
connection.dns-over-tls: -1 (default)
connection.wait-device-timeout: -1
ipv4.method: auto
ipv4.dns: --
ipv4.dns-search: --
ipv4.dns-options: --
ipv4.dns-priority: 0
ipv4.addresses: --
ipv4.gateway: --
ipv4.routes: --
ipv4.route-metric: -1
ipv4.route-table: 0 (unspec)
ipv4.routing-rules: --
ipv4.ignore-auto-routes: いいえ
ipv4.ignore-auto-dns: いいえ
ipv4.dhcp-client-id: --
ipv4.dhcp-iaid: --
ipv4.dhcp-timeout: 0 (default)
ipv4.dhcp-send-hostname: はい
ipv4.dhcp-hostname: --
ipv4.dhcp-fqdn: --
ipv4.dhcp-hostname-flags: 0x0 (none)
ipv4.never-default: はい
ipv4.may-fail: はい
ipv4.required-timeout: -1 (default)
ipv4.dad-timeout: -1 (default)
ipv4.dhcp-vendor-class-identifier: --
ipv4.dhcp-reject-servers: --
ipv6.method: link-local
ipv6.dns: --
ipv6.dns-search: --
ipv6.dns-options: --
ipv6.dns-priority: 0
3-5 ユーザ操作で OpenVPN tap接続 を起動するスクリプトを用意
システム起動時に OpenVPN の tap接続 を起動するようにするには、 systemd で openvpn@client
を有効化すればいいです。
user<clienthost~> % sudo systemctl enable openvpn@client
しかし、私の場合は、クライアントはつねにネットワークに接続しているわけではないので、必要に応じてユーザが操作して OpenVPN の tap接続 を起動するようにします。
そのためのスクリプトを用意します。
user<clienthost~> % cd bin/
user<clienthost~/bin> % vim start_vpn_with_dhcp
内容は次のとおりです。
#!/bin/sh
/usr/bin/nmcli connection up tap0
実行パーミッションを付与しておきます。
user<clienthost~/bin> % chmod a+x start_vpn_with_dhcp
ユーザーは、ネットワークに繋がっている状態で、このスクリプトを実行すれば、いつでも、 tap接続 を開始することができます。
以上で、すべての準備が完了しました。