Improve firewall rules for Fuel Master

Replaces hardcoded functions to create iptables
rules for Nailgun and Cobbler with firewall module
managed rules. Restricts network access to Fuel
Master for all services (except Fuel Web/API) to
Admin Network, plus restricts postgres to localhost
access only.

blueprint master-node-iptables-ruleset

Change-Id: Ib5d0c554bf97957c45b206b8bf4f6e64c9be109f
This commit is contained in:
Matthew Mosesohn 2014-06-23 21:41:37 +04:00
parent 967c047bf5
commit 3a418e3420
8 changed files with 247 additions and 121 deletions

View File

@ -13,29 +13,9 @@
# under the License.
class cobbler::iptables {
define access_to_cobbler_port($port, $protocol='tcp') {
$rule = "-p $protocol -m state --state NEW -m $protocol --dport $port -j ACCEPT"
case $operatingsystem {
/(?i)(centos|redhat)/: {
exec { "access_to_cobbler_${protocol}_port: $port":
command => "iptables -t filter -I INPUT 1 $rule; \
/etc/init.d/iptables save",
unless => "iptables -t filter -S INPUT | grep -q \"^-A INPUT $rule\"",
path => '/usr/bin:/bin:/usr/sbin:/sbin',
}
}
/(?i)(debian|ubuntu)/: {
exec { "access_to_cobbler_${protocol}_port: $port":
command => "iptables -t filter -I INPUT 1 $rule; \
iptables-save -c > /etc/iptables.rules",
unless => "iptables -t filter -S INPUT | grep -q \"^-A INPUT $rule\"",
path => '/usr/bin:/bin:/usr/sbin:/sbin',
}
}
}
}
class cobbler::iptables (
$chain = "INPUT",
) {
case $operatingsystem {
/(?i)(debian|ubuntu)/:{
@ -54,32 +34,40 @@ class cobbler::iptables {
}
}
# HERE IS IPTABLES RULES TO MAKE COBBLER AVAILABLE FROM OUTSIDE
# https://github.com/cobbler/cobbler/wiki/Using%20Cobbler%20Import
# SSH
access_to_cobbler_port { "ssh": port => '22' }
# DNS
access_to_cobbler_port { "dns_tcp": port => '53' }
access_to_cobbler_port { "dns_udp": port => '53', protocol => 'udp' }
# DHCP
access_to_cobbler_port { "dhcp_67": port => '67', protocol => 'udp' }
access_to_cobbler_port { "dhcp_68": port => '68', protocol => 'udp' }
# SQUID PROXY
access_to_cobbler_port { "http_3128": port => '3128',protocol => 'tcp' }
# PXE
access_to_cobbler_port { "pxe_4011": port => '4011',protocol => 'udp' }
# TFTP
access_to_cobbler_port { "tftp_tcp": port => '69' }
access_to_cobbler_port { "tftp_udp": port => '69', protocol => 'udp' }
# NTP
access_to_cobbler_port { "ntp_udp": port => '123', protocol => 'udp' }
# HTTP/HTTPS
access_to_cobbler_port { "http": port => '80' }
access_to_cobbler_port { "https": port => '443'}
# SYSLOG FOR COBBLER
access_to_cobbler_port { "syslog_tcp": port => '25150'}
# xmlrpc API
access_to_cobbler_port { "xmlrpc_api": port => '25151' }
firewall { '101 dns_tcp':
chain => $chain,
port => '53',
proto => 'tcp',
action => 'accept',
}
firewall { '102 dns_udp':
chain => $chain,
port => '53',
proto => 'udp',
action => 'accept',
}
firewall { '103 dhcp':
chain => $chain,
port => ['67','68'],
proto => 'udp',
action => 'accept',
}
firewall { '104 tftp':
chain => $chain,
port => '69',
proto => 'udp',
action => 'accept',
}
firewall { '110 squidproxy':
chain => $chain,
port => '3128',
proto => 'tcp',
action => 'accept',
}
firewall { '111 cobbler_web':
chain => $chain,
port => ['80','443'],
proto => 'tcp',
action => 'accept',
}
}

View File

@ -1,8 +1,9 @@
class docker::dockerctl (
$bin_dir = '/usr/bin',
$share_dir = '/usr/share/dockerctl',
$config_dir = '/etc/dockerctl',
$profile_dir = '/etc/profile.d',
$bin_dir = '/usr/bin',
$share_dir = '/usr/share/dockerctl',
$config_dir = '/etc/dockerctl',
$profile_dir = '/etc/profile.d',
$admin_ipaddress = $::fuel_settings['ADMIN_NETWORK']['ipaddress'],
$release,
$production,
) {

View File

@ -1,4 +1,5 @@
class docker (
$admin_ipaddress = $::fuel_settings['ADMIN_NETWORK']['ipaddress'],
$limit = "102400",
$docker_package = "docker-io",
$docker_service = "docker",

View File

@ -9,6 +9,9 @@ SOURCE_DIR="${DOCKER_ROOT}/sources"
#SUPERVISOR_CONF_DIR="${docker_root}/supervisor"
#SUPERVISOR_CONF_DIR="<%= @config_dir %>/supervisor/"
ASTUTE_YAML="<%= @astute_settings_file %>"
ADMIN_IP="<%= @admin_ipaddress %>"
LOCAL_IP="127.0.0.1"
#Version of Fuel to deploy
VERSION=$(awk '/release/{gsub(/"/, "");print $2}' /etc/fuel/version.yaml || echo <%= @release %>)
IMAGE_PREFIX="fuel"
@ -60,17 +63,20 @@ declare -A CONTAINER_OPTIONS
base_opts="-t"
FOREGROUND="-i"
BACKGROUND="-d"
CONTAINER_OPTIONS["cobbler"]="-p 53:53/udp -p 69:69/udp -p 80:80 -p 443:443 --privileged $base_opts"
CONTAINER_OPTIONS["postgres"]="-p 5432:5432 $base_opts"
CONTAINER_OPTIONS["rabbitmq"]="-p 5672:5672 -p 4369:4369 -p 15672:15672 -p 61613:61613 $base_opts"
CONTAINER_OPTIONS["rsync"]="-p 873:873 $base_opts"
BIND_ALL=""
BIND_ADMIN="${ADMIN_IP}:"
BIND_LOCAL="${LOCAL_IP}:"
CONTAINER_OPTIONS["cobbler"]="-p ${BIND_ADMIN}53:53/udp -p ${BIND_LOCAL}53:53/udp -p ${BIND_ADMIN}69:69/udp -p ${BIND_LOCAL}69:69/udp -p ${BIND_ALL}80:80 -p ${BIND_ALL}443:443 --privileged $base_opts"
CONTAINER_OPTIONS["postgres"]="-p ${BIND_ADMIN}5432:5432 -p ${BIND_LOCAL}5432:5432 $base_opts"
CONTAINER_OPTIONS["rabbitmq"]="-p ${BIND_ADMIN}5672:5672 -p ${BIND_LOCAL}5672:5672 -p ${BIND_ADMIN}4369:4369 -p ${BIND_LOCAL}4369:4369 -p ${BIND_ADMIN}15672:15672 -p ${BIND_LOCAL}15672:15672 -p ${BIND_ADMIN}61613:61613 -p ${BIND_LOCAL}61613:61613 $base_opts"
CONTAINER_OPTIONS["rsync"]="-p ${BIND_ADMIN}873:873 -p ${BIND_LOCAL}873:873 $base_opts"
CONTAINER_OPTIONS["astute"]="$base_opts"
CONTAINER_OPTIONS["nailgun"]="-v /etc/nailgun -p 8001:8001 $base_opts"
CONTAINER_OPTIONS["ostf"]="-p 8777:8777 $base_opts"
CONTAINER_OPTIONS["nginx"]="-p 8000:8000 -p 8080:8080 $base_opts"
CONTAINER_OPTIONS["rsyslog"]="--privileged -p 514:514 -p 514:514/udp -p 25150 $base_opts"
CONTAINER_OPTIONS["nailgun"]="-v /etc/nailgun -p ${BIND_ADMIN}8001:8001 -p ${BIND_LOCAL}8001:8001 $base_opts"
CONTAINER_OPTIONS["ostf"]="-p ${BIND_ADMIN}8777:8777 -p ${BIND_LOCAL}8777:8777 $base_opts"
CONTAINER_OPTIONS["nginx"]="-p ${BIND_ALL}8000:8000 -p ${BIND_ALL}8080:8080 $base_opts"
CONTAINER_OPTIONS["rsyslog"]="--privileged -p ${BIND_ADMIN}514:514 -p ${BIND_LOCAL}514:514 -p ${BIND_ADMIN}514:514/udp -p ${BIND_LOCAL}514:514/udp -p ${BIND_ADMIN}25150:25150 -p ${BIND_LOCAL}25150:25150 $base_opts"
CONTAINER_OPTIONS["mcollective"]="--privileged $base_opts"
CONTAINER_OPTIONS["keystone"]="-p 5000:5000 -p 35357:35357 $base_opts"
CONTAINER_OPTIONS["keystone"]="-p ${BIND_ALL}5000:5000 -p ${BIND_ALL}35357:35357 $base_opts"
######
#DRAFT: Dependency of volumes for deployment

View File

@ -106,20 +106,20 @@ function check_ready {
failure=0
echo "checking container $1"
case $1 in
nailgun) retry_checker '[ $(curl --connect-timeout 1 -s -w %{http_code} http://127.0.0.1:8000/api/version -o /dev/null) = "200" ]' ;;
ostf) retry_checker '[ $(curl --connect-timeout 1 -s -w '%{http_code}' http://127.0.0.1:8000/ostf/not_found -o /dev/null) = "404" ]' ;;
nailgun) retry_checker "grep -q 200 < <(curl --connect-timeout 1 -s -w %{http_code} http://$ADMIN_IP:8000/api/version -o /dev/null)" ;;
ostf) retry_checker "grep -q 404 < <(curl --connect-timeout 1 -s -w '%{http_code}' http://$ADMIN_IP:8000/ostf/not_found -o /dev/null)" ;;
#NOTICE: Cobbler console tool does not comply unix conversation: 'cobbler profile find' always return 0 as exit code
cobbler) retry_checker "shell_container cobbler ps aux | grep -q 'cobblerd -F'"
retry_checker "shell_container cobbler cobbler profile find --name=centos* | grep -q centos"
retry_checker "shell_container cobbler cobbler profile find --name=ubuntu* | grep -q ubuntu"
retry_checker "shell_container cobbler cobbler profile find --name=bootstrap* | grep -q bootstrap" ;;
rabbitmq) retry_checker "curl -f -L -i -u \"$astute_user:$astute_password\" http://127.0.0.1:15672/api/nodes 1>/dev/null 2>&1"
retry_checker "curl -f -L -u \"$mcollective_user:$mcollective_password\" -s http://127.0.0.1:15672/api/exchanges | grep -qw 'mcollective_broadcast'"
retry_checker "curl -f -L -u \"$mcollective_user:$mcollective_password\" -s http://127.0.0.1:15672/api/exchanges | grep -qw 'mcollective_directed'" ;;
postgres) retry_checker "PGPASSWORD=$postgres_nailgun_password shell_container postgres psql -h 127.0.0.1 -U \"$postgres_nailgun_user\" \"$postgres_nailgun_dbname\" -c '\copyright' 2>&1 1>/dev/null" ;;
rabbitmq) retry_checker "curl -f -L -i -u \"$astute_user:$astute_password\" http://$ADMIN_IP:15672/api/nodes 1>/dev/null 2>&1"
retry_checker "curl -f -L -u \"$mcollective_user:$mcollective_password\" -s http://$ADMIN_IP:15672/api/exchanges | grep -qw 'mcollective_broadcast'"
retry_checker "curl -f -L -u \"$mcollective_user:$mcollective_password\" -s http://$ADMIN_IP:15672/api/exchanges | grep -qw 'mcollective_directed'" ;;
postgres) retry_checker "PGPASSWORD=$postgres_nailgun_password shell_container postgres psql -h $ADMIN_IP -U \"$postgres_nailgun_user\" \"$postgres_nailgun_dbname\" -c '\copyright' 2>&1 1>/dev/null" ;;
astute) retry_checker "shell_container astute ps aux | grep -q 'astuted'"
retry_checker "curl -f -L -u \"$astute_user:$astute_password\" -s http://127.0.0.1:15672/api/exchanges | grep -qw 'nailgun'"
retry_checker "curl -f -L -u \"$astute_user:$astute_password\" -s http://127.0.0.1:15672/api/exchanges | grep -qw 'naily_service'" ;;
retry_checker "curl -f -L -u \"$astute_user:$astute_password\" -s http://$ADMIN_IP:15672/api/exchanges | grep -qw 'nailgun'"
retry_checker "curl -f -L -u \"$astute_user:$astute_password\" -s http://$ADMIN_IP:15672/api/exchanges | grep -qw 'naily_service'" ;;
rsync) retry_checker "shell_container rsync netstat -ntl | grep -q 873" ;;
rsyslog) retry_checker "shell_container rsyslog netstat -nl | grep -q 514" ;;
mcollective) retry_checker "shell_container mcollective ps aux | grep -q mcollectived" ;;

