CentOS下OpenVPN实现公网IP映射到内网(iptables转发功能)(转)

Stella981
• 阅读 3872

说明:这种方案的实现前提是必须要有一台拥有公网IP的电脑,OpenVPN搭建过程很普通,关键技术在于iptables的转发。搭建教程可能有点旧了,可以只看iptables的关键点技术。

方案背景:

公司办公网络使用长城宽带上网有一段时间了,有4个固定IP(2个电信,2个网通),链路不太稳定,经常有问题,因此考虑取消长城宽带,采用原来的adsl上网。但是有个问题,因为公司内网有几台服务器,需要通过固定IP接受外网用户发送的数据,因此如果没有公网IP,而ADSL获取的IP会变化,那么内网服务器接受外面用户的数据就会受到影响,通过采用OpenVPN很好的解决了这个问题。这个前提是你在机房的服务器有固定IP。

应用场景

公司在托管机房有公网IP,在公司内部采用ADSL上网,又需要接受外网用户发送的数据,那么就可以在托管机房有公网IP的服务器部署OpenVPN,然后内网找一台服务器拨上去获取IP后,通过iptables的端口转发2次就可以完美解决公司网络没有公网IP的问题。

详细方案

下面就来详细讲述如何用OpenVPN完美的解决公司网络没有公网IP的解决方案!

一、 需求

在没有固定公网IP的情况下,借助托管机房的固定公网IP,实现发布内网服务器的端口给外网用户调用,具体环境如下面网络图中所示,需要把内网服务器192.168.100.113的708端口借助托管机房的固定IP发布给外网用户调用

二、 网络图

CentOS下OpenVPN实现公网IP映射到内网(iptables转发功能)(转)

三、OpenVPN****服务器的安装配置

1、OpenVPN服务器端的环境

OS: CentOS 5.5 64bit 2.6.18

lzo version: 2.0.6(最新版本)

OpenVPN version: 2.2.2(最新版本)

2、OpenVPN服务器端软件的安装

下载软件包

wget http://www.oberhumer.com/opensource/lzo/download/lzo-2.06.tar.gz
wget http://swupdate.openvpn.org/community/releases/openvpn-2.2.2.tar.gz

安装openssl

yum -y install openssl

记录下openssl的版本号,一会有用,我这里安装的openssl-0.9.8e-20.el5.x86_64版本

安装lzo

tar xzvf lzo-2.06.tar.gz
cd lzo-2.06
./configure
make && make check && make install

安装OpenVPN

tar xzvf openvpn-2.2.2.tar.gz
cd openvpn-2.2.2
./configure --prefix=/usr/local/openvpn --with-lzo-headers=/usr/local/include --with-lzo-lib=/usr/local/lib \
--with-ssl-headers=/usr/local/include/openssl --with-ssl-lib=/usr/local/lib
make && make install

3、制作OpenVPN证书key

初始话PKI

生成key变量可以采用export或者需改配置文件的形式,这里我只说采用export命令的形式!代码如下:

cd openvpn-2.2.2/easy-rsa/2.0    #注意这个路径和以前的版本不太一样
cp openssl-0.9.8.cnf openssl.cnf   #这里有三个版本的openssl的文件供你选择,这里需要选择前面我们安装的openssl版本
export D=`pwd`                        #设置路径
export KEY_CONFIG=$D/openssl.cnf       #设置openssl文件的位置
export KEY_DIR=$D/keys                 #设置生成key的保存路径
export KEY_SIZE=1024                                #设置生成key的加密位数
export KEY_COUNTRY=CN                #设置国家
export KEY_PROVINCE=GD                #设置省
export KEY_CITY=SZ                      #设置城市
export KEY_ORG="jsoft"               #设置组织
export KEY_EMAIL=easonjim@163.com  #设置邮箱./clean-all    #这个命令执行完成以后会创建前面设置的key保存路径  

生成ca证书和私钥

./build-ca    #执行这个命令以后按照提示操作就可以了!一路回车

生成Server端证书和私钥

./build-key-server server   #执行这个命令以后按照提示操作就可以了!一路回车,最后两个yes

生成客户端证书和私钥

/build-key client1     #client1为客户端的登录名,按照提示操作,一路回车,最后两个yes

打包证书和私钥

./build-dh     #通过这个命令创建Diffie Hellman参数

tar zcvf key.tar.gz keys
#将生成的key.tar.gz下载备用

4、OpenVPN服务器端配置

mkdir /usr/local/openvpn/etc
mkdir /usr/local/openvpn/keys/

将前面生成的如下key文件和证书文件拷到/usr/local/openvpn/keys目录下:

ca.crt、server.crt、server.key、dh1024.pem

vim /usr/local/openvpn/etc/server.conf

添加如下内容

