iptables-web 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 8a139530b147346fe830287212857940a70cfad5
4
+ data.tar.gz: c0fc21ed2e8c05aada06d3d06d869df259cabd22
5
+ SHA512:
6
+ metadata.gz: 672789d5c2099099ad2589abe1eb3bcc3fbb0cf30f4bb7b829284c4a6211385c99bade46ffa8ac792f6e98d60d4813079caed35789b18d164cf48cc698b66fd0
7
+ data.tar.gz: 88add871cab6f009691bc3f1036c0c9e954845b912cb068baa4b69d992532884a989003faf0130d9dfc47989df116c608bd3d5338b9ef2ac5b16ee0b6b8f9171
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 NikolayMurga
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # Iptables::Client
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'iptables-client'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install iptables-client
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it ( https://github.com/[my-github-username]/iptables-client/fork )
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create a new Pull Request
data/bin/iptables-web ADDED
@@ -0,0 +1,81 @@
1
+ #!/bin/env ruby
2
+ require 'commander/import'
3
+ require 'system/getifaddrs'
4
+ require 'iptables_web'
5
+ # :name is optional, otherwise uses the basename of this executable
6
+ program :name, 'IPtables Web client'
7
+ program :version, IptablesWeb::VERSION
8
+ program :description, 'Update iptables '
9
+ default_command :update
10
+ command :install do |c|
11
+ c.syntax = 'iptables-web install'
12
+ c.description = 'Displays foo'
13
+ c.action do |args, options|
14
+ config = IptablesWeb::Configuration.new
15
+ api_url = ask('Api base url: ') { |q| q.default = config['api_base_url'] }
16
+ token = ask('Access token: ') { |q| q.default = config['access_token'] }
17
+ update_period = ask('Update every [min]', Integer) { |q| q.default = 1; q.in = 0..59 }
18
+ config_dir = IptablesWeb::Configuration.config_dir
19
+ unless File.exist?(config_dir)
20
+ say "Create config directory: #{config_dir}"
21
+ Dir.mkdir(config_dir)
22
+ end
23
+ config_file = File.join(config_dir, 'config.yml')
24
+ say "Write config to #{config_file}"
25
+ File.write config_file, <<CONFIG
26
+ api_base_url: #{api_url}
27
+ access_token: #{token}
28
+ CONFIG
29
+ if system("LANG=C bash -l -c \"type rvm | cat | head -1 | grep -q '^rvm is a function$'\"")
30
+ wrapper = "#{ENV['HOME']}/.rvm/wrappers/#{`rvm current`.strip}/iptables-web"
31
+ else
32
+ wrapper = 'iptables-web'
33
+ end
34
+
35
+ cron_file = File.join(config_dir, 'cron.sh')
36
+ say "Write file #{cron_file}"
37
+ File.write cron_file, <<CONFIG
38
+ #/bin/env ruby
39
+ #{wrapper} update
40
+ CONFIG
41
+ File.chmod(0700, cron_file)
42
+ say "Add cronjob #{cron_file}"
43
+ crontab = IptablesWeb::Crontab.new(false)
44
+ jobs = crontab.jobs
45
+ jobs.reject! { |job| job.include?('.iptables-web') }
46
+ jobs << "*/#{update_period} * * * * #{File.join(ENV['HOME'], '.iptables-web', 'cron.sh')}"
47
+ crontab.save(jobs)
48
+
49
+ static_rules = File.join(config_dir, 'static_rules')
50
+
51
+ say "Create file for static rules #{static_rules}"
52
+ say "* * * * * * * * * * * * * * * * * * * * * * * *\n"
53
+ say "* You can write predefined rules to this file.\n"
54
+ say "* This file will be concat with rules \n"
55
+ say "* See 'iptables-save' format.\n"
56
+ say "* * * * * * * * * * * * * * * * * * * * * * * * \n"
57
+
58
+ if File.exist?(static_rules)
59
+ say 'File already exist!'
60
+ else
61
+ File.write static_rules, <<STATIC_RULES
62
+ -A INPUT -i lo -j ACCEPT
63
+ -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
64
+ # -A INPUT -p tcp ! --syn -m state --state NEW -j DROP
65
+ STATIC_RULES
66
+ end
67
+ end
68
+ end
69
+
70
+ command :update do |c|
71
+ c.syntax = 'iptables-web update'
72
+ c.description = 'Display bar with optional prefix and suffix'
73
+ c.option '--config STRING', String, 'Path to config file'
74
+ c.action do |args, options|
75
+ IptablesWeb::Configuration.load(options.config) if options.config
76
+ IptablesWeb::Model::Node.handshake do
77
+ iptables = IptablesWeb::Iptables.new
78
+ iptables.restore(IptablesWeb::Model::AccessRule.all)
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,32 @@
1
+ require 'yaml'
2
+ module IptablesWeb
3
+ class Configuration < Hash
4
+ attr_accessor :loaded
5
+ CONFIG_FILES = %W(#{ENV['HOME']}/.iptables-web/config.yml /etc/iptables-web/config.yml)
6
+ STATIC_RULES_FILES = %W(#{ENV['HOME']}/.iptables-web/static_rules /etc/iptables-web/static_rules)
7
+
8
+ def initialize
9
+ CONFIG_FILES.each do |config|
10
+ if load(config)
11
+ @loaded = true
12
+ break
13
+ end
14
+ end
15
+ end
16
+
17
+ def load(config)
18
+ clear
19
+ merge! YAML.load File.read(config) if File.exist?(config)
20
+ end
21
+
22
+ def self.static_rules
23
+ STATIC_RULES_FILES.map do |file|
24
+ File.exist?(file) ? File.read(file) : nil
25
+ end.compact.join("\n").strip
26
+ end
27
+
28
+ def self.config_dir
29
+ File.join(ENV['HOME'], '.iptables-web')
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,39 @@
1
+ require 'tempfile'
2
+ module IptablesWeb
3
+ class Crontab
4
+ include IptablesWeb::Mixin::Sudo
5
+
6
+ def jobs
7
+ execute('crontab -l 2> /dev/null').split("\n").reject { |l| l.empty? || l.include?('no crontab for') || l[0] == '#' }
8
+ end
9
+
10
+ def save(jobs)
11
+ lines = ["##{Time.now}"]
12
+ jobs.each do |job|
13
+ lines << job
14
+ lines << ''
15
+ end
16
+ file = Tempfile.new('crontab')
17
+ file.write lines.join("\n")
18
+ file.rewind
19
+ execute "crontab #{file.path}"
20
+ ensure
21
+ if file
22
+ file.close
23
+ file.unlink
24
+ end
25
+ end
26
+
27
+ def execute(command)
28
+ if is_root?
29
+ `sudo #{command}`
30
+ else
31
+ `#{command}`
32
+ end
33
+ end
34
+
35
+ def is_root?
36
+ Process.uid == 0
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,40 @@
1
+ require 'tempfile'
2
+ module IptablesWeb
3
+ class Iptables
4
+ include IptablesWeb::Mixin::Sudo
5
+
6
+ def restore(access_rules)
7
+ temp_file = Tempfile.new('rules')
8
+ puts render(access_rules)
9
+ temp_file.write render(access_rules)
10
+ temp_file.rewind
11
+ execute("iptables-restore -c < #{temp_file.path}")
12
+ ensure
13
+ if temp_file
14
+ temp_file.close
15
+ temp_file.unlink
16
+ end
17
+ end
18
+
19
+ def save
20
+ execute('iptables-save').split("\n")
21
+ end
22
+
23
+ def static_rules
24
+ IptablesWeb::Configuration.static_rules
25
+ end
26
+
27
+ def render(rules, name = 'filter')
28
+ lines = []
29
+ lines << "*#{name}"
30
+ lines << ':INPUT DROP [0:0]'
31
+ lines << ':FORWARD DROP [0:0]'
32
+ lines << ':OUTPUT ACCEPT [0:0]'
33
+ lines << static_rules
34
+ lines << Array(rules).map(&:to_s).join("\n")
35
+ lines << 'COMMIT'
36
+ lines << '#end'
37
+ lines.join("\n")
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,17 @@
1
+ module IptablesWeb
2
+ module Mixin
3
+ module Sudo
4
+ def execute(command)
5
+ if is_root? || command.include?('sudo')
6
+ `#{command}`
7
+ else
8
+ `sudo #{command}`
9
+ end
10
+ end
11
+
12
+ def is_root?
13
+ Process.uid == 0
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,76 @@
1
+ module IptablesWeb
2
+ module Model
3
+ class AccessRule < Base
4
+ self.element_name = 'access_rule'
5
+
6
+ MAPPING = {
7
+ chain: 'INPUT',
8
+ target_chain: 'ACCEPT',
9
+ protocol: '-p {value}',
10
+ port: '--dport {value}',
11
+ ip: '-s {value}',
12
+ description: '-m comment --comment "{value}"'
13
+ }
14
+
15
+ def to_s
16
+ command = %w(-A INPUT)
17
+ self.attributes.each do |name, value|
18
+
19
+ case name.to_sym
20
+ when :port
21
+ next unless value
22
+ if value.include?(',')
23
+ command << '-m'
24
+ command << 'multiport'
25
+ command << '--dports'
26
+ command << value
27
+ else
28
+ command << '--dport'
29
+ command << value
30
+ end
31
+ when :ip
32
+ command << '-s'
33
+ command << value
34
+ when :protocol
35
+ command << '-p'
36
+ command << value
37
+ when :description
38
+ if value
39
+ command << '-m'
40
+ command << 'comment'
41
+ command << '--comment'
42
+ command << Shellwords.escape(value)
43
+ end
44
+ else
45
+ #skip
46
+ end
47
+ end
48
+ command << '-j'
49
+ command << 'ACCEPT'
50
+ command.join(' ')
51
+ # -A INPUT -s 88.150.233.48/29 -p tcp -m tcp --dport 9200 -j ACCEPT
52
+ end
53
+
54
+ def mapping(parameter)
55
+
56
+ end
57
+ end
58
+ end
59
+ end
60
+
61
+ # *filter
62
+ # :INPUT ACCEPT [217626552:31573175391]
63
+ # :FORWARD ACCEPT [0:0]
64
+ # :OUTPUT ACCEPT [1334268962:861811554534]
65
+ # -A INPUT -s 88.150.233.48/29 -p tcp -m tcp --dport 9200 -j ACCEPT
66
+ # -A INPUT -s 88.150.213.250/32 -p tcp -m tcp --dport 9200 -j ACCEPT
67
+ # -A INPUT -s 127.0.0.1/32 -p tcp -m tcp --dport 9200 -j ACCEPT
68
+ # -A INPUT -s 37.220.8.122/32 -p tcp -m tcp --dport 9200 -j ACCEPT
69
+ # -A INPUT -p tcp -m tcp --dport 9200 -j DROP
70
+ # -A INPUT -s 88.150.233.48/29 -p tcp -m tcp --dport 9300 -j ACCEPT
71
+ # -A INPUT -s 88.150.213.250/32 -p tcp -m tcp --dport 9300 -j ACCEPT
72
+ # -A INPUT -p tcp -m tcp --dport 9300 -j DROP
73
+ # -A INPUT -s 193.105.70.192/29 -p tcp -m tcp --dport 22 -j ACCEPT
74
+ # -A INPUT -s 92.60.190.109/32 -p tcp -m tcp --dport 22 -j ACCEPT
75
+ # -A INPUT -p tcp -m tcp --dport 22 -j DROP
76
+ # COMMIT
@@ -0,0 +1,11 @@
1
+ require 'active_resource'
2
+ module IptablesWeb
3
+ module Model
4
+ class Base < ActiveResource::Base
5
+ def self.configure(config)
6
+ self.site = "#{config['api_base_url']}/api"
7
+ headers['X-Node-Access-Token'] = config['access_token']
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,42 @@
1
+ module IptablesWeb
2
+ module Model
3
+ class Node < Base
4
+ self.element_name = 'node'
5
+ self.include_root_in_json = true
6
+
7
+ def self.handshake
8
+ node = find('current')
9
+ node.ips = []
10
+ System.get_ifaddrs.each do |interface, config|
11
+ next if interface.to_s.include?('lo')
12
+ node.ips.push({
13
+ interface: interface,
14
+ ip: config[:inet_addr],
15
+ netmask: config[:netmask]
16
+ })
17
+ end
18
+ node.hostname = `hostname -f`
19
+ if node.save && block_given?
20
+ yield
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+
27
+ # *filter
28
+ # :INPUT ACCEPT [217626552:31573175391]
29
+ # :FORWARD ACCEPT [0:0]
30
+ # :OUTPUT ACCEPT [1334268962:861811554534]
31
+ # -A INPUT -s 88.150.233.48/29 -p tcp -m tcp --dport 9200 -j ACCEPT
32
+ # -A INPUT -s 88.150.213.250/32 -p tcp -m tcp --dport 9200 -j ACCEPT
33
+ # -A INPUT -s 127.0.0.1/32 -p tcp -m tcp --dport 9200 -j ACCEPT
34
+ # -A INPUT -s 37.220.8.122/32 -p tcp -m tcp --dport 9200 -j ACCEPT
35
+ # -A INPUT -p tcp -m tcp --dport 9200 -j DROP
36
+ # -A INPUT -s 88.150.233.48/29 -p tcp -m tcp --dport 9300 -j ACCEPT
37
+ # -A INPUT -s 88.150.213.250/32 -p tcp -m tcp --dport 9300 -j ACCEPT
38
+ # -A INPUT -p tcp -m tcp --dport 9300 -j DROP
39
+ # -A INPUT -s 193.105.70.192/29 -p tcp -m tcp --dport 22 -j ACCEPT
40
+ # -A INPUT -s 92.60.190.109/32 -p tcp -m tcp --dport 22 -j ACCEPT
41
+ # -A INPUT -p tcp -m tcp --dport 22 -j DROP
42
+ # COMMIT
@@ -0,0 +1,3 @@
1
+ module IptablesWeb
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,26 @@
1
+ require 'iptables_web/version'
2
+ require 'iptables_web/configuration'
3
+ require 'iptables_web/mixin/sudo'
4
+ require 'iptables_web/model/base'
5
+ require 'iptables_web/model/access_rule'
6
+ require 'iptables_web/model/node'
7
+ require 'iptables_web/crontab'
8
+ require 'iptables_web/iptables'
9
+
10
+ module IptablesWeb
11
+ class << self
12
+ attr_accessor :configuration
13
+ def configuration
14
+ self.configuration = Configuration.new unless @configuration
15
+ @configuration
16
+ end
17
+
18
+ def configuration=(config)
19
+ @configuration = config
20
+ IptablesWeb::Model::Base.configure(config)
21
+ @configuration
22
+ end
23
+ end
24
+ end
25
+
26
+ IptablesWeb.configuration = IptablesWeb::Configuration.new #set default configuration
metadata ADDED
@@ -0,0 +1,127 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: iptables-web
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - NikolayMurga
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-11-06 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: system-getifaddrs
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: 0.2.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: 0.2.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: activeresource
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: 4.0.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: 4.0.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: commander
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: 4.0.0
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 4.0.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: bundler
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '1.6'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: '1.6'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ~>
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ~>
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description: Write a longer description. Optional.
84
+ email:
85
+ - nikolay.m@randrmusic.com
86
+ executables:
87
+ - iptables-web
88
+ extensions: []
89
+ extra_rdoc_files: []
90
+ files:
91
+ - LICENSE.txt
92
+ - README.md
93
+ - bin/iptables-web
94
+ - lib/iptables_web.rb
95
+ - lib/iptables_web/configuration.rb
96
+ - lib/iptables_web/crontab.rb
97
+ - lib/iptables_web/iptables.rb
98
+ - lib/iptables_web/mixin/sudo.rb
99
+ - lib/iptables_web/model/access_rule.rb
100
+ - lib/iptables_web/model/base.rb
101
+ - lib/iptables_web/model/node.rb
102
+ - lib/iptables_web/version.rb
103
+ homepage: ''
104
+ licenses:
105
+ - MIT
106
+ metadata: {}
107
+ post_install_message:
108
+ rdoc_options: []
109
+ require_paths:
110
+ - lib
111
+ required_ruby_version: !ruby/object:Gem::Requirement
112
+ requirements:
113
+ - - '>='
114
+ - !ruby/object:Gem::Version
115
+ version: '0'
116
+ required_rubygems_version: !ruby/object:Gem::Requirement
117
+ requirements:
118
+ - - '>='
119
+ - !ruby/object:Gem::Version
120
+ version: '0'
121
+ requirements: []
122
+ rubyforge_project:
123
+ rubygems_version: 2.2.2
124
+ signing_key:
125
+ specification_version: 4
126
+ summary: Write a short summary. Required.
127
+ test_files: []