OpenVPN, DD-WRT, OpenWRT, Raspberry Piで作るVPN環境

在宅勤務、と言われても、みんながみんな某C社のAny Connectなどを使えるとは限らないんですよ。
そこで、安価、オープンで手に入る素材で、拠点(server側)と、自分のPCもしくはネットワーク(client側)をつないでみます。

なお、今回の記事では、拠点(server)側のIPアドレスは、グローバルIPでかつ既知であることを前提とします。

#概要

```
      [アクセスしたい環境]               
             |
           Server (dd-wrt対応ルータ)
             |
         GateWay(光回線/Mobile Routerほか。要グローバルIP)
             |
       インターネット
             |
         GateWay(Mobile Router/公衆WiFiほか)
             |
             +------------------------+
             |                        |
         Client(OpenWRT)          Client(Windows/Androidほか)
             |
       [リモート環境]               
```

Serverの後ろに、アクセスしたい環境、たとえば、拠点だったり、作業場だったり、です。
それに対して、ClientからVPNをはり、アクセスすることを目指します。


#準備
OpenVPNのcertやkeyファイルを作成します。基本、[こちら](https://wiki.dd-wrt.com/wiki/index.php/OpenVPN)(https://wiki.dd-wrt.com/wiki/index.php/OpenVPN)に従って、ファイルを準備します。

##OpenVPN関連ファイルの作成

###サーバ関係準備

(初めての場合のみ)
次のコマンドで、からファイルを作成します。
1. vars
2. clean-all
3. build-ca

windowsでの実施例

```
C:\Program Files\OpenVPN\easy-rsa>vars.bat

C:\Program Files\OpenVPN\easy-rsa>clean-all.bat
指定されたファイルが見つかりません。
        1 個のファイルをコピーしました。
        1 個のファイルをコピーしました。

C:\Program Files\OpenVPN\easy-rsa>build-ca.bat
WARNING: can't open config file: /etc/ssl/openssl.cnf
Loading 'screen' into random state - done
Generating a 1024 bit RSA private key
.......................................++++++
.........++++++
writing new private key to 'keys\ca.key'
-----
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.
-----
Country Name (2 letter code) [JP]:
State or Province Name (full name) [TOKYO]:
Locality Name (eg, city) [TOKYO]:
Organization Name (eg, company) [MyNetwork]:
Organizational Unit Name (eg, section) [mynetwork]:
Common Name (eg, your name or your server's hostname) [mynetwork]:
Name [mynetwork]:
Email Address [mynetwork@foobar.com]:
```

続いて、サーバ用のファイル作成。
こちらも、今回のケースでは、サーバは1台だけなので、1回のみ実施。もし、複数台のサーバなら、#3を複数回実施。#2は、一度だけでよろし。

1. vars
2. build-dh
3. build-key-server <machine-name>

```
C:\Program Files\OpenVPN\easy-rsa>vars.bat

C:\Program Files\OpenVPN\easy-rsa>build-dh.bat
WARNING: can't open config file: /etc/ssl/openssl.cnf
Loading 'screen' into random state - done
Generating DH parameters, 1024 bit long safe prime, generator 2
This is going to take a long time
........................................................+........+..................................+...................................................................................................................+......................................+........................................................................+.+...............................................................................................................................+.........................................+.........................................................+.....................................................+.......+..+..................................+................+........................................+.+.......+............................................................................................+.................+..........+................+.....................................................+.......................................................................................................................................................................................................................+..........................................+......................................................................+.....................................+.................................+.........+.........+....................+.......................................................+............+..........+........................................................................................................................+................................+.............................+..+................................+....................................................+............................................+.........................................................+.....................+.............+...........................................................................................................................+..............+.....+......................................+.................................................+.............................................+............................................................................+................................+..................................................................................................................................................................................................+......................+....+.........+.................................................+...................................+.............................................................................+...............................+................................................................................+...................................+...........................+............+..........+.....+..........................................+.............+....................................+.......................................+.........+..........+...............................................................+.........................................+...........................................................................+................................................................++*++*++*

C:\Program Files\OpenVPN\easy-rsa>build-key-server.bat dd-wrt
WARNING: can't open config file: /etc/ssl/openssl.cnf
Loading 'screen' into random state - done
Generating a 1024 bit RSA private key
....++++++
.............................++++++
writing new private key to 'keys\dd-wrt.key'
-----
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.
-----
Country Name (2 letter code) [JP]:
State or Province Name (full name) [TOKYO]:
Locality Name (eg, city) [TOKYO]:
Organization Name (eg, company) [MyNetwork]:
Organizational Unit Name (eg, section) [mynetwork]:
Common Name (eg, your name or your server's hostname) [mynetwork]:
Name [mynetwork]:
Email Address [mynetwork@foobar.com]:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
WARNING: can't open config file: /etc/ssl/openssl.cnf
Using configuration from openssl-1.0.0.cnf
Loading 'screen' into random state - done
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName           :PRINTABLE:'JP'
stateOrProvinceName   :PRINTABLE:'TOKYO'
localityName          :PRINTABLE:'TOKYO'
organizationName      :PRINTABLE:'MyNetwork'
organizationalUnitName:PRINTABLE:'mynetwork'
commonName            :PRINTABLE:'mynetwork'
name                  :PRINTABLE:'mynetwork'
emailAddress          :IA5STRING:'mynetwork@foobar.com'
Certificate is to be certified until Apr XX XX:XX:XX 2030 GMT (3650 days)
Sign the certificate? [y/n]:y


1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
C:\Program Files\OpenVPN\easy-rsa>
```

ここまでで、サーバ側の鍵が完成。windowsだと、keysの配下に収まります。

```
C:\Program Files\OpenVPN\easy-rsa>dir keys
 ドライブ C のボリューム ラベルは Windows です
 ボリューム シリアル番号は XXXX-XXXX です

 C:\Program Files\OpenVPN\easy-rsa\keys のディレクトリ

2020/xx/xx  yy/yy    <DIR>          .
2020/xx/xx  yy/yy    <DIR>          ..
2020/xx/xx  yy/yy             4,120 01.pem
2020/xx/xx  yy/yy             1,383 ca.crt
2020/xx/xx  yy/yy               912 ca.key
2020/xx/xx  yy/yy             4,120 dd-wrt.crt
2020/xx/xx  yy/yy               733 dd-wrt.csr
2020/xx/xx  yy/yy               916 dd-wrt.key
2020/xx/xx  yy/yy               245 dh1024.pem
2020/xx/xx  yy/yy               138 index.txt
2020/xx/xx  yy/yy                21 index.txt.attr
2020/xx/xx  yy/yy                 3 serial
              10 個のファイル              12,591 バイト
               2 個のディレクトリ   Z,ZZZ,ZZZ,ZZZ バイトの空き領域
```

###クライアント関係準備

ここからは、クライアントに入れる証明書づくりです。クライアントの数だけ行ったほうがよいです。なお、同じ証明書を使っても、同時アクセスはできるけど、少なくとも、ユーザ単位で分けるのが無難。証明書の使いまわしは、万が一の際、アクセスログから誰が問題を起こしたか追えなくなるので、よろしくないです。

1. vars
2. build-key <machine-name>

```
C:\Program Files\OpenVPN\easy-rsa>vars.bat

C:\Program Files\OpenVPN\easy-rsa>build-key.bat mypc
WARNING: can't open config file: /etc/ssl/openssl.cnf
Loading 'screen' into random state - done
Generating a 1024 bit RSA private key
.++++++
............................++++++
writing new private key to 'keys\mypc.key'
-----
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.
-----
Country Name (2 letter code) [JP]:
State or Province Name (full name) [TOKYO]:
Locality Name (eg, city) [TOKYO]:
Organization Name (eg, company) [MyNetwork]:
Organizational Unit Name (eg, section) [mynetwork]:
Common Name (eg, your name or your server's hostname) [mynetwork]:
Name [mynetwork]:
Email Address [mynetwork@foobar.com]:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
WARNING: can't open config file: /etc/ssl/openssl.cnf
Using configuration from openssl-1.0.0.cnf
Loading 'screen' into random state - done
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName           :PRINTABLE:'JP'
stateOrProvinceName   :PRINTABLE:'TOKYO'
localityName          :PRINTABLE:'TOKYO'
organizationName      :PRINTABLE:'MyNetwork'
organizationalUnitName:PRINTABLE:'mynetwork'
commonName            :PRINTABLE:'mynetwork'
name                  :PRINTABLE:'mynetwork'
emailAddress          :IA5STRING:'mynetwork@foobar.com'
Certificate is to be certified until Apr XX XX:XX:XX 2030 GMT (3650 days)
Sign the certificate? [y/n]:y
failed to update database
TXT_DB error number 2
C:\Program Files\OpenVPN\easy-rsa\keys\*.old が見つかりませんでした。

C:\Program Files\OpenVPN\easy-rsa>build-key.bat myrooter
WARNING: can't open config file: /etc/ssl/openssl.cnf
Loading 'screen' into random state - done
Generating a 1024 bit RSA private key
...............++++++
...................................................................................................++++++
writing new private key to 'keys\myrooter.key'
-----
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.
-----
Country Name (2 letter code) [JP]:
State or Province Name (full name) [TOKYO]:
Locality Name (eg, city) [TOKYO]:
Organization Name (eg, company) [MyNetwork]:
Organizational Unit Name (eg, section) [mynetwork]:
Common Name (eg, your name or your server's hostname) [mynetwork]:
Name [mynetwork]:
Email Address [mynetwork@foobar.com]:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
WARNING: can't open config file: /etc/ssl/openssl.cnf
Using configuration from openssl-1.0.0.cnf
Loading 'screen' into random state - done
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName           :PRINTABLE:'JP'
stateOrProvinceName   :PRINTABLE:'TOKYO'
localityName          :PRINTABLE:'TOKYO'
organizationName      :PRINTABLE:'MyNetwork'
organizationalUnitName:PRINTABLE:'mynetwork'
commonName            :PRINTABLE:'mynetwork'
name                  :PRINTABLE:'mynetwork'
emailAddress          :IA5STRING:'mynetwork@foobar.com'
Certificate is to be certified until Apr XX XX:XX:XX 2030 GMT (3650 days)
Sign the certificate? [y/n]:y
failed to update database
TXT_DB error number 2
C:\Program Files\OpenVPN\easy-rsa\keys\*.old が見つかりませんでした。
```


##Server (DD-WRT対応ルータ)設定

### Services->VPN

ここは、guiなので、作成したファイルをコピペします。
各種証明書の入力は、実際のテキストを貼り付けます。下の例は、ファイル名を入れました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213097/54398fec-408f-e39e-f698-1710a56571e8.png)

