---
# System prepended metadata

title: OpenVPN with AWS

---

# OpenVPN with AWS
DigitalOcean 的 tutorial
但把兩個server放一起

Note: 這個ubuntu機器的使用者名稱叫做ubuntu

## Step 1
* 下載
```
sudo apt update
sudo apt install openvpn
```

* 去 https://github.com/OpenVPN/easy-rsa/releases 拿最新版網址 (2021/7/15 是 v3.0.8)
```
wget -P ~/ https://github.com/OpenVPN/easy-rsa/releases/download/v3.0.8/EasyRSA-3.0.8.tgz
tar xvf EasyRSA-3.0.8.tgz
```

## Step 2
* 這部分是在 "CA server" 上做的

```
cd ~/EasyRSA-3.0.8/
cp vars.example vars
vim vars
```
> EasyRSA-<version> 這個資料夾是前面解壓縮出來的

* 把下圖最下面幾行 set_var 取消註解 (要更改也可以)，儲存退出
![](https://i.imgur.com/hz14Dvs.png)
    :::spoiler (複製用...)
    ```
    #set_var EASYRSA_REQ_COUNTRY    "US"
    #set_var EASYRSA_REQ_PROVINCE   "California"
    #set_var EASYRSA_REQ_CITY       "San Francisco"
    #set_var EASYRSA_REQ_ORG        "Copyleft Certificate Co"
    #set_var EASYRSA_REQ_EMAIL      "me@example.net"
    #set_var EASYRSA_REQ_OU         "My Organizational Unit"
    ```
    :::

* 退出後執行
```
./easyrsa init-pki
```
> 最下面出現 "Your newly created PKI dir is: /home/ubuntu/EasyRSA-3.0.8/pki"


```
./easyrsa build-ca nopass
```
> 生出 ca.crt、ca.key
> 會要求填寫一些東西，可以直接按 enter 用預設值
> 完成後出現 "Your new CA certificate file for publishing is at: /home/ubuntu/EasyRSA-3.0.8/pki/ca.crt"


## Step 3 - Creating the Server Certificate, Key, and Encryption Files
* "VPN server"
```
cd ~/EasyRSA-3.0.8/
./easyrsa gen-req server nopass
```
> 生出 server.req
> 第二行第三個參數 "server" 可以改，但後面的操作也要一起改

* server.key 放到 openvpn
```
sudo cp ~/EasyRSA-3.0.8/pki/private/server.key /etc/openvpn/
```

* CA server

~~`./easyrsa import-req ~/EasyRSA-3.0.8/pki/reqs/server.req server`~~

`./easyrsa sign-req server server`
> 第一個 server 是 type，第二個 server 是 name
> 回答 yes 後 enter
> 生出 /home/ubuntu/EasyRSA-3.0.8/pki/issued/server.crt

* 複製到 openvpn
```
sudo cp ./pki/issued/server.crt /etc/openvpn/
sudo cp ./pki/ca.crt /etc/openvpn/
```

* 製作 Diffie-Hellman key (會花個一分鐘)
```
./easyrsa gen-dh
```

* 製作 HMAC 簽章
```
openvpn --genkey --secret ta.key
```

* 再複製到 openvpn
```
sudo cp ./ta.key /etc/openvpn/
sudo cp ./pki/dh.pem /etc/openvpn/
```

## Step 4 - Generating a Client Certificate and Key Pair

```
mkdir -p ~/client-configs/keys
chmod -R 700 ~/client-configs
```

* start -- 後續新增 client

```
cd ~/EasyRSA-3.0.8/
```
> 請移到這個資料夾，因後面呼叫 easyrsa 會直接把 .req、.key 生在目前所在的資料夾
> 如果機器重新啟動過
> 要先執行 `~/EasyRSA-3.0.8/easyrsa init-pki`
> 下面的 "client1" 也改成新的名字
> 這段 step4 執行完後，新的名字就是給 make_config.sh 的參數

```
./easyrsa gen-req client1 nopass
```
> 按 enter

```
cp ./pki/private/client1.key ~/client-configs/keys/
```

```
./easyrsa sign-req client client1
```
> 輸入 yes 按 enter
> sign-req 後面的 client 是一個 type，跟 step3 第一個指令的 server 一樣

```
cp ~/EasyRSA-3.0.8/pki/issued/client1.crt ~/client-configs/keys/
```
* finish

```
cp ./ta.key ~/client-configs/keys/
sudo cp /etc/openvpn/ca.crt ~/client-configs/keys/
```


## Step 5 - Configuring the OpenVPN Service

```
sudo cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz /etc/openvpn/
sudo gzip -d /etc/openvpn/server.conf.gz
```

* 編輯 `/etc/openvpn/server.conf`
    * 如果以下幾行被註解，就取消註解
        `tls-auth ta.key 0`
        `cipher AES-256-CBC`
        `user nobody`
        `group nogroup`
    * 在`cipher AES-256-CBC`下面加上一行
        `auth SHA256`
    * 尋找 dh 開頭的一行，很可能會是 `dh dh2048.pem`；去掉2048，把整行改成
        `dh dh.pem`
    *

### Mostlikely nessesary step
* 取消註解: 
    `push "redirect-gateway def1 bypass-dhcp"`  (建議搜尋redirect-gateway)
    `push "dhcp-option DNS 208.67.222.222"` (就在redirect-gateway下面)
    `push "dhcp-option DNS 208.67.220.220"`

* **(Optional)** 改 port
    * 如果 VPN server 沒有同時開著 web server，可以改成 443 port
        `port 1194` -> `port 443`
    * 下面的也改成
        `proto tcp`
    * 搜尋 `explicit-exit-notify 1` (應該是最後一行)，1 改為 0
        `explicit-exit-notify 0`


## Step 6 — Adjusting the Server Networking Configuration

* sudo 編輯 /etc/sysctl.conf
    找 `net.ipv4.ip_forward=1`，取消註解

* 重新啟動服務 (?)
```
sudo sysctl -p
```
    
* 看看 "public interface"
    執行 ip route | grep default
    看 dev 後面的名稱 (這裡是eth0)
    > default via 172.31.32.1 dev **eth0** proto dhcp src 172.31.46.92 metric 100

* 編輯 `/etc/ufw/before.rules`
    在這串...
    ```
    #
    # rules.before
    #
    # Rules that should be run before the ufw command line added rules. Custom
    # rules should be added to one of these chains:
    #   ufw-before-input
    #   ufw-before-output
    #   ufw-before-forward
    #
    ```
    
    還有這串中間...
    ```
    # Don't delete these required lines, otherwise there will be errors
    ...
    ```
    
    加上這段:
    ```
    # START OPENVPN RULES
    # NAT table rules
    *nat
    :POSTROUTING ACCEPT [0:0]
    # Allow traffic from OpenVPN client to eth0 (change to the interface you discovered!)
    -A POSTROUTING -s 10.8.0.0/8 -o eth0 -j MASQUERADE
    COMMIT
    # END OPENVPN RULES
    ```
    注意! **eth0** 要改成前面查到的 public interface

* sudo 編輯 `/etc/default/ufw`
    找到 `DEFAULT_FORWARD_POLICY="DROP"`，把 DROP 改成 ACCEPT

* 更改 UFW，允許 port 通過
```
sudo ufw allow 1194/udp
sudo ufw allow OpenSSH
```
> 如果在前面 [Mostlikely nessesary step](#Mostlikely-nessesary-step) 的 Optional 有改掉 1194，上面的 1194 也要改掉

* 重開 UFW
```
sudo ufw disable
sudo ufw enable
```
> 完成後應該會看到
![](https://i.imgur.com/lnXzuZD.png =400x)


## Step 7 - Starting and Enabling the OpenVPN Service

* 用 systemd 的 systemctl 啟動 OpenVPN 伺服器
```
sudo systemctl start openvpn@server
```
> 由於設定檔叫做 `/etc/openvpn/server.conf`
> 所以加上 `@server` 來告訴 systemctl 要用他

* 確認有跑起來
```
sudo systemctl status openvpn@server
```
> 看看下面這行是否有這個 "active (running)"
> Active: **active (running)** since Thu 2021-07-15 08:51:33 UTC; 3min 1s ago

* 讓 OpenVPN 在開機時就跑起來
```
sudo systemctl enable openvpn@server
```


## Step 8 - Creating the Client Configuration Infrastructure
* 建立一個能夠快速生出新 client 設定檔的 script

* 放 script 相關檔案的位置
```
mkdir -p ~/client-configs/files
```

* base file
```
cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf ~/client-configs/base.conf
```

* 編輯複製過來的 base file (~/client-configs/base.conf)
    * 搜尋 `remote my-server-1 1194`
        把 `my-server-1` 改成伺服器的 IP (或網址)
        如果有做 [Mostlikely nessesary step](#Mostlikely-nessesary-step) 的 Optional，也把 1194 改掉
    * 搜尋 `proto udp`
        如果在 [Mostlikely nessesary step](#Mostlikely-nessesary-step) 也有動過 server 的設定，也改成一樣的
    * 把下面兩行的註解移除
        `user nobody`
        `group nogroup`
    * **註解掉**下面四行
        `#ca ca.crt`
        `#cert client.crt`
        `#key client.key` (這三行在一起)
        `#tls-auth ta.key 1` (這個另外找)
    * 找 `cipher AES-256-CBC`
        如果被註解就取消註解
        同時也跟 server 一樣在下一行加上 
        `auth SHA256`
    * 在任意地方加上一行
        `key-direction 1`
    * 也加上下面兩段，處理少數 case 的
        ```
        ; script-security 2
        ; up /etc/openvpn/update-resolv-conf
        ; down /etc/openvpn/update-resolv-conf
        ```
        ```
        ; script-security 2
        ; up /etc/openvpn/update-systemd-resolved
        ; down /etc/openvpn/update-systemd-resolved
        ; down-pre
        ; dhcp-option DOMAIN-ROUTE .
        ```

* script 的部分
    寫一個 make_config.sh
```
vim ~/client-configs/make_config.sh
```

塞入下面這段
```
#!/bin/bash

# First argument: Client identifier

KEY_DIR=~/client-configs/keys
OUTPUT_DIR=~/client-configs/files
BASE_CONFIG=~/client-configs/base.conf

cat ${BASE_CONFIG} \
    <(echo -e '<ca>') \
    ${KEY_DIR}/ca.crt \
    <(echo -e '</ca>\n<cert>') \
    ${KEY_DIR}/${1}.crt \
    <(echo -e '</cert>\n<key>') \
    ${KEY_DIR}/${1}.key \
    <(echo -e '</key>\n<tls-auth>') \
    ${KEY_DIR}/ta.key \
    <(echo -e '</tls-auth>') \
    > ${OUTPUT_DIR}/${1}.ovpn
```
:::spoiler 無縮排版
    ```
    #!/bin/bash

    # First argument: Client identifier

    KEY_DIR=~/client-configs/keys
    OUTPUT_DIR=~/client-configs/files
    BASE_CONFIG=~/client-configs/base.conf

    cat ${BASE_CONFIG} \
    <(echo -e '<ca>') \
    ${KEY_DIR}/ca.crt \
    <(echo -e '</ca>\n<cert>') \
    ${KEY_DIR}/${1}.crt \
    <(echo -e '</cert>\n<key>') \
    ${KEY_DIR}/${1}.key \
    <(echo -e '</key>\n<tls-auth>') \
    ${KEY_DIR}/ta.key \
    <(echo -e '</tls-auth>') \
    > ${OUTPUT_DIR}/${1}.ovpn
    ```
:::


* 設成可執行
```
chmod 700 ~/client-configs/make_config.sh
```


## Step 9 - Generating Client Configurations
* 實際使用前面的 make_config.sh

* 這個 script 是用 ~/client-configs/keys 資料夾裡面的 XXX.crt、XXX.key
    所以產生他們還是要在 easyrsa，然後複製過來

* 建立新的 .crt、.key，參考 [Step 4](#Step-4---Generating-a-Client-Certificate-and-Key-Pair)

```
sudo ./make_config.sh client1
```
> 就會在 file 資料夾生出 client1.ovpn


## Step 10 - Client
### Windows 10
* 下載 https://openvpn.net/community-downloads/
* 把上一步的 client1.ovpn 丟到 C:\Users\\[你的名字]\OpenVPN\config