Ubuntu Server搭建OpenVPN服务器实战

0x00 实验背景

Server:选用腾讯云的云主机  Ubuntu Server 14.04.1 LTS 64位

Client-1:Acer笔记本 Win7 x64系统

Client-2:安卓机小米4  Android 6.0系统(MIUI8)

 

0x01  OpenVPN的背景知识

********以下内容摘自维基百科********

OpenVPN是一个用于创建虚拟专用网络加密通道的软件包,最早由James Yonan编写。OpenVPN允许创建的VPN使用公开密钥、电子证书、或者用户名/密码来进行身份验证。

它大量使用了OpenSSL加密库中的SSLv3/TLSv1协议函数库。

目前OpenVPN能在Solaris、Linux、OpenBSD、FreeBSD、NetBSD、MacOS X与Microsoft Windows以及Android和iOS上运行,并包含了许多安全性的功能。它并不是一个基于Web的VPN软件,也不与IPsec及其他VPN软件包兼容。

OpenVPN的技术核心是虚拟网卡,其次是SSL协议实现。

在OpenVPN中,如果用户访问一个远程的虚拟地址(属于虚拟网卡配用的地址系列,区别于真实地址),则操作系统会通过路由机制将数据包(TUN模式)或数据帧(TAP模式)发送到虚拟网卡上,服务程序接收该数据并进行相应的处理后,会通过SOCKET从外网上发送出去。这完成了一个单向传输的过程,反之亦然。当远程服务程序通过SOCKET从外网上接收到数据,并进行相应的处理后,又会发送回给虚拟网卡,则该应用软件就可以接收到。

OpenVPN所有的通信都基于一个单一的IP端口,默认且推荐使用UDP协议通讯,同时也支持TCP。IANA(InternetAssigned Numbers Authority)指定给OpenVPN的官方端口为1194。OpenVPN 2.0以后版本每个进程可以同时管理数个并发的隧道。OpenVPN使用通用网络协议(TCP与UDP)的特点使它成为IPsec等协议的理想替代,尤其是在ISP(Internet service provider)过滤某些特定VPN协议的情况下。

OpenVPN连接能通过大多数的代理服务器,并且能够在NAT的环境中很好地工作。

服务端具有向客户端“推送”某些网络配置信息的功能,这些信息包括:IP地址、路由设置等。

OpenVPN提供了两种虚拟网络接口:通用Tun/Tap驱动,通过它们,可以创建三层IP隧道,或者虚拟二层以太网,后者可以传送任何类型的二层以太网络数据。

传送的数据可通过LZO算法压缩。


0x02  Server端的配置

由于UbuntuServer的默认登录用户是ubuntu,并不是root,而后续实验过程需要root权限完成,所以先使用sudo命令临时获得root权限,为了方便,本文直接使用sudo –i保证后续都是root身份。

首先,安装OpenVPN软件和easy-rsa软件:

apt-get install openvpn
apt-get install easy-rsa

安装成功后,拷贝“easy-rsa”到openvpn文件夹,并进入到该目录:

mkdir /etc/openvpn/easy-rsa
cp -r /usr/share/easy-rsa /etc/openvpn/easy-rsa
mv /etc/openvpn/easy-rsa/easy-rsa /etc/openvpn/easy-rsa/2.0
cd /etc/openvpn/easy-rsa/2.0

拷贝已有的openssl配置文件到本目录下:

cp openssl-1.0.0.cnf openssl.cnf

然后配置后续证书及密钥生成的变量文件(vars),这里采用vim命令编辑文件,有图形界面的可以直接用文本编辑器打开。

vim vars

修改以下信息:

export KEY_COUNTRY="CN"
export KEY_PROVINCE="BJ"
export KEY_CITY="BeiJing"
export KEY_ORG="BUAA"
export KEY_EMAIL="liuyonggang@horizoner.ren"
export KEY_OU="server"
export KEY_CN="server"

编辑完成后:wq命令保存并退出,现在可以加载该环境变量了:

source ./vars

之后要清空旧的证书和密钥,以及生成新密钥的序列号和索引文件:

./clean-all

上述都是准备工作啦,接下来进入到搭建CA并签发证书的操作了,先搭建CA,生成根证书:

./build-ca

由于之前已经编辑过vars文件,所以这里我们按照屏幕提示的对话一路回车确认即可。

接下来生成server的密钥:

./build-key-server server

这里的流程同上,Common Name参数推荐改成server然后回车确认,最后两个关于“签署证书”和“提交”的问题,我们必须回答“yes”。

然后生成Diffie-Hellman密钥,时间大概1分钟,耐心等待即可:

./build-dh

生成ta.key密钥,该密钥用于TLS验证,提高服务器本身的安全性:

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

至此,证书生成完毕,我们现在复制所有生成的文件到/etc/openvpn目录下:

cp -r /etc/openvpn/easy-rsa/2.0/keys/ /etc/openvpn/

证书生成完毕后,还需要为服务器端的OpenVPN软件创建一个配置文件,我们可以从sample中拷贝过来,然后根据实际需要修改:

cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz /etc/openvpn/
cd /etc/openvpn
gunzip -d /etc/openvpn/server.conf.gz
编辑server.conf 配置文件:

vim /etc/openvpn/server.conf

需要修改的地方如下:

# 这里是重点,必须指定SSL/TLS root certificate (ca),
# certificate(cert), and private key (key)
# ca文件是服务端和客户端都必须使用的,但不需要ca.key
# 服务端和客户端指定各自的.crt和.key
# 请注意路径,可以使用以配置文件开始为根的相对路径,
# 也可以使用绝对路径
# 请小心存放.key密钥文件
ca /etc/openvpn/keys/ca.crt
cert /etc/openvpn/keys/server.crt
key /etc/openvpn/keys/server.key
dh /etc/openvpn/keys/dh2048.pem
# 取消前面的;注释,这样可以使客户端的所有流量都必须经过VPN转发
push "redirect-gateway def1 bypass-dhcp"
# 取消前面的;注释,并设置DNS服务器的地址,该DNS信息将推送到
# 客户端并设置到TAP网卡中,我选用了百度公共DNS地址180.76.76.76
push "dhcp-option DNS 180.76.76.76" 
# 取消前面的;注释,使客户端之间可以互通,根据实际需要决定是否
# 开启,默认客户端之间是不能直接通讯的
client-to-client
duplicate-cn
user nobody
group nogroup
# 取消前面的;注释,并设置log保存的位置
log   /var/log/openvpn.log

OpenVPN自身的配置到此结束,但在使用前还必须开启Linux系统的路由转发功能:

vim /etc/sysctl.conf

找到 “#net.ipv4.ip_forward=1” 这一行,删除那个 “#” 号,然后保存退出。接下来使转发生效:

sysctl –p

如果一切正常,你将只会看到以下结果:

net.ipv4.ip_forward=1

然后设置iptables规则,通过配置NAT将VPN网段IP转发到eth0网卡:

iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j SNAT --to 119.29.96.172 (适用于固定IP的VPS)

或者

iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE (通用方法,自动获取eth0网卡的IP地址)

以上两条命令二选一即可!

设置OpenVPN端口通过:

iptables -A INPUT -p TCP --dport 1194 -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

上述工作完成后,还需要在腾讯云的控制台安全组策略中进行设置,开放1194端口。添加协议为UDP,端口号:1194,入站出站均允许通过。

 

一切就绪!开启OpenVPN服务吧:

service openvpn restart

0x03  Windows客户端的配置(Client-1)

首先下载OpenVPN软件,此处可能需要科学上网。先给出官网下载页面的地址:

https://openvpn.net/index.php/open-source/downloads.html

如果您是64位Windows系统,可以直接下载我分享的openvpn-install-2.3.11-I601-x86_64  百度云地址如下:

链接:http://pan.baidu.com/s/1hsnsljY    密码:eqj7

安装过程就不赘述了。

