summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVishvananda Ishaya <vishvananda@yahoo.com>2010-09-29 03:28:20 +0000
committerTarmac <>2010-09-29 03:28:20 +0000
commit3ebea539c25f913a22f86e7dd500bf5d7771614f (patch)
treeba8c975713f645a3c42e48f30659a9d6ad86490d
parent9b7fc3e3051b32bb944ef9dd0a3edfe1afcd245c (diff)
parentbc88c73a4e986289be7835b95ec97ffb7a50f7d7 (diff)
downloadnova-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.py2
-rw-r--r--nova/manager.py7
-rw-r--r--nova/network/linux_net.py68
-rw-r--r--nova/network/manager.py7
-rw-r--r--nova/service.py1
-rwxr-xr-xtools/setup_iptables.sh158
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
+
+