diff options
author | elijah <elijah@riseup.net> | 2013-02-27 23:46:58 -0800 |
---|---|---|
committer | elijah <elijah@riseup.net> | 2013-02-27 23:46:58 -0800 |
commit | ffb88e54c5e4e30fa61ea1009f3eee62f98ab17c (patch) | |
tree | 0d28846e9de15d7580b3b232aac16e2f4e8cb6e4 | |
parent | 5f8b63892ec9d08471a43ac642ed8f291d27c4f5 (diff) |
openvpn -- added support for optional "free" rate-limited service via special client certificates with the FREE prefix in the common name.
-rw-r--r-- | provider_base/files/service-definitions/eip-service.json.erb | 33 | ||||
-rw-r--r-- | provider_base/provider.json | 12 | ||||
-rw-r--r-- | provider_base/services/openvpn.json | 7 | ||||
-rw-r--r-- | provider_base/services/webapp.json | 4 | ||||
-rw-r--r-- | puppet/modules/site_openvpn/manifests/init.pp | 45 | ||||
-rw-r--r-- | puppet/modules/site_openvpn/manifests/server_config.pp | 18 | ||||
-rw-r--r-- | puppet/modules/site_openvpn/templates/leap_add_second_ip.sh.erb | 11 | ||||
-rw-r--r-- | puppet/modules/site_shorewall/manifests/dnat_rule.pp | 21 | ||||
-rw-r--r-- | puppet/modules/site_webapp/templates/config.yml.erb | 8 |
9 files changed, 137 insertions, 22 deletions
diff --git a/provider_base/files/service-definitions/eip-service.json.erb b/provider_base/files/service-definitions/eip-service.json.erb index 8dc7211d..09b65bbb 100644 --- a/provider_base/files/service-definitions/eip-service.json.erb +++ b/provider_base/files/service-definitions/eip-service.json.erb @@ -6,21 +6,34 @@ words end + def gateway_definition(node) + gateway = {} + gateway["capabilities"] = node.openvpn.pick(:ports, :protocols, :user_ips, :adblock, :filter_dns) + gateway["capabilities"]["transport"] = ["openvpn"] + gateway["host"] = node.domain.full + gateway["cluster"] = underscore(node.openvpn.location) + gateway + end + hsh = {} hsh["serial"] = 1 hsh["version"] = 1 clusters = {} gateways = [] - global.services['openvpn'].node_list.each_node do |node| - next if node.vagrant? - gateway = {} - gateway["capabilities"] = node.openvpn.pick( - :ports, :protocols, :user_ips, :adblock, :filter_dns) - gateway["capabilities"]["transport"] = ["openvpn"] - gateway["ip_address"] = node.openvpn.gateway_address - gateway["host"] = node.domain.full - gateway["cluster"] = underscore(node.openvpn.location) - gateways << gateway + nodes_like_me[:services => 'openvpn'].each_node do |node| + if node.openvpn.gateway_address + gateway = gateway_definition(node) + gateway["ip_address"] = node.openvpn.gateway_address + gateway["capabilities"]["free"] = false + gateways << gateway + end + if node.openvpn.free_gateway_address && node.openvpn.free_gateway_address != "REQUIRED" + gateway = gateway_definition(node) + gateway["ip_address"] = node.openvpn.free_gateway_address + gateway["capabilities"]["free"] = true + gateway["capabilities"]["rate_limit"] = node.openvpn.free_rate_limit + gateways << gateway + end clusters[gateway["cluster"]] ||= { "name" => gateway["cluster"], "label" => {"en" => node.openvpn.location} diff --git a/provider_base/provider.json b/provider_base/provider.json index 8ce848f3..14eabdc2 100644 --- a/provider_base/provider.json +++ b/provider_base/provider.json @@ -13,6 +13,12 @@ "languages": ["en"], "default_language": "en", "enrollment_policy": "open", + "service_levels": [ + {"name": "free", "bandwidth":102400, "storage":50}, + {"name": "basic", "bandwidth":null, "storage":1000}, + {"name": "premium", "bandwidth":null, "storage":10000} + ], + "service_allow_free": false, "ca": { "name": "= global.provider.ca.organization + ' Root CA'", "organization": "= global.provider.name[global.provider.default_language]", @@ -24,6 +30,12 @@ "bit_size": 3248, "digest": "SHA256", "life_span": "1y" + }, + "client_certificates": { + "bit_size": 2024, + "digest": "SHA256", + "life_span": "2m", + "free_prefix": "FREE" } }, "hiera_sync_destination": "/etc/leap" diff --git a/provider_base/services/openvpn.json b/provider_base/services/openvpn.json index 7b67ccb3..e78a02ac 100644 --- a/provider_base/services/openvpn.json +++ b/provider_base/services/openvpn.json @@ -7,10 +7,15 @@ }, "openvpn": { "location": "Location Unknown", + "gateway_address": "REQUIRED", + "free_gateway_address": "= openvpn.allow_free ? 'REQUIRED' : nil", "ports": ["80", "443", "53", "1194"], "protocols": ["tcp", "udp"], "filter_dns": false, "adblock": false, - "user_ips": false + "user_ips": false, + "allow_free": "= global.provider.service_allow_free", + "free_prefix": "= global.provider.ca.client_certificates.free_prefix", + "free_rate_limit": "= openvpn.allow_free ? global.provider.service_levels.detect{|level| level['name'] == 'free'}['bandwidth'] : nil" } } diff --git a/provider_base/services/webapp.json b/provider_base/services/webapp.json index e3055c6f..8ede0ecf 100644 --- a/provider_base/services/webapp.json +++ b/provider_base/services/webapp.json @@ -8,7 +8,9 @@ "favicon": "= file_path 'branding/favicon.ico'", "tail_scss": "= file_path 'branding/tail.scss'", "head_scss": "= file_path 'branding/head.scss'", - "img_dir": "= file_path 'branding/img'" + "img_dir": "= file_path 'branding/img'", + "client_certificates": "= global.provider.ca.client_certificates", + "allow_free": "= global.provider.service_allow_free" }, "definition_files": { "provider": "= file :provider_json_template", diff --git a/puppet/modules/site_openvpn/manifests/init.pp b/puppet/modules/site_openvpn/manifests/init.pp index 165ba96e..0c9f1795 100644 --- a/puppet/modules/site_openvpn/manifests/init.pp +++ b/puppet/modules/site_openvpn/manifests/init.pp @@ -1,9 +1,9 @@ class site_openvpn { tag 'leap_service' + # parse hiera config $ip_address = hiera('ip_address') $interface = getvar("interface_${ip_address}") - #$gateway_address = hiera('gateway_address') $openvpn_config = hiera('openvpn') $openvpn_gateway_address = $openvpn_config['gateway_address'] $openvpn_tcp_network_prefix = '10.1.0' @@ -12,6 +12,10 @@ class site_openvpn { $openvpn_udp_network_prefix = '10.2.0' $openvpn_udp_netmask = '255.255.248.0' $openvpn_udp_cidr = '21' + $openvpn_allow_free = $openvpn_config['allow_free'] + $openvpn_free_gateway_address = $openvpn_config['free_gateway_address'] + $openvpn_free_rate_limit = $openvpn_config['free_rate_limit'] + $openvpn_free_prefix = $openvpn_config['free_prefix'] $x509_config = hiera('x509') # deploy ca + server keys @@ -26,22 +30,47 @@ class site_openvpn { push => "\"dhcp-option DNS ${openvpn_tcp_network_prefix}.1\"", management => '127.0.0.1 1000' } + site_openvpn::server_config { 'udp_config': port => '1194', proto => 'udp', + local => $openvpn_gateway_address, server => "${openvpn_udp_network_prefix}.0 ${openvpn_udp_netmask}", push => "\"dhcp-option DNS ${openvpn_udp_network_prefix}.1\"", - local => $openvpn_gateway_address, management => '127.0.0.1 1001' } + if $openvpn_allow_free { + site_openvpn::server_config { 'free_tcp_config': + port => '1194', + proto => 'tcp', + local => $openvpn_free_gateway_address, + tls_remote => "\"${openvpn_free_prefix}\"", + shaper => $openvpn_free_rate_limit, + server => "${openvpn_tcp_network_prefix}.0 ${openvpn_tcp_netmask}", + push => "\"dhcp-option DNS ${openvpn_tcp_network_prefix}.1\"", + management => '127.0.0.1 1002' + } + site_openvpn::server_config { 'free_udp_config': + port => '1194', + proto => 'udp', + local => $openvpn_free_gateway_address, + tls_remote => "\"${openvpn_free_prefix}\"", + shaper => $openvpn_free_rate_limit, + server => "${openvpn_udp_network_prefix}.0 ${openvpn_udp_netmask}", + push => "\"dhcp-option DNS ${openvpn_udp_network_prefix}.1\"", + management => '127.0.0.1 1003' + } + } else { + tidy { "/etc/openvpn/free_tcp_config.conf": } + tidy { "/etc/openvpn/free_udp_config.conf": } + } + # add second IP on given interface - file { '/usr/local/bin/leap_add_second_ip.sh': - content => "#!/bin/sh -ip addr show dev ${interface} | grep -q ${openvpn_gateway_address}/24 || ip addr add ${openvpn_gateway_address}/24 dev ${interface} -/bin/echo 1 > /proc/sys/net/ipv4/ip_forward -", - mode => '0755', + file { + '/usr/local/bin/leap_add_second_ip.sh': + content => template('site_openvpn/leap_add_second_ip.sh.erb'), + mode => '0755'; } exec { '/usr/local/bin/leap_add_second_ip.sh': diff --git a/puppet/modules/site_openvpn/manifests/server_config.pp b/puppet/modules/site_openvpn/manifests/server_config.pp index 436dd272..1f42400a 100644 --- a/puppet/modules/site_openvpn/manifests/server_config.pp +++ b/puppet/modules/site_openvpn/manifests/server_config.pp @@ -52,7 +52,9 @@ # note: the default is BF-CBC (blowfish) # -define site_openvpn::server_config ($port, $proto, $local, $server, $push, $management ) { +define site_openvpn::server_config( + $port, $proto, $local, $server, $push, + $management, $tls_remote = undef, $shaper = undef) { $openvpn_configname = $name @@ -66,6 +68,20 @@ define site_openvpn::server_config ($port, $proto, $local, $server, $push, $mana notify => Service['openvpn']; } + # special options for the "free" gateway daemons + if $shaper != undef { + openvpn::option { + "shaper $openvpn_configname": + key => 'shaper', + value => $shaper, + server => $openvpn_configname; + "tls-remote $openvpn_configname": + key => 'tls-remote', + value => $tls_remote, + server => $openvpn_configname; + } + } + openvpn::option { "ca $openvpn_configname": key => 'ca', diff --git a/puppet/modules/site_openvpn/templates/leap_add_second_ip.sh.erb b/puppet/modules/site_openvpn/templates/leap_add_second_ip.sh.erb new file mode 100644 index 00000000..40866116 --- /dev/null +++ b/puppet/modules/site_openvpn/templates/leap_add_second_ip.sh.erb @@ -0,0 +1,11 @@ +#!/bin/sh + +ip addr show dev <%= @interface %> | grep -q <%= @openvpn_gateway_address %>/24 || + ip addr add <%= @openvpn_gateway_address %>/24 dev <%= @interface %> + +<% if @openvpn_allow_free %> +ip addr show dev <%= @interface %> | grep -q <%= @openvpn_free_gateway_address %>/24 || + ip addr add <%= @openvpn_free_gateway_address %>/24 dev <%= @interface %> +<% end %> + +/bin/echo 1 > /proc/sys/net/ipv4/ip_forward diff --git a/puppet/modules/site_shorewall/manifests/dnat_rule.pp b/puppet/modules/site_shorewall/manifests/dnat_rule.pp index 68f480d8..0b4370df 100644 --- a/puppet/modules/site_shorewall/manifests/dnat_rule.pp +++ b/puppet/modules/site_shorewall/manifests/dnat_rule.pp @@ -11,7 +11,6 @@ define site_shorewall::dnat_rule { destinationport => $port, order => 100; } - shorewall::rule { "dnat_udp_port_$port": action => 'DNAT', @@ -21,5 +20,25 @@ define site_shorewall::dnat_rule { destinationport => $port, order => 100; } + if $site_openvpn::openvpn_allow_free { + shorewall::rule { + "dnat_free_tcp_port_$port": + action => 'DNAT', + source => 'net', + destination => "\$FW:${site_openvpn::openvpn_free_gateway_address}:1194", + proto => 'tcp', + destinationport => $port, + order => 100; + } + shorewall::rule { + "dnat_free_udp_port_$port": + action => 'DNAT', + source => 'net', + destination => "\$FW:${site_openvpn::openvpn_free_gateway_address}:1194", + proto => 'udp', + destinationport => $port, + order => 100; + } + } } } diff --git a/puppet/modules/site_webapp/templates/config.yml.erb b/puppet/modules/site_webapp/templates/config.yml.erb index 9cf85f0c..cd67d1fd 100644 --- a/puppet/modules/site_webapp/templates/config.yml.erb +++ b/puppet/modules/site_webapp/templates/config.yml.erb @@ -1,5 +1,13 @@ +<%- cert_options = @webapp['client_certificates'] -%> production: admins: [admin] domain: <%= @provider_domain %> client_ca_key: <%= scope.lookupvar('site_webapp::client_ca::key_path') %> client_ca_cert: <%= scope.lookupvar('site_webapp::client_ca::cert_path') %> + +cert_options: + client_cert_lifespan: <%= cert_options['life_span'].to_i %> + client_cert_bit_size: <%= cert_options['bit_size'].to_i %> + client_cert_hash: <%= cert_options['digest'] %> + free_certs_enabled: <%= @webapp['allow_free'].inspect %> + free_cert_prefix: "<%= cert_options['free_prefix'] %>" |