opennebula-4.12.1-securitygroup6.diff

IPv6 Security Group Patch, third attempt - Roy Keene, 11/14/2015 03:22 AM

Download (35.8 KB)

View differences:

opennebula-4.12.1-securitygroup6/share/pkgs/CentOS/opennebula.sudoers 2015-11-13 12:03:04.865595680 -0600
2 2
Defaults:oneadmin secure_path = /sbin:/bin:/usr/sbin:/usr/bin
3 3

  
4 4
Cmnd_Alias ONE_MISC = /bin/dd, /sbin/mkfs, /bin/sync
5
Cmnd_Alias ONE_NET = /usr/sbin/brctl, /sbin/ebtables, /sbin/iptables, /sbin/ip, /usr/sbin/ipset
5
Cmnd_Alias ONE_NET = /usr/sbin/brctl, /sbin/ebtables, /sbin/iptables, /sbin/ip6tables, /sbin/ip, /usr/sbin/ipset
6 6
Cmnd_Alias ONE_LVM = /sbin/lvcreate, /sbin/lvremove, /sbin/lvrename, /sbin/lvs, /sbin/vgdisplay
7 7
Cmnd_Alias ONE_ISCSI = /sbin/iscsiadm, /usr/sbin/tgt-admin, /usr/sbin/tgtadm
8 8
Cmnd_Alias ONE_OVS = /usr/bin/ovs-ofctl, /usr/bin/ovs-vsctl
opennebula-4.12.1-securitygroup6/share/pkgs/Debian/opennebula.sudoers 2015-11-13 12:02:42.022596856 -0600
2 2
Defaults:oneadmin secure_path = /sbin:/bin:/usr/sbin:/usr/bin
3 3

  
4 4
Cmnd_Alias ONE_MISC = /bin/dd, /sbin/mkfs, /bin/sync
5
Cmnd_Alias ONE_NET = /sbin/brctl, /sbin/ebtables, /sbin/iptables, /sbin/ip, /sbin/ipset
5
Cmnd_Alias ONE_NET = /sbin/brctl, /sbin/ebtables, /sbin/iptables, /sbin/ip6tables, /sbin/ip, /sbin/ipset
6 6
Cmnd_Alias ONE_LVM = /sbin/lvcreate, /sbin/lvremove, /sbin/lvrename, /sbin/lvs, /sbin/vgdisplay
7 7
Cmnd_Alias ONE_ISCSI = /usr/bin/iscsiadm, /usr/sbin/tgt-admin, /usr/sbin/tgtadm
8 8
Cmnd_Alias ONE_OVS = /usr/bin/ovs-ofctl, /usr/bin/ovs-vsctl
opennebula-4.12.1-securitygroup6/share/pkgs/Ubuntu/opennebula.sudoers 2015-11-13 12:02:53.003596290 -0600
2 2
Defaults:oneadmin secure_path = /sbin:/bin:/usr/sbin:/usr/bin
3 3

  
4 4
Cmnd_Alias ONE_MISC = /bin/dd, /sbin/mkfs, /bin/sync
5
Cmnd_Alias ONE_NET = /sbin/brctl, /sbin/ebtables, /sbin/iptables, /sbin/ip, /sbin/ipset
5
Cmnd_Alias ONE_NET = /sbin/brctl, /sbin/ebtables, /sbin/iptables, /sbin/ip6tables, /sbin/ip, /sbin/ipset
6 6
Cmnd_Alias ONE_LVM = /sbin/lvcreate, /sbin/lvremove, /sbin/lvrename, /sbin/lvs, /sbin/vgdisplay
7 7
Cmnd_Alias ONE_ISCSI = /usr/bin/iscsiadm, /usr/sbin/tgt-admin, /usr/sbin/tgtadm
8 8
Cmnd_Alias ONE_OVS = /usr/bin/ovs-ofctl, /usr/bin/ovs-vsctl
opennebula-4.12.1-securitygroup6/share/pkgs/openSUSE/opennebula.sudoers 2015-11-13 12:02:32.918597324 -0600
2 2
Defaults:oneadmin secure_path = /sbin:/bin:/usr/sbin:/usr/bin
3 3

  
4 4
Cmnd_Alias ONE_MISC = /usr/bin/dd, /sbin/mkfs, /usr/bin/sync
5
Cmnd_Alias ONE_NET = /sbin/brctl, /usr/sbin/ebtables, /usr/sbin/iptables, /sbin/ip
5
Cmnd_Alias ONE_NET = /sbin/brctl, /usr/sbin/ebtables, /usr/sbin/iptables, /usr/sbin/ip6tables, /sbin/ip
6 6
Cmnd_Alias ONE_LVM = /sbin/lvcreate, /sbin/lvremove, /sbin/lvrename, /sbin/lvs, /sbin/vgdisplay
7 7
Cmnd_Alias ONE_ISCSI = /sbin/iscsiadm, /usr/sbin/tgt-admin, /usr/sbin/tgtadm
8 8
Cmnd_Alias ONE_OVS = /usr/bin/ovs-ofctl, /usr/bin/ovs-vsctl
opennebula-4.12.1-securitygroup6/share/sudoers/sudo_commands.rb 2015-11-13 12:02:16.774598155 -0600
22 22

  
23 23
CMDS = {
24 24
    :MISC  => %w(dd mkfs sync),
25
    :NET   => %w(brctl ebtables iptables ip ipset),
25
    :NET   => %w(brctl ebtables iptables ip6tables ip ipset),
26 26
    :LVM   => %w(lvcreate lvremove lvrename lvs vgdisplay),
27 27
    :ISCSI => %w(iscsiadm tgt-admin tgtadm),
28 28
    :OVS   => %w(ovs-ofctl ovs-vsctl),
opennebula-4.12.1-securitygroup6/src/cli/one_helper/onesecgroup_helper.rb 2015-11-13 14:43:27.143389017 -0600
110 110
                d["ICMP_TYPE"]
111 111
            end
112 112

  
113
            column :ICMVP6_TYPE, "", :left, :size=>11 do |d|
114
                d["ICMPV6_TYPE"]
115
            end
116

  
113 117
            column :NETWORK, "", :left, :donottruncate, :size=>35 do |d|
114 118
                network = ""
115 119
                if(!d["NETWORK_ID"].nil? && d["NETWORK_ID"] != "")
opennebula-4.12.1-securitygroup6/src/secgroup/SecurityGroup.cc 2015-11-13 14:39:40.657700182 -0600
333 333

  
334 334
    one_util::toupper(proto);
335 335

  
336
    if ( proto != "TCP" && proto != "UDP" && proto != "ICMP" && proto != "IPSEC"
337
        && proto != "ALL")
336
    if ( proto != "TCP" && proto != "UDP" && proto != "ICMP" && proto != "ICMP6"
337
        && proto != "IPSEC" && proto != "ALL")
338 338
    {
339
        error = "Wrong PROTOCOL in rule. Valid options: TCP, UDP, ICMP, IPSEC,"
340
            " ALL.";
339
        error = "Wrong PROTOCOL in rule. Valid options: TCP, UDP, ICMP, ICMP6,"
340
            " IPSEC, ALL.";
341 341
        return false;
342 342
    }
343 343

  
......
376 376
        }
