Created
December 10, 2015 20:58
-
-
Save hassenius/57c9e71784e6fa1af5fc to your computer and use it in GitHub Desktop.
OpenVPN Server to access private openstack networks network
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
heat_template_version: 2013-05-23 | |
description: Create an OpenVPN server to create connectivity to private networks | |
parameters: | |
key_name: | |
type: string | |
label: Keypair Name | |
description: Name of a KeyPair to enable SSH access to the instance. | |
constraints: | |
- custom_constraint: nova.keypair | |
instance_type: | |
type: string | |
label: OpenVPN Instance Type | |
description: Instance type for the OpenVPN server. | |
constraints: | |
- custom_constraint: nova.flavor | |
image_id: | |
type: string | |
label: OpenVPN Image | |
description: Name or ID of the image to use for the OpenVPN server (Tested with ubuntu 14.04 LTS). | |
constraints: | |
- custom_constraint: glance.image | |
shared_net_id: | |
type: string | |
label: External Network | |
description: Name or ID of the shared network for which floating IP addresses will be allocated. | |
constraints: | |
- custom_constraint: neutron.network | |
private_net_id: | |
type: string | |
label: Private Network | |
description: Private network in which OpenVPN will be linked. | |
constraints: | |
- custom_constraint: neutron.network | |
vpn_cidr: | |
type: string | |
default: 10.9.0.0/24 | |
description: OpenVPN CIDR. It has to be unique and must not overlap the CIDR of your private_net_id, shared_net_id, and neither of your clients connecting to the VPN. | |
allowed_downloads: | |
type: string | |
default: 1 | |
description: How many times can the client access package be downloaded before the | |
resources: | |
# IP addresses | |
server_shared_ip: | |
type: OS::Neutron::FloatingIP | |
depends_on: | |
- server_private_ip | |
properties: | |
floating_network: { get_param: shared_net_id } | |
port_id: { get_resource: server_private_ip } | |
server_private_ip: | |
type: OS::Neutron::Port | |
properties: | |
network: { get_param: private_net_id } | |
security_groups: [{ get_resource: secgroup-ovpn },{ get_resource: secgroup-ssh }, { get_resource: secgroup-http-cred }] | |
# Security Groups | |
secgroup-ovpn: | |
type: OS::Neutron::SecurityGroup | |
properties: | |
description: Enable traffic external traffic on UDP:1194 for OpenVPN trafic | |
rules: [{protocol: udp, port_range_max: 1194, port_range_min: 1194},] | |
secgroup-ssh: | |
type: OS::Neutron::SecurityGroup | |
properties: | |
description: Enable traffic external traffic on SSH. | |
rules: [{protocol: tcp, port_range_max: 22, port_range_min: 22},] | |
secgroup-http-cred: | |
type: OS::Neutron::SecurityGroup | |
properties: | |
description: Enable http connection to download client credentials on port 8080 from internet | |
rules: [{protocol: tcp, port_range_max: 8080, port_range_min: 8080, remote_ip_prefix: 0.0.0.0/0},] | |
# Servers | |
openvpn_instance: | |
type: OS::Nova::Server | |
depends_on: | |
- server_private_ip | |
properties: | |
image: { get_param: image_id } | |
flavor: { get_param: instance_type } | |
key_name: { get_param: key_name } | |
networks: | |
- port: { get_resource: server_private_ip } | |
user_data_format: RAW | |
user_data: | |
get_resource: software-init | |
# Software | |
openvpn-packages: | |
type: OS::Heat::CloudConfig | |
properties: | |
cloud_config: | |
merge_how: 'dict(recurse_array,no_replace)+list(append)' | |
runcmd: | |
- ufw allow openvpn | |
packages: | |
- openvpn | |
- easy-rsa | |
- woof | |
- zip | |
openvpn-server-config: | |
type: OS::Heat::CloudConfig | |
depends_on: | |
- openvpn-packages | |
- server_shared_ip | |
properties: | |
cloud_config: | |
merge_how: 'dict(recurse_array,no_replace)+list(append)' | |
packages: | |
- ipcalc | |
write_files: | |
- path: /etc/openvpn/route-up.sh | |
owner: root:root | |
permissions: '0755' | |
content: | |
str_replace: | |
params: | |
"%vpncidr%": { get_param: vpn_cidr } | |
template: | | |
#!/bin/bash | |
/sbin/sysctl -n net.ipv4.conf.all.forwarding > /var/log/openvpn/net.ipv4.conf.all.forwarding.bak | |
/sbin/sysctl net.ipv4.conf.all.forwarding=1 | |
/sbin/iptables-save > /var/log/openvpn/iptables.save | |
/sbin/iptables -t nat -F | |
/sbin/iptables -t nat -A POSTROUTING -s %vpncidr% -j MASQUERADE | |
- path: /etc/openvpn/down.sh | |
owner: root:root | |
permissions: '0755' | |
content: | | |
#!/bin/bash | |
FORWARDING=$(cat /var/log/openvpn/net.ipv4.conf.all.forwarding.bak) | |
echo "restoring net.ipv4.conf.all.forwarding=$FORWARDING" | |
/sbin/sysctl net.ipv4.conf.all.forwarding=$FORWARDING | |
/etc/openvpn/fw.stop | |
echo "Restoring iptables" | |
/sbin/iptables-restore < /var/log/openvpn/iptables.save | |
- path: /etc/openvpn/fw.stop | |
owner: root:root | |
permissions: '0755' | |
content: | | |
#!/bin/sh | |
echo "Stopping firewall and allowing everyone..." | |
/sbin/iptables -F | |
/sbin/iptables -X | |
/sbin/iptables -t nat -F | |
/sbin/iptables -t nat -X | |
/sbin/iptables -t mangle -F | |
/sbin/iptables -t mangle -X | |
/sbin/iptables -P INPUT ACCEPT | |
/sbin/iptables -P FORWARD ACCEPT | |
/sbin/iptables -P OUTPUT ACCEPT | |
- path: /etc/openvpn/server.conf | |
owner: root:root | |
permissions: '0644' | |
content: | | |
port 1194 | |
proto udp | |
dev tun | |
ca /etc/openvpn/ca.crt | |
cert /etc/openvpn/server.crt | |
key /etc/openvpn/server.key | |
crl-verify /etc/openvpn/crl.pem | |
dh /etc/openvpn/dh2048.pem | |
server OVPN_IP OVPN_MASK | |
ifconfig-pool-persist ipp.txt | |
push "route PRIVATE_NETWORK_IP PRIVATE_NETWORK_MASK" | |
keepalive 10 120 | |
tls-auth ta.key 0 | |
comp-lzo | |
persist-key | |
persist-tun | |
status /var/log/openvpn/openvpn-status.log | |
log /var/log/openvpn/openvpn.log | |
verb 3 | |
script-security 2 | |
route-up /etc/openvpn/route-up.sh | |
down /etc/openvpn/down.sh | |
duplicate-cn | |
- path: /etc/openvpn/populate-configs.sh | |
owner: root:root | |
permissions: '0755' | |
content: | |
str_replace: | |
params: | |
"%public_ip%": { get_attr: [server_shared_ip, floating_ip_address] } | |
# { get_resource: floating } | |
"%vpncidr%": { get_param: vpn_cidr } | |
template: | | |
#!/bin/bash | |
echo "Populating OpenVPN Configs" | |
FLOATING_IP=%public_ip% | |
OVPN_IP=$(ipcalc -nb %vpncidr% | grep ^Address | awk '{print $2}') | |
OVPN_MASK=$(ipcalc -nb %vpncidr% | grep ^Netmask | awk '{print $2}') | |
PRIVATE_IP_CIDR=$(ip addr show dev eth0 | grep 'inet .*$' | awk '{print $2}') | |
PRIVATE_NETWORK_CIDR=$(ipcalc -nb $PRIVATE_IP_CIDR | grep ^Network | awk '{print $2}') | |
PRIVATE_NETWORK_IP=$(ipcalc -nb $PRIVATE_NETWORK_CIDR | grep ^Address | awk '{print $2}') | |
PRIVATE_NETWORK_MASK=$(ipcalc -nb $PRIVATE_NETWORK_CIDR | grep ^Netmask | awk '{print $2}') | |
cd /etc/openvpn | |
sed -i -e "s/PRIVATE_NETWORK_IP/$PRIVATE_NETWORK_IP/g" server.conf | |
sed -i -e "s/PRIVATE_NETWORK_MASK/$PRIVATE_NETWORK_MASK/g" server.conf | |
sed -i -e "s/OVPN_IP/$OVPN_IP/g" server.conf | |
sed -i -e "s/OVPN_MASK/$OVPN_MASK/g" server.conf | |
# Run some additional setup tasks | |
mkdir -p /var/log/openvpn | |
runcmd: | |
- /etc/openvpn/populate-configs.sh | |
# ufw interferes with iptables masquarading. Disable | |
- ufw disable | |
openvpn-server-certificate: | |
type: OS::Heat::SoftwareConfig | |
depends_on: | |
- openvpn-packages | |
- openvpn-server-config | |
properties: | |
config: | | |
#!/bin/bash | |
echo "Generating server certificates" | |
mkdir /etc/openvpn/easy-rsa | |
cp -r /usr/share/easy-rsa /etc/openvpn/ | |
cd /etc/openvpn/easy-rsa | |
ln -s openssl-1.0.0.cnf openssl.cnf | |
source vars | |
./clean-all | |
./build-dh | |
KEY_EMAIL=ca@openvpn ./pkitool --initca | |
KEY_EMAIL=server@pilgrim ./pkitool --server server | |
KEY_EMAIL=revoked@pilgrim ./pkitool revoked | |
./revoke-full revoked # Generates a crl.pem revocation list | |
openvpn --genkey --secret keys/ta.key | |
ln keys/{ca.crt,server.crt,server.key,dh2048.pem,crl.pem,ta.key} /etc/openvpn/ | |
echo "Starting OpenVPN" | |
# cloud-init entries might be out of order, with runcmd running after part-xxx are completed. | |
# spawn a while loop to wait for server.conf to be updated. | |
eval 'while grep -q OVPN_MASK /etc/openvpn/server.conf ; do echo "Waiting for configuration files to be updated...." ; sleep 2s ; done ; service openvpn start ' & | |
#while grep -q OVPN_MASK /etc/openvpn/server.conf ; do | |
# echo "Waiting for configuration files to be updated...." | |
# sleep 2s | |
#done | |
#service openvpn start | |
openvpn-client-certificate: | |
type: OS::Heat::SoftwareConfig | |
depends_on: | |
- openvpn-server-certificate | |
- server_shared_ip | |
properties: | |
config: | |
str_replace: | |
params: | |
"%public_ip%": { get_attr: [server_shared_ip, floating_ip_address] } | |
"%allowed_downloads%": { get_param: allowed_downloads } | |
template: | | |
#!/bin/bash | |
# Get the default user. This may change from system to system, | |
# but the cloud-init add user script has already run, so will be the | |
# last user in the system | |
user=$(tail -1 /etc/passwd | cut -d: -f1) | |
gid=$(tail -1 /etc/passwd | cut -d: -f3) | |
userhome=$(tail -1 /etc/passwd | cut -d: -f6) | |
echo "Creating the client OpenVPN config" | |
cat > /etc/openvpn/easy-rsa/client.conf <<EOF | |
client | |
dev tun | |
proto udp | |
# remote $FLOATING_IP 1194 | |
remote %public_ip% 1194 | |
resolv-retry infinite | |
nobind | |
user nobody | |
group nogroup | |
persist-key | |
persist-tun | |
ca keys/ca.crt | |
cert keys/client.crt | |
key keys/client.key | |
ns-cert-type server | |
tls-auth keys/ta.key 1 | |
comp-lzo | |
verb 3 | |
EOF | |
echo "Creating the client certificate" | |
cd /etc/openvpn/easy-rsa | |
source vars | |
KEY_EMAIL=client@pilgrim ./pkitool client | |
echo "Create and share vpnaccecss files" | |
zip vpnaccess.zip client.conf keys/ca.crt keys/client.key keys/client.crt keys/ta.key | |
mkdir -p ${userhome}/clientaccess | |
cp vpnaccess.zip ${userhome}/clientaccess | |
chown ${user}:${gid} ${userhome}/clientaccess/vpnaccess.zip | |
ufw allow 8080 | |
ufw reload | |
cd ${userhome}/clientaccess | |
su -c 'woof -p 8080 -c %allowed_downloads% vpnaccess.zip ' ${user} >> /var/log/vpnclientdownloads.log 2>&1 & | |
software-init: | |
type: OS::Heat::MultipartMime | |
properties: | |
parts: | |
- config: { get_resource: openvpn-packages } | |
- config: { get_resource: openvpn-server-config } | |
- config: { get_resource: openvpn-server-certificate } | |
- config: { get_resource: openvpn-client-certificate } | |
## - config: { get_resource: share-client-cert } | |
outputs: | |
client_credentials: | |
description: You can download the OpenVPN client credentials from this link | |
value: | |
str_replace: | |
template: http://host:8080/vpnaccess.zip | |
params: | |
host: { get_attr: [server_shared_ip, floating_ip_address] } | |
private_network_ip: | |
description: Private network IP for the instance | |
value: { get_attr: [server_private_ip, fixed_ips, 0, ip_address] } | |
vpn_network: | |
description: Network address for the VPN network | |
value: { get_param: vpn_cidr } | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment