OpenVPNでリモート接続の作業環境を作る


# 0.はじめに

外出先の作業環境をもう少しストレスのないものにするために対策したメモ。

VPNサーバー等の基盤は、以下のProxmoxVEを使用する。
[ProxmoxVEのセットアップと利用](https://qiita.com/mozo/items/a6b5c689cdb0c8ac5949)

## 課題
* Macのため、WindowsやLinuxを使用する作業はVMWareFusionを使用しているが起動・動作が重い。
* 外出先でモバイルルーター経由の作業が多いが、速度が遅くかつパケット代がかかる。

## 対策

以下を作って、外部から自宅の作業環境と固定回線を使用して作業できるようにする。

* 自宅にVPNサーバーと作業環境（Windows10など）を用意する。（手順1,2）
* ネットワーク設定をし、外部から自宅にVPN接続できるようにする。（手順3）
* 外出先のクライアントから自宅の作業環境に接続する。（手順4）

## 評価・感想
* 自宅の作業用環境での作業はかなりストレスを減らすことができた。
* モバイルルーターのパケット使用量が減った。
* 自宅の仮想環境を使ってネットワーク構成を含めた検証環境構築もできるのでやれることが増えた。
* 電気代はどうなっただろうか。

# 1. VPNサーバー（CentOS）の作成

ProxmoxVEにて、VPNサーバー用のゲストOSのセットアップを行う。
OSはCentOS7を使用する。

## 1.1. インストールイメージの準備

以下からISOイメージをダウンロードする。
https://www.centos.org/download/

## 1.2. VMの作成とOSインストール

[ProxmoxVEのセットアップと利用#3.1.Linux機のセットアップ](https://qiita.com/mozo/items/a6b5c689cdb0c8ac5949#31-linux機のセットアップ)を参照。

* sudoの設定などは任意で行う。

## 1.3. サーバーの設定

* 参考
	* [CentOS7でVPNサーバを作ってみた（tun編）・・・サーバ起動まで](https://qiita.com/horus19761108/items/9c7879149218d9325c5e)
	* https://gtrt7.com/blog/linux/install-openvpn#i-3
	* https://www.labohyt.net/blog/server/post-1129/

### 1.3.1. SSHの設定

クライアントからSSH接続を許可する。

1. クライアント（Mac）上でSSH鍵を準備し、VPNサーバーに転送する。
	1. sshの公開鍵を作成する。

		```
		$ ssh-keygen -t rsa -C "コメント：利用者のメアドなど"
		→ 保存先、パスフレーズを入力して鍵を作成
		```
	1. ssh鍵をVPNサーバーに転送する。

		```
		$ ssh-copy-id -i "公開鍵ファイル（xxx.pub)" "作業用ユーザー"@"VPNサーバーIPアドレス"
		```
1. コンソール or SSH（パスワード認証）でVPNサーバーにログインし、SSHの認証を公開鍵認証のみにする。
	1. sshdの設定ファイルを編集する。
	
		```:/etc/ssh/sshd_config
		※ Rootはログインまたはパスワード認証を禁止
		PermitRootLogin yes
		↓
		PermitRootLogin no
		または
		PermitRootLogin without-password
		
		
		※ パスワード認証を禁止
		#PasswordAuthentication yes
		↓
		PasswordAuthentication no
		

		※ 以下はそのまま
		#PubkeyAuthentication yes
		ChallengeResponseAuthentication no
		
		※ セキュリティ強化のため暗号化アルゴリズムを指定する
		Ciphers aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com,chacha20-poly1305@openssh.com
		```

	1. sshdを再起動する。
	
		```
		$ sudo systemctl restart sshd
		```
1. ログアウトして、SSH（公開鍵認証）でログインする。
	
		```
		$ ssh -i "秘密鍵ファイル" "作業用ユーザー"@"VPNサーバーIPアドレス"
		```

### 1.3.2. OpenVPNの設定

OpenVPNのインストール、設定をする。

1. rootになる。
	
	```
	$ su -
	```
1. 必要なパッケージをインストールする。

	```
	epelリポジトリを追加
	# yum install epel-release -y

   
    # yum --enablerepo=epel -y install openvpn easy-rsa
	```
1. 認証局を設置する。
	1. easy-rsaのファイルをコピー
	
		```
	    # mkdir /etc/openvpn/easy-rsa
	    # cp -R /usr/share/easy-rsa/3.0.3/* /etc/openvpn/easy-rsa/
		```
	1. 初期化
	
		```
		# cd /etc/openvpn/easy-rsa
		# ./easyrsa init-pki
		```
	1. 認証局の作成
	
		```
		# ./easyrsa build-ca
		→パスフレーズの入力
		→パスフレーズ（確認）の入力
		→Common Nameの入力

		→ 以下が作成される
		/etc/openvpn/easy-rsa/pki/ca.crt （ca証明書）
		/etc/openvpn/easy-rsa/pki/ca.key （ca秘密鍵）
		```

	1. DHパラメータの作成
	
		```
		# ./easyrsa gen-dh
		→ /etc/openvpn/easy-rsa/pki/dh.pem が作成される
		```

	1. サーバー用の証明書と秘密鍵をパスフレーズなしで作成
	
		```
		# ./easyrsa build-server-full server1 nopass
		→ca秘密鍵(ca.key)のパスフレーズを入力
		
		→ 以下が作成される
		/etc/openvpn/easy-rsa/pki/issued/server1.crt （サーバ用証明書）
		/etc/openvpn/easy-rsa/pki/private/server1.key （サーバ用秘密鍵）
		```

	1. クライアント用の証明書と秘密鍵の作成
	
		```
		# ./easyrsa build-client-full client1 nopass
		→ca秘密鍵(ca.key)のパスフレーズを入力
		
		→ 以下が作成される
		/etc/openvpn/easy-rsa/pki/issued/client1.crt （クライアント用証明書）
		/etc/openvpn/easy-rsa/pki/private/client1.key （クライアント用秘密鍵）
		```

1. OpenVPNのサーバー設定
	1. サーバーの設定ファイル雛型を作業用ディレクトリにコピーする。
		
		```
		# cd /etc/openvpn/
		# cp /usr/share/doc/openvpn-2.4.6/sample/sample-config-files/server.conf server1.conf
		```

	1. サーバーの設定ファイルを確認・変更する。

		```:server1.conf
		[32行目：使用するポート番号]
		　port 1194
		[36行目：使用するプロトコル]
		　proto udp
		[53行目：TAP/TUNデバイス指定]
		　dev tun
		[78,79,80行目(変更)：ca証明書、サーバ証明書、秘密鍵の指定]
		　ca /etc/openvpn/easy-rsa/pki/ca.crt
		　cert /etc/openvpn/easy-rsa/pki/issued/server1.crt
		　key /etc/openvpn/easy-rsa/pki/private/server1.key  # This file should be kept secret
		[85行目(変更)：乱数(DH)パラメータの指定]
		　dh /etc/openvpn/easy-rsa/pki/dh.pem
		[101行目：仮想ネットワークの指定(TUNモードの時に指定)]
		　server 10.8.0.0 255.255.255.0
		[108行目：配布用IPアドレスのテーブル(固定IPを使用する場合、ipp.txtを編集)]
		　ifconfig-pool-persist ipp.txt
		[142行目(変更)：サーバ側のLANセグメント(TUNモードの時に指定)]
		　push "route 192.168.1.0 255.255.255.0"  （192.168.1.0は例）
		[209行目(変更)：クライアント間通信の許可]
		　client-to-client
		[231行目：キープアライブ設定（10秒ごとに生存確認、120秒無応答でダウン）]
		　keepalive 10 120
		[244行目：TLS認証キーの指定]
		　tls-auth ta.key 0 # This file is secret
		[263行目(変更)：圧縮の有効可]
		　comp-lzo
		[274,275行目：ユーザ権限の設定]
		　;user nobody
		　;group nobody
		[281,282行目：rootのプロセス起動時のみtunデバイスと鍵ファイルにアクセス]
		　persist-key
		　persist-tun
		[287行目(変更)：ステータスログ]
		　status /var/log/openvpn-status.log
		[296行目(変更)：稼働ログ]
		　log    /var/log/openvpn.log
		[306行目：ログレベル]
		　verb 3
		```
	1. TLS認証キーの作成
	
		```
		# openvpn --genkey --secret /etc/openvpn/ta.key
		
		→ /etc/openvpn/ta.key が作成される
		```
 
 	1. サーバーのテスト起動と動作確認
 	
 		```
 		# openvpn server1.conf
 		
 		
 		Sun Apr  1 03:28:46 2018 OpenVPN 2.4.6 x86_64-redhat-linux-gnu [Fedora EPEL patched] [SSL (OpenSSL)] [LZO] [LZ4] [EPOLL] [PKCS11] [MH/PKTINFO] [AEAD] built on Mar  1 2018

		(省略)

		Sun Apr  1 03:28:46 2018 Initialization Sequence Completed
 		```
 		
 	1. サーバー起動と自動起動設定
 	
 		```
 		サーバー起動
 		# systemctl start openvpn@server1
 		
 		自動起動設定
  		# systemctl enable openvpn@server1
		 		
  		```

### 1.3.3. ファイアウォールの設定

CentOSのFirewalldにて以下を設定する。

* ゾーン"public"に外部からのVPN接続のアクセス制御を設定
* ゾーン"trusted"にVPN接続後のアクセス制御を設定


1. ゾーン"public"にopenvpnサービス（またはポート1194/UDP）の許可を設定する。

	```
永続的に設定
$ sudo firewall-cmd --zone=public --add-service openvpn --permanent
success
	```
1. ゾーン"public"にIPマスカレードを設定する。

	```
永続的に設定
$ sudo firewall-cmd --zone=public --add-masquerade --permanent 
success
　
一時的に設定して確認（なくても良い）
$ sudo firewall-cmd --zone=public --add-masquerade --permanent 
success
$ sudo firewall-cmd --query-masquerade
yes
	```
1. ゾーン"trusted"にVPNインターフェース（tun+）を追加する。

	```
永続して設定
$ sudo firewall-cmd --zone=trusted --change-interface=tun+ --permanent
	```

1. firewalldの設定をリロードする。

	```
$ sudo firewall-cmd --reload
	```

1. firewalldの設定を確認する。

	```
$ sudo firewall-cmd --list-all --zone-public
public (active)
	target: default
	icmp-block-inversion: no
	interfaces: eth0
	sources: 
	services: ssh dhcpv6-client openvpn
	ports: 
	protocols: 
	masquerade: yes
	forward-ports: 
	source-ports: 
	icmp-blocks: 
	rich rules: 
　
$ sudo firewall-cmd --list-all --zone-trusted
trusted (active)
	target: ACCEPT
	icmp-block-inversion: no
	interfaces: tun+
	sources: 
	services: 
	ports: 
	protocols: 
	masquerade: no
	forward-ports: 
	source-ports: 
	icmp-blocks: 
	rich rules: 
	```
  
### 1.3.4. ログローテーションの設定

1. ログローテーションの設定ファイルを作成する。

	```:/etc/logrotate.d/openvpn
/var/log/openvpn-status.log {
    weekly	# 週次でローテートする
    delaycompress
    compress
    missingok
    notifempty
}
/var/log/openvpn.log {
    weekly	# 週次でローテートする
    delaycompress
    compress
    missingok
    notifempty
    sharedscripts # ローテート時にサービス再起動のスクリプト実行
    postrotate
    systemctl restart openvpn 2>&1 > /dev/null || true
    endscript
}
	```
1. dry-runを実行し、設定に誤りがないか確認する。

	```
$ sudo logrotate -dv /etc/logrotate.conf
	```


# 2. 作業環境（Windows10の仮想ゲスト）の作成

リモートデスクトップで接続するWindowsゲスト環境を作成する。

## 2.1. インストールイメージの準備

以下からISOイメージをダウンロード
https://www.microsoft.com/ja-jp/software-download/windows10ISO

## 2.2. VMの作成とOSインストール

[ProxmoxVEのセットアップと利用#3.2.Windows機（Windows10）のインストール](https://qiita.com/mozo/items/a6b5c689cdb0c8ac5949#32-windows機のセットアップ)を参照。

* 外部から接続したい方法（リモートデスクトップなど）の設定をする。（手順は割愛）


# 3. ネットワークの設定

## 3.1. DDNSによる外部からの接続先特定

自宅の固定回線プロバイダは固定グローバルIPアドレスを配布していないため、
ダイナミックDNSサービスを設定し、外部から自宅のIPアドレスを特定できるようにする。

* DDNSサービス: no-ip (https://www.noip.com/)

1. no-ipのサイトにてアカウントを作成する。
1. no-ipの無料ダイナミックドメインを登録する。（xxx.xxx.org）
	* サブドメイン： 任意
	* ドメイン: Freeのものをプルダウンから選択
1. 転送先のグローバルIPアドレス（自宅アドレス）を登録する。
	* 以下などで確認
	* https://www.cman.jp/network/support/go_access.cgi
1. hostコマンドなどで設定の適用を確認する。

  ```
  $ host "設定したダイナミックドメイン"
  →グローバルIPアドレスが参照できること
  ```
1. 自動的に更新するため、自宅の任意の端末にDUC（Dynamic Update Client）を設定する。
	* 参照：https://my.noip.com/#!/dynamic-dns/duc
	* フリーアカウントではDNSホスト名の有効期限が30日のため、定期的（メールで通知あり）に更新の承認が必要

## 3.2. ルータのポートフォワーディング

VPN接続リクエストをVPNサーバーに転送するため、ブロードバンドルーターにポートフォワーディングの設定をする。

* ポート： 1194/UDP
* 転送先： VPNサーバーのIPアドレス


# 4. クライアント設定

クライアント（Mac）にVPN接続用の設定をする。

## 4.1. 接続用ファイル取得

1. VPNサーバーの /etc/openvpn/ 下にある以下のファイルを取得し、設定ファイルの保存先ディレクトリ（任意）に置く。
	* ca証明書(ca.crt)
	* クライアント用証明書(client1.crt) 
	* クライアント用秘密鍵(client1.key)
	* TSL認証キー(ta.key)
1. 上記の保存先ディレクトリにクライアント設定ファイルを作成する。

	```:"VPN接続の表示名".ovpn
client
remote "自宅のIPアドレス/DDNSホスト名" 1194
dev tun
proto udp
ca ca.crt
cert client1.crt
key client1.key
tls-auth ta.key 1
comp-lzo
persist-key
persist-tun
	```

## 4.2. クライアント設定

VPNクライアントはtunnelblickを使用する。
https://tunnelblick.net/

1. 以下からダウンロードしてインストールする。<br>https://tunnelblick.net/downloads.html
2. 4.1のクライアント設定ファイル（"VPN接続の表示名".ovpn）をダブルクリック、またはtunnelblickへドラッグ＆ドロップし設定を反映する。
3. 接続し、認証用のパスフレーズを入力し、接続できることを確認する。