377 377
    }
378 378

  
379
    value = rule->vector_value("ICMPV6_TYPE");
380

  
381
    if (!value.empty())
382
    {
383
        if (proto != "ICMP6")
384
        {
385
            error = "ICMPV6_TYPE is supported only for ICMP6 protocol.";
386
            return false;
387
        }
388

  
389
        if (rule->vector_value("ICMPV6_TYPE", ivalue) != 0)
390
        {
391
            error = "Wrong ICMPV6_TYPE, it must be integer";
392
            return false;
393
        }
394
    }
395

  
379 396
    // -------------------------------------------------------------------------
380 397
    // RULE_TYPE
381 398
    // -------------------------------------------------------------------------
......
398 415

  
399 416
    if (!ip.empty()) //Target as IP & SIZE
400 417
    {
401
        struct in_addr ip_addr;
418
        struct in6_addr ip_addr;
402 419

  
403 420
        if (rule->vector_value("SIZE", ivalue) != 0)
404 421
        {
......
406 423
            return false;
407 424
        }
408 425

  
409
        if (inet_pton(AF_INET, ip.c_str(), static_cast<void*>(&ip_addr)) != 1)
426
        if (inet_pton(AF_INET6, ip.c_str(), static_cast<void*>(&ip_addr)) != 1)
410 427
        {
411
            error = "Wrong format for IP value.";
412
            return false;
428
            if (inet_pton(AF_INET, ip.c_str(), static_cast<void*>(&ip_addr)) != 1)
429
            {
430
                error = "Wrong format for IP value.";
431
                return false;
432
            }
413 433
        }
414 434
    }
415 435
    else //Target is ANY or NETWORK_ID
opennebula-4.12.1-securitygroup6/src/vnm_mad/remotes/lib/address.rb 2015-11-13 15:14:38.015388649 -0600
14 14
# limitations under the License.                                             #
15 15
#--------------------------------------------------------------------------- #
16 16

  
17
require 'ipaddr'
18

  
17 19
module VNMMAD
18 20

  
19 21
module VNMNetwork
......
26 28
    #   @return [Array<String>] The networks in CIDR
27 29
    def self.to_nets(ip_start, size)
28 30
        nets = Array.new
29
        ip_i = IPv4.to_i(ip_start)
31

  
32
        if ip_start.match(/:/)
33
            family = "inet6"
34
        else
35
            family = "inet"
36
        end
37

  
38
        if family == "inet"
39
            ip_i = IPv4.to_i(ip_start)
40
            ip_totalLength = 32
41
        else
42
            ip_i = IPv6.to_i(ip_start)
43
            ip_totalLength = 128
44
        end
30 45

  
31 46
        # Find the largest address block (look for the first 1-bit)
32 47
        lblock = 0
33 48

  
34
        lblock += 1 while (ip_i[lblock] == 0 && lblock < 32 )
49
        lblock += 1 while (ip_i[lblock] == 0 && lblock < ip_totalLength )
35 50

  
36 51
        # Allocate whole blocks till the size fits
37 52
        while ( size >= 2**lblock )
38
            nets << "#{IPv4.to_s(ip_i)}/#{32-lblock}"
53
            if family == "inet"
