# 记一次搭建 OpenVPN 过程

之前公司的 VPN 都是使用路由器上自带的 VPN 功能，速度慢不说，能连上的几率就跟中彩票一样，为了做开发的同志们回家也能继续安心工作，于是在公司内部的一台服务器上搭建了一个 OpenVPN，通过路由器的端口映射，将服务器的 1194 端口映射到公网上，以下是 OpenVPN 的搭建过程。

#### 1、安装前准备

* 关闭 `selinux`

```shell
setenforce 0
sed -i '/^SELINUX=/c\SELINUX=disabled' /etc/selinux/config
```

* 安装 `openssl` 和 `lzo`，`lzo` 用于压缩通讯数据，加快数据的传输速度

```shell
yum -y install openssl openssl-devel
yum -y install lzohell
```

* 安装 `epel` 源

```shell
rpm -ivh http://mirrors.sohu.com/fedora-epel/6/x86_64/epel-release-6-8.noarch.rpm
sed -i 's/^mirrorlist=https/mirrorlist=http/' /etc/yum.repos.d/epel.repo
```

#### 2、安装及配置 OpenVPN 和 easy-rsa

* 安装 `openvpn` 和 `easy-rsa`

```shell
yum -y install openvpn easy-rsa
```

* 修改 `vars` 文件

```shell
cd /usr/share/easy-rsa/2.0/
vim vars
```

{% code title="vars" %}

```shell
# 修改注册信息，比如公司地址、公司名称、部门名称等。
export KEY_COUNTRY="CN"
export KEY_PROVINCE="Beijing"
export KEY_CITY="Beijing"
export KEY_ORG="xianda365"
export KEY_EMAIL="774247851@qq.com"
export KEY_OU="Tech"
```

{% endcode %}

* 初始化环境变量

```shell
source vars
```

* 清除 `keys` 目录下所有与证书相关的文件

> 下面步骤生成的证书和密钥都在 `/usr/share/easy-rsa/2.0/keys` 目录里

```shell
./clean-all
```

* 生成根证书 `ca.crt` 和根密钥 `ca.key`（一路按回车即可）

```shell
./build-ca
```

* 为**服务端**生成证书和密钥（一路按回车，直到提示需要输入y/n时，输入y再按回车，一共两次）

```shell
./build-key-server server
```

* 为**客户端**生成证书和密钥（一路按回车，直到提示需要输入y/n时，输入y再按回车，一共两次）

```shell
./build-key client
```

* 创建迪菲·赫尔曼密钥，会生成 `dh2048.pem` 文件（生成过程比较慢，在此期间不要去中断它）

```shell
./build-dh
```

* 生成 `ta.key` 文件（防 DDos 攻击、UDP 淹没等恶意攻击）

```shell
openvpn --genkey --secret keys/ta.key
```

#### 3、创建服务器端配置文件

* 在 openvpn 的配置目录下新建一个 `keys` 目录

```shell
mkdir /etc/openvpn/keys
```

* 将需要用到的 openvpn 证书和密钥复制一份到刚创建好的 `keys` 目录中

```shell
cp /usr/share/easy-rsa/2.0/keys/{ca.crt,server.{crt,key},dh2048.pem,ta.key} /etc/openvpn/keys/
```

* 复制一份服务器端配置文件模板 `server.conf` 到 `/etc/openvpn/`

```shell
cp /usr/share/doc/openvpn-2.3.12/sample/sample-config-files/server.conf /etc/openvpn/
```

* 查看 `server.conf` 里的配置参数

```shell
grep '^[^#;]' /etc/openvpn/server.conf
```

* 编辑 `server.conf`

```
vim /etc/openvpn/server.conf
```

{% code title="server.conf" %}

```shell
port 1194
# 改成tcp，默认使用udp，如果使用HTTP Proxy，必须使用tcp协议
proto tcp
dev tun
# 路径前面加keys，全路径为/etc/openvpn/keys/ca.crt
ca keys/ca.crt
cert keys/server.crt
key keys/server.key  # This file should be kept secret
dh keys/dh2048.pem
# 默认虚拟局域网网段，不要和实际的局域网冲突即可
server 192.168.20.0 255.255.255.0
ifconfig-pool-persist ipp.txt
# VPN服务器所在的内网的网段
push "route 192.168.10.0 255.255.255.0"
# 让客户端所有的流量都通过VPN转发(全局模式)
push "redirect-gateway def1 bypass-dhcp"
# 可以让客户端之间相互访问直接通过openvpn程序转发
client-to-client
# 如果客户端都使用相同的证书和密钥连接VPN，一定要打开这个选项，否则每个证书只允许一个人连接VPN
duplicate-cn
keepalive 10 120
tls-auth keys/ta.key 0 # This file is secret
comp-lzo
persist-key
persist-tun
# OpenVPN的状态日志，默认为/etc/openvpn/openvpn-status.log
status openvpn-status.log
# OpenVPN的运行日志，默认为/etc/openvpn/openvpn.log 
log-append openvpn.log
# 改成verb 5可以多查看一些调试信息
verb 5
```

{% endcode %}

#### 4、配置内核和防火墙，启动服务

> 路由转发功能由 iptables 服务实现，不可将 iptables 服务关闭。

* 开启路由转发功能

```shell
sed -i '/net.ipv4.ip_forward/s/0/1/' /etc/sysctl.conf
sysctl -p
```

* 配置防火墙

```shell
iptables -I INPUT -p tcp --dport 1194 -m comment --comment "openvpn" -j ACCEPT
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -j MASQUERADE
service iptables save
vim /etc/sysconfig/iptables
```

{% code title="iptables" %}

```shell
# 在配置中注释此行，否则路由转发功能不可用
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
```

{% endcode %}

* 启动 `openvpn` 并设置为开机启动

```shell
service openvpn start
chkconfig openvpn on
```

#### 5、创建客户端配置文件

* 创建 client 文件夹，复制一份 `client.conf` 模板命名为 `client.ovpn`

> 将之前生成的客户端证书、密钥一起复制到此文件夹中

```shell
mkdir /etc/openvpn/client
cp /usr/share/doc/openvpn-2.3.12/sample/sample-config-files/client.conf /etc/openvpn/client/client.ovpn
cp /usr/share/easy-rsa/2.0/keys/{ca.crt,client.{crt,key},ta.key} /etc/openvpn/client/
```

* 编辑 `client.ovpn`

```
vim client.ovpn
```

{% code title="client.ovpn" %}

```shell
client
dev tun
# 改为tcp
proto tcp
# OpenVPN服务器的外网IP和端口
# 此处已在路由器上将101.254.123.234:8866端口映射到192.168.10.18:1194
remote 101.254.123.234 8866
resolv-retry infinite
nobind
persist-key
persist-tun
ca ca.crt
# client的证书
cert client.crt
# client的密钥
key client.key
ns-cert-type server
# 去掉前面的注释
tls-auth ta.key 1
comp-lzo
verb 3
```

{% endcode %}

* 将 `client` 文件夹打包为 `client.zip` 供客户端使用

```shell
zip -r client.zip /etc/openvpn/client/
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://www.onee.io/blog/ji-yi-ci-da-jian-openvpn-guo-cheng.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
