iptable 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ec29d57d27a6e6476d7e7b45ce0b00e2a6e2d18b
4
- data.tar.gz: 741f015325d6734dfa087f872923ab23763c4672
3
+ metadata.gz: f5f4f3b42e0340211d5f76976dcacc8a93634f90
4
+ data.tar.gz: 384ae7df7d10bd7e9843bf0ba8426d62a0b738b5
5
5
  SHA512:
6
- metadata.gz: a7b8932b08f65e35b209a39cbbf44d5e10129e2ad60135d3b87c7bf8c0bf2217601aed294d953257481e2c0fbea17436c3030ce27b10e3128bbc1eeba0aceeb1
7
- data.tar.gz: 9649433b362c790c7496dbc0a2d07a4fbdebb95cd462eb9697a014fa610aed75e3da84c5625a9457bf2b4a99d699c2af1cbcee86e6034f07296a773152c23cdb
6
+ metadata.gz: 9a831bb0c4de7c088e51452086c468a4ef8bac4a317abacaa78365da22360f75d1e693e77ac5959e8f68ef4adf11ae3f5ebc0f6318f9eedcbedd29c6e7d7ef84
7
+ data.tar.gz: 06fdcec05df266c35efca59f6c8a0ed745bb58f06668c7fbc13dff8ced7735d0006a2840c90a26203c86dbc0d063442409c0ffb495aca4b38a51fc5dd0833f5d
@@ -0,0 +1,2 @@
1
+ *gem
2
+ *swp
@@ -0,0 +1,20 @@
1
+ iptable
2
+ =======
3
+
4
+ Manipulate iptables with ruby, for packet accounting of ports
5
+
6
+ Must be run as root, typically with rvmsudo
7
+
8
+ ```ruby
9
+ require 'iptable'
10
+ # load the current iptables
11
+ table = IP::Table.new
12
+ chain = table.add_chain :name => "nginx_in"
13
+ table.chains["INPUT"].append_jump_to chain
14
+ chain.add_rule :protocol => :tcp, :src => "208.51.40.2", :dport => 34576
15
+ sleep 5
16
+ chain.reload
17
+ puts chain.packets
18
+ puts chain.bytes
19
+ chain.delete
20
+ ```
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'iptable'
3
- s.version = '0.0.1'
3
+ s.version = '0.0.2'
4
4
  s.date = '2014-11-05'
5
5
  s.summary = "IP Table"
6
6
  s.description = "manipulate iptables"
@@ -24,10 +24,16 @@ module IP
24
24
  end
25
25
  end
26
26
 
27
+ def add_chain(options)
28
+ new_chain = Chain.new(options)
29
+ new_chain.save
30
+ @chains[options[:name]] = new_chain
31
+ end
32
+
27
33
  def match_chain(line)
28
34
  if match = line.match(CHAIN_RE)
29
35
  name = match[1]
30
- @current_chain = @chains[name] = Chain.new(name)
36
+ @current_chain = @chains[name] = Chain.new(:name => name)
31
37
  return true
32
38
  end
33
39
  false
@@ -35,30 +41,91 @@ module IP
35
41
  end
36
42
 
37
43
  class Chain
38
- attr_reader :rules
44
+ attr_reader :rules, :name
45
+ attr_accessor :reference
39
46
 
40
- def initialize(name)
41
- @name = name
47
+ def initialize(options)
48
+ @name = options[:name]
42
49
  @rules = []
50
+ @reference = nil
51
+ end
52
+
53
+ def save
54
+ IO.popen("/sbin/iptables -N #{@name}") do |output|
55
+ if output.read =~ /Chain already exists/
56
+ return false
57
+ else
58
+ return true
59
+ end
60
+ end
61
+ end
62
+
63
+ def append_jump_to chain
64
+ chain.reference = self
65
+ IO.popen("/sbin/iptables -I #{@name} -j #{chain.name}") do |output|
66
+ puts output.read
67
+ end
68
+ end
69
+
70
+ def init_rule(options)
71
+ @rules << Rule.new(options.merge(:chain => self))
43
72
  end
44
73
 
45
- def add_rule(*args)
46
- @rules << Rule.new(args)
74
+ def add_rule(options)
75
+ new_rule = Rule.new(options.merge(:chain => self))
76
+ new_rule.save
77
+ @rules << new_rule
47
78
  end
48
79
 
49
80
  def match_rule(string)
50
81
  if match = string.match(RULE_RE)
