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']        %>" | 