Additional Configは、実際のところ次の通り

```
dev tun0                                 ; ifconfigにて、tun0と表示させる
push "route 192.168.x.0 255.255.255.0"   ; サーバ側のローカルネットワーク情報を通知する場合、ローカルネットワークのサブネット情報を登録
push "dhcp-option DNS 192.168.x.x"       ; DNSを接続先(サーバ側)のものを使わせる場合、サーバ側のDNSを設定
```

### Administration -> Commands

tunを指定した場合には、iptablesにパケット処理情報を登録しないと、実際のパケットは流れません。そこで、Commandsにて、ベタにiptables情報を入力します。

```
iptables -t nat -A POSTROUTING -s 192.168.x.0/24 -o br0 -j MASQUERADE
iptables -A INPUT -i tun+ -j ACCEPT
iptables -A OUTPUT -o tun+ -j ACCEPT
iptables -I FORWARD -i tun0 -o br0 -s 192.168.x.0/24 -d 192.168.x.0/24 -m conntrack --ctstate NEW -j ACCEPT
iptables -A INPUT -i br0 -m state --state NEW -p udp --dport 1194 -j ACCEPT
iptables -A FORWARD -i tun+ -j ACCEPT
iptables -A FORWARD -i tun+ -o br0 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i br0 -o tun+ -m state --state RELATED,ESTABLISHED -j ACCEPT
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213097/7a199148-8008-6364-b3c2-a07569dc7ffe.png)


###ログの確認 (Status -> OpenVPN)

簡単なログの確認なら、Status -> OpenVPNの順にタブをクリックすることで確認可能です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213097/a45ff096-f0d1-52e1-9e1c-71574c06ae21.png)


## Client (OpenWRT)

Raspberry Piに、OpenWRTを仕込みます。(もう一台別のdd-wrt対応ルータでも、openwrt対応ルータでも可。実験機材の関係で、Raspberry Pi (無地 B+)を再利用)
ここでは、[こちらの記事で紹介した内容](https://qiita.com/mbamba/items/4afe3e8ce2964a4ee908)の続きで説明します。もともとのインストールは、[こちらの記事](https://qiita.com/mbamba/items/4afe3e8ce2964a4ee908)を参照してください。

### OpenVPNの選択&ビルド

[OpenWRT本家の説明](https://openwrt.org/docs/guide-user/services/vpn/openvpn/client-luci)に従って、進めます。

**openvpn-openssl** と **luci-app-openvpn** を追加で選択します。(もしくは、opkgを作成)
そして、できたimgをOpenWRTへロードします。


### OpenVPNの設定

OpenVPNをサポートすると、VPNというタブが増えます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213097/b9738fea-1ed4-7e32-75c1-ac8bbe673967.png)

下段に、OVPN configuration file upload があるので、OVPNのファイル形式を読み込ませます。

```
client
proto udp
remote xxx.xxx.xx.xxx xxxx
resolv-retry infinite
redirect-gateway def1
nobind
dev tun
persist-key
persist-tun
cipher BF-CBC
ca /etc/openvpn/ca.crt
cert /etc/openvpn/openwrt.crt
key /etc/openvpn/openwrt.key
ns-cert-type server
comp-lzo
verb 3
```

読み込ませると、/etc/openvpnの配下に、ovpnがアップロードされます。
同じフォルダに、crt/keyファイルも置きます。

```
root@OpenWrt:/etc/openvpn# ls -l
-rw-r--r--    1 root     root           xxx xxx  x xx:xx openwrt.auth
-rw-r--r--    1 root     root           xxx xxx  x xx:xx openwrt.ovpn
-rw-------    1 root     root           xxx xxx  x xx:xx openwrt.crt
-rw-------    1 root     root           xxx xxx  x xx:xx openwrt.key
-rw-------    1 root     root           xxx xxx  x xx:xx ca.crt
```

この状態で、enebledをONにして、startを押すと、上記の画面イメージになります。

これで、dd-wrtとOpenWRTの接続が完了です。

#確認

画面上では、接続を確認できますが(dd-wrtならStatus->OpenVPN, OpenWRTならVPN -> started (yes))、実際に、Pingを飛ばしてみます。もちろん、宛先IPは、VPNで指定したサブネットのアドレスです。

OpenWRT->dd-wrt

```
root@OpenWrt:/etc/openvpn# ping -c 2 192.168.xx.1
PING 192.168.xx.1 (192.168.xx.1): 56 data bytes
64 bytes from 192.168.xx.1: seq=0 ttl=64 time=5.216 ms
64 bytes from 192.168.xx.1: seq=1 ttl=64 time=5.742 ms