然后将服务器端生成的证书和密钥文件(ca.crt,client.crt,client.key,ta.key)下载到本地。我这里使用WinSCP软件,SSH登录腾讯云服务器,安装openssl后即可支持SFTP传输协议。

进入客户端OpenVPN目录,将sample-config下的client.ovpn文件复制到config目录,并修改以下信息来设置服务器的IP和端口号:

remote 119.29.96.172 1194

现在可以以管理员身份运行OpenVPN GUI应用了,之后右键屏幕右下角的系统托盘区应用图标,选择Connect即可连接。过一会儿,OpenVPN图标变成绿色就是连接成功了。


0x04  Android客户端的配置(Client-2)

首先获取OpenVPN for Android的应用,两种方式,可以去github上下载源码自行使用Android Studio编译,也可以从Google Play上下载官方发布的APP,为了下载方便,我已将官方发布的APP放在了百度云上。

OpenVPN for Android开源项目地址:

https://github.com/schwabe/ics-openvpn

懒得编译的可以直接下载:

链接:http://pan.baidu.com/s/1boW7ykZ  密码:nd91

 

Android客户端需要的文件清单如下:

ca.crt,(从服务器获取)

dh2048.pem, (从服务器获取)

client.crt, (从服务器获取)

client.key, (从服务器获取)

client.ovpn (安卓客户端配置文件,参考以下内容自行编辑)

client tls-client
dev tun
proto udp
# 远程 OpenVPN 服务器的 IP 和 端口号
remote 111.222.333.444 1194
resolv-retry infinite
nobind
ca ca.crt
cert client.crt
key client.key
dh dh2048.pem
persist-tun
persist-key
verb 3
mute 20

复制以上所有文件到Android设备的存储卡中,然后在手机上尝试打开client.ovpn文件,文件类型选择文本文件,之后就会弹出导入OpenVPN的选项,点击即可将配置信息成功导入到OpenVPN中(前提是已经安装了OpenVPN APP)。此时打开OpenVPN APP,就可以成功连接VPN了。


祝大家顺利!我懒得放图了,不要打我。。。


参考文献:

https://docs.ucloud.cn/software/vpn/OpenVPN4Ubuntu.html

https://boweihe.me/?p=1313

https://zh.wikipedia.org/wiki/OpenVPN








































本页内容版权归属为原作者,如有侵犯您的权益,请通知我们删除。

逐步深入TCP/IP协议栈 - 2016-07-24 14:07:36

一、关于应用层用户数据的历程,见下图:                                                                             TCP/IP数据包的封装 过程: 应用层将数据通过协议栈逐层向下传递,其下的每层接到来自上层的数据时,根据每层的协议都要在其数据 的前端添加首部信息进行封装。不同的协议层对数据包有不同 的称谓,在传输层叫做数据段,在网络层叫做数据报, 在链路层叫做数据帧。在经过链路层时,数据已经封装成帧并递交给物理层的传输介质上,到

Java事务--JTA原理 - 2016-07-23 19:07:54

        上一篇文章介绍了JDBC事务,JDBC可以处理单数据源的事务,满足大部分事务处理的需求,但是JDBC事务不能解决多数据源和分布式事务问题,Java平台给我们提供了解决方案--JTA。本文将探讨JTA的一些细节。          一 分布式事务          通常把一个数据库内部的事务处理,如对多个表的操作,作为本地事务看待。数据库和JDBC的事务处理对象是本地事务,而分布式事务处理的对象是全局事务。          所谓全局事务,是指分布式事务处理环境中,多个数据库可能需要共同完成
LINUX下SVN安装,配置,web目录同步 注: 各服务器运行环境可能有所不同,操作过程中可能出现其他问题,自行查阅资料解决 SVN的具体使用方法很多,本文档只是使用了SVN最简单的用法,感兴趣的同学可以查阅相关资料。 一、 安装subversion 首先输入rpm -qa | grep subversion 查看SVN是否已经安装过 如果输出类似如下结果,则说明已经安装:subversion-1.6.11-7.el6.x86_64 执行 yum -y install subversion 安装SVN
一、目录结构 首先是目录结构如图: 二、pom.xml文件 project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd" modelVersion4.0.0/modelVe