View File

@ -34,8 +34,9 @@ class { "openstack::clocksync":
}
class { "docker::dockerctl":
release => $::fuel_version['VERSION']['release'],
production => $production,
release => $::fuel_version['VERSION']['release'],
production => $production,
admin_ipaddress => $::fuel_settings['ADMIN_NETWORK']['ipaddress'],
}
class { "docker": }

View File

@ -1,27 +1,179 @@
class nailgun::iptables {
define access_to_nailgun_port($port, $protocol='tcp') {
$rule = "-p $protocol -m state --state NEW -m $protocol --dport $port -j ACCEPT"
exec { "access_to_nailgun_${protocol}_port: $port":
command => "iptables -t filter -I INPUT 1 $rule; \
/etc/init.d/iptables save",
unless => "iptables -t filter -S INPUT | grep -q \"^-A INPUT $rule\""
}
}
define ip_forward($network) {
$rule = "-s $network ! -o docker0 -j MASQUERADE"
exec { "ip_forward: $network":
command => "iptables -t nat -I POSTROUTING 1 $rule; \
/etc/init.d/iptables save",
unless => "iptables -t nat -S POSTROUTING | grep -q \"^-A POSTROUTING $rule\""
}
sysctl::value{'net.ipv4.ip_forward': value=>'1'}
}
access_to_nailgun_port { "nailgun_web": port => '8000' }
access_to_nailgun_port { "nailgun_repo": port => '8080' }
class nailgun::iptables (
$production = 'docker',
$admin_iface = 'eth0',
$ssh_port = '22',
$nailgun_web_port = '8000',
$nailgun_internal_port = '8001',
$nailgun_repo_port = '8080',
$postgres_port = '5432',
$ostf_port = '8777',
$rsync_port = '873',
$rsyslog_port = '514',
$ntp_port = '123',
$rabbitmq_ports = ['4369','5672','15672','61613'],
$chain = 'INPUT',
)
{
#Host services
$network_address = ipcalc_network_by_address_netmask($::fuel_settings['ADMIN_NETWORK']['ipaddress'],$::fuel_settings['ADMIN_NETWORK']['netmask'])
$network_cidr = ipcalc_network_cidr_by_netmask($::fuel_settings['ADMIN_NETWORK']['netmask'])
ip_forward {'forward_slaves': network => "${network_address}/${network_cidr}"}
firewall { '004 forward_admin_net':
chain => 'POSTROUTING',
table => 'nat',
source => "${network_address}/${network_cidr}",
outiface => 'eth+',
jump => 'MASQUERADE',
}
sysctl::value{'net.ipv4.ip_forward': value=>'1'}
firewall { '005 ssh':
port => $ssh_port,
proto => 'tcp',
action => 'accept',
}
firewall { '006 ntp':
port => $ntp_port,
proto => 'tcp',
iniface => $admin_iface,
action => 'accept',
}
firewall { '007 ntp_udp':
port => $ntp_port,
proto => 'udp',
iniface => $admin_iface,
action => 'accept',
}
firewall { '008 snmp':
port => '162',
proto => 'udp',
action => 'accept',
}
#Containerized services
firewall { '009 nailgun_web':
chain => $chain,
port => $nailgun_web_port,
proto => 'tcp',
action => 'accept',
}
firewall { '010 nailgun_internal':
chain => $chain,
port => $nailgun_internal_port,
proto => 'tcp',
iniface => 'docker0',
action => 'accept',
}
firewall { '011 nailgun_internal_local':
chain => $chain,
port => $nailgun_internal_port,
proto => 'tcp',
src_type => "LOCAL",
action => 'accept',
}
firewall { '012 nailgun_internal_block_ext':
chain => $chain,
port => $nailgun_internal_port,
proto => 'tcp',
action => 'reject',
}
firewall { '013 postgres_local':
chain => $chain,
port => $postgres_port,
proto => 'tcp',
src_type => "LOCAL",
action => 'accept',
}
firewall { '014 postgres':
chain => $chain,
port => $postgres_port,
proto => 'tcp',
iniface => 'docker0',
action => 'accept',
}
firewall { '015 postgres_block_ext':
chain => $chain,
port => $postgres_port,
proto => 'tcp',
action => 'reject',
}
firewall { '020 ostf_admin':
chain => $chain,
port => $ostf_port,
proto => 'tcp',
iniface => $admin_iface,
action => 'accept',
}
firewall { '021 ostf_local':
chain => $chain,
port => $ostf_port,
proto => 'tcp',
src_type => "LOCAL",
action => 'accept',
}
firewall { '022 ostf_block_ext':
chain => $chain,
port => $ostf_port,
proto => 'tcp',
action => 'reject',
}
firewall { '023 rsync':
chain => $chain,
port => $rsync_port,
proto => 'tcp',
action => 'accept',
}
firewall { '024 rsyslog':
chain => $chain,
port => $rsync_port,
proto => 'tcp',
iniface => $admin_iface,
action => 'accept',
}
firewall { '040 rabbitmq_admin':
chain => $chain,
port => $rabbitmq_ports,
proto => 'tcp',
iniface => $admin_iface,
action => 'accept',
}
firewall { '041 rabbitmq_local':
chain => $chain,
port => $rabbitmq_ports,
proto => 'tcp',
src_type => "LOCAL",
action => 'accept',
}
firewall { '042 rabbitmq_block_ext':
chain => $chain,
port => $rabbitmq_ports,
proto => 'tcp',
action => 'reject',
}
firewall {'999 iptables denied':
chain => 'INPUT',
limit => '5/min',
jump => 'LOG',
log_prefix => 'iptables denied: ',
log_level => '7',
}
}

View File

@ -16,17 +16,6 @@ class nailgun::rabbitmq (
anchor { 'nailgun::rabbitmq start' :}
anchor { 'nailgun::rabbitmq end' :}
define access_to_rabbitmq_port ($port, $protocol = 'tcp') {
$rule = "-p $protocol -m state --state NEW -m $protocol --dport $port -j ACCEPT"
exec { "access_to_cobbler_${protocol}_port: $port":
command => "iptables -t filter -I INPUT 1 $rule; \
/etc/init.d/iptables save",
unless => "iptables -t filter -S INPUT | grep -q \"^-A INPUT $rule\"",
path => '/bin:/usr/bin:/sbin:/usr/sbin',
}
}
if $production =~ /docker/ {
#Known issue: ulimit is disabled inside docker containers
file { '/etc/default/rabbitmq-server':
@ -35,18 +24,6 @@ class nailgun::rabbitmq (
before => Service['rabbitmq-server'],
}
}
else {
case $::osfamily {
'Debian' : {
}
'RedHat' : {
access_to_rabbitmq_port { "${stompport}_tcp": port => $stompport }
}
default : {
fail("Unsupported osfamily: ${osfamily} for os ${operatingsystem}")
}
}
}
rabbitmq_user { $astute_user:
admin => true,