Refactor firewall to listen on only on internal networks

Refactors firewall rules to create source
based rules that only permit connections
from the management network for most services.

The only services that should have public access
are Horizon and OpenStack APIs. And from those,
nova metadata and nova VNC should only be
accessible internally. All other services should
accept connections from private or storage
networks.

New defined type openstack::firewall::multi_net
accepts firewall definitions with an array of
source networks.

New function prepare_firewall_rules creates a hash
of firewall rules coming from an array of source
networks.

Removed unneeded openstack::firewall::allow class.
Obsoleted openstack::firewall:vnc defined type.

Sorted parameters on openstack::firewall and added
docstrings

DocImpact: TBD

Change-Id: Ie63c01dcbd0bbd9adf17363b0db0b0a99b837b4e
Closes-Bug: #1514014
This commit is contained in:
Matthew Mosesohn 2015-11-13 17:38:25 +03:00
parent aff0b7f926
commit 27b086f212
10 changed files with 776 additions and 211 deletions

View File

@ -0,0 +1,51 @@
module Puppet::Parser::Functions
newfunction(:prepare_firewall_rules, :type => :rvalue, :doc => <<-EOS
Creates a hash of firewall rules from an array of specified source_nets.
Example:
prepare_firewall_rules(['10.20.0.0/24','10.20.0.1']','020 ssh', 'accept',
'INPUT', '22','tcp') returns
{
'020 ssh from 10.0.0.0/24' => {'action' => 'accept',
'chain' => 'INPUT',
'port' => '22',
'proto' => 'tcp',
'source' => '10.0.0.0/24'},
'020 ssh from 10.0.1.0/24' => {'action' => 'accept',
'chain' => 'INPUT',
'port' => '22',
'proto' => 'tcp',
'source' => '10.0.1.0/24'}
}
EOS
) do |args|
raise ArgumentError, ("prepare_firewall_rules(): wrong number of arguments (#{args.length}; must be 6)") if args.length != 6
rule_basename = args[1]
action = args[2]
chain = args[3]
port = args[4]
proto = args[5]
raise ArgumentError, 'prepare_firewall_rules(): rule_basename is not a string' if !rule_basename.is_a?(String)
raise ArgumentError, 'prepare_firewall_rules(): source_net is not an array of strings' if args[0].any? { |v| !v.is_a?(String) }
fw_rules = {}
args[0].each do |source_net|
name = "#{rule_basename} from #{source_net}"
fw_rules[name] = {}
# Add params only if nonempty
fw_rules[name]['action'] = action unless [nil, ''].include?(action)
fw_rules[name]['chain'] = chain unless [nil, ''].include?(chain)
fw_rules[name]['port'] = port unless [nil, ''].include?(port)
fw_rules[name]['proto'] = proto unless [nil, ''].include?(proto)
fw_rules[name]['source'] = source_net
end
return fw_rules
end
end

View File