54
                nets << "#{IPv4.to_s(ip_i)}/#{ip_totalLength-lblock}"
55
            else
56
                nets << "#{IPv6.to_s(ip_i)}/#{ip_totalLength-lblock}"
57
            end
39 58

  
40 59
            ip_i += 2**lblock
41 60
            size -= 2**lblock
42 61

  
43
            lblock += 1 while (ip_i[lblock] == 0 && lblock < 32 )
62
            lblock += 1 while (ip_i[lblock] == 0 && lblock < ip_totalLength )
44 63
        end
45 64

  
46 65
        # Fit remaining address blocks
47
        32.downto(0) { |i|
66
        ip_totalLength.downto(0) { |i|
48 67
            next if size[i] == 0
49 68

  
50
            nets << "#{IPv4.to_s(ip_i)}/#{32-i}"
69
            if family == "inet"
70
                nets << "#{IPv4.to_s(ip_i)}/#{ip_totalLength-i}"
71
            else
72
                nets << "#{IPv6.to_s(ip_i)}/#{ip_totalLength-i}"
73
            end
51 74

  
52 75
            ip_i += 2**i
53 76
        }
......
72 95
            ip = 3.downto(0).collect {|s| (ip >> 8*s) & 0xff }.join('.')
73 96
        end
74 97
    end
98

  
99
    module IPv6
100
        # Returns the binary equivalent of a IP address
101
        #  @param ip [String] IP in dot notation
102
        #  @return [Fixnum] IP as an integer
103
        def self.to_i(ip)
104
            ipaddr = IPAddr.new ip, Socket::AF_INET6
105

  
106
            return ipaddr.to_i
107
        end
108

  
109
        # Returns the string equivalent  of a IP address 
110
        #  @param ip [Fixnum] IP as an integer
111
        #  @return [String] IP in dot notation
112
        def self.to_s(ip)
113
            ipaddr = IPAddr.new ip, Socket::AF_INET6
114

  
115
            return ipaddr.to_s
116
        end
117
    end
75 118
end 
76 119

  
77 120
end
opennebula-4.12.1-securitygroup6/src/vnm_mad/remotes/lib/command.rb 2015-11-13 13:28:43.743331109 -0600
38 38
    COMMANDS = {
39 39
      :ebtables => "sudo ebtables",
40 40
      :iptables => "sudo iptables",
41
      :ip6tables=> "sudo ip6tables",
41 42
      :brctl    => "sudo brctl",
42 43
      :ip       => "sudo ip",
43 44
      :virsh    => "virsh -c qemu:///system",
......
83 84
    end
84 85
end
85 86

  
86
end
87
end
opennebula-4.12.1-securitygroup6/src/vnm_mad/remotes/lib/fw_driver.rb 2015-11-13 12:21:32.476538655 -0600
82 82
                        end
83 83
                    end
84 84

  
85
                    #ICMPv6
86
                    if nic[:icmp6]
87
                        if %w(no drop).include? nic[:icmp6].downcase
88
                            nic_rules << filter_established(chain, :icmp6, :accept)
89
                            nic_rules << filter_protocol(chain, :icmp6, :drop)
90
                        end
91
                    end
92

  
85 93
                    process_chain(chain, tap, nic_rules)
86 94
                end
87 95
            end
......
96 104
            vm_id =  @vm['ID']
97 105
            process do |nic|
98 106
                chain   = "one-#{vm_id}-#{nic[:network_id]}"
99
                iptables_out = `#{command(:iptables)} -n -v --line-numbers -L FORWARD`
100
                if m = iptables_out.match(/.*#{chain}.*/)
101
                    rule_num = m[0].split(/\s+/)[0]
102
                    purge_chain(chain, rule_num)
103
                end
107
                purge_chain(chain)
104 108
            end
105 109

  
106 110
            unlock
......
111 115
        ########################################################################
112 116
        private
113 117

  
114
        def purge_chain(chain, rule_num)
118
        def purge_chain(chain)
115 119
            rules = Array.new
116
            rules << rule("-D FORWARD #{rule_num}")
120

  
121
            # IPv4
122
            iptables_out = `#{command(:iptables)} -n -v --line-numbers -L FORWARD`
123
            rule_name = nil
124
            if m = iptables_out.match(/.* #{chain}$/)
125
                rule_num = m[0].split(/\s+/)[0]
126
            end
127

  
128
            if ! rule_num.nil?
129
                rules << rule("-D FORWARD #{rule_num}")
130
            end
117 131
            rules << rule("-F #{chain}")
118 132
            rules << rule("-X #{chain}")
133

  
134
            # IPv6
135
            iptables_out = `#{command(:ip6tables)} -n -v --line-numbers -L FORWARD`
136
            rule_num = nil
137
            if m = iptables_out.match(/.* #{chain}$/)
138
                rule_num = m[0].split(/\s+/)[0]
139
            end
140

  
141
            if ! rule_num.nil?
142
                rules << rule6("-D FORWARD #{rule_num}")
143
            end
144
            rules << rule6("-F #{chain}")
145
            rules << rule6("-X #{chain}")
146

  
119 147
            run_rules rules
120 148
        end
121 149

  
......
134 162

  
135 163
        def filter_established(chain, protocol, policy)
136 164
            policy   = policy.to_s.upcase
137
            rule "-A #{chain} -p #{protocol} -m state --state ESTABLISHED -j #{policy}"
165

  
166
            rules = Array.new
167
            rules << rule("-A #{chain} -p #{protocol} -m state --state ESTABLISHED -j #{policy}")
168
            rules << rule6("-A #{chain} -p #{protocol} -m state --state ESTABLISHED -j #{policy}")
169

  
170
            return rules
138 171
        end
139 172

  
140 173
        def run_rules(rules)
......
149 182

  
150 183
        def filter_protocol(chain, protocol, policy)
151 184
            policy   = policy.to_s.upcase
152
            rule "-A #{chain} -p #{protocol} -j #{policy}"
185

  
186
            rules = Array.new
187
            rules << rule("-A #{chain} -p #{protocol} -j #{policy}")
188
            rules << rule6("-A #{chain} -p #{protocol} -j #{policy}")
189

  
190
            return rules
153 191
        end
154 192

  
155 193
        def filter_ports(chain, protocol, range, policy)
156 194
            policy   = policy.to_s.upcase
157 195
            range.gsub!(/\s+/,"")
158 196

  
197
            rules = Array.new
159 198
            if range? range
160
               rule "-A #{chain} -p #{protocol} -m multiport --dports #{range} -j #{policy}"
199
               rules << rule("-A #{chain} -p #{protocol} -m multiport --dports #{range} -j #{policy}")
200
               rules << rule6("-A #{chain} -p #{protocol} -m multiport --dports #{range} -j #{policy}")
161 201
            end
202

  
203
            return rules
162 204
        end
163 205

  
164 206
        def tap_to_chain(tap, chain)
207
            # IPv4
165 208
            iptables_out = `#{command(:iptables)} -n -v --line-numbers -L FORWARD`
166 209

  
167 210
            # Insert the rule on top of the 'opennebula' chain if it exists, so it
......
175 218
                end
176 219
            end
177 220

  
221
            rules = Array.new
178 222
            if index
179
                rule "-I FORWARD #{index} -m physdev --physdev-out #{tap} -j #{chain}"
223
                rules << rule("-I FORWARD #{index} -m physdev --physdev-out #{tap} -j #{chain}")
180 224
            else
181
                rule "-A FORWARD -m physdev --physdev-out #{tap} -j #{chain}"
225
                rules << rule("-A FORWARD -m physdev --physdev-out #{tap} -j #{chain}")
182 226
            end
227

  
228
            # IPv6
229
            iptables_out = `#{command(:ip6tables)} -n -v --line-numbers -L FORWARD`
230

  
231
            # Insert the rule on top of the 'opennebula' chain if it exists, so it
232
            # doesn't conflict with the security groups driver
233
            index = nil
234
            iptables_out.lines.each do |line|
235
                fields = line.split
236
                if fields.include?("opennebula") && fields.include?("--physdev-is-bridged")
237
                    index = fields[0]
238
                    break
239
                end
240
            end
241

  
242
            if index
243
                rules << rule6("-I FORWARD #{index} -m physdev --physdev-out #{tap} -j #{chain}")
244
            else
245
                rules << rule6("-A FORWARD -m physdev --physdev-out #{tap} -j #{chain}")
246
            end
247

  
248
            return rules
183 249
        end
184 250

  
185 251
        def new_chain(chain)
186
            rule "-N #{chain}"
252
            rules = Array.new
253

  
254
            rules << rule("-N #{chain}")
255
            rules << rule6("-N #{chain}")
256

  
257
            return rules
187 258
        end
188 259

  
189 260
        def chain_exists?(chain)
......
195 266
        def rule(rule)
196 267
            "#{command(:iptables)} #{rule}"
197 268
        end
269

  
270
        def rule6(rule)
271
            "#{command(:ip6tables)} #{rule}"
272
        end
198 273
    end
199
end
274
end
opennebula-4.12.1-securitygroup6/src/vnm_mad/remotes/lib/security_groups.rb 2015-11-13 15:02:46.151535316 -0600
24 24
    #
25 25
    # PROTOCOL (mandatory)
26 26
    #   - Specifies the protocol of the rule
27
    #   - values: ['ALL', 'TCP', 'UDP', 'ICMP', 'IPSEC']
27
    #   - values: ['ALL', 'TCP', 'UDP', 'ICMP', 'ICMP6', 'IPSEC']
28 28
    #
29 29
    # RULE_TYPE (mandatory)
30 30
    #   - Specifies the direction of application of the rule
......
34 34
    #   - only works for protocols ['TCP', 'UDP']
35 35
    #   - uses the iptables multiports syntax
36 36
    #
37
    # ICMP_TYPE (optional)
38
    #   - Only works for protocol 'ICMP'
37
    # ICMP_TYPE and ICMPV6_TYPE (optional)
38
    #   - Only works for protocol 'ICMP' (for ICMP_TYPE) or protocol 'ICMP6' (for
39
    #     ICMPV6_TYPE)
39 40
    #   - Is either in the form of '<TYPE>' or '<TYPE>/<CODE>', where both
40 41
    #     '<TYPE>' and '<CODE>' are integers. This class has a helper method
41 42
    #     tgat expands '<TYPE>' into all the '<TYPE>/<CODE>' subtypes.
......
50 51
            :protocol,      # Type  1: block the whole protocol
51 52
            :portrange,     # Type 2a: block a port range within a protocol 
52 53
            :icmp_type,     # Type 2b: block selected icmp types 
54
            :icmp6_type,    # Type 2c: block selected icmp6 types 
53 55
            :net,           # Type  3: block a whole protocol for a network
54 56
            :net_portrange, # Type 4a: block a port range from a network
55
            :net_icmp_type  # Type 4b: block selected icmp types from a network 
57
            :net_icmp_type, # Type 4b: block selected icmp types from a network 
58
            :net_icmp6_type # Type 4c: block selected icmpv6 types from a network 
56 59
        ]
57 60

  
58 61
        # Initialize a new rule. 
......
63 66

  
64 67
            @rule_type = @rule[:rule_type].downcase.to_sym
65 68
            @icmp_type = @rule[:icmp_type]
69
            @icmp6_type = @rule[:icmp6_type]
66 70

  
67 71
            @range = @rule[:range]
68 72
            @ip    = @rule[:ip]
......
92 96

  
93 97
                when :net_icmp_type
94 98
                    process_net_icmp_type(cmds, vars)
99

  
100
                when :net_icmp6_type
101
                    process_net_icmp6_type(cmds, vars)
95 102
            end
96 103
        end        
97 104

  
......
113 120
            end
114 121
        end
115 122

  
123
        # Expand the ICMP type with associated codes if any 
124
        #   @return [Array<String>] expanded ICMP types to include all codes
125
        def icmpv6_type_expand
126
            # XXX:TODO: Implement expansion of codes for IPv6 types
127
            ["#{@icmpv6_type}/0"]
128
        end
129

  
116 130
        private
117 131

  
118 132
        # ICMP Codes for each ICMP type
......
129 143
        # @protocol + @rule_type => Type 1: 'protocol'
130 144
        # @protocol + @rule_type + @range => Type 2A: 'portrange'
131 145
        # @protocol + @rule_type + @icmp_type => Type 2B: 'icmp_type'
146
        # @protocol + @rule_type + @icmpv6_type => Type 2C: 'icmp6_type'
132 147
        # @protocol + @rule_type + @ip + @size => Type 3: 'net'
133 148
        # @protocol + @rule_type + @ip + @size + @range => Type 4A: 'net_portrange'
134 149
        # @protocol + @rule_type + @ip + @size + @icmp_type => Type 4B: 'net_icmp_type'
150
        # @protocol + @rule_type + @ip + @size + @icmpv6_type => Type 4C: 'net_icmp6_type'
135 151
        #
136 152
        # @return [Symbol] The rule type
137 153
        def set_type
138 154
            if @ip.nil? && @size.nil?
155
                return :icmp6_type if !@icmpv6_type.nil?
139 156
                return :icmp_type if !@icmp_type.nil?
140 157
                return :portrange if !@range.nil?
141 158
                return :protocol
142 159
            else
160
                return :net_icmp6_type if !@icmpv6_type.nil?
143 161
                return :net_icmp_type if !@icmp_type.nil?
144 162
                return :net_portrange if !@range.nil?
145 163
                return :net
......
169 187

  
170 188
        def process_net_icmp_type(cmds, vars)
171 189
        end            
190

  
191
        def process_net_icmp6_type(cmds, vars)
192
        end            
172 193
    end
173 194

  
174 195
    ############################################################################
......
219 240

  
220 241
end
221 242

  
222
end
243
end
opennebula-4.12.1-securitygroup6/src/vnm_mad/remotes/lib/security_groups_iptables.rb 2015-11-13 21:17:28.134879387 -0600
34 34
            chain = @rule_type == :inbound ? vars[:chain_in] : vars[:chain_out]
35 35

  
36 36
            cmds.add :iptables, "-A #{chain} -p #{@protocol} -j RETURN"
37
            cmds.add :ip6tables, "-A #{chain} -p #{@protocol} -j RETURN"
37 38
        end
38 39

  
39 40
        # Implements the :portrange rule. Example:
......
43 44
            
44 45
            cmds.add :iptables, "-A #{chain} -p #{@protocol} -m multiport" \
45 46
                " --dports #{@range} -j RETURN"
47
            cmds.add :ip6tables, "-A #{chain} -p #{@protocol} -m multiport" \
48
                " --dports #{@range} -j RETURN"
46 49
        end
47 50

  
48 51
        # Implements the :icmp_type rule. Example:
......
54 57
                " -j RETURN"
55 58
        end
56 59

  
60
        # Implements the :icmp6_type rule. Example:
61
        #   ip6tables -A one-3-0-o -p icmp6 --icmpv6-type 128 -j RETURN
62
        def     process_icmp6_type(cmds, vars)
63
            chain = @rule_type == :inbound ? vars[:chain_in] : vars[:chain_out]
64

  
65
            cmds.add :ip6tables, "-A #{chain} -p icmp6 --icmpv6-type #{@icmpv6_type}" \
66
                " -j RETURN"
67
        end
68

  
57 69
        # Implements the :net rule. Example:
58
        #   ipset create one-3-0-1-i-tcp-n hash:net
59
        #   iptables -A one-3-0-i -p tcp -m set --match-set one-3-0-1-i src -j RETURN
60
        #   ipset add -exist one-3-0-1-i-tcp-n 10.0.0.0/24
70
        #   ipset create one-3-0-1-i-tcp-n-inet hash:net family inet
71
        #   iptables -A one-3-0-i -p tcp -m set --match-set one-3-0-1-i-tcp-n-inet src -j RETURN
72
        #   ipset add -exist one-3-0-1-i-tcp-n-inet 10.0.0.0/24
61 73
        def process_net(cmds, vars)
62
            if @rule_type == :inbound
63
                chain = vars[:chain_in]
64
                set = "#{vars[:set_sg_in]}-#{@protocol}-n"
65
                dir = "src"
66
            else
67
                chain = vars[:chain_out]
68
                set = "#{vars[:set_sg_out]}-#{@protocol}-n"
69
                dir = "dst"
70
            end
74
            ["inet", "inet6"].each do |family|
75
                if family == "inet"
76
                    command = :iptables
77
                else
78
                    command = :ip6tables
79
                end
71 80

  
72
            cmds.add :ipset, "create #{set} hash:net"
73
            cmds.add :iptables, "-A #{chain} -p #{@protocol} -m set" \
74
                " --match-set #{set} #{dir} -j RETURN"
81
                if @rule_type == :inbound
82
                    chain = vars[:chain_in]
83
                    set = "#{vars[:set_sg_in]}-#{@protocol}-n-#{family}"
84
                    dir = "src"
85
                else
86
                    chain = vars[:chain_out]
87
                    set = "#{vars[:set_sg_out]}-#{@protocol}-n-#{family}"
88
                    dir = "dst"
89
                end
75 90

  
76
            net.each do |n|
77
                cmds.add :ipset, "add -exist #{set} #{n}"
91
                cmds.add :ipset, "create #{set} hash:net family #{family}"
92
                cmds.add command, "-A #{chain} -p #{@protocol} -m set" \
93
                    " --match-set #{set} #{dir} -j RETURN"
94

  
95
                net.each do |n|
96
                    if n.match(/:/)
97
                        n_family = "inet6"
98
                    else
99
                        n_family = "inet"
100
                    end
101

  
102
                    if n_family != family
103
                        next
104
                    end
105

  
106
                    cmds.add :ipset, "add -exist #{set} #{n}"
107
                end
78 108
            end
79 109
        end
80 110

  
81 111
        # Implements the :net_portrange rule. Example:
82
        #   ipset create one-3-0-1-i-nr hash:net,port
83
        #   iptables -A one-3-0-i -m set --match-set one-3-0-1-i-nr src,dst -j RETURN
84
        #   ipset add -exist one-3-0-1-i-nr 10.0.0.0/24,tcp:80
112
        #   ipset create one-3-0-1-i-nr-inet hash:net,port family inet
113
        #   iptables -A one-3-0-i -m set --match-set one-3-0-1-i-nr-inet src,dst -j RETURN
114
        #   ipset add -exist one-3-0-1-i-nr-inet 10.0.0.0/24,tcp:80
85 115
        def process_net_portrange(cmds, vars)
86
            if @rule_type == :inbound
87
                chain = vars[:chain_in]
88
                set = "#{vars[:set_sg_in]}-nr"
89
                dir = "src,dst"
90
            else
91
                chain = vars[:chain_out]
92
                set = "#{vars[:set_sg_out]}-nr"
93
                dir = "dst,dst"
94
            end
116
            ["inet", "inet6"].each do |family|
117
                if family == "inet"
118
                    command = :iptables
119
                else
120
                    command = :ip6tables
121
                end
95 122

  
96
            cmds.add :ipset, "create #{set} hash:net,port"
97
            cmds.add :iptables, "-A #{chain} -m set --match-set" \
98
                " #{set} #{dir} -j RETURN"
123
                if @rule_type == :inbound
124
                    chain = vars[:chain_in]
125
                    set = "#{vars[:set_sg_in]}-nr-#{family}"
126
                    dir = "src,dst"
127
                else
128
                    chain = vars[:chain_out]
129
                    set = "#{vars[:set_sg_out]}-nr-#{family}"
130
                    dir = "dst,dst"
131
                end
99 132

  
100
            net.each do |n|
101
                @range.split(",").each do |r|
102
                    r.gsub!(":","-")
103
                    net_range = "#{n},#{@protocol}:#{r}"
104
                    cmds.add :ipset, "add -exist #{set} #{net_range}"
133
                cmds.add :ipset, "create #{set} hash:net,port family #{family}"
134
                cmds.add command, "-A #{chain} -m set --match-set" \
135
                    " #{set} #{dir} -j RETURN"
136

  
137
                net.each do |n|
138
                    if n.match(/:/)
139
                        n_family = "inet6"
140
                    else
141
                        n_family = "inet"
142
                    end
143

  
144
                    if n_family != family
145
                        next
146
                    end
147

  
148
                    @range.split(",").each do |r|
149
                        r.gsub!(":","-")
150
                        net_range = "#{n},#{@protocol}:#{r}"
151
                        cmds.add :ipset, "add -exist #{set} #{net_range}"
152
                    end
105 153
                end
106 154
            end
107 155
        end
108 156

  
109 157
        # Implements the :net_icmp_type rule. Example:
110
        #   ipset create one-3-0-1-i-ni hash:net,port
111
        #   iptables -A one-3-0-i -m set --match-set one-3-0-1-i-nr src,dst -j RETURN
158
        #   ipset create one-3-0-1-i-ni hash:net,port family inet
159
        #   iptables -A one-3-0-i -m set --match-set one-3-0-1-i-ni src,dst -j RETURN
112 160
        #   ipset add -exist one-3-0-1-i-ni 10.0.0.0/24,icmp:8/0
113 161
        def process_net_icmp_type(cmds, vars)
114 162
            if @rule_type == :inbound
......
121 169
                dir = "dst,dst"
122 170
            end
123 171

  
124
            cmds.add :ipset, "create #{set} hash:net,port"
172
            cmds.add :ipset, "create #{set} hash:net,port family inet"
125 173
            cmds.add :iptables, "-A #{chain} -m set --match-set #{set} #{dir} -j RETURN"
126 174

  
127 175
            net.each do |n|
......
130 178
                end
131 179
            end
132 180
        end
181

  
182
        # Implements the :net_icmp6_type rule. Example:
183
        #   ipset create one-3-0-1-i-ni6 hash:net,port family inet6
184
        #   ip6tables -A one-3-0-i -m set --match-set one-3-0-1-i-ni6 src,dst -j RETURN
185
        #   ipset add -exist one-3-0-1-i-ni6 10.0.0.0/24,icmpv6:128/0
186
        def process_net_icmp6_type(cmds, vars)
187
            if @rule_type == :inbound
188
                chain = vars[:chain_in]
189
                set = "#{vars[:set_sg_in]}-ni6"
190
                dir = "src,dst"
191
            else
192
                chain = vars[:chain_out]
193
                set = "#{vars[:set_sg_out]}-ni6"                
194
                dir = "dst,dst"
195
            end
196

  
197
            cmds.add :ipset, "create #{set} hash:net,port family inet6"
198
            cmds.add :ip6tables, "-A #{chain} -m set --match-set #{set} #{dir} -j RETURN"
199

  
200
            net.each do |n|
201
                icmpv6_type_expand.each do |type_code|
202
                    cmds.add :ipset, "add -exist #{set} #{n},icmpv6:#{type_code}"
203
                end
204
            end
205
        end
133 206
    end
134 207

  
135 208
    ############################################################################
......
166 239
        commands.add :iptables, "-S"
167 240
        iptables_s = commands.run!
168 241

  
242
        commands.add :ip6tables, "-S"
243
        ip6tables_s = commands.run!
244

  
169 245
        iptables_forwards = ""
246
        ip6tables_forwards = ""
170 247

  
171 248
        if iptables_s.match(/^-N #{GLOBAL_CHAIN}$/)
172 249
            commands.add :iptables, "-L #{GLOBAL_CHAIN} --line-numbers"
173 250
            iptables_forwards = commands.run!    
174 251
        end
175 252

  
253
        if ip6tables_s.match(/^-N #{GLOBAL_CHAIN}$/)
254
            commands.add :ip6tables, "-L #{GLOBAL_CHAIN} --line-numbers"
255
            ip6tables_forwards = commands.run!    
256
        end
257

  
176 258
        commands.add :ipset, "list -name"
177 259
        ipset_list = commands.run!
178 260

  
179 261
        {
180 262
            :iptables_forwards => iptables_forwards,
181 263
            :iptables_s => iptables_s,
264
            :ip6tables_forwards => ip6tables_forwards,
265
            :ip6tables_s => ip6tables_s,
182 266
            :ipset_list => ipset_list
183 267
        }
184 268
    end
......
190 274
    def self.global_bootstrap
191 275
        info = SGIPTables.info
192 276

  
193
        return if info[:iptables_s].split("\n").include? "-N #{GLOBAL_CHAIN}"
194
            
277
        if info[:iptables_s].split("\n").include? "-N #{GLOBAL_CHAIN}"
278
            if info[:ip6tables_s].split("\n").include? "-N #{GLOBAL_CHAIN}"
279
                return
280
            end
281
        end
282

  
195 283
        commands = VNMNetwork::Commands.new
196 284

  
197 285
        commands.add :iptables, "-N #{GLOBAL_CHAIN}"
198 286
        commands.add :iptables, "-A FORWARD -m physdev --physdev-is-bridged -j #{GLOBAL_CHAIN}"
199 287
        commands.add :iptables, "-A #{GLOBAL_CHAIN} -j ACCEPT"
288
        commands.add :ip6tables, "-N #{GLOBAL_CHAIN}"
289
        commands.add :ip6tables, "-A FORWARD -m physdev --physdev-is-bridged -j #{GLOBAL_CHAIN}"
290
        commands.add :ip6tables, "-A #{GLOBAL_CHAIN} -j ACCEPT"
200 291

  
201 292
        commands.run!
202 293
    end
......
259 350
        # create chains
260 351
        commands.add :iptables, "-N #{chain_in}"  # inbound
261 352
        commands.add :iptables, "-N #{chain_out}" # outbound
353
        commands.add :ip6tables, "-N #{chain_in}"  # inbound
354
        commands.add :ip6tables, "-N #{chain_out}" # outbound
262 355

  
263 356
        # Send traffic to the NIC chains
264 357
        commands.add :iptables, "-I #{GLOBAL_CHAIN} -m physdev --physdev-out #{nic[:tap]} --physdev-is-bridged -j #{chain_in}"
265 358
        commands.add :iptables, "-I #{GLOBAL_CHAIN} -m physdev --physdev-in  #{nic[:tap]} --physdev-is-bridged -j #{chain_out}"
359
        commands.add :ip6tables, "-I #{GLOBAL_CHAIN} -m physdev --physdev-out #{nic[:tap]} --physdev-is-bridged -j #{chain_in}"
360
        commands.add :ip6tables, "-I #{GLOBAL_CHAIN} -m physdev --physdev-in  #{nic[:tap]} --physdev-is-bridged -j #{chain_out}"
266 361

  
267 362
        # Mac-spofing
268 363
        if nic[:filter_mac_spoofing] == "YES"
269 364
            commands.add :iptables, "-A #{chain_out} -m mac ! --mac-source #{nic[:mac]} -j DROP"
365
            commands.add :ip6tables, "-A #{chain_out} -m mac ! --mac-source #{nic[:mac]} -j DROP"
270 366
        end
271 367

  
272 368
        # IP-spofing
273 369
        if nic[:filter_ip_spoofing] == "YES"
274
            commands.add :iptables, "-A #{chain_out} ! --source #{nic[:ip]} -j DROP"
370
            if !nic[:ip].nil? and !nic[:ip].empty?
371
                commands.add :iptables, "-A #{chain_out} ! --source #{nic[:ip]} -j DROP"
372
            end
373

  
374
            ip6_addrs = Array.new
375

  
376
            [:ip6_global, :ip6_link, :ip6_ula].each do |keyName|
377
                if !nic[keyName].nil? and !nic[keyName].empty?
378
                    ip6_addrs << nic[keyName]
379
                end
380
            end
381

  
382
            if ip6_addrs.length > 1
383
                set = "#{chain_out}-nospoof-inet66"
384

  
385
                commands.add :ipset, "create #{set} hash:ip family inet6"
386
                ip6_addrs.each do |ip6_addr|
387
                    commands.add :ipset, "add -exist #{set} #{ip6_addr}"
388
                end
389

  
390
                commands.add :ip6tables, "-A #{chain_out} -m set ! --match-set #{set} src -j DROP"
391
            elsif ip6_addrs.length == 1
392
                commands.add :ip6tables, "-A #{chain_out} ! --source #{ip6_addrs[0]} -j DROP"
393
            end
275 394
        end
276 395

  
277 396
        # Related, Established
278 397
        commands.add :iptables, "-A #{chain_in} -m state --state ESTABLISHED,RELATED -j ACCEPT"
279 398
        commands.add :iptables, "-A #{chain_out} -m state --state ESTABLISHED,RELATED -j ACCEPT"
399
        commands.add :ip6tables, "-A #{chain_in} -m state --state ESTABLISHED,RELATED -j ACCEPT"
400
        commands.add :ip6tables, "-A #{chain_out} -m state --state ESTABLISHED,RELATED -j ACCEPT"
280 401

  
281 402
        commands.run!
282 403
    end
......
292 413
        commands = VNMNetwork::Commands.new
293 414
        commands.add :iptables, "-A #{chain_in} -j DROP"
294 415
        commands.add :iptables, "-A #{chain_out} -j DROP"
416
        commands.add :ip6tables, "-A #{chain_in} -j DROP"
417
        commands.add :ip6tables, "-A #{chain_out} -j DROP"
295 418

  
296 419
        commands.run!
297 420
    end
......
306 429
        info              = self.info
307 430
        iptables_forwards = info[:iptables_forwards]
308 431
        iptables_s        = info[:iptables_s]
432
        ip6tables_forwards = info[:ip6tables_forwards]
433
        ip6tables_s       = info[:ip6tables_s]
309 434
        ipset_list        = info[:ipset_list]
310 435

  
311 436
        commands = VNMNetwork::Commands.new
......
318 443
            end
319 444
        end
320 445

  
446
        ip6tables_forwards.lines.reverse_each do |line|
447
            fields = line.split
448
            if [chain_in, chain_out].include?(fields[1])
449
                n = fields[0]
450
                commands.add :ip6tables, "-D #{GLOBAL_CHAIN} #{n}"
451
            end
452
        end
453

  
321 454
        remove_chains = []
322 455
        iptables_s.lines.each do |line|
323 456
            if line.match(/^-N #{chain}/)
......
326 459
        end
327 460
        remove_chains.each {|c| commands.add :iptables, "-F #{c}" }
328 461
        remove_chains.each {|c| commands.add :iptables, "-X #{c}" }
462
        remove_chains.each {|c| commands.add :ip6tables, "-F #{c}" }
463
        remove_chains.each {|c| commands.add :ip6tables, "-X #{c}" }
329 464

  
330 465
        ipset_list.lines.each do |line|
331 466
            if line.match(/^#{chain}/)
......
338 473
    end
339 474
end
340 475

  
341
end
476
end