12.1 概述
随着云计算的普及,将OpenVPN与各种云服务集成已成为企业网络架构的重要组成部分。本章将探讨如何在主流云平台上部署OpenVPN,以及如何将OpenVPN与云服务集成,实现安全、高效的混合云网络架构。
graph TD
A[OpenVPN与云服务集成] --> B[主流云平台部署]
A --> C[混合云网络架构]
A --> D[云原生部署模式]
A --> E[自动化与编排]
A --> F[安全与合规]
A --> G[监控与管理]
A --> H[灾备与高可用]
B --> B1[AWS部署]
B --> B2[Azure部署]
B --> B3[GCP部署]
B --> B4[阿里云部署]
C --> C1[站点到云VPN]
C --> C2[多云连接]
C --> C3[云间网络隔离]
D --> D1[容器化部署]
D --> D2[Kubernetes集成]
D --> D3[Serverless VPN]
E --> E1[基础设施即代码]
E --> E2[CI/CD管道集成]
E --> E3[自动扩展配置]
F --> F1[云平台安全组配置]
F --> F2[IAM集成]
F --> F3[合规性考量]
G --> G1[云监控集成]
G --> G2[日志聚合与分析]
G --> G3[性能监控]
H --> H1[跨区域部署]
H --> H2[灾难恢复策略]
H --> H3[自动故障转移]
12.2 主流云平台部署
12.2.1 AWS部署
在AWS上部署OpenVPN服务器:
#!/bin/bash
# aws_openvpn_deploy.sh
# 设置变量
REGION="us-east-1"
VPC_CIDR="10.0.0.0/16"
SUBNET_CIDR="10.0.1.0/24"
AVAILABILITY_ZONE="us-east-1a"
INSTANCE_TYPE="t3.small"
KEY_NAME="openvpn-key"
AMI_ID="ami-0c55b159cbfafe1f0" # Amazon Linux 2 AMI ID
VPN_NETWORK="172.16.0.0/24"
# 创建VPC
echo "创建VPC..."
VPC_ID=$(aws ec2 create-vpc \
--cidr-block $VPC_CIDR \
--region $REGION \
--query 'Vpc.VpcId' \
--output text)
aws ec2 create-tags \
--resources $VPC_ID \
--tags Key=Name,Value=OpenVPN-VPC \
--region $REGION
echo "VPC创建完成: $VPC_ID"
# 创建互联网网关
echo "创建互联网网关..."
IGW_ID=$(aws ec2 create-internet-gateway \
--region $REGION \
--query 'InternetGateway.InternetGatewayId' \
--output text)
aws ec2 create-tags \
--resources $IGW_ID \
--tags Key=Name,Value=OpenVPN-IGW \
--region $REGION
# 将互联网网关附加到VPC
aws ec2 attach-internet-gateway \
--internet-gateway-id $IGW_ID \
--vpc-id $VPC_ID \
--region $REGION
echo "互联网网关创建并附加完成: $IGW_ID"
# 创建子网
echo "创建子网..."
SUBNET_ID=$(aws ec2 create-subnet \
--vpc-id $VPC_ID \
--cidr-block $SUBNET_CIDR \
--availability-zone $AVAILABILITY_ZONE \
--region $REGION \
--query 'Subnet.SubnetId' \
--output text)
aws ec2 create-tags \
--resources $SUBNET_ID \
--tags Key=Name,Value=OpenVPN-Subnet \
--region $REGION
echo "子网创建完成: $SUBNET_ID"
# 创建路由表
echo "创建路由表..."
ROUTE_TABLE_ID=$(aws ec2 create-route-table \
--vpc-id $VPC_ID \
--region $REGION \
--query 'RouteTable.RouteTableId' \
--output text)
aws ec2 create-tags \
--resources $ROUTE_TABLE_ID \
--tags Key=Name,Value=OpenVPN-RouteTable \
--region $REGION
# 创建到互联网的路由
aws ec2 create-route \
--route-table-id $ROUTE_TABLE_ID \
--destination-cidr-block 0.0.0.0/0 \
--gateway-id $IGW_ID \
--region $REGION
# 将路由表与子网关联
aws ec2 associate-route-table \
--route-table-id $ROUTE_TABLE_ID \
--subnet-id $SUBNET_ID \
--region $REGION
echo "路由表创建并配置完成: $ROUTE_TABLE_ID"
# 创建安全组
echo "创建安全组..."
SECURITY_GROUP_ID=$(aws ec2 create-security-group \
--group-name OpenVPN-SG \
--description "Security group for OpenVPN server" \
--vpc-id $VPC_ID \
--region $REGION \
--query 'GroupId' \
--output text)
aws ec2 create-tags \
--resources $SECURITY_GROUP_ID \
--tags Key=Name,Value=OpenVPN-SG \
--region $REGION
# 配置安全组规则
aws ec2 authorize-security-group-ingress \
--group-id $SECURITY_GROUP_ID \
--protocol tcp \
--port 22 \
--cidr 0.0.0.0/0 \
--region $REGION
aws ec2 authorize-security-group-ingress \
--group-id $SECURITY_GROUP_ID \
--protocol udp \
--port 1194 \
--cidr 0.0.0.0/0 \
--region $REGION
aws ec2 authorize-security-group-ingress \
--group-id $SECURITY_GROUP_ID \
--protocol tcp \
--port 443 \
--cidr 0.0.0.0/0 \
--region $REGION
echo "安全组创建并配置完成: $SECURITY_GROUP_ID"
# 创建EC2实例
echo "创建EC2实例..."
INSTANCE_ID=$(aws ec2 run-instances \
--image-id $AMI_ID \
--instance-type $INSTANCE_TYPE \
--key-name $KEY_NAME \
--security-group-ids $SECURITY_GROUP_ID \
--subnet-id $SUBNET_ID \
--associate-public-ip-address \
--user-data file://openvpn_userdata.sh \
--region $REGION \
--query 'Instances[0].InstanceId' \
--output text)
aws ec2 create-tags \
--resources $INSTANCE_ID \
--tags Key=Name,Value=OpenVPN-Server \
--region $REGION
echo "EC2实例创建完成: $INSTANCE_ID"
# 等待实例运行
echo "等待实例运行..."
aws ec2 wait instance-running \
--instance-ids $INSTANCE_ID \
--region $REGION
# 获取实例公共IP
PUBLIC_IP=$(aws ec2 describe-instances \
--instance-ids $INSTANCE_ID \
--region $REGION \
--query 'Reservations[0].Instances[0].PublicIpAddress' \
--output text)
echo "OpenVPN服务器部署完成!"
echo "服务器公共IP: $PUBLIC_IP"
echo "使用以下命令连接到服务器:"
echo "ssh -i $KEY_NAME.pem ec2-user@$PUBLIC_IP"
echo "OpenVPN配置将在约5-10分钟后完成"
echo "完成后,您可以使用SCP下载客户端配置文件:"
echo "scp -i $KEY_NAME.pem ec2-user@$PUBLIC_IP:/home/ec2-user/client.ovpn ."
用户数据脚本 openvpn_userdata.sh
:
#!/bin/bash
# openvpn_userdata.sh
# 更新系统并安装依赖
yum update -y
yum install -y epel-release
yum install -y openvpn easy-rsa
# 设置Easy-RSA
cp -r /usr/share/easy-rsa/3.0/* /etc/openvpn/
cd /etc/openvpn
# 初始化PKI
./easyrsa init-pki
# 创建CA(无需交互)
EASYRSA_BATCH=1 ./easyrsa build-ca nopass
# 创建服务器证书和密钥
EASYRSA_BATCH=1 ./easyrsa build-server-full server nopass
# 创建Diffie-Hellman参数
./easyrsa gen-dh
# 创建TLS认证密钥
openvpn --genkey --secret /etc/openvpn/pki/ta.key
# 创建客户端证书和密钥
EASYRSA_BATCH=1 ./easyrsa build-client-full client nopass
# 配置OpenVPN服务器
cat > /etc/openvpn/server.conf << EOF
port 1194
proto udp
dev tun
ca /etc/openvpn/pki/ca.crt
cert /etc/openvpn/pki/issued/server.crt
key /etc/openvpn/pki/private/server.key
dh /etc/openvpn/pki/dh.pem
tls-auth /etc/openvpn/pki/ta.key 0
server 172.16.0.0 255.255.255.0
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 8.8.8.8"
push "dhcp-option DNS 8.8.4.4"
keepalive 10 120
cipher AES-256-GCM
auth SHA256
compress lz4-v2
push "compress lz4-v2"
user nobody
group nobody
persist-key
persist-tun
status /var/log/openvpn/status.log
log-append /var/log/openvpn/openvpn.log
verb 3
EOF
# 创建日志目录
mkdir -p /var/log/openvpn
# 创建客户端配置
cat > /home/ec2-user/client.ovpn << EOF
client
dev tun
proto udp
remote $(curl -s http://169.254.169.254/latest/meta-data/public-ipv4) 1194
resolv-retry infinite
nobind
persist-key
persist-tun
remote-cert-tls server
cipher AES-256-GCM
auth SHA256
compress lz4-v2
verb 3
<ca>
$(cat /etc/openvpn/pki/ca.crt)
</ca>
<cert>
$(cat /etc/openvpn/pki/issued/client.crt)
</cert>
<key>
$(cat /etc/openvpn/pki/private/client.key)
</key>
<tls-auth>
$(cat /etc/openvpn/pki/ta.key)
</tls-auth>
key-direction 1
EOF
# 设置权限
chown ec2-user:ec2-user /home/ec2-user/client.ovpn
chmod 600 /home/ec2-user/client.ovpn
# 启用IP转发
echo "net.ipv4.ip_forward = 1" > /etc/sysctl.d/99-openvpn.conf
sysctl -p /etc/sysctl.d/99-openvpn.conf
# 配置iptables
iptables -t nat -A POSTROUTING -s 172.16.0.0/24 -o eth0 -j MASQUERADE
# 保存iptables规则
yum install -y iptables-services
systemctl enable iptables
service iptables save
# 启动OpenVPN服务
systemctl enable openvpn@server
systemctl start openvpn@server
# 安装Web管理界面(可选)
yum install -y nginx php php-fpm
systemctl enable nginx php-fpm
systemctl start nginx php-fpm
echo "OpenVPN服务器设置完成"
12.2.2 Azure部署
使用Azure CLI部署OpenVPN服务器:
#!/bin/bash
# azure_openvpn_deploy.sh
# 设置变量
RESOURCE_GROUP="OpenVPN-RG"
LOCATION="eastus"
VNET_NAME="OpenVPN-VNet"
SUBNET_NAME="OpenVPN-Subnet"
NSG_NAME="OpenVPN-NSG"
PUBLIC_IP_NAME="OpenVPN-PublicIP"
NIC_NAME="OpenVPN-NIC"
VM_NAME="OpenVPN-Server"
VM_SIZE="Standard_B2s"
ADMIN_USERNAME="azureuser"
VPN_NETWORK="172.16.0.0/24"
# 创建资源组
echo "创建资源组..."
az group create \
--name $RESOURCE_GROUP \
--location $LOCATION
# 创建虚拟网络和子网
echo "创建虚拟网络和子网..."
az network vnet create \
--resource-group $RESOURCE_GROUP \
--name $VNET_NAME \
--address-prefix 10.0.0.0/16 \
--subnet-name $SUBNET_NAME \
--subnet-prefix 10.0.1.0/24
# 创建网络安全组
echo "创建网络安全组..."
az network nsg create \
--resource-group $RESOURCE_GROUP \
--name $NSG_NAME
# 添加安全规则
az network nsg rule create \
--resource-group $RESOURCE_GROUP \
--nsg-name $NSG_NAME \
--name SSH \
--priority 1000 \
--protocol Tcp \
--destination-port-range 22 \
--access Allow
az network nsg rule create \
--resource-group $RESOURCE_GROUP \
--nsg-name $NSG_NAME \
--name OpenVPN-UDP \
--priority 1010 \
--protocol Udp \
--destination-port-range 1194 \
--access Allow
az network nsg rule create \
--resource-group $RESOURCE_GROUP \
--nsg-name $NSG_NAME \
--name HTTPS \
--priority 1020 \
--protocol Tcp \
--destination-port-range 443 \
--access Allow
# 创建公共IP地址
echo "创建公共IP地址..."
az network public-ip create \
--resource-group $RESOURCE_GROUP \
--name $PUBLIC_IP_NAME \
--allocation-method Static
# 创建网络接口
echo "创建网络接口..."
az network nic create \
--resource-group $RESOURCE_GROUP \
--name $NIC_NAME \
--vnet-name $VNET_NAME \
--subnet $SUBNET_NAME \
--network-security-group $NSG_NAME \
--public-ip-address $PUBLIC_IP_NAME
# 生成SSH密钥对
echo "生成SSH密钥对..."
ssh-keygen -t rsa -b 2048 -f ./azure_openvpn_key -N ""
# 创建虚拟机
echo "创建虚拟机..."
az vm create \
--resource-group $RESOURCE_GROUP \
--name $VM_NAME \
--nics $NIC_NAME \
--image UbuntuLTS \
--size $VM_SIZE \
--admin-username $ADMIN_USERNAME \
--ssh-key-value ./azure_openvpn_key.pub \
--custom-data ./azure_openvpn_cloud_init.txt
# 获取公共IP地址
PUBLIC_IP=$(az network public-ip show \
--resource-group $RESOURCE_GROUP \
--name $PUBLIC_IP_NAME \
--query ipAddress \
--output tsv)
echo "OpenVPN服务器部署完成!"
echo "服务器公共IP: $PUBLIC_IP"
echo "使用以下命令连接到服务器:"
echo "ssh -i azure_openvpn_key $ADMIN_USERNAME@$PUBLIC_IP"
echo "OpenVPN配置将在约5-10分钟后完成"
echo "完成后,您可以使用SCP下载客户端配置文件:"
echo "scp -i azure_openvpn_key $ADMIN_USERNAME@$PUBLIC_IP:/home/$ADMIN_USERNAME/client.ovpn ."
Cloud-init配置文件 azure_openvpn_cloud_init.txt
:
#cloud-config
package_update: true
package_upgrade: true
packages:
- openvpn
- easy-rsa
- iptables-persistent
- net-tools
write_files:
- path: /etc/openvpn/setup.sh
permissions: '0755'
content: |
#!/bin/bash
# 设置Easy-RSA
mkdir -p /etc/openvpn/easy-rsa
cp -r /usr/share/easy-rsa/* /etc/openvpn/easy-rsa/
cd /etc/openvpn/easy-rsa
# 初始化PKI
./easyrsa init-pki
# 创建CA(无需交互)
EASYRSA_BATCH=1 ./easyrsa build-ca nopass
# 创建服务器证书和密钥
EASYRSA_BATCH=1 ./easyrsa build-server-full server nopass
# 创建Diffie-Hellman参数
./easyrsa gen-dh
# 创建TLS认证密钥
openvpn --genkey --secret /etc/openvpn/pki/ta.key
# 创建客户端证书和密钥
EASYRSA_BATCH=1 ./easyrsa build-client-full client nopass
# 配置OpenVPN服务器
cat > /etc/openvpn/server.conf << EOF
port 1194
proto udp
dev tun
ca /etc/openvpn/easy-rsa/pki/ca.crt
cert /etc/openvpn/easy-rsa/pki/issued/server.crt
key /etc/openvpn/easy-rsa/pki/private/server.key
dh /etc/openvpn/easy-rsa/pki/dh.pem
tls-auth /etc/openvpn/pki/ta.key 0
server 172.16.0.0 255.255.255.0
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 8.8.8.8"
push "dhcp-option DNS 8.8.4.4"
keepalive 10 120
cipher AES-256-GCM
auth SHA256
compress lz4-v2
push "compress lz4-v2"
user nobody
group nogroup
persist-key
persist-tun
status /var/log/openvpn/status.log
log-append /var/log/openvpn/openvpn.log
verb 3
EOF
# 创建日志目录
mkdir -p /var/log/openvpn
# 获取公共IP地址
PUBLIC_IP=$(curl -s https://api.ipify.org)
# 创建客户端配置
cat > /home/azureuser/client.ovpn << EOF
client
dev tun
proto udp
remote $PUBLIC_IP 1194
resolv-retry infinite
nobind
persist-key
persist-tun
remote-cert-tls server
cipher AES-256-GCM
auth SHA256
compress lz4-v2
verb 3
<ca>
$(cat /etc/openvpn/easy-rsa/pki/ca.crt)
</ca>
<cert>
$(cat /etc/openvpn/easy-rsa/pki/issued/client.crt)
</cert>
<key>
$(cat /etc/openvpn/easy-rsa/pki/private/client.key)
</key>
<tls-auth>
$(cat /etc/openvpn/pki/ta.key)
</tls-auth>
key-direction 1
EOF
# 设置权限
chown azureuser:azureuser /home/azureuser/client.ovpn
chmod 600 /home/azureuser/client.ovpn
# 启用IP转发
echo "net.ipv4.ip_forward = 1" > /etc/sysctl.d/99-openvpn.conf
sysctl -p /etc/sysctl.d/99-openvpn.conf
# 配置iptables
iptables -t nat -A POSTROUTING -s 172.16.0.0/24 -o eth0 -j MASQUERADE
# 保存iptables规则
netfilter-persistent save
netfilter-persistent reload
# 启动OpenVPN服务
systemctl enable openvpn@server
systemctl start openvpn@server
echo "OpenVPN服务器设置完成"
runcmd:
- bash /etc/openvpn/setup.sh
12.2.3 GCP部署
使用Google Cloud CLI部署OpenVPN服务器:
#!/bin/bash
# gcp_openvpn_deploy.sh
# 设置变量
PROJECT_ID="your-project-id"
REGION="us-central1"
ZONE="us-central1-a"
VPC_NAME="openvpn-vpc"
SUBNET_NAME="openvpn-subnet"
SUBNET_RANGE="10.0.0.0/24"
FIREWALL_NAME="openvpn-firewall"
INSTANCE_NAME="openvpn-server"
MACHINE_TYPE="e2-small"
VPN_NETWORK="172.16.0.0/24"
# 设置项目
gcloud config set project $PROJECT_ID
# 创建VPC网络
echo "创建VPC网络..."
gcloud compute networks create $VPC_NAME \
--subnet-mode=custom
# 创建子网
echo "创建子网..."
gcloud compute networks subnets create $SUBNET_NAME \
--network=$VPC_NAME \
--region=$REGION \
--range=$SUBNET_RANGE
# 创建防火墙规则
echo "创建防火墙规则..."
gcloud compute firewall-rules create $FIREWALL_NAME-ssh \
--network=$VPC_NAME \
--allow=tcp:22 \
--source-ranges=0.0.0.0/0 \
--description="Allow SSH from anywhere"
gcloud compute firewall-rules create $FIREWALL_NAME-openvpn \
--network=$VPC_NAME \
--allow=udp:1194 \
--source-ranges=0.0.0.0/0 \
--description="Allow OpenVPN from anywhere"
gcloud compute firewall-rules create $FIREWALL_NAME-https \
--network=$VPC_NAME \
--allow=tcp:443 \
--source-ranges=0.0.0.0/0 \
--description="Allow HTTPS from anywhere"
# 创建实例
echo "创建实例..."
gcloud compute instances create $INSTANCE_NAME \
--zone=$ZONE \
--machine-type=$MACHINE_TYPE \
--subnet=$SUBNET_NAME \
--network-tier=PREMIUM \
--metadata-from-file startup-script=gcp_openvpn_startup.sh \
--tags=openvpn,http-server,https-server \
--image-family=debian-10 \
--image-project=debian-cloud \
--boot-disk-size=10GB \
--boot-disk-type=pd-standard \
--boot-disk-device-name=$INSTANCE_NAME
# 获取实例外部IP
EXTERNAL_IP=$(gcloud compute instances describe $INSTANCE_NAME \
--zone=$ZONE \
--format='get(networkInterfaces[0].accessConfigs[0].natIP)')
echo "OpenVPN服务器部署完成!"
echo "服务器公共IP: $EXTERNAL_IP"
echo "使用以下命令连接到服务器:"
echo "gcloud compute ssh $INSTANCE_NAME --zone=$ZONE"
echo "OpenVPN配置将在约5-10分钟后完成"
echo "完成后,您可以使用SCP下载客户端配置文件:"
echo "gcloud compute scp $INSTANCE_NAME:/home/$(whoami)/client.ovpn . --zone=$ZONE"
启动脚本 gcp_openvpn_startup.sh
:
#!/bin/bash
# 更新系统并安装依赖
apt-get update
apt-get install -y openvpn easy-rsa iptables-persistent net-tools
# 设置Easy-RSA
mkdir -p /etc/openvpn/easy-rsa
cp -r /usr/share/easy-rsa/* /etc/openvpn/easy-rsa/
cd /etc/openvpn/easy-rsa
# 初始化PKI
./easyrsa init-pki
# 创建CA(无需交互)
EASYRSA_BATCH=1 ./easyrsa build-ca nopass
# 创建服务器证书和密钥
EASYRSA_BATCH=1 ./easyrsa build-server-full server nopass
# 创建Diffie-Hellman参数
./easyrsa gen-dh
# 创建TLS认证密钥
openvpn --genkey --secret /etc/openvpn/ta.key
# 创建客户端证书和密钥
EASYRSA_BATCH=1 ./easyrsa build-client-full client nopass
# 配置OpenVPN服务器
cat > /etc/openvpn/server.conf << EOF
port 1194
proto udp
dev tun
ca /etc/openvpn/easy-rsa/pki/ca.crt
cert /etc/openvpn/easy-rsa/pki/issued/server.crt
key /etc/openvpn/easy-rsa/pki/private/server.key
dh /etc/openvpn/easy-rsa/pki/dh.pem
tls-auth /etc/openvpn/ta.key 0
server 172.16.0.0 255.255.255.0
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 8.8.8.8"
push "dhcp-option DNS 8.8.4.4"
keepalive 10 120
cipher AES-256-GCM
auth SHA256
compress lz4-v2
push "compress lz4-v2"
user nobody
group nogroup
persist-key
persist-tun
status /var/log/openvpn/status.log
log-append /var/log/openvpn/openvpn.log
verb 3
EOF
# 创建日志目录
mkdir -p /var/log/openvpn
# 获取公共IP地址
PUBLIC_IP=$(curl -s https://api.ipify.org)
# 创建客户端配置
USERNAME=$(curl -s "http://metadata.google.internal/computeMetadata/v1/instance/attributes/created-by" -H "Metadata-Flavor: Google" | cut -d'@' -f1)
if [ -z "$USERNAME" ]; then
USERNAME="user"
fi
cat > /home/$USERNAME/client.ovpn << EOF
client
dev tun
proto udp
remote $PUBLIC_IP 1194
resolv-retry infinite
nobind
persist-key
persist-tun
remote-cert-tls server
cipher AES-256-GCM
auth SHA256
compress lz4-v2
verb 3
<ca>
$(cat /etc/openvpn/easy-rsa/pki/ca.crt)
</ca>
<cert>
$(cat /etc/openvpn/easy-rsa/pki/issued/client.crt)
</cert>
<key>
$(cat /etc/openvpn/easy-rsa/pki/private/client.key)
</key>
<tls-auth>
$(cat /etc/openvpn/ta.key)
</tls-auth>
key-direction 1
EOF
# 设置权限
chown $USERNAME:$USERNAME /home/$USERNAME/client.ovpn
chmod 600 /home/$USERNAME/client.ovpn
# 启用IP转发
echo "net.ipv4.ip_forward = 1" > /etc/sysctl.d/99-openvpn.conf
sysctl -p /etc/sysctl.d/99-openvpn.conf
# 配置iptables
iptables -t nat -A POSTROUTING -s 172.16.0.0/24 -o eth0 -j MASQUERADE
# 保存iptables规则
netfilter-persistent save
netfilter-persistent reload
# 启动OpenVPN服务
systemctl enable openvpn@server
systemctl start openvpn@server
echo "OpenVPN服务器设置完成"
12.2.4 阿里云部署
使用阿里云CLI部署OpenVPN服务器:
#!/bin/bash
# aliyun_openvpn_deploy.sh
# 设置变量
REGION="cn-hangzhou"
VPC_NAME="openvpn-vpc"
VPC_CIDR="10.0.0.0/16"
VSWITCH_NAME="openvpn-vswitch"
VSWITCH_CIDR="10.0.1.0/24"
SECURITY_GROUP_NAME="openvpn-sg"
INSTANCE_NAME="openvpn-server"
INSTANCE_TYPE="ecs.t5-lc1m1.small"
IMAGE_ID="ubuntu_18_04_64_20G_alibase_20190624.vhd"
KEY_PAIR_NAME="openvpn-key"
VPN_NETWORK="172.16.0.0/24"
# 创建VPC
echo "创建VPC..."
VPC_ID=$(aliyun vpc CreateVpc \
--RegionId $REGION \
--VpcName $VPC_NAME \
--CidrBlock $VPC_CIDR \
--Description "VPC for OpenVPN server" \
| jq -r '.VpcId')
echo "VPC创建完成: $VPC_ID"
# 等待VPC可用
sleep 5
# 创建交换机
echo "创建交换机..."
ZONE_ID=$(aliyun ecs DescribeZones \
--RegionId $REGION \
| jq -r '.Zones.Zone[0].ZoneId')
VSWITCH_ID=$(aliyun vpc CreateVSwitch \
--RegionId $REGION \
--VpcId $VPC_ID \
--ZoneId $ZONE_ID \
--VSwitchName $VSWITCH_NAME \
--CidrBlock $VSWITCH_CIDR \
--Description "VSwitch for OpenVPN server" \
| jq -r '.VSwitchId')
echo "交换机创建完成: $VSWITCH_ID"
# 创建安全组
echo "创建安全组..."
SECURITY_GROUP_ID=$(aliyun ecs CreateSecurityGroup \
--RegionId $REGION \
--VpcId $VPC_ID \
--SecurityGroupName $SECURITY_GROUP_NAME \
--Description "Security group for OpenVPN server" \
| jq -r '.SecurityGroupId')
echo "安全组创建完成: $SECURITY_GROUP_ID"
# 添加安全组规则
aliyun ecs AuthorizeSecurityGroup \
--RegionId $REGION \
--SecurityGroupId $SECURITY_GROUP_ID \
--IpProtocol tcp \
--PortRange 22/22 \
--SourceCidrIp 0.0.0.0/0 \
--Priority 1
aliyun ecs AuthorizeSecurityGroup \
--RegionId $REGION \
--SecurityGroupId $SECURITY_GROUP_ID \
--IpProtocol udp \
--PortRange 1194/1194 \
--SourceCidrIp 0.0.0.0/0 \
--Priority 1
aliyun ecs AuthorizeSecurityGroup \
--RegionId $REGION \
--SecurityGroupId $SECURITY_GROUP_ID \
--IpProtocol tcp \
--PortRange 443/443 \
--SourceCidrIp 0.0.0.0/0 \
--Priority 1
# 创建密钥对
echo "创建密钥对..."
aliyun ecs CreateKeyPair \
--RegionId $REGION \
--KeyPairName $KEY_PAIR_NAME \
> $KEY_PAIR_NAME.json
# 保存私钥
jq -r '.PrivateKeyBody' $KEY_PAIR_NAME.json > $KEY_PAIR_NAME.pem
chmod 400 $KEY_PAIR_NAME.pem
# 创建ECS实例
echo "创建ECS实例..."
INSTANCE_ID=$(aliyun ecs CreateInstance \
--RegionId $REGION \
--ZoneId $ZONE_ID \
--ImageId $IMAGE_ID \
--InstanceType $INSTANCE_TYPE \
--InstanceName $INSTANCE_NAME \
--SecurityGroupId $SECURITY_GROUP_ID \
--VSwitchId $VSWITCH_ID \
--KeyPairName $KEY_PAIR_NAME \
--SystemDiskCategory cloud_efficiency \
--SystemDiskSize 40 \
--InstanceChargeType PostPaid \
--UserData $(base64 -w 0 aliyun_openvpn_userdata.sh) \
| jq -r '.InstanceId')
echo "ECS实例创建完成: $INSTANCE_ID"
# 分配公网IP
echo "分配公网IP..."
PUBLIC_IP=$(aliyun ecs AllocatePublicIpAddress \
--RegionId $REGION \
--InstanceId $INSTANCE_ID \
| jq -r '.IpAddress')
echo "公网IP分配完成: $PUBLIC_IP"
# 启动实例
echo "启动实例..."
aliyun ecs StartInstance \
--RegionId $REGION \
--InstanceId $INSTANCE_ID
echo "OpenVPN服务器部署完成!"
echo "服务器公共IP: $PUBLIC_IP"
echo "使用以下命令连接到服务器:"
echo "ssh -i $KEY_PAIR_NAME.pem root@$PUBLIC_IP"
echo "OpenVPN配置将在约5-10分钟后完成"
echo "完成后,您可以使用SCP下载客户端配置文件:"
echo "scp -i $KEY_PAIR_NAME.pem root@$PUBLIC_IP:/root/client.ovpn ."
用户数据脚本 aliyun_openvpn_userdata.sh
:
#!/bin/bash
# 更新系统并安装依赖
apt-get update
apt-get install -y openvpn easy-rsa iptables-persistent net-tools
# 设置Easy-RSA
mkdir -p /etc/openvpn/easy-rsa
cp -r /usr/share/easy-rsa/* /etc/openvpn/easy-rsa/
cd /etc/openvpn/easy-rsa
# 初始化PKI
./easyrsa init-pki
# 创建CA(无需交互)
EASYRSA_BATCH=1 ./easyrsa build-ca nopass
# 创建服务器证书和密钥
EASYRSA_BATCH=1 ./easyrsa build-server-full server nopass
# 创建Diffie-Hellman参数
./easyrsa gen-dh
# 创建TLS认证密钥
openvpn --genkey --secret /etc/openvpn/ta.key
# 创建客户端证书和密钥
EASYRSA_BATCH=1 ./easyrsa build-client-full client nopass
# 配置OpenVPN服务器
cat > /etc/openvpn/server.conf << EOF
port 1194
proto udp
dev tun
ca /etc/openvpn/easy-rsa/pki/ca.crt
cert /etc/openvpn/easy-rsa/pki/issued/server.crt
key /etc/openvpn/easy-rsa/pki/private/server.key
dh /etc/openvpn/easy-rsa/pki/dh.pem
tls-auth /etc/openvpn/ta.key 0
server 172.16.0.0 255.255.255.0
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 8.8.8.8"
push "dhcp-option DNS 8.8.4.4"
keepalive 10 120
cipher AES-256-GCM
auth SHA256
compress lz4-v2
push "compress lz4-v2"
user nobody
group nogroup
persist-key
persist-tun
status /var/log/openvpn/status.log
log-append /var/log/openvpn/openvpn.log
verb 3
EOF
# 创建日志目录
mkdir -p /var/log/openvpn
# 获取公共IP地址
PUBLIC_IP=$(curl -s https://api.ipify.org)
# 创建客户端配置
cat > /root/client.ovpn << EOF
client
dev tun
proto udp
remote $PUBLIC_IP 1194
resolv-retry infinite
nobind
persist-key
persist-tun
remote-cert-tls server
cipher AES-256-GCM
auth SHA256
compress lz4-v2
verb 3
<ca>
$(cat /etc/openvpn/easy-rsa/pki/ca.crt)
</ca>
<cert>
$(cat /etc/openvpn/easy-rsa/pki/issued/client.crt)
</cert>
<key>
$(cat /etc/openvpn/easy-rsa/pki/private/client.key)
</key>
<tls-auth>
$(cat /etc/openvpn/ta.key)
</tls-auth>
key-direction 1
EOF
# 设置权限
chmod 600 /root/client.ovpn
# 启用IP转发
echo "net.ipv4.ip_forward = 1" > /etc/sysctl.d/99-openvpn.conf
sysctl -p /etc/sysctl.d/99-openvpn.conf
# 配置iptables
iptables -t nat -A POSTROUTING -s 172.16.0.0/24 -o eth0 -j MASQUERADE
# 保存iptables规则
netfilter-persistent save
netfilter-persistent reload
# 启动OpenVPN服务
systemctl enable openvpn@server
systemctl start openvpn@server
echo "OpenVPN服务器设置完成"
12.3 混合云网络架构
12.3.1 站点到云VPN
以下是使用OpenVPN连接本地数据中心与AWS VPC的配置示例:
#!/bin/bash
# site_to_cloud_vpn.sh
# 设置变量
LOCAL_NETWORK="192.168.0.0/24" # 本地网络CIDR
CLOUD_NETWORK="10.0.0.0/16" # 云端VPC CIDR
CLOUD_VPN_IP="54.123.45.67" # 云端OpenVPN服务器公共IP
LOCAL_VPN_IP="203.0.113.10" # 本地OpenVPN服务器公共IP
# 本地OpenVPN服务器配置
cat > /etc/openvpn/server.conf << EOF
port 1194
proto udp
dev tun
ca /etc/openvpn/pki/ca.crt
cert /etc/openvpn/pki/issued/server.crt
key /etc/openvpn/pki/private/server.key
dh /etc/openvpn/pki/dh.pem
tls-auth /etc/openvpn/pki/ta.key 0
server 172.16.0.0 255.255.255.0
# 路由配置 - 将云端网络流量路由到VPN
push "route $CLOUD_NETWORK 255.255.255.0"
# 不将所有流量重定向到VPN,只路由特定网络
;push "redirect-gateway def1 bypass-dhcp"
keepalive 10 120
cipher AES-256-GCM
auth SHA256
compress lz4-v2
push "compress lz4-v2"
user nobody
group nogroup
persist-key
persist-tun
status /var/log/openvpn/status.log
log-append /var/log/openvpn/openvpn.log
verb 3
# 允许客户端之间通信
client-to-client
# 保持连接,即使没有客户端
keepalive 10 60
EOF
# 创建云端OpenVPN客户端配置
cat > /etc/openvpn/cloud_client.conf << EOF
client
dev tun
proto udp
remote $CLOUD_VPN_IP 1194
resolv-retry infinite
nobind
persist-key
persist-tun
remote-cert-tls server
cipher AES-256-GCM
auth SHA256
compress lz4-v2
verb 3
# 添加本地网络路由到云端
route $LOCAL_NETWORK 255.255.255.0
<ca>
# 粘贴云端CA证书
</ca>
<cert>
# 粘贴云端客户端证书
</cert>
<key>
# 粘贴云端客户端密钥
</key>
<tls-auth>
# 粘贴云端TLS密钥
</tls-auth>
key-direction 1
EOF
# 启用IP转发
echo "net.ipv4.ip_forward = 1" > /etc/sysctl.d/99-openvpn.conf
sysctl -p /etc/sysctl.d/99-openvpn.conf
# 配置iptables以允许VPN流量通过
iptables -t nat -A POSTROUTING -s 172.16.0.0/24 -o eth0 -j MASQUERADE
iptables -A FORWARD -i tun0 -o eth0 -s 172.16.0.0/24 -j ACCEPT
iptables -A FORWARD -i eth0 -o tun0 -d 172.16.0.0/24 -j ACCEPT
# 保存iptables规则
netfilter-persistent save
netfilter-persistent reload
# 启动OpenVPN服务器和客户端
systemctl enable openvpn@server
systemctl start openvpn@server
systemctl enable openvpn@cloud_client
systemctl start openvpn@cloud_client
echo "站点到云VPN配置完成"
12.3.2 多云连接
以下是使用OpenVPN连接多个云平台的配置示例:
”`python #!/usr/bin/env python3
multi_cloud_vpn_manager.py
import os import sys import subprocess import argparse import yaml import time
class MultiCloudVPNManager: def init(self, config_file): self.config_file = config_file self.load_config() self.openvpn_base_dir = “/etc/openvpn” self.ensure_directories()
def load_config(self):
try:
with open(self.config_file, 'r') as f:
self.config = yaml.safe_load(f)
except Exception as e:
print(f"Error loading configuration: {e}")
sys.exit(1)
def ensure_directories(self):
os.makedirs(f"{self.openvpn_base_dir}/ccd", exist_ok=True)
os.makedirs(f"{self.openvpn_base_dir}/keys", exist_ok=True)
os.makedirs(f"{self.openvpn_base_dir}/clients", exist_ok=True)
def setup_hub_server(self):
"""设置中心OpenVPN服务器"""
hub_config = self.config.get('hub', {})
if not hub_config:
print("Error: Hub configuration missing")
return False
# 创建服务器配置
server_conf = f"""\
port {hub_config.get(‘port’, 1194)}
proto {hub_config.get(‘protocol’, ‘udp’)}
dev tun
ca {self.openvpn_base_dir}/keys/ca.crt
cert {self.openvpn_base_dir}/keys/server.crt
key {self.openvpn_base_dir}/keys/server.key
dh {self.openvpn_base_dir}/keys/dh.pem
tls-auth {self.openvpn_base_dir}/keys/ta.key 0
server {hub_config.get(‘vpn_network’, ‘10.8.0.0’)} {hub_config.get(‘vpn_netmask’, ‘255.255.255.0’)}
keepalive 10 120
cipher AES-256-GCM
auth SHA256
compress lz4-v2
push “compress lz4-v2”
user nobody
group nogroup
persist-key
persist-tun
status /var/log/openvpn/status.log
log-append /var/log/openvpn/openvpn.log
verb 3
允许客户端之间通信
client-to-client
使用客户端配置目录
client-config-dir {self.openvpn_base_dir}/ccd
”“”
# 添加路由推送配置
for cloud in self.config.get('clouds', []):
network = cloud.get('network')
if network:
server_conf += f"push \"route {network}\"\n"
# 写入服务器配置文件
with open(f"{self.openvpn_base_dir}/server.conf", 'w') as f:
f.write(server_conf)
print("Hub server configuration created")
return True
def setup_cloud_clients(self):
"""为每个云平台设置客户端配置"""
for cloud in self.config.get('clouds', []):
cloud_name = cloud.get('name')
if not cloud_name:
print("Warning: Cloud without name found, skipping")
continue
# 创建客户端配置
client_conf = f"""\
client
dev tun
proto {cloud.get(‘protocol’, ‘udp’)}
remote {cloud.get(‘vpn_server’)} {cloud.get(‘port’, 1194)}
resolv-retry infinite
nobind
persist-key
persist-tun
remote-cert-tls server
cipher AES-256-GCM
auth SHA256
compress lz4-v2
verb 3
添加路由
”“”
# 添加本地网络路由
local_network = self.config.get('hub', {}).get('local_network')
if local_network:
client_conf += f"route {local_network}\n"
# 添加其他云网络路由
for other_cloud in self.config.get('clouds', []):
if other_cloud.get('name') != cloud_name and other_cloud.get('network'):
client_conf += f"route {other_cloud.get('network')}\n"
# 添加证书和密钥占位符
client_conf += """\
CA certificate placeholder
Client certificate placeholder
Client key placeholder
TLS key placeholder
key-direction 1
”“”
# 写入客户端配置文件
with open(f"{self.openvpn_base_dir}/clients/{cloud_name}.conf", 'w') as f:
f.write(client_conf)
# 创建CCD文件以设置固定IP和路由
with open(f"{self.openvpn_base_dir}/ccd/{cloud_name}", 'w') as f:
if cloud.get('fixed_ip'):
f.write(f"ifconfig-push {cloud.get('fixed_ip')} {self.config.get('hub', {}).get('vpn_netmask', '255.255.255.0')}\n")
if cloud.get('network'):
f.write(f"iroute {cloud.get('network')}\n")
print(f"Client configuration for {cloud_name} created")
return True
def setup_iptables(self):
"""配置iptables规则"""
try:
# 启用IP转发
with open("/etc/sysctl.d/99-openvpn.conf", 'w') as f:
f.write("net.ipv4.ip_forward = 1\n")
subprocess.run(["sysctl", "-p", "/etc/sysctl.d/99-openvpn.conf"], check=True)
# 配置NAT
vpn_network = self.config.get('hub', {}).get('vpn_network', '10.8.0.0/24')
subprocess.run(["iptables", "-t", "nat", "-A", "POSTROUTING", "-s", vpn_network, "-o", "eth0", "-j", "MASQUERADE"], check=True)
# 允许转发
subprocess.run(["iptables", "-A", "FORWARD", "-i", "tun+", "-j", "ACCEPT"], check=True)
subprocess.run(["iptables", "-A", "FORWARD", "-o", "tun+", "-j", "ACCEPT"], check=True)
# 保存规则
subprocess.run(["netfilter-persistent", "save"], check=True)
print("iptables rules configured")
return True
except subprocess.SubprocessError as e:
print(f"Error configuring iptables: {e}")
return False