require ‘eventmachine’ require ‘fileutils’ require ‘json’ require ‘logger’ require ‘rubygems’ require ‘sequel’ require ‘sinatra’ require ‘thin’ require ‘yaml’
require ‘./ip_wrangler/db’ require ‘./ip_wrangler/ip’ require ‘./ip_wrangler/iptables’ require ‘./ip_wrangler/nat’ require ‘./ip_wrangler/exec’
unless ENV.has_key?(‘__config_file’)
puts 'No config file. Exiting.' exit(1)
end
config_file = ENV
unless File.file?(config_file)
puts "#{config_file} not found. Exiting." exit(2)
end
config = YAML.load_file(config_file)
unless ENV.has_key?(‘__no_log’)
console_logger = File.new("#{config['log_dir']}/thin_output.log", 'a') STDOUT.reopen(console_logger) STDERR.reopen(console_logger)
end
puts “Checking if #{config} is existing…”
unless File.file?(config)
puts "Create #{config['db_path']}" FileUtils.touch(config['db_path'])
end
puts ‘Checking database…’
db = Sequel.connect(“sqlite://#{config}”)
unless db.table_exists?(:nat_ports)
puts 'No nat_ports table. Creating it...' db.create_table?(:nat_ports) do primary_key :id String :public_ip Int :public_port String :private_ip Int :private_port String :protocol end db.add_index(:nat_ports, [:public_ip, :public_port]) %w(tcp udp).each do |protocol| ports = (config['port_start']..config['port_stop']).map { |port| [config['port_ip'], port, nil, nil, protocol] }.to_a db[:nat_ports].import([:public_ip, :public_port, :private_ip, :private_port, :protocol], ports) end
end
unless db.table_exists?(:nat_ips)
puts 'No nat_ips table. Creating it...' db.create_table?(:nat_ips) do primary_key :id String :public_ip String :private_ip end db.add_index(:nat_ips, :public_ip) if config['ip'] != nil config['ip'].each do |public_ip| db[:nat_ips].insert(public_ip: public_ip, private_ip: nil) puts "Add ip:#{public_ip}" end end
end
db.disconnect
puts “Creating chain #{config}_PRE in nat table…” command_new_pre_nat_chain = IpWrangler::Command.new_chain
(“#{config}_PRE”, ‘nat’) IpWrangler::Exec.execute_iptables_command(command_new_pre_nat_chain)
puts “Creating chain #{config}_POST in nat table…” command_new_post_nat_chain = IpWrangler::Command.new_chain
(“#{config}_POST”, ‘nat’) IpWrangler::Exec.execute_iptables_command(command_new_post_nat_chain)
puts ‘Appending rule, if not exists, to PREROUTING chain…’ command_check_pre_nat_jump_rule = IpWrangler::Command.check_rule
(‘PREROUTING’, ‘nat’, [IpWrangler::Parameter.jump(“#{config}_PRE”)]) IpWrangler::Exec.execute_iptables_command(command_check_pre_nat_jump_rule)
if $?.exitstatus == 1
command_append_pre_nat_jump_rule = IpWrangler::Command.append_rule('PREROUTING', 'nat', [IpWrangler::Parameter.jump("#{config['iptables_chain_name']}_PRE")]) IpWrangler::Exec.execute_iptables_command(command_append_pre_nat_jump_rule)
end
puts ‘Appending rule, if not exists, to POSTROUTING chain…’ command_check_post_nat_jump_rule = IpWrangler::Command.check_rule
(‘POSTROUTING’, ‘nat’, [IpWrangler::Parameter.jump(“#{config}_POST”)]) IpWrangler::Exec.execute_iptables_command(command_check_post_nat_jump_rule)
if $?.exitstatus == 1
command_append_post_nat_jump_rule = IpWrangler::Command.append_rule('POSTROUTING', 'nat', [IpWrangler::Parameter.jump("#{config['iptables_chain_name']}_POST")]) IpWrangler::Exec.execute_iptables_command(command_append_post_nat_jump_rule)
end
require File.dirname(__FILE__) + ‘/ip_wrangler/main.rb’
set :environment, ENV.to_sym set :app_file, ‘ip_wrangler/main.rb’ set :raise_errors, true
use Rack::MethodOverride disable :run, :reload
run Sinatra::Application