Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Rejig files and namespaces for better use as library

  • Loading branch information...
commit 22e4d41610afe679256e97a243e8cef24888f573 1 parent 056973c
@johnl authored
View
7 lib/firewall.rb
@@ -1,7 +0,0 @@
-require 'lib/combinate'
-
-require 'lib/protocols'
-include Protocols
-
-require 'lib/netfilter'
-include Netfilter
View
241 lib/netfilter.rb
@@ -1,240 +1,3 @@
-module Netfilter
-
- require 'lib/combinate'
-
- class Table
- attr_reader :name
- attr_reader :chains
-
- def initialize(name)
- @name = name
- @chains = []
- end
-
- def new_chain(name)
- @chains.unshift(Chain.new(self, name))
- @chains.first
- end
-
- def method_missing(method, *args)
- if chain = @chains.find { |c| c.name.to_s.downcase == method.to_s.downcase }
- chain
- else
- super
- end
- end
-
- def rules
- all_rules = []
- @chains.each do |c|
- c.rules.each { |r| all_rules << [to_nfarg, r].join(' ') }
- end
- all_rules
- end
-
- def to_nfarg
- "-t #{name}"
- end
-
- end
-
- class FilterTable < Table
- def initialize(*args)
- super(args)
- @name = "filter"
- new_chain("INPUT")
- new_chain("FORWARD")
- new_chain("OUTPUT")
- end
- end
-
- class Chain
- attr_reader :name
- attr_reader :table
-
- def initialize(table, name)
- @table = table
- @name = name
- @rules = []
- end
-
- def with_scope(*args, &block)
- @scope = args.first
- self.instance_exec(&block)
- ensure
- @scope = nil
- end
-
- def scope
- @scope||{}
- end
-
- def accept(options = {})
- new_rule(options.update(:action => "ACCEPT"))
- end
-
- def drop(options = {})
- new_rule(options.update(:action => "DROP"))
- end
-
- def log(options = {})
- new_rule(options.update(:action => "LOG"))
- end
-
- def jump(options = {})
- chain_name = options.delete(:chain)
- new_rule(options.update(:jump => chain_name))
- end
-
- def policy=(new_policy = nil)
- @policy = new_policy.to_s.upcase
- end
-
- def policy
- @policy || "ACCEPT"
- end
-
- def reject(options = {})
- reject_with = options.delete(:with)
- new_rule(options.update(:reject_with => reject_with))
- end
-
- # Create a new rule, merging in any scope and passing in this chain
- def new_rule(options = {})
- @rules << Rule.new(options.update(scope).update(:chain => self))
- end
-
- def rules
- if @rules.empty?
- []
- else
- all_rules = []
- @rules.each { |r| all_rules += [to_nfarg, r.rules].combinate }
- all_rules
- end
- end
-
- def to_nfarg
- "-A #{name}"
- end
-
- def to_nfheader
- if is_builtin?
- ":#{name} #{policy} [0:0]"
- else
- ":#{name} - [0:0]"
- end
- end
-
- def is_builtin?
- name =~ /^A-Z+$/
- end
- end
-
- class Rule
- attr_reader :options
- attr_reader :chain
-
- NFOPTS = {
- :src => '-s',
- :dst => '-d',
- :protocol => { :opt => '-p', :aliases => :p },
- :state => { :opt => '-m state --state', :upcase => true },
- :dport => '--dport',
- :sport => '--sport',
- :dports => '--dports',
- :sports => '--sports',
- :in => '-i',
- :out => '-o',
- :prefix => { :opt => '-j LOG --log-prefix', :quote => true },
- :action => { :opt => '-j', :upcase => true },
- :jump => '-j',
- :limit => { :opt => '-m limit --limit', :aliases => :limit_rate },
- :burst => { :opt => '-m limit --limit-burst', :aliases => :limit_burst },
- :pkt_type => '-m pkttype --pkt-type',
- :policy => {:opt => '-P', :upcase => true},
- :reject_with => { :opt => '-j REJECT --reject-with' },
- :cmdline => '',
- }
-
- def initialize(options = {})
- @chain = options.delete(:chain)
- @options = options
- end
-
- def rules
- options.combinate.collect { |o| Rule.new(o).to_nfargs }
- end
-
- def to_nfargs
- s = []
- options.keys.each do |k|
- val = options[k]
-
- s << render_nfarg(k,options[k])
- end
- s.join(" ")
- end
-
- private
-
- def render_nfarg(search_key, value)
- if value.respond_to?(:to_nfcmdline)
- return value.to_nfcmdline(find_nfopt(search_key))
- end
-
- if value.respond_to?(:to_nfarg)
- value = value.to_nfarg
- end
-
-
- if options = find_nfopt(search_key)
- if options[:quote]
- value = "\"#{value}\""
- else
- value = value.to_s.gsub('_','-')
- end
- opt = options[:opt]
- value = value.to_s.upcase if options[:upcase]
- "#{opt} #{value}"
- else
- nil
- end
- end
-
- def find_nfopt(search_key)
- NFOPTS.keys.each do |k|
- if NFOPTS[k].is_a? Hash
- options = NFOPTS[k]
- keys = [k, options[:aliases]].flatten
- else
- keys = [k]
- options = { :opt => NFOPTS[k]}
- end
- return options if keys.include? search_key
- end
- nil
- end
-
- end
-
- def filter
- @filter_table ||= FilterTable.new
- end
-
- def render_netfilter
- out = []
- out << "# Generated by firewall.rb on #{Time.now}"
- [filter].each do |table|
- out << "*#{table.name}"
- table.chains.each do |chain|
- out << chain.to_nfheader
- chain.rules.each do |rule|
- out << rule.join(" ")
- end
- end
- end
- puts out.join("\n")
- end
+['combinate', 'protocols', 'netfilter'].each do |f|
+ require File.join(File.dirname(__FILE__), 'netfilter', f)
end
-
View
0  lib/combinate.rb → lib/netfilter/combinate.rb
File renamed without changes
View
238 lib/netfilter/netfilter.rb
@@ -0,0 +1,238 @@
+module Netfilter
+
+ class Table
+ attr_reader :name
+ attr_reader :chains
+
+ def initialize(name)
+ @name = name
+ @chains = []
+ end
+
+ def new_chain(name)
+ @chains.unshift(Chain.new(self, name))
+ @chains.first
+ end
+
+ def method_missing(method, *args)
+ if chain = @chains.find { |c| c.name.to_s.downcase == method.to_s.downcase }
+ chain
+ else
+ super
+ end
+ end
+
+ def rules
+ all_rules = []
+ @chains.each do |c|
+ c.rules.each { |r| all_rules << [to_nfarg, r].join(' ') }
+ end
+ all_rules
+ end
+
+ def to_nfarg
+ "-t #{name}"
+ end
+
+ end
+
+ class FilterTable < Table
+ def initialize(*args)
+ super(args)
+ @name = "filter"
+ new_chain("INPUT")
+ new_chain("FORWARD")
+ new_chain("OUTPUT")
+ end
+ end
+
+ class Chain
+ attr_reader :name
+ attr_reader :table
+
+ def initialize(table, name)
+ @table = table
+ @name = name
+ @rules = []
+ end
+
+ def with_scope(*args, &block)
+ @scope = args.first
+ self.instance_exec(&block)
+ ensure
+ @scope = nil
+ end
+
+ def scope
+ @scope||{}
+ end
+
+ def accept(options = {})
+ new_rule(options.update(:action => "ACCEPT"))
+ end
+
+ def drop(options = {})
+ new_rule(options.update(:action => "DROP"))
+ end
+
+ def log(options = {})
+ new_rule(options.update(:action => "LOG"))
+ end
+
+ def jump(options = {})
+ chain_name = options.delete(:chain)
+ new_rule(options.update(:jump => chain_name))
+ end
+
+ def policy=(new_policy = nil)
+ @policy = new_policy.to_s.upcase
+ end
+
+ def policy
+ @policy || "ACCEPT"
+ end
+
+ def reject(options = {})
+ reject_with = options.delete(:with)
+ new_rule(options.update(:reject_with => reject_with))
+ end
+
+ # Create a new rule, merging in any scope and passing in this chain
+ def new_rule(options = {})
+ @rules << Rule.new(options.update(scope).update(:chain => self))
+ end
+
+ def rules
+ if @rules.empty?
+ []
+ else
+ all_rules = []
+ @rules.each { |r| all_rules += [to_nfarg, r.rules].combinate }
+ all_rules
+ end
+ end
+
+ def to_nfarg
+ "-A #{name}"
+ end
+
+ def to_nfheader
+ if is_builtin?
+ ":#{name} #{policy} [0:0]"
+ else
+ ":#{name} - [0:0]"
+ end
+ end
+
+ def is_builtin?
+ name =~ /^A-Z+$/
+ end
+ end
+
+ class Rule
+ attr_reader :options
+ attr_reader :chain
+
+ NFOPTS = {
+ :src => '-s',
+ :dst => '-d',
+ :protocol => { :opt => '-p', :aliases => :p },
+ :state => { :opt => '-m state --state', :upcase => true },
+ :dport => '--dport',
+ :sport => '--sport',
+ :dports => '--dports',
+ :sports => '--sports',
+ :in => '-i',
+ :out => '-o',
+ :prefix => { :opt => '-j LOG --log-prefix', :quote => true },
+ :action => { :opt => '-j', :upcase => true },
+ :jump => '-j',
+ :limit => { :opt => '-m limit --limit', :aliases => :limit_rate },
+ :burst => { :opt => '-m limit --limit-burst', :aliases => :limit_burst },
+ :pkt_type => '-m pkttype --pkt-type',
+ :policy => {:opt => '-P', :upcase => true},
+ :reject_with => { :opt => '-j REJECT --reject-with' },
+ :cmdline => '',
+ }
+
+ def initialize(options = {})
+ @chain = options.delete(:chain)
+ @options = options
+ end
+
+ def rules
+ options.combinate.collect { |o| Rule.new(o).to_nfargs }
+ end
+
+ def to_nfargs
+ s = []
+ options.keys.each do |k|
+ val = options[k]
+
+ s << render_nfarg(k,options[k])
+ end
+ s.join(" ")
+ end
+
+ private
+
+ def render_nfarg(search_key, value)
+ if value.respond_to?(:to_nfcmdline)
+ return value.to_nfcmdline(find_nfopt(search_key))
+ end
+
+ if value.respond_to?(:to_nfarg)
+ value = value.to_nfarg
+ end
+
+
+ if options = find_nfopt(search_key)
+ if options[:quote]
+ value = "\"#{value}\""
+ else
+ value = value.to_s.gsub('_','-')
+ end
+ opt = options[:opt]
+ value = value.to_s.upcase if options[:upcase]
+ "#{opt} #{value}"
+ else
+ nil
+ end
+ end
+
+ def find_nfopt(search_key)
+ NFOPTS.keys.each do |k|
+ if NFOPTS[k].is_a? Hash
+ options = NFOPTS[k]
+ keys = [k, options[:aliases]].flatten
+ else
+ keys = [k]
+ options = { :opt => NFOPTS[k]}
+ end
+ return options if keys.include? search_key
+ end
+ nil
+ end
+
+ end
+
+ def filter
+ @filter_table ||= FilterTable.new
+ end
+
+ def render_netfilter
+ out = []
+ out << "# Generated by firewall.rb on #{Time.now}"
+ [filter].each do |table|
+ out << "*#{table.name}"
+ table.chains.each do |chain|
+ out << chain.to_nfheader
+ chain.rules.each do |rule|
+ out << rule.join(" ")
+ end
+ end
+ end
+ puts out.join("\n")
+ end
+end
+
View
111 lib/netfilter/protocols.rb
@@ -0,0 +1,111 @@
+module Netfilter
+ module Protocols
+ require 'ipaddr'
+ require 'set'
+
+ class Protocol
+ PROTOCOL = nil
+
+ def protocol
+ self.class.const_get(:PROTOCOL)
+ end
+ end
+
+ class ProtocolWithPort < Protocol
+ attr_reader :port
+
+ def initialize(port)
+ @port = port
+ end
+
+ def to_nfargs
+ if port.is_a? Range
+ "#{port.min}:#{port.max}"
+ else
+ port.to_s
+ end
+ end
+
+ def to_nfcmdline(options = {})
+ "-p #{protocol} #{options[:opt]} #{to_nfarg}"
+ end
+ end
+
+ class ProtocolWithMultiport < ProtocolWithPort
+ attr_reader :ports
+
+ def initialize(newports)
+ @ports = newports.find_all { |p| p.is_a? Fixnum }
+ end
+
+ def to_nfcmdline(options = {})
+ "-p #{protocol} -m multiport #{options[:opt]}s #{to_nfarg}"
+ end
+
+ def to_nfarg
+ ports.join(",")
+ end
+
+ def empty?
+ ports.empty?
+ end
+ end
+
+ class Udp < ProtocolWithPort
+ PROTOCOL = 'udp'
+ end
+
+ class Tcp < ProtocolWithPort
+ PROTOCOL = 'tcp'
+ end
+
+ class MultiportUdp < ProtocolWithMultiport
+ PROTOCOL = 'udp'
+ end
+
+ class MultiportTcp < MultiportUdp
+ PROTOCOL = 'tcp'
+ end
+
+ class Icmp
+ def initialize(type)
+ @type = type
+ end
+
+ def to_s
+ "icmp.#{@type}"
+ end
+
+ def to_nfcmdline(options = {})
+ "-p icmp --icmp-type #{@type}"
+ end
+ end
+
+ def tcp(*ports)
+ build_protocols(ports.flatten, Tcp, MultiportTcp)
+ end
+
+ def udp(*ports)
+ build_protocols(ports.flatten, Udp, MultiportUdp)
+ end
+
+ def icmp(types)
+ [types].flatten.collect { |t| Icmp.new(t) }
+ end
+
+ def ip(*ips)
+ ips.collect { |a| a.split(/ +/).collect { |b| IPAddr.new(b) } }.flatten
+ end
+
+ def build_protocols(ports, protocol, multiport_protocol)
+ if ports.size > 1
+ multiport = multiport_protocol.new(ports)
+ ports -= multiport.ports
+ end
+ ports.collect! { |p| protocol.new(p) }
+ ports << multiport unless multiport.nil? or multiport.empty?
+ ports
+ end
+ end
+end
+
View
110 lib/protocols.rb
@@ -1,110 +0,0 @@
-module Protocols
- require 'ipaddr'
- require 'set'
-
- class Protocol
- PROTOCOL = nil
-
- def protocol
- self.class.const_get(:PROTOCOL)
- end
- end
-
- class ProtocolWithPort < Protocol
- attr_reader :port
-
- def initialize(port)
- @port = port
- end
-
- def to_nfarg
- if port.is_a? Range
- "#{port.min}:#{port.max}"
- else
- port.to_s
- end
- end
-
- def to_nfcmdline(options = {})
- "-p #{protocol} #{options[:opt]} #{to_nfarg}"
- end
- end
-
- class ProtocolWithMultiport < ProtocolWithPort
- attr_reader :ports
-
- def initialize(newports)
- @ports = newports.find_all { |p| p.is_a? Fixnum }
- end
-
- def to_nfcmdline(options = {})
- "-p #{protocol} -m multiport #{options[:opt]}s #{to_nfarg}"
- end
-
- def to_nfarg
- ports.join(",")
- end
-
- def empty?
- ports.empty?
- end
- end
-
- class Udp < ProtocolWithPort
- PROTOCOL = 'udp'
- end
-
- class Tcp < ProtocolWithPort
- PROTOCOL = 'tcp'
- end
-
- class MultiportUdp < ProtocolWithMultiport
- PROTOCOL = 'udp'
- end
-
- class MultiportTcp < MultiportUdp
- PROTOCOL = 'tcp'
- end
-
- class Icmp
- def initialize(type)
- @type = type
- end
-
- def to_s
- "icmp.#{@type}"
- end
-
- def to_nfcmdline(options = {})
- "-p icmp --icmp-type #{@type}"
- end
- end
-
- def tcp(*ports)
- build_protocols(ports.flatten, Tcp, MultiportTcp)
- end
-
- def udp(*ports)
- build_protocols(ports.flatten, Udp, MultiportUdp)
- end
-
- def icmp(types)
- [types].flatten.collect { |t| Icmp.new(t) }
- end
-
- def ip(*ips)
- ips.collect { |a| a.split(/ +/).collect { |b| IPAddr.new(b) } }.flatten
- end
-
- def build_protocols(ports, protocol, multiport_protocol)
- if ports.size > 1
- multiport = multiport_protocol.new(ports)
- ports -= multiport.ports
- end
- ports.collect! { |p| protocol.new(p) }
- ports << multiport unless multiport.nil? or multiport.empty?
- ports
- end
-end
-
-
View
7 test/protocols_test.rb
@@ -1,11 +1,8 @@
-# To change this template, choose Tools | Templates
-# and open the template in the editor.
-
$:.unshift File.join(File.dirname(__FILE__),'..','lib')
require 'test/unit'
-require 'protocols'
-include Protocols
+require 'netfilter'
+include Netfilter::Protocols
module Protocols
class ProtocolsTest < Test::Unit::TestCase
Please sign in to comment.
Something went wrong with that request. Please try again.