Linux内核之进程管理 - 2016-07-23 19:07:13

进程: 进程就是处于执行期的程序以及它包含的资源总和。 线程是进程中的活动对象,每个线程拥有一个独立的程序计数器、进程栈和一组进程寄存器。 内核调度的是线程,而不是进程。 进程描述符: 内核的进程描述符为 task_struct 结构体,定义在linux/sched.h,进程描述符包含了一个进程的所有信息。包括:进程标识符、进程当前状态、栈地址空间、内存地址空间、文件系统、打开的文件、信号量等。 内核把进程的列表存放在叫做 任务列表(task list) 的双向循环链表,链表中每一项都是类型为task_s

SSH权限管理控制到按钮 - 2016-07-23 19:07:11

数据库设计 我的设计如下: 用户:fu_admin 角色:sys_role 权限:sys_purview 用户-角色:sys_user_role 角色-权限:sys_role_purview 标准的权限管理系统设计为以上5张表。 注:用户、用户-角色我就不做说明了,这两个是很简单的两块,用户的crud,以及为用户分配角色(多对多的关系)稍微琢磨一下就清楚了, 下面都是针对为角色分配权限的实现 后台实现 展示层采用ztree树 roleList.jsp !DOCTYPE html PUBLIC "-//W3

docker容器扫盲 - 2016-07-23 18:07:08

Centos 6.5 安装和使用docker 基于本人一贯的习惯,关于“某某某是什么”这样的问题,请百度吧,会有更专业的人士,会比我说的更详细更深,这里我只给出本人亲历的安装和使用过程。 1.安装 先检查服务器环境,docker要求操作系统CentOS6以上,kernel 版本必须2.6.32-431或更高,即=CentOS 6.5,运行docker时实际提示3.8.0及以上,必须64bit,32bit不支持docker。 [root @201 ~] # uname -r 2.6 .32 - 642.1
 原文地址: https://yq.aliyun.com/articles/57901?spm=5176.100239.blogcont57826.25.oaM83B 摘要:   在阿里巴巴在线在线技术峰会上的第三天,来自阿里云高级技术专家李金波为大家题为《企业大数据平台仓库架构建设思路》。本次分享中,李金波主要从总体思路、模型设计、数加架构、数据治理四个方面介绍了如何利用大数据平台的特性,构建更贴合大数据应用的数据仓库。 本文根据阿里云高级技术专家李金波在首届阿里巴巴在线峰会的《企业大数据平台仓库架

linux教程——1.启动过程 - 2016-07-23 17:07:29

Linux  系统启动过程 linux启动时我们会看到许多启动信息。 Linux系统的启动过程并不是大家想象中的那么复杂,其过程可以分为5个阶段: 内核的引导。 运行init。 系统初始化。 建立终端 。 用户登录系统。 内核引导 当计算机打开电源后,首先是BIOS开机自检,按照BIOS中设置的启动设备(通常是硬盘)来启动。 操作系统接管硬件以后,首先读入 /boot 目录下的内核文件。 运行init init 进程是系统所有进程的起点,你可以把它比拟成系统所有进程的老祖宗,没有这个进程,系统中任何进程都
用一种分布式处理方法 挖掘分布式系统检测到的事件联系   点击下载演示文档 abstract: 现在,对监控、分析和控制大规模分布式系统的需求越来越高涨。监控下的事件往往呈现出相关联的关系,这对资源分配、工作调度还有故障预测有很大帮助。为了发现在检测到的事件中的联系,很多已有的方法是把被检测事件放到数据库中并对其进行数据挖掘。但是我们认为这些方法并不适合大规模分布式系统,因为监控事件的数据量增长得非常快以至于很难用一台计算机的力量来进行事件之间联系的发现。在本文中,我们提出了一种分布式的方法有效地检测事件