--- 192.168.xx.1 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 5.216/5.479/5.742 ms
```

dd-wrt -> OpenWRT

```
root@dd-wrt:~# ping -c 2 192.168.xx.2
PING 192.168.50.2 (192.168.xx.2): 56 data bytes
64 bytes from 192.168.xx.2: seq=0 ttl=64 time=5.243 ms
64 bytes from 192.168.xx.2: seq=1 ttl=64 time=5.347 ms

--- 192.168.50.2 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 5.243/5.295/5.347 ms
```

Pingも通ることなので、疎通ということになります。
実際に運用する際には、上記の手順に加えて、次の点が必要です。

1. Serverが接続しているRouter (NTTから借用している箱など) に、NATの設定を実施
2. OpenWRTにおけるOPVN内のremote項へ、グローバルアドレスを設定

NATの設定は、1194(もしくは設定したPort)を外部から受信した場合、サーバのIPアドレスへ仕向ける設定となります。
また、グローバルアドレスは、Routeの情報で確認することができます。

RS-500KIなら、トップページ ＞ 情報 ＞ 現在の状態 を表示の上、下のほうへスクロールすると、**機器状態情報**という欄があります。ここの**WAN側IPアドレス**が、必要な情報です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213097/e30e59db-a479-ae83-4ec0-fab2a368c657.png)

OVPN形式なので、androidやiPhone, iPadに、keysのフォルダの場所さえ修正できれば、テンプレとして、使いまわしできます。


おしまい