iptable 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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