@ -1,75 +1,277 @@
# == Class: openstack::firewall
#
# This class creates firewall rules that apply to any OpenStack node.
#
# === Parameters
# [*admin_nets*]
# Array. List of networks in CIDR notation for Admin nets.
# Default value is ['0.0.0.0/0']
#
# [*public_nets*]
# Array. List of networks in CIDR notation for Public nets.
# Default value is ['0.0.0.0/0']
#
# [*management_nets*]
# Array. List of networks in CIDR notation for Management nets.
# Default value is ['0.0.0.0/0']
#
# [*storage_nets*]
# Array. List of networks in CIDR notation for Storage nets.
# Default value is ['0.0.0.0/0']
#
# [*keystone_network*]
# String. Network for for keystone public API
# Default value is '0.0.0.0/0'
#
# [*ceilometer_port*]
# String. Port for ceilometer
# Default value is 8777
#
# [*corosync_input_port*]
# String. Port for corosync_input
# Default value is 5404
#
# [*corosync_output_port*]
# String. Port for corosync_output
# Default value is 5405
#
# [*dhcp_server_port*]
# String. Port for dhcp_server
# Default value is 67
#
# [*dns_server_port*]
# String. Port for dns_server
# Default value is 53
#
# [*erlang_epmd_port*]
# String. Port for erlang_epmd
# Default value is 4369
#
# [*erlang_inet_dist_port*]
# String. Port for erlang_inet_dist
# Default value is 41055
#
# [*erlang_rabbitmq_backend_port*]
# String. Port for erlang_rabbitmq_backend
# Default value is 5673
#
# [*erlang_rabbitmq_port*]
# String. Port for erlang_rabbitmq
# Default value is 5672
#
# [*galera_clustercheck_port*]
# String. Port for galera_clustercheck
# Default value is 49000
#
# [*galera_ist_port*]
# String. Port for galera_ist
# Default value is 4568
#
# [*glance_api_port*]
# String. Port for glance_api
# Default value is 9292
#
# [*glance_nova_api_ec2_port*]
# String. Port for glance_nova_api_ec2
# Default value is 8773
#
# [*glance_reg_port*]
# String. Port for glance_reg
# Default value is 9191
#
# [*heat_api_cfn_port*]
# String. Port for heat_api_cfn
# Default value is 8000
#
# [*heat_api_cloudwatch_port*]
# String. Port for heat_api_cloudwatch
# Default value is 8003
#
# [*heat_api_port*]
# String. Port for heat_api
# Default value is 8004
#
# [*http_port*]
# String. Port for http
# Default value is 80
#
# [*https_port*]
# String. Port for https
# Default value is 443
#
# [*iscsi_port*]
# String. Port for iscsi
# Default value is 3260
#
# [*keystone_admin_port*]
# String. Port for keystone_admin
# Default value is 35357
#
# [*keystone_public_port*]
# String. Port for keystone_public
# Default value is 5000
#
# [*libvirt_migration_ports*]
# String. Port for libvirt_migration_ports
# Default value is '49152-49215'
#
# [*libvirt_port*]
# String. Port for libvirt
# Default value is 16509
#
# [*memcached_port*]
# String. Port for memcached
# Default value is 11211
#
# [*mongodb_port*]
# String. Port for mongodb
# Default value is 27017
#
# [*mysql_backend_port*]
# String. Port for mysql_backend
# Default value is 3307
#
# [*mysql_gcomm_port*]
# String. Port for mysql_gcomm
# Default value is 4567
#
# [*mysql_port*]
# String. Port for mysql
# Default value is 3306
#
# [*neutron_api_port*]
# String. Port for neutron_api
# Default value is 9696
#
# [*nova_api_compute_port*]
# String. Port for nova_api_compute
# Default value is 8774
#
# [*nova_api_metadata_port*]
# String. Port for nova_api_metadata
# Default value is 8775
#
# [*nova_api_vnc_ports*]
# String. Port for nova_api_vnc_ports
# Default value is '5900-6100'
#
# [*nova_api_volume_port*]
# String. Port for nova_api_volume
# Default value is 8776
#
# [*nova_vncproxy_port*]
# String. Port for nova_vncproxy
# Default value is 6080
#
# [*nrpe_server_port*]
# String. Port for nrpe_server
# Default value is 5666
#
# [*ntp_server_port*]
# String. Port for ntp_server
# Default value is 123
#
# [*openvswitch_db_port*]
# String. Port for openvswitch_db
# Default value is 58882
#
# [*pcsd_port*]
# String. Port for pcsd
# Default value is 2224
#
# [*rsync_port*]
# String. Port for rsync
# Default value is 873
#
# [*ssh_port*]
# String. Port for ssh
# Default value is 22
#
# [*swift_account_port*]
# String. Port for swift_account
# Default value is 6002
#
# [*swift_container_port*]
# String. Port for swift_container
# Default value is 6001
#
# [*swift_object_port*]
# String. Port for swift_object
# Default value is 6000
#
# [*swift_proxy_check_port*]
# String. Port for swift_proxy_check
# Default value is 49001
#
# [*swift_proxy_port*]
# String. Port for swift_proxy
# Default value is 8080
#
# [*vxlan_udp_port*]
# String. Port for vxlan_udp
# Default value is 4789
#
class openstack::firewall (
$ssh_port = 22,
$http_port = 80,
$https_port = 443,
$mysql_port = 3306,
$mysql_backend_port = 3307,
$mysql_gcomm_port = 4567,
$galera_ist_port = 4568,
$galera_clustercheck_port = 49000,
$swift_proxy_check_port = 49001,
$keystone_public_port = 5000,
$swift_proxy_port = 8080,
$swift_object_port = 6000,
$swift_container_port = 6001,
$swift_account_port = 6002,
$keystone_admin_port = 35357,
$glance_api_port = 9292,
$glance_reg_port = 9191,
$glance_nova_api_ec2_port = 8773,
$nova_api_compute_port = 8774,
$nova_api_metadata_port = 8775,
$nova_api_volume_port = 8776,
$nova_vncproxy_port = 6080,
$nova_vnc_ip_range = '0.0.0.0/0',
$nova_api_ip_range = '0.0.0.0/0',
$libvirt_network = '0.0.0.0/0',
$erlang_epmd_port = 4369,
$erlang_rabbitmq_port = 5672,
$erlang_rabbitmq_backend_port = 5673,
$erlang_inet_dist_port = 41055,
$memcached_port = 11211,
$rsync_port = 873,
$iscsi_port = 3260,
$iscsi_ip = '0.0.0.0',
$neutron_api_port = 9696,
$dns_server_port = 53,
$dhcp_server_port = 67,
$ntp_server_port = 123,
$admin_nets = ['0.0.0.0/0'],
$public_nets = ['0.0.0.0/0'],
$management_nets = ['0.0.0.0/0'],
$storage_nets = ['0.0.0.0/0'],
$keystone_network = '0.0.0.0/0',
$ceilometer_port = 8777,
$corosync_input_port = 5404,
$corosync_output_port = 5405,
$pcsd_port = 2224,
$openvswitch_db_port = 58882,
$libvirt_port = 16509,
$nrpe_server_port = 5666,
$ceilometer_port = 8777,
$heat_api_port = 8004,
$dhcp_server_port = 67,
$dns_server_port = 53,
$erlang_epmd_port = 4369,
$erlang_inet_dist_port = 41055,
$erlang_rabbitmq_backend_port = 5673,
$erlang_rabbitmq_port = 5672,
$galera_clustercheck_port = 49000,
$galera_ist_port = 4568,
$glance_api_port = 9292,
$glance_nova_api_ec2_port = 8773,
$glance_reg_port = 9191,
$heat_api_cfn_port = 8000,
$heat_api_cloudwatch_port = 8003,
$heat_api_port = 8004,
$http_port = 80,
$https_port = 443,
$iscsi_port = 3260,
$keystone_admin_port = 35357,
$keystone_public_port = 5000,
$libvirt_migration_ports = '49152-49215',
$libvirt_port = 16509,
$memcached_port = 11211,
$mongodb_port = 27017,
$mysql_backend_port = 3307,
$mysql_gcomm_port = 4567,
$mysql_port = 3306,
$neutron_api_port = 9696,
$nova_api_compute_port = 8774,
$nova_api_metadata_port = 8775,
$nova_api_vnc_ports = '5900-6100',
$nova_api_volume_port = 8776,
$nova_vncproxy_port = 6080,
$nrpe_server_port = 5666,
$ntp_server_port = 123,
$openvswitch_db_port = 58882,
$pcsd_port = 2224,
$rsync_port = 873,
$ssh_port = 22,
$swift_account_port = 6002,
$swift_container_port = 6001,
$swift_object_port = 6000,
$swift_proxy_check_port = 49001,
$swift_proxy_port = 8080,
$vxlan_udp_port = 4789,
$keystone_network = '0.0.0.0/0',
) {
# file {"iptables":
# path => $operatingsystem ? {
# /(Debian|Ubuntu)/ => '/etc/network/rules.v4',
# /(RedHat|CentOS)/ => '/etc/sysconfig/iptables',
# },
# source => "puppet:///modules/openstack/iptables"
# }->
#
# exec { 'startup-firewall':
# command => $operatingsystem ? {
# /(Debian|Ubuntu)/ => '/sbin/iptables-restore /etc/network/rules.v4',
# /(RedHat|CentOS)/ => '/sbin/iptables-restore /etc/sysconfig/iptables',
# }
# }
# }
class {'::firewall':}
firewall { "000 accept all icmp requests":
firewall { '000 accept all icmp requests':
proto => 'icmp',
action => 'accept',
}->
@ -81,15 +283,16 @@ class openstack::firewall (
}->
firewall { '002 accept related established rules':
proto => 'all',
state => ['RELATED', 'ESTABLISHED'],
action => 'accept',
proto => 'all',
state => ['RELATED', 'ESTABLISHED'],
action => 'accept',
}
firewall {'020 ssh':
port => $ssh_port,
proto => 'tcp',
action => 'accept',
openstack::firewall::multi_net {'020 ssh':
port => $ssh_port,
proto => 'tcp',
action => 'accept',
source_nets => concat($admin_nets, $management_nets, $storage_nets),
}
firewall { '100 http':
@ -98,17 +301,19 @@ class openstack::firewall (
action => 'accept',
}
firewall {'101 mysql':
port => [$mysql_port, $mysql_backend_port, $mysql_gcomm_port, $galera_ist_port, $galera_clustercheck_port],
proto => 'tcp',
action => 'accept',
openstack::firewall::multi_net {'101 mysql':
port => [$mysql_port, $mysql_backend_port, $mysql_gcomm_port,
$galera_ist_port, $galera_clustercheck_port],
proto => 'tcp',
action => 'accept',
source_nets => $management_nets,
}
firewall {'102 keystone':
port => [$keystone_public_port,$keystone_admin_port],
proto => 'tcp',
action => 'accept',
destination => "${keystone_network}",
destination => $keystone_network,
}
firewall {'103 swift':
@ -125,59 +330,73 @@ class openstack::firewall (
}
firewall {'105 nova':
port => [$nova_api_compute_port,$nova_api_volume_port, $nova_vncproxy_port],
port => [$nova_api_compute_port,$nova_api_volume_port,
$nova_vncproxy_port],
proto => 'tcp',
action => 'accept',
}
firewall {'105 nova private - no ssl':
port => $nova_api_metadata_port,
proto => 'tcp',
source => $nova_api_ip_range,
action => 'accept',
openstack::firewall::multi_net {'105 nova internal - no ssl':
port => [$nova_api_metadata_port, $nova_api_vnc_ports],
proto => 'tcp',
action => 'accept',
source_nets => $management_nets,
}
firewall {'106 rabbitmq ':
port => [$erlang_epmd_port, $erlang_rabbitmq_port, $erlang_rabbitmq_backend_port, $erlang_inet_dist_port],
proto => 'tcp',
action => 'accept',
openstack::firewall::multi_net {'106 rabbitmq':
port => [$erlang_epmd_port, $erlang_rabbitmq_port,
$erlang_rabbitmq_backend_port, $erlang_inet_dist_port],
proto => 'tcp',
action => 'accept',
source_nets => $management_nets,
}
firewall {'107 memcached tcp':
port => $memcached_port,
proto => 'tcp',
action => 'accept',
openstack::firewall::multi_net {'107 memcache tcp':
port => $memcached_port,
proto => 'tcp',
action => 'accept',
source_nets => $management_nets,
}
firewall {'107 memcached udp':
port => $memcached_port,
proto => 'udp',
action => 'accept',
openstack::firewall::multi_net {'107 memcache udp':
port => $memcached_port,
proto => 'udp',
action => 'accept',
source_nets => $management_nets,
}
firewall {'108 rsync':
port => $rsync_port,
proto => 'tcp',
action => 'accept',
openstack::firewall::multi_net {'108 rsync':
port => $rsync_port,
proto => 'tcp',
action => 'accept',
source_nets => concat($management_nets, $storage_nets),
}
firewall {'109 iscsi ':
openstack::firewall::multi_net {'109 iscsi':
port => $iscsi_port,
proto => 'tcp',
destination => $iscsi_ip,
action => 'accept',
source_nets => $storage_nets,
}
firewall {'110 neutron ':
firewall {'110 neutron':
port => $neutron_api_port,
proto => 'tcp',
action => 'accept',
}
firewall {'111 dns-server':
port => $dns_server_port,
proto => 'udp',
action => 'accept',
openstack::firewall::multi_net {'111 dns-server udp':
port => $dns_server_port,
proto => 'udp',
action => 'accept',
source_nets => $management_nets,
}
openstack::firewall::multi_net {'111 dns-server tcp':
port => $dns_server_port,
proto => 'tcp',
action => 'accept',
source_nets => $management_nets,
}
firewall {'111 dhcp-server':
@ -186,96 +405,103 @@ class openstack::firewall (
action => 'accept',
}
firewall {'112 ntp-server':
port => $ntp_server_port,
proto => 'udp',
action => 'accept',
openstack::firewall::multi_net {'112 ntp-server':
port => $ntp_server_port,
proto => 'udp',
action => 'accept',
source_nets => $management_nets,
}
firewall {'113 corosync-input':
port => $corosync_input_port,
proto => 'udp',
action => 'accept',
openstack::firewall::multi_net {'113 corosync-input':
port => $corosync_input_port,
proto => 'udp',
action => 'accept',
source_nets => $management_nets,
}
firewall {'114 corosync-output':
port => $corosync_output_port,
proto => 'udp',
action => 'accept',
openstack::firewall::multi_net {'114 corosync-output':
port => $corosync_output_port,
proto => 'udp',
action => 'accept',
source_nets => $management_nets,
}
firewall {'115 pcsd-server':
port => $pcsd_port,
proto => 'tcp',
action => 'accept',
openstack::firewall::multi_net {'115 pcsd-server':
port => $pcsd_port,
proto => 'tcp',
action => 'accept',
source_nets => $management_nets,
}
firewall {'116 openvswitch db':
port => $openvswitch_db_port,
proto => 'udp',
action => 'accept',
openstack::firewall::multi_net {'116 openvswitch db':
port => $openvswitch_db_port,
proto => 'udp',
action => 'accept',
source_nets => $management_nets,
}
firewall {'117 nrpe-server':
port => $nrpe_server_port,
proto => 'tcp',
action => 'accept',
openstack::firewall::multi_net {'117 nrpe-server':
port => $nrpe_server_port,
proto => 'udp',
action => 'accept',
source_nets => concat($admin_nets, $management_nets),
}
firewall {'118 libvirt':
port => $libvirt_port,
proto => 'tcp',
action => 'accept',
source => "${libvirt_network}",
openstack::firewall::multi_net {'118 libvirt':
port => $libvirt_port,
proto => 'tcp',
action => 'accept',
source_nets => $management_nets,
}
firewall {'119 libvirt migration':
port => '49152-49215',
proto => 'tcp',
action => 'accept',
openstack::firewall::multi_net {'119 libvirt-migration':
port => $libvirt_migration_ports,
proto => 'tcp',
action => 'accept',
source_nets => $management_nets,
}
firewall {'121 ceilometer':
port => $ceilometer_port,
proto => 'tcp',
port => $ceilometer_port,
proto => 'tcp',
action => 'accept',
}
firewall {'204 heat-api':
port => $heat_api_port,
port => $heat_api_port,
proto => 'tcp',
action => 'accept',
}
firewall {'205 heat-api-cfn':
port => $heat_api_cfn_port,
port => $heat_api_cfn_port,
proto => 'tcp',
action => 'accept',
}
firewall {'206 heat-api-cloudwatch':
port => $heat_api_cloudwatch_port,
port => $heat_api_cloudwatch_port,
proto => 'tcp',
action => 'accept',
}
firewall { '333 notrack gre':
chain => 'PREROUTING',
table => 'raw',
proto => 'gre',
chain => 'PREROUTING',
table => 'raw',
proto => 'gre',
jump => 'NOTRACK',
}
firewall { '334 accept gre':
chain => 'INPUT',
table => 'filter',
proto => 'gre',
action => 'accept',
chain => 'INPUT',
table => 'filter',
proto => 'gre',
action => 'accept',
}
firewall {'340 vxlan_udp_port':
port => $vxlan_udp_port,
proto => 'udp',
port => $vxlan_udp_port,
proto => 'udp',
action => 'accept',
}
@ -285,6 +511,5 @@ class openstack::firewall (
action => 'drop',
}
openstack::firewall::vnc { $nova_vnc_ip_range: }
}

View File

@ -1,10 +0,0 @@
define openstack::firewall::allow (
) {
::firewall { "100 snat for port $title":
chain => 'INPUT',
action => 'accept',
proto => 'tcp',
dport => $title,
table => 'filter',
}
}

View File

@ -0,0 +1,49 @@
# Create firewall rules for multiple source networks
#
# Parameters
#
# [*action*]
# Action to be taken.
#
# [*chain*]
# iptables chain to use
#
# [*iniface*]
# Apply rule only to specified interface
#
# [*port*]
# Network port for the iptables rule.
#
# [*proto*]
# Network port for the iptables rule.
#
# [*rule_name*]
# Name to identify firewall rule.
# Example: '100 allow ssh'
#
# [*source_nets*]
# Array of networks from which to accept connections.
#
define openstack::firewall::multi_net (
# From firewall
$action = undef,
$chain = undef,
$iniface = undef,
$port = undef,
$proto = undef,
# Custom
$rule_name = $title,
$source_nets = undef,
) {
validate_string($rule_name)
if ! is_array($source_nets) {
fail('This provider should only be used for multiple source_nets.')
}
$firewall_rule_hashes = prepare_firewall_rules($source_nets, $rule_name,
$action, $chain, $port, $proto)
create_resources('firewall', $firewall_rule_hashes)
}

View File

@ -1,8 +0,0 @@
define openstack::firewall::vnc ($net = $title) {
firewall {"120 vnc ports for $title":
port => '5900-6100',
proto => 'tcp',
source => $net,
action => 'accept',
}
}

View File

@ -1,20 +1,157 @@
require 'spec_helper'
describe 'openstack::firewall' do
let(:params) { {:nova_vnc_ip_range => ['1.2.3.0/24','2.3.4.0/24','3.4.5.0/24'],
:iscsi_ip => ['9.9.9.9']
let(:params) { {:admin_nets => ['admin_nets'],
:management_nets => ['management_nets'],
:public_nets => ['public_nets'],
:storage_nets => ['storage_nets'],
} }
let(:facts) { {:kernel => 'Linux'} }
it 'should contain firewall rules for all nova vnc ip ranges' do
should contain_firewall('120 vnc ports for 1.2.3.0/24')
should contain_firewall('120 vnc ports for 2.3.4.0/24')
should contain_firewall('120 vnc ports for 3.4.5.0/24')
it 'should contain firewall rules for ssh' do
should contain_openstack__firewall__multi_net('020 ssh').with(
:port => '22',
:proto => 'tcp',
:action => 'accept',
:source_nets => ['admin_nets', 'management_nets', 'storage_nets'],
)
end
it 'should contain firewall rule for iscsi addr' do
should contain_firewall('109 iscsi ').with(
:destination => '9.9.9.9',
it 'should contain firewall rules for mysql' do
should contain_openstack__firewall__multi_net('101 mysql').with(
:port => ['3306', '3307', '4567', '4568', '49000'],
:proto => 'tcp',
:action => 'accept',
:source_nets => ['management_nets'],
)
end
it 'should contain firewall rule from private nova services' do
should contain_openstack__firewall__multi_net('105 nova internal - no ssl').with(
:port => ['8775', '5900-6100'],
:proto => 'tcp',
:action => 'accept',
:source_nets => ['management_nets'],
)
end
it 'should contain firewall rules for rabbitmq' do
should contain_openstack__firewall__multi_net('106 rabbitmq').with(
:port => ['4369','5672','5673','41055'],
:proto => 'tcp',
:action => 'accept',
:source_nets => ['management_nets'],
)
end
it 'should contain firewall rules for memcache' do
should contain_openstack__firewall__multi_net('107 memcache tcp').with(
:port => '11211',
:proto => 'tcp',
:action => 'accept',
:source_nets => ['management_nets'],
)
should contain_openstack__firewall__multi_net('107 memcache udp').with(
:port => '11211',
:proto => 'udp',
:action => 'accept',
:source_nets => ['management_nets'],
)
end
it 'should contain firewall rules for rsync' do
should contain_openstack__firewall__multi_net('108 rsync').with(
:port => '873',
:proto => 'tcp',
:action => 'accept',
:source_nets => ['management_nets', 'storage_nets'],
)
end
it 'should contain firewall rules for iscsi' do
should contain_openstack__firewall__multi_net('109 iscsi').with(
:port => '3260',
:proto => 'tcp',
:action => 'accept',
:source_nets => ['storage_nets'],
)
end
it 'should contain firewall rules for dns-server' do
should contain_openstack__firewall__multi_net('111 dns-server udp').with(
:port => '53',
:proto => 'udp',
:action => 'accept',
:source_nets => ['management_nets'],
)
should contain_openstack__firewall__multi_net('111 dns-server tcp').with(
:port => '53',
:proto => 'tcp',
:action => 'accept',
:source_nets => ['management_nets'],
)
end
it 'should contain firewall rules for ntp-server' do
should contain_openstack__firewall__multi_net('112 ntp-server').with(
:port => '123',
:proto => 'udp',
:action => 'accept',
:source_nets => ['management_nets'],
)
end
it 'should contain firewall rules for corosync' do
should contain_openstack__firewall__multi_net('113 corosync-input').with(
:port => '5404',
:proto => 'udp',
:action => 'accept',
:source_nets => ['management_nets'],
)
should contain_openstack__firewall__multi_net('114 corosync-output').with(
:port => '5405',
:proto => 'udp',
:action => 'accept',
:source_nets => ['management_nets'],
)
should contain_openstack__firewall__multi_net('115 pcsd-server').with(
:port => '2224',
:proto => 'tcp',
:action => 'accept',
:source_nets => ['management_nets'],
)
end
it 'should contain firewall rules for ovs' do
should contain_openstack__firewall__multi_net('116 openvswitch db').with(
:port => '58882',
:proto => 'udp',
:action => 'accept',
:source_nets => ['management_nets'],
)
end
it 'should contain firewall rules for nrpe' do
should contain_openstack__firewall__multi_net('117 nrpe-server').with(
:port => '5666',
:proto => 'udp',
:action => 'accept',
:source_nets => ['admin_nets', 'management_nets'],
)
end
it 'should contain firewall rules for libvirt' do
should contain_openstack__firewall__multi_net('118 libvirt').with(
:port => '16509',
:proto => 'tcp',
:action => 'accept',
:source_nets => ['management_nets'],
)
should contain_openstack__firewall__multi_net('119 libvirt-migration').with(
:port => '49152-49215',
:proto => 'tcp',
:action => 'accept',
:source_nets => ['management_nets'],
)
end
end

View File

@ -0,0 +1,53 @@
require 'spec_helper'
describe 'openstack::firewall::multi_net' do
let(:default_params) { {
:source_nets => [],
} }
context 'with ssh rule config' do
let(:title) { '020 ssh' }
let(:params) { {
:action => 'accept',
:port => '22',
:proto => 'tcp',
:source_nets => ['10.20.0.0/24'],
} }
it 'contains ssh firewall rule' do
should contain_firewall("020 ssh from 10.20.0.0/24").with(
:action => 'accept',
:port => '22',
:proto => 'tcp',
:source => '10.20.0.0/24',
)
end
end
context 'with icmp block rule config' do
let(:title) { '299 icmp' }
let(:params) { {
:action => 'drop',
:chain => 'INPUT',
:proto => 'icmp',
:source_nets => ['120.0.0.0/8', '12.34.56.78/32'],
} }
it 'contains ssh firewall rule' do
should contain_firewall("299 icmp from 120.0.0.0/8").with(
:action => 'drop',
:chain => 'INPUT',
:proto => 'icmp',
:source => '120.0.0.0/8',
)
should contain_firewall("299 icmp from 12.34.56.78/32").with(
:action => 'drop',
:chain => 'INPUT',
:proto => 'icmp',
:source => '12.34.56.78/32',
)
end
end
end

View File

@ -0,0 +1,74 @@
require 'puppet'
require 'spec_helper'
describe 'function to prepare hash of firewall rules for multiple networks' do
def setup_scope
@compiler = Puppet::Parser::Compiler.new(Puppet::Node.new("floppy", :environment => 'production'))
if Puppet.version =~ /^3\./
@scope = Puppet::Parser::Scope.new(@compiler)
else
@scope = Puppet::Parser::Scope.new(:compiler => @compiler)
end
@topscope = @topscope
@scope.parent = @topscope
Puppet::Parser::Functions.function(:prepare_firewall_rules)
end
describe 'basic tests' do
before :each do
setup_scope
end
it "should exist" do
Puppet::Parser::Functions.function(:prepare_firewall_rules).should == "function_prepare_firewall_rules"
end
it 'error if no arguments' do
lambda { @scope.function_prepare_firewall_rules([]) }.should \
raise_error(ArgumentError,
'prepare_firewall_rules(): wrong number of arguments (0; must be 6)')
end
it 'should require six arguments' do
lambda { @scope.function_prepare_firewall_rules(
['a','b','c','d','e','f', 'g']) }.should \
raise_error(ArgumentError,
'prepare_firewall_rules(): wrong number of arguments (7; must be 6)')
end
it 'should require rule_basename to be a string' do
lambda {
@scope.function_prepare_firewall_rules([['0.0.0.0/0'],
{'hash' => 'notastring'},nil,nil,nil,nil]) }.should \
raise_error(ArgumentError,
'prepare_firewall_rules(): rule_basename is not a string')
end
it 'should require source_nets to be an array of strings' do
lambda {
@scope.function_prepare_firewall_rules([['0.0.0.0/0', nil],
'020 ssh',nil,nil,nil,nil]) }.should \
raise_error(ArgumentError,
'prepare_firewall_rules(): source_net is not an array of strings')
end
it 'should be able to prepare an ssh rule' do
result = {
'020 ssh from 10.0.0.0/24' => {'action' => 'accept',
'port' => '22',
'proto' => 'tcp',
'source' => '10.0.0.0/24'},
'020 ssh from 10.0.1.0/24' => {'action' => 'accept',
'port' => '22',
'proto' => 'tcp',
'source' => '10.0.1.0/24'},
}
expect(@scope.function_prepare_firewall_rules([['10.0.0.0/24',
'10.0.1.0/24'],'020 ssh', 'accept', nil, '22', 'tcp'])).to eq result
end
end
end

View File

@ -3,6 +3,12 @@ notice('MODULAR: firewall.pp')
$network_scheme = hiera_hash('network_scheme')
$ironic_hash = hiera_hash('ironic', {})
$admin_nets = get_routable_networks_for_network_role($network_scheme, 'admin/pxe')
$public_nets = get_routable_networks_for_network_role($network_scheme, 'ex')
$management_nets = get_routable_networks_for_network_role($network_scheme, 'management')
$storage_nets = get_routable_networks_for_network_role($network_scheme, 'storage')
# Workaround for fuel bug with firewall
firewall {'003 remote rabbitmq ':
sport => [ 4369, 5672, 41055, 55672, 61613 ],
@ -46,11 +52,11 @@ firewall {'030 allow connections from haproxy namespace':
prepare_network_config(hiera_hash('network_scheme'))
class { 'openstack::firewall' :
nova_vnc_ip_range => get_routable_networks_for_network_role($network_scheme, 'nova/api'),
nova_api_ip_range => get_network_role_property('nova/api', 'network'),
libvirt_network => get_network_role_property('management', 'network'),
admin_nets => $admin_nets,
public_nets => $public_nets,
management_nets => $management_nets,
storage_nets => $storage_nets,
keystone_network => get_network_role_property('keystone/api', 'network'),
iscsi_ip => get_network_role_property('cinder/iscsi', 'ipaddr'),
}
if $ironic_hash['enabled'] {

View File

@ -18,18 +18,13 @@ describe manifest do
Noop.puppet_function 'get_network_role_property', 'keystone/api', 'network'
end
let(:nova_vnc_ip_range) do
let(:management_nets) do
prepare
Noop.puppet_function 'get_routable_networks_for_network_role', network_scheme, 'nova/api'
Noop.puppet_function 'get_routable_networks_for_network_role', network_scheme, 'management'
end
let(:nova_api_ip_range) do
let(:storage_nets) do
prepare
Noop.puppet_function 'get_routable_networks_for_network_role', network_scheme, 'nova/api'
end
let(:iscsi_ip) do
Noop.puppet_function 'get_network_role_property', 'cinder/iscsi', 'ipaddr'
Noop.puppet_function 'get_routable_networks_for_network_role', network_scheme, 'storage'
end
let(:baremetal_network) do
@ -72,32 +67,25 @@ describe manifest do
end
it 'should accept connections to nova without ssl' do
should contain_firewall('105 nova private - no ssl').with(
'port' => [ 8775 ],
'proto' => 'tcp',
'action' => 'accept',
'source' => nova_api_ip_range,
)
end
it 'should accept connections to vnc' do
nova_vnc_ip_range.each do |source|
should contain_firewall("120 vnc ports for #{source}").with(
'port' => '5900-6100',
'proto' => 'tcp',
'source' => source,
'action' => 'accept',
management_nets.each do |source|
should contain_firewall("105 nova internal - no ssl from #{source}").with(
'port' => [ 8775, '5900-6100' ],
'proto' => 'tcp',
'action' => 'accept',
'source' => source,
)
end
end
it 'should accept connections to iscsi' do
should contain_firewall('109 iscsi ').with(
'port' => [ 3260 ],
'proto' => 'tcp',
'destination' => iscsi_ip,
'action' => 'accept',
)
storage_nets.each do |source|
should contain_firewall("109 iscsi from #{source}").with(
'port' => [ 3260 ],
'proto' => 'tcp',
'action' => 'accept',
'source' => source,
)
end
end
it 'should create rules for heat' do