1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-01-11 05:17:41 +03:00

feature #476: firewall hook and class

This commit is contained in:
Jaime Melis 2011-05-20 11:18:11 +02:00
parent df3aa7f438
commit bf961d4fa4
2 changed files with 139 additions and 0 deletions

View File

@ -26,6 +26,7 @@ CONF = {
COMMANDS = {
:ebtables => "sudo /sbin/ebtables",
:iptables => "sudo /usr/sbin/iptables",
:brctl => "/usr/sbin/brctl",
:virsh => "virsh -c qemu:///system",
:xm => "sudo /usr/sbin/xm",
@ -275,3 +276,119 @@ class EbtablesVLAN < OpenNebulaVLAN
system("#{COMMANDS[:ebtables]} -D FORWARD #{rule}")
end
end
class OpenNebulaFirewall < OpenNebulaVLAN
def initialize(vm, hypervisor = nil)
super(vm,hypervisor)
end
def activate
vm_id = @vm['ID']
process do |nic|
#:white_ports_tcp => iptables_range
#:white_ports_udp => iptables_range
#:black_ports_tcp => iptables_range
#:black_ports_udp => iptables_range
#:icmp => 'DROP' or 'NO'
nic_rules = Array.new
chain = "one-#{vm_id}-#{nic[:network_id]}"
tap = nic[:tap]
if tap
#TCP
if range = nic[:white_ports_tcp]
nic_rules << filter_ports(chain, :tcp, range, :accept)
nic_rules << filter_protocol(chain, :tcp, :drop)
elsif range = nic[:black_ports_tcp]
nic_rules << filter_ports(chain, :tcp, range, :drop)
end
#UDP
if range = nic[:white_ports_udp]
nic_rules << filter_ports(chain, :ucp, range, :accept)
nic_rules << filter_protocol(chain, :ucp, :drop)
elsif range = nic[:black_ports_udp]
nic_rules << filter_ports(chain, :ucp, range, :drop)
end
#ICMP
if nic[:icmp]
if %w(no drop).include? nic[:icmp].downcase
nic_rules << filter_protocol(chain, :icmp, :drop)
end
end
process_chain(chain, tap, nic_rules)
end
end
end
def deactivate
vm_id = @vm['ID']
process do |nic|
chain = "one-#{vm_id}-#{nic[:network_id]}"
iptables_out = `#{COMMANDS[:iptables]} -n -v --line-numbers -L FORWARD`
if m = iptables_out.match(/.*#{chain}.*/)
rule_num = m[0].split(/\s+/)[0]
purge_chain(chain, rule_num)
end
end
end
def purge_chain(chain, rule_num)
rules = Array.new
rules << rule("-D FORWARD #{rule_num}")
rules << rule("-F #{chain}")
rules << rule("-X #{chain}")
run_rules rules
end
def process_chain(chain, tap, nic_rules)
rules = Array.new
if !nic_rules.empty?
# new chain
rules << new_chain(chain)
# move tap traffic to chain
rules << tap_to_chain(tap, chain)
rules << nic_rules
end
run_rules rules
end
def run_rules(rules)
rules.flatten.each do |rule|
system(rule)
puts(rule)
end
end
def range?(range)
range.match(/^(?:(?:\d+|\d+:\d+),)*(?:\d+|\d+:\d+)$/)
end
def filter_protocol(chain, protocol, policy)
policy = policy.to_s.upcase
rule "-A #{chain} -p #{protocol} -j #{policy}"
end
def filter_ports(chain, protocol, range, policy)
policy = policy.to_s.upcase
if range? range
rule "-A #{chain} -p #{protocol} -m multiport --dports #{range} -j #{policy}"
end
end
def tap_to_chain(tap, chain)
rule "-A FORWARD -m physdev --physdev-in #{tap} -j #{chain}"
end
def new_chain(chain)
rule "-N #{chain}"
end
def rule(rule)
"#{COMMANDS[:iptables]} #{rule}"
end
end

22
share/hooks/firewall Executable file
View File

@ -0,0 +1,22 @@
#!/usr/bin/env ruby
$: << File.dirname(__FILE__)
require 'base64'
require 'OpenNebulaVLAN'
action = ARGV[0]
template = ARGV[1]
#vm_xml = Base64::decode64(ARGV[0])
vm_xml = `onevm show -x #{template}`
fw = OpenNebulaFirewall.new(vm_xml)
case action
when "on"
fw.activate
when "off"
fw.deactivate
end