51
- add_rule match[1, -1]
82
+ init_rule :packets => match[1], :protocol => match[2]
83
+ end
84
+ end
85
+
86
+ def delete
87
+ @rules.each do |rule|
88
+ IO.popen("/sbin/iptables -D #{@name} 1") do |output|
89
+ puts output.read
90
+ end
91
+ end
92
+ if @reference
93
+ IO.popen("/sbin/iptables -D #{@reference.name} -j #{@name}") do |output|
94
+ puts output.read
95
+ end
96
+ end
97
+ IO.popen("/sbin/iptables -X #{@name}") do |output|
98
+ puts output.read
99
+ end
100
+ end
101
+
102
+ def reload
103
+ @rules = []
104
+ IO.popen("/sbin/iptables -L #{@name} -n -v -x") do |output|
105
+ output.readlines.each do |line|
106
+ match_rule(line)
107
+ end
52
108
  end
53
109
  end
54
110
  end
55
111
 
56
112
  class Rule
57
113
  attr_accessor :chain, :target
114
+ attr_reader :packets
58
115
 
59
- def initialize(*args)
60
- @chain = nil
116
+ def initialize(options)
117
+ @chain = options[:chain]
118
+ raise "Rule needs a chain" unless @chain
119
+ @packets = options[:packets].to_i
61
120
  @target = nil
121
+ @dport = options[:dport]
122
+ @protocol = options[:protocol] || "all"
123
+ end
124
+
125
+ def save
126
+ IO.popen("/sbin/iptables -A #{@chain.name} -p #{@protocol} --dport #{@dport}") do |output|
127
+ puts output.read
128
+ end
62
129
  end
63
130
  end
64
131
  end
@@ -2,10 +2,11 @@ gem 'mocha'
2
2
  require 'minitest/autorun'
3
3
  require 'iptable'
4
4
  require 'mocha/mini_test'
5
+ require 'socket'
5
6
 
6
7
  class Tests < Minitest::Test
7
8
  def test_rule_matching
8
- chain = IP::Chain.new "hey"
9
+ chain = IP::Chain.new :name => "hey"
9
10
  str = "607939 956613034 TRAFFIC_ACCT_OUT all -- * * 0.0.0.0/0 0.0.0.0/0 "
10
11
  chain.match_rule str
11
12
  assert chain.rules.size == 1
@@ -22,4 +23,49 @@ class Tests < Minitest::Test
22
23
  table = IP::Table.new
23
24
  assert table.match_chain "Chain TRAFFIC_ACCT (0 references)"
24
25
  end
26
+
27
+ def test_add_chain_tcp
28
+ table = IP::Table.new
29
+ chain = table.add_chain :name => "nginx_in"
30
+ table.chains["INPUT"].append_jump_to chain
31
+ rule = chain.add_rule :protocol => :tcp, :dport => 1999
32
+ server_thread = Thread.new do
33
+ server = TCPServer.new 1999
34
+ server.accept
35
+ sleep 0.1
36
+ end
37
+ client_thread = Thread.new do
38
+ client = TCPSocket.new 'localhost', 1999
39
+ sleep 0.1
40
+ client.puts "hey"
41
+ end
42
+ client_thread.join
43
+ server_thread.join
44
+ chain.reload
45
+ assert_equal 4, chain.rules.first.packets
46
+ ensure
47
+ chain.delete
48
+ end
49
+
50
+ def test_add_chain_udp
51
+ table = IP::Table.new
52
+ chain = table.add_chain :name => "nginx_in"
53
+ table.chains["INPUT"].append_jump_to chain
54
+ rule = chain.add_rule :protocol => :udp, :dport => 1998
55
+ server_thread = Thread.new do
56
+ server = UDPSocket.new
57
+ server.bind "localhost", 1998
58
+ text, sender = server.recvfrom(1)
59
+ end
60
+ client_thread = Thread.new do
61
+ client = UDPSocket.new
62
+ client.send("hello", 0, 'localhost', 1998)
63
+ end
64
+ client_thread.join
65
+ server_thread.join
66
+ chain.reload
67
+ assert_equal 1, chain.rules.first.packets
68
+ ensure
69
+ chain.delete
70
+ end
25
71
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: iptable
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - towski
@@ -16,6 +16,8 @@ executables: []
16
16
  extensions: []
17
17
  extra_rdoc_files: []
18
18
  files:
19
+ - .gitignore
20
+ - README.md
19
21
  - Rakefile
20
22
  - iptable.gemspec
21
23
  - lib/iptable.rb