~soren/nova/iptables-security-groups

« back to all changes in this revision

Viewing changes to plugins/xenserver/networking/etc/xensource/scripts/vif_rules.py

  • Committer: Soren Hansen
  • Date: 2011-01-03 09:56:21 UTC
  • mfrom: (430.2.79 nova)
  • Revision ID: soren@linux2go.dk-20110103095621-qy398qk1uk8o7cy3
Merge trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/env python
 
2
# vim: tabstop=4 shiftwidth=4 softtabstop=4
 
3
 
 
4
# Copyright 2010 OpenStack LLC.
 
5
# All Rights Reserved.
 
6
#
 
7
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
 
8
#    not use this file except in compliance with the License. You may obtain
 
9
#    a copy of the License at
 
10
#
 
11
#         http://www.apache.org/licenses/LICENSE-2.0
 
12
#
 
13
#    Unless required by applicable law or agreed to in writing, software
 
14
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 
15
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 
16
#    License for the specific language governing permissions and limitations
 
17
#    under the License.
 
18
 
 
19
"""
 
20
This script is used to configure iptables, ebtables, and arptables rules on
 
21
XenServer hosts.
 
22
"""
 
23
 
 
24
import os
 
25
import subprocess
 
26
import sys
 
27
 
 
28
# This is written to Python 2.4, since that is what is available on XenServer
 
29
import simplejson as json
 
30
 
 
31
 
 
32
def main(dom_id, command, only_this_vif=None):
 
33
    xsls = execute("/usr/bin/xenstore-ls /local/domain/%s/vm-data/networking" \
 
34
                  % dom_id, True)
 
35
    macs = [line.split("=")[0].strip() for line in xsls.splitlines()]
 
36
 
 
37
    for mac in macs:
 
38
        xsr = "/usr/bin/xenstore-read /local/domain/%s/vm-data/networking/%s"
 
39
        xsread = execute(xsr % (dom_id, mac), True)
 
40
        data = json.loads(xsread)
 
41
        for ip in data['ips']:
 
42
            if data["label"] == "public":
 
43
                vif = "vif%s.0" % dom_id
 
44
            else:
 
45
                vif = "vif%s.1" % dom_id
 
46
 
 
47
            if (only_this_vif is None) or (vif == only_this_vif):
 
48
                params = dict(IP=ip['ip'], VIF=vif, MAC=data['mac'])
 
49
                apply_ebtables_rules(command, params)
 
50
                apply_arptables_rules(command, params)
 
51
                apply_iptables_rules(command, params)
 
52
 
 
53
 
 
54
def execute(command, return_stdout=False):
 
55
    devnull = open(os.devnull, 'w')
 
56
    proc = subprocess.Popen(command, shell=True, close_fds=True,
 
57
                            stdout=subprocess.PIPE, stderr=devnull)
 
58
    devnull.close()
 
59
    if return_stdout:
 
60
        return proc.stdout.read()
 
61
    else:
 
62
        return None
 
63
 
 
64
# A note about adding rules:
 
65
#   Whenever we add any rule to iptables, arptables or ebtables we first
 
66
#   delete the same rule to ensure the rule only exists once.
 
67
 
 
68
 
 
69
def apply_iptables_rules(command, params):
 
70
    iptables = lambda rule: execute("/sbin/iptables %s" % rule)
 
71
 
 
72
    iptables("-D FORWARD -m physdev --physdev-in %(VIF)s -s %(IP)s \
 
73
              -j ACCEPT" % params)
 
74
    if command == 'online':
 
75
        iptables("-A FORWARD -m physdev --physdev-in %(VIF)s -s %(IP)s \
 
76
                  -j ACCEPT" % params)
 
77
 
 
78
 
 
79
def apply_arptables_rules(command, params):
 
80
    arptables = lambda rule: execute("/sbin/arptables %s" % rule)
 
81
 
 
82
    arptables("-D FORWARD --opcode Request --in-interface %(VIF)s \
 
83
               --source-ip %(IP)s --source-mac %(MAC)s -j ACCEPT" % params)
 
84
    arptables("-D FORWARD --opcode Reply --in-interface %(VIF)s \
 
85
               --source-ip %(IP)s --source-mac %(MAC)s -j ACCEPT" % params)
 
86
    if command == 'online':
 
87
        arptables("-A FORWARD --opcode Request --in-interface %(VIF)s \
 
88
                  --source-ip %(IP)s --source-mac %(MAC)s -j ACCEPT" % params)
 
89
        arptables("-A FORWARD --opcode Reply --in-interface %(VIF)s \
 
90
                  --source-ip %(IP)s --source-mac %(MAC)s -j ACCEPT" % params)
 
91
 
 
92
 
 
93
def apply_ebtables_rules(command, params):
 
94
    ebtables = lambda rule: execute("/sbin/ebtables %s" % rule)
 
95
 
 
96
    ebtables("-D FORWARD -p 0806 -o %(VIF)s --arp-ip-dst %(IP)s -j ACCEPT" %
 
97
             params)
 
98
    ebtables("-D FORWARD -p 0800 -o %(VIF)s --ip-dst %(IP)s -j ACCEPT" %
 
99
             params)
 
100
    if command == 'online':
 
101
        ebtables("-A FORWARD -p 0806 -o %(VIF)s --arp-ip-dst %(IP)s \
 
102
                  -j ACCEPT" % params)
 
103
        ebtables("-A FORWARD -p 0800 -o %(VIF)s --ip-dst %(IP)s \
 
104
                  -j ACCEPT" % params)
 
105
 
 
106
    ebtables("-D FORWARD -s ! %(MAC)s -i %(VIF)s -j DROP" % params)
 
107
    if command == 'online':
 
108
        ebtables("-I FORWARD 1 -s ! %(MAC)s -i %(VIF)s -j DROP" % params)
 
109
 
 
110
 
 
111
if __name__ == "__main__":
 
112
    if len(sys.argv) < 3:
 
113
        print "usage: %s dom_id online|offline [vif]" % \
 
114
               os.path.basename(sys.argv[0])
 
115
        sys.exit(1)
 
116
    else:
 
117
        dom_id, command = sys.argv[1:3]
 
118
        vif = len(sys.argv) == 4 and sys.argv[3] or None
 
119
        main(dom_id, command, vif)