diff options
author | Vishvananda Ishaya <vishvananda@yahoo.com> | 2010-09-29 03:28:20 +0000 |
---|---|---|
committer | Tarmac <> | 2010-09-29 03:28:20 +0000 |
commit | 3ebea539c25f913a22f86e7dd500bf5d7771614f (patch) | |
tree | ba8c975713f645a3c42e48f30659a9d6ad86490d | |
parent | 9b7fc3e3051b32bb944ef9dd0a3edfe1afcd245c (diff) | |
parent | bc88c73a4e986289be7835b95ec97ffb7a50f7d7 (diff) | |
download | nova-3ebea539c25f913a22f86e7dd500bf5d7771614f.tar.gz nova-3ebea539c25f913a22f86e7dd500bf5d7771614f.tar.xz nova-3ebea539c25f913a22f86e7dd500bf5d7771614f.zip |
Updates the fix-iptables branch with a number of bugfixes.
-rw-r--r-- | nova/flags.py | 2 | ||||
-rw-r--r-- | nova/manager.py | 7 | ||||
-rw-r--r-- | nova/network/linux_net.py | 68 | ||||
-rw-r--r-- | nova/network/manager.py | 7 | ||||
-rw-r--r-- | nova/service.py | 1 | ||||
-rwxr-xr-x | tools/setup_iptables.sh | 158 |
6 files changed, 222 insertions, 21 deletions
diff --git a/nova/flags.py b/nova/flags.py index 6a1c14490..c32cdd7a4 100644 --- a/nova/flags.py +++ b/nova/flags.py @@ -188,6 +188,8 @@ DEFINE_string('rabbit_userid', 'guest', 'rabbit userid') DEFINE_string('rabbit_password', 'guest', 'rabbit password') DEFINE_string('rabbit_virtual_host', '/', 'rabbit virtual host') DEFINE_string('control_exchange', 'nova', 'the main exchange to connect to') +DEFINE_string('cc_host', '127.0.0.1', 'ip of api server') +DEFINE_integer('cc_port', 8773, 'cloud controller port') DEFINE_string('ec2_url', 'http://127.0.0.1:8773/services/Cloud', 'Url to ec2 api server') diff --git a/nova/manager.py b/nova/manager.py index e9aa50c56..94e4ae959 100644 --- a/nova/manager.py +++ b/nova/manager.py @@ -37,3 +37,10 @@ class Manager(object): if not db_driver: db_driver = FLAGS.db_driver self.db = utils.import_object(db_driver) # pylint: disable-msg=C0103 + + def init_host(self): + """Do any initialization that needs to be run if this is a standalone service. + + Child classes should override this method. + """ + pass diff --git a/nova/network/linux_net.py b/nova/network/linux_net.py index b5346218a..709195ba4 100644 --- a/nova/network/linux_net.py +++ b/nova/network/linux_net.py @@ -36,13 +36,34 @@ flags.DEFINE_string('dhcpbridge_flagfile', flags.DEFINE_string('networks_path', utils.abspath('../networks'), 'Location to keep network config files') flags.DEFINE_string('public_interface', 'vlan1', - 'Interface for public IP addresses') + 'Interface for public IP addresses') flags.DEFINE_string('bridge_dev', 'eth0', - 'network device for bridges') - + 'network device for bridges') +flags.DEFINE_string('routing_source_ip', '127.0.0.1', + 'Public IP of network host') +flags.DEFINE_bool('use_nova_chains', False, + 'use the nova_ routing chains instead of default') DEFAULT_PORTS = [("tcp", 80), ("tcp", 22), ("udp", 1194), ("tcp", 443)] +def init_host(): + """Basic networking setup goes here""" + # NOTE(devcamcar): Cloud public DNAT entries, CloudPipe port + # forwarding entries and a default DNAT entry. + _confirm_rule("PREROUTING", "-t nat -s 0.0.0.0/0 " + "-d 169.254.169.254/32 -p tcp -m tcp --dport 80 -j DNAT " + "--to-destination %s:%s" % (FLAGS.cc_host, FLAGS.cc_port)) + + # NOTE(devcamcar): Cloud public SNAT entries and the default + # SNAT rule for outbound traffic. + _confirm_rule("POSTROUTING", "-t nat -s %s " + "-j SNAT --to-source %s" + % (FLAGS.private_range, FLAGS.routing_source_ip)) + + _confirm_rule("POSTROUTING", "-t nat -s %s -j MASQUERADE" % + FLAGS.private_range) + _confirm_rule("POSTROUTING", "-t nat -s %(range)s -d %(range)s -j ACCEPT" % + {'range': FLAGS.private_range}) def bind_floating_ip(floating_ip): """Bind ip to public interface""" @@ -58,37 +79,37 @@ def unbind_floating_ip(floating_ip): def ensure_vlan_forward(public_ip, port, private_ip): """Sets up forwarding rules for vlan""" - _confirm_rule("FORWARD -d %s -p udp --dport 1194 -j ACCEPT" % private_ip) - _confirm_rule( - "PREROUTING -t nat -d %s -p udp --dport %s -j DNAT --to %s:1194" + _confirm_rule("FORWARD", "-d %s -p udp --dport 1194 -j ACCEPT" % + private_ip) + _confirm_rule("PREROUTING", + "-t nat -d %s -p udp --dport %s -j DNAT --to %s:1194" % (public_ip, port, private_ip)) def ensure_floating_forward(floating_ip, fixed_ip): """Ensure floating ip forwarding rule""" - _confirm_rule("PREROUTING -t nat -d %s -j DNAT --to %s" + _confirm_rule("PREROUTING", "-t nat -d %s -j DNAT --to %s" % (floating_ip, fixed_ip)) - _confirm_rule("POSTROUTING -t nat -s %s -j SNAT --to %s" + _confirm_rule("POSTROUTING", "-t nat -s %s -j SNAT --to %s" % (fixed_ip, floating_ip)) # TODO(joshua): Get these from the secgroup datastore entries - _confirm_rule("FORWARD -d %s -p icmp -j ACCEPT" + _confirm_rule("FORWARD", "-d %s -p icmp -j ACCEPT" % (fixed_ip)) for (protocol, port) in DEFAULT_PORTS: - _confirm_rule( - "FORWARD -d %s -p %s --dport %s -j ACCEPT" + _confirm_rule("FORWARD","-d %s -p %s --dport %s -j ACCEPT" % (fixed_ip, protocol, port)) def remove_floating_forward(floating_ip, fixed_ip): """Remove forwarding for floating ip""" - _remove_rule("PREROUTING -t nat -d %s -j DNAT --to %s" + _remove_rule("PREROUTING", "-t nat -d %s -j DNAT --to %s" % (floating_ip, fixed_ip)) - _remove_rule("POSTROUTING -t nat -s %s -j SNAT --to %s" + _remove_rule("POSTROUTING", "-t nat -s %s -j SNAT --to %s" % (fixed_ip, floating_ip)) - _remove_rule("FORWARD -d %s -p icmp -j ACCEPT" + _remove_rule("FORWARD", "-d %s -p icmp -j ACCEPT" % (fixed_ip)) for (protocol, port) in DEFAULT_PORTS: - _remove_rule("FORWARD -d %s -p %s --dport %s -j ACCEPT" + _remove_rule("FORWARD", "-d %s -p %s --dport %s -j ACCEPT" % (fixed_ip, protocol, port)) @@ -124,9 +145,10 @@ def ensure_bridge(bridge, interface, net_attrs=None): net_attrs['gateway'], net_attrs['broadcast'], net_attrs['netmask'])) - _confirm_rule("FORWARD --in-interface %s -j ACCEPT" % bridge) else: _execute("sudo ifconfig %s up" % bridge) + _confirm_rule("FORWARD", "--in-interface %s -j ACCEPT" % bridge) + _confirm_rule("FORWARD", "--out-interface %s -j ACCEPT" % bridge) def get_dhcp_hosts(context, network_id): @@ -195,15 +217,19 @@ def _device_exists(device): return not err -def _confirm_rule(cmd): +def _confirm_rule(chain, cmd): """Delete and re-add iptables rule""" - _execute("sudo iptables --delete %s" % (cmd), check_exit_code=False) - _execute("sudo iptables -I %s" % (cmd)) + if FLAGS.use_nova_chains: + chain = "nova_%s" % chain.lower() + _execute("sudo iptables --delete %s %s" % (chain, cmd), check_exit_code=False) + _execute("sudo iptables -I %s %s" % (chain, cmd)) -def _remove_rule(cmd): +def _remove_rule(chain, cmd): """Remove iptables rule""" - _execute("sudo iptables --delete %s" % (cmd)) + if FLAGS.use_nova_chains: + chain = "%S" % chain.lower() + _execute("sudo iptables --delete %s %s" % (chain, cmd)) def _dnsmasq_cmd(net): diff --git a/nova/network/manager.py b/nova/network/manager.py index 7afc30d6c..a7126ea4f 100644 --- a/nova/network/manager.py +++ b/nova/network/manager.py @@ -218,6 +218,13 @@ class FlatManager(NetworkManager): class VlanManager(NetworkManager): """Vlan network with dhcp""" + + def init_host(self): + """Do any initialization that needs to be run if this is a + standalone service. + """ + self.driver.init_host() + def allocate_fixed_ip(self, context, instance_id, *args, **kwargs): """Gets a fixed ip from the pool""" network_ref = self.db.project_get_network(context, context.project.id) diff --git a/nova/service.py b/nova/service.py index 870dd6ceb..dcd2a09ef 100644 --- a/nova/service.py +++ b/nova/service.py @@ -50,6 +50,7 @@ class Service(object, service.Service): self.topic = topic manager_class = utils.import_class(manager) self.manager = manager_class(host=host, *args, **kwargs) + self.manager.init_host() self.model_disconnected = False super(Service, self).__init__(*args, **kwargs) try: diff --git a/tools/setup_iptables.sh b/tools/setup_iptables.sh new file mode 100755 index 000000000..673353eb4 --- /dev/null +++ b/tools/setup_iptables.sh @@ -0,0 +1,158 @@ +#!/usr/bin/env bash +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2010 United States Government as represented by the +# Administrator of the National Aeronautics and Space Administration. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +# NOTE(vish): This script sets up some reasonable defaults for iptables and +# creates nova-specific chains. If you use this script you should +# run nova-network and nova-compute with --use_nova_chains=True + +# NOTE(vish): If you run nova-api on a different port, make sure to change +# the port here +API_PORT=${API_PORT:-"8773"} +if [ -n "$1" ]; then + CMD=$1 +else + CMD="all" +fi + +if [ -n "$2" ]; then + IP=$2 +else + # NOTE(vish): This will just get the first ip in the list, so if you + # have more than one eth device set up, this will fail, and + # you should explicitly pass in the ip of the instance + IP=`ifconfig | grep -m 1 'inet addr:'| cut -d: -f2 | awk '{print $1}'` +fi + +if [ -n "$3" ]; then + PRIVATE_RANGE=$3 +else + PRIVATE_RANGE="10.0.0.0/12" +fi + + +if [ -n "$4" ]; then + # NOTE(vish): Management IP is the ip over which to allow ssh traffic. It + # will also allow traffic to nova-api + MGMT_IP=$4 +else + MGMT_IP="$IP" +fi +if [ "$CMD" == "clear" ]; then + iptables -P INPUT ACCEPT + iptables -P FORWARD ACCEPT + iptables -P OUTPUT ACCEPT + iptables -F + iptables -t nat -F + iptables -F nova_input + iptables -F nova_output + iptables -F nova_forward + iptables -t nat -F nova_input + iptables -t nat -F nova_output + iptables -t nat -F nova_forward + iptables -t nat -X + iptables -X +fi + +if [ "$CMD" == "base" ] || [ "$CMD" == "all" ]; then + iptables -P INPUT DROP + iptables -A INPUT -m state --state INVALID -j DROP + iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT + iptables -A INPUT -m tcp -p tcp -d $MGMT_IP --dport 22 -j ACCEPT + iptables -A INPUT -m udp -p udp --dport 123 -j ACCEPT + iptables -N nova_input + iptables -A INPUT -j nova_input + iptables -A INPUT -p icmp -j ACCEPT + iptables -A INPUT -p tcp -j REJECT --reject-with tcp-reset + iptables -A INPUT -j REJECT --reject-with icmp-port-unreachable + + iptables -P FORWARD DROP + iptables -A FORWARD -m state --state INVALID -j DROP + iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT + iptables -A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu + iptables -N nova_forward + iptables -A FORWARD -j nova_forward + + # NOTE(vish): DROP on output is too restrictive for now. We need to add + # in a bunch of more specific output rules to use it. + # iptables -P OUTPUT DROP + iptables -A OUTPUT -m state --state INVALID -j DROP + iptables -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT + iptables -N nova_output + iptables -A OUTPUT -j nova_output + + iptables -t nat -N nova_prerouting + iptables -t nat -A PREROUTING -j nova_prerouting + + iptables -t nat -N nova_postrouting + iptables -t nat -A POSTROUTING -j nova_postrouting + + iptables -t nat -N nova_output + iptables -t nat -A OUTPUT -j nova_output +fi + +if [ "$CMD" == "ganglia" ] || [ "$CMD" == "all" ]; then + iptables -A nova_input -m tcp -p tcp -d $IP --dport 8649 -j ACCEPT + iptables -A nova_input -m udp -p udp -d $IP --dport 8649 -j ACCEPT +fi + +if [ "$CMD" == "web" ] || [ "$CMD" == "all" ]; then + # NOTE(vish): This opens up ports for web access, allowing web-based + # dashboards to work. + iptables -A nova_input -m tcp -p tcp -d $IP --dport 80 -j ACCEPT + iptables -A nova_input -m tcp -p tcp -d $IP --dport 443 -j ACCEPT +fi + +if [ "$CMD" == "objectstore" ] || [ "$CMD" == "all" ]; then + iptables -A nova_input -m tcp -p tcp -d $IP --dport 3333 -j ACCEPT +fi + +if [ "$CMD" == "api" ] || [ "$CMD" == "all" ]; then + iptables -A nova_input -m tcp -p tcp -d $IP --dport $API_PORT -j ACCEPT + if [ "$IP" != "$MGMT_IP" ]; then + iptables -A nova_input -m tcp -p tcp -d $MGMT_IP --dport $API_PORT -j ACCEPT + fi +fi + +if [ "$CMD" == "redis" ] || [ "$CMD" == "all" ]; then + iptables -A nova_input -m tcp -p tcp -d $IP --dport 6379 -j ACCEPT +fi + +if [ "$CMD" == "mysql" ] || [ "$CMD" == "all" ]; then + iptables -A nova_input -m tcp -p tcp -d $IP --dport 3306 -j ACCEPT +fi + +if [ "$CMD" == "rabbitmq" ] || [ "$CMD" == "all" ]; then + iptables -A nova_input -m tcp -p tcp -d $IP --dport 4369 -j ACCEPT + iptables -A nova_input -m tcp -p tcp -d $IP --dport 5672 -j ACCEPT + iptables -A nova_input -m tcp -p tcp -d $IP --dport 53284 -j ACCEPT +fi + +if [ "$CMD" == "dnsmasq" ] || [ "$CMD" == "all" ]; then + # NOTE(vish): this could theoretically be setup per network + # for each host, but it seems like overkill + iptables -A nova_input -m tcp -p tcp -s $PRIVATE_RANGE --dport 53 -j ACCEPT + iptables -A nova_input -m udp -p udp -s $PRIVATE_RANGE --dport 53 -j ACCEPT + iptables -A nova_input -m udp -p udp --dport 67 -j ACCEPT +fi + +if [ "$CMD" == "ldap" ] || [ "$CMD" == "all" ]; then + iptables -A nova_input -m tcp -p tcp -d $IP --dport 389 -j ACCEPT +fi + + |