# firewall definitions for physical servers
class firewall(
  $local_net     = hiera('nodo::firewall::local_net',     false),
  $in_bandwidth  = hiera('nodo::firewall::in_bandwidth',  '2mbit'),
  $out_bandwidth = hiera('nodo::firewall::out_bandwidth', '2mbit')
) {
  class { 'shorewall': }

  $rfc1918 = $local_net ? {
    true    => true,
    false   => false,
    default => false,
  }

  #
  # Interfaces
  #
  shorewall::interface { 'eth0':
   zone    => '-',
   rfc1918 => $rfc1918,
  }

  #
  # Policy
  #
  shorewall::policy { 'vm-net':
    sourcezone      => 'vm',
    destinationzone => 'net', 
    policy          => 'ACCEPT',
    order           => 1,
  }

  shorewall::policy { 'fw-net':
    sourcezone      => '$FW',
    destinationzone => 'net',
    policy          => 'ACCEPT',
    order           => 2,
  }

  shorewall::policy { 'fw-vm':
    sourcezone      => '$FW',
    destinationzone => 'vm',
    policy          => 'ACCEPT',
    order           => 3,
  }
  
  shorewall::policy { 'net-all':
    sourcezone      => 'net',
    destinationzone => 'all', 
    policy          => 'DROP',
    order           => 4,
  }

  shorewall::policy { 'all-all':
    sourcezone      => 'all',
    destinationzone => 'all',
    policy          => 'REJECT',
    order           => 90,
  }

  #
  # Hosts
  #
  shorewall::host { "eth0-subnet":
    name    => 'eth0:192.168.0.0/24',
    zone    => 'vm',
    options => '',
    order   => '1',
  }

  shorewall::host { "eth0":
    name    => 'eth0:0.0.0.0/0',
    zone    => 'net',
    options => '',
    order   => '2',
  }

  shorewall::masq { "eth0":
    interface => 'eth0:!192.168.0.0/24',
    source    => '192.168.0.0/24',
    order     => '1',
  }

  #
  # Rules
  #
  shorewall::rule { 'ssh':
    action          => 'SSH/ACCEPT',
    source          => 'net',
    destination     => '$FW',
    proto           => '-',
    destinationport => '-',
    ratelimit       => '-',
    order           => 100,
  }

  shorewall::rule { 'ping':
    action          => 'Ping/ACCEPT',
    source          => 'net',
    destination     => '$FW',
    proto           => '-',
    destinationport => '-',
    ratelimit       => '-',
    order           => 101,
  }

  shorewall::rule { 'http':
    action          => 'HTTP/ACCEPT',
    source          => 'net',
    destination     => '$FW',
    proto           => '-',
    destinationport => '-',
    ratelimit       => '-',
    order           => 102,
  }

  # SSL computational DoS mitigation
  # See http://vincent.bernat.im/en/blog/2011-ssl-dos-mitigation.html
  shorewall::rule { 'https':
    action          => 'HTTPS/ACCEPT',
    source          => 'net',
    destination     => '$FW',
    proto           => '-',
    destinationport => '-',
    ratelimit       => hiera("nodo::firewall::ssl_ratelimit", '-'),
    order           => 103,
  }

  $munin_port = $node_munin_port ? {
    ''      => "4900",
    default => "$node_munin_port",
  }

  shorewall::rule { "munin":
    action          => 'ACCEPT',
    source          => 'net',
    destination     => '$FW',
    proto           => 'tcp',
    destinationport => "$munin_port",
    ratelimit       => '-',
    order           => 104,
  }

  #
  # Zones
  #
  shorewall::zone { 'vm':
    type  => 'ipv4',
    order => '2',
  }

  shorewall::zone { 'net':
    type  => 'ipv4',
    order => '3',
  }

  #
  # Traffic shapping
  #
  shorewall::tcdevices { "eth0":
    in_bandwidth  => "$in_bandwidth",
    out_bandwidth => "$out_bandwidth",
  }

  shorewall::tcrules { "ssh-tcp":
    order       => "1",
    source      => "0.0.0.0/0",
    destination => "0.0.0.0/0", 
    protocol    => "tcp",
    ports       => "22",
  }

  shorewall::tcrules { "ssh-udp":
    order       => "1",
    source      => "0.0.0.0/0",
    destination => "0.0.0.0/0", 
    protocol    => "udp",
    ports       => "22",
  }

  shorewall::tcclasses { "ssh":
    order     => "1",
    interface => "eth0",
    rate      => "4*full/100",
    ceil      => "full",
    priority  => "1",
  }

  shorewall::tcclasses { "default":
    order     => "2",
    interface => "eth0",
    rate      => "6*full/100",
    ceil      => "full",
    priority  => "2",
    options   => "default",
  }

  if $local_net {
    class { "firewall::local": }
  }
}