local 58.33.123.75
client-config-dir /usr/local/openvpn/etc/ccd       #介绍一下这个选项,这个选项是为制定的登录名使用单独的配置,比如制定固定的IP,本文就用到了这个配置,在这个目录下,创建一个用户名文件,然后写入你的需求配置,稍后会介绍
port 1194
proto udp
dev tun
ca /usr/local/openvpn/keys/ca.crt
cert /usr/local/openvpn/keys/server.crt
key /usr/local/openvpn/keys/server.key 
dh /usr/local/openvpn/keys/dh1024.pem
server 172.16.100.0 255.255.255.0
ifconfig-pool-persist ipp.txt
push "route 172.16.88.0 255.255.255.0"
push "route 172.16.100.0 255.255.255.0"
push "dhcp-option DNS 172.16.88.10"
client-to-client
keepalive 10 120
comp-lzo
persist-key
persist-tun
status /var/log/openvpn-status.log
log         /var/log/openvpn.log
verb 4

vim  /usr/local/openvpn/etc/ccd/client1

添加如下内容:

ifconfig-push 172.16.100.9 172.16.100.10
可能有人会想为什么要制定两个IP,这是因为openvpn只支持255.255.255.252 的子网,而且252的子网只有两个IP,一个分配给客户端,一个留给服务器用.因此只能ccd目录下面的文件内容只能是:
ifconfig-push 172.16.100.1 172.16.100.2
ifconfig-push 172.16.100.5 172.16.100.6  …..

如果配置错误,会报如下错误:

Tue Jan 10 18:02:33 2012 us=197724 read UDPv4 [ECONNREFUSED]: Connection refused (code=111)

启动OpenVPN服务端:

/usr/local/openvpn/sbin/openvpn --config /usr/local/openvpn/etc/server.conf > /dev/null 2>&1 &

然后将该命令写入到/etc/rc.local中      

查看是否启动成功:

netstat -lnp | grep openvpn
udp        0      0  58.33.123.75:1194          0.0.0.0:*                              11545/openvpn

四、OpenVPN****客户端的安装配置

1、OpenVPN客户端的环境

客户端的环境和服务器端的环境一样

OS: CentOS 5.5 64bit 2.6.18

lzo version: 2.0.6(最新版本)

OpenVPN version: 2.2.2(最新版本)

2、OpenVPN客户端的安装

安装也和服务器的一样,这里就不赘述

3、OpenVPN客户端的配置

mkdir /usr/local/openvpn/etc
mkdir /usr/local/openvpn/keys/

将需要的前面打包的相关key文件放到keys目录下,比如client1用户需要copy到客户端的文件如下:

ca.crt ca.key client1.crt client1.csr client1.key

vim /usr/local/openvpn/etc/client.conf

添加如下内容:

client
dev tun
proto udp
remote 58.33.123.75 1194
persist-key
persist-tun
ca /usr/local/openvpn/keys/ca.crt
cert /usr/local/openvpn/keys/client2.crt
key /usr/local/openvpn/keys/client2.key
ns-cert-type server
comp-lzo
verb 4 

启动客户端:

/usr/local/openvpn/sbin/openvpn --config /usr/local/openvpn/etc/client.conf > /dev/null 2>&1 &

并将该命令写入/etc/rc.local 

检查是否链接成功,已经分配的IP是否是制定的IP

ifconfig

显示如下内容:

tun0      Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 
          inet addr:172.16.100.9  P-t-P:172.16.100.10  Mask:255.255.255.255

五、OpenVPN服务器端iptables****的设置(关键设置)

配置支持转发

# 开启路由转发功能
sed -i '/net.ipv4.ip_forward/s/0/1/' /etc/sysctl.conf
sysctl -p

配置iptables转发规则

iptables -t nat -A PREROUTING -d 58.33.123.75 -p tcp -m tcp --dport 708 -j DNAT --to-destination 172.16.100.9:708
iptables -t nat -A POSTROUTING -j MASQUERADE
iptables -A INPUT -p udp -m udp --dport 1194 -j ACCEPT
iptables -A  INPUT -s 172.16.100.0/255.255.255.0 -j ACCEPT

说明:将外面请求机房中58.33.123.75端口708的请求都发往公司内网的VPN客户端,打开OpenVPN的1194端口,允许网段的访问!

六、OpenVPN客户端iptables****的设置(关键设置)

配置支持转发

# 开启路由转发功能
sed -i '/net.ipv4.ip_forward/s/0/1/' /etc/sysctl.conf
sysctl -p

配置iptables转发规则 

iptables -t nat -A PREROUTING -s 58.33.123.75 -p tcp -m tcp --dport 708 -j DNAT --to-destination 192.168.100.113:708
iptables -t nat -A POSTROUTING -j MASQUERADE

说明:将源是来自58.33.123.75并且目标端口为708的请就转发到内网的192.168.100.113的708端口,这就完成了整个转发过程

七、测试端口调用是否OK

因为发布的tcp的端口,因此可以采用telnet的方式来调用,在外网找台机器,执行如下命令看看是否OK!

telnet 58.33.123.75 708

如果不能连接,就需要检查VPN是否OK。Ping是个很好的工具,以及检查防火墙规则

参考:

http://blog.chinaunix.net/uid-20639775-id-3123671.html(以上内容转自此篇文章)

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Stella981 Stella981
2年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Easter79 Easter79
2年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
2年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
2年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
2年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
3个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这