tormanager 0.4.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/tormanager.rb +1 -0
- data/lib/tormanager/create_eye_config.rb +27 -0
- data/lib/tormanager/ip_address_control.rb +4 -2
- data/lib/tormanager/process_helper.rb +7 -5
- data/lib/tormanager/tor_process.rb +16 -28
- data/lib/tormanager/version.rb +1 -1
- metadata +3 -3
- data/lib/tormanager/eye/tor.god.rb +0 -105
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a1d766b2c286eacb7f7efa82f21dc1662e212f4d
|
4
|
+
data.tar.gz: 32410bc4be8b53b6b655bb769d670685bf822a98
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a82a54925256086092b0077286a4d550367281dcad947ffbe31aeb022643c215c34042fbf2ab2d75d63f76225d9eb24e8843792446a67a01f49f2116aada385b
|
7
|
+
data.tar.gz: f5abb39b3cec9703b81731696d8e9e36f1c3103f65ec47202b2436081e6b445e8b24a517d9b80439f02f1c1e913c82d96098f94dcaf5b8f78d2ef22e1fdcf2bd
|
data/lib/tormanager.rb
CHANGED
@@ -0,0 +1,27 @@
|
|
1
|
+
module TorManager
|
2
|
+
class CreateEyeConfig
|
3
|
+
def initialize params={}
|
4
|
+
@settings = params
|
5
|
+
end
|
6
|
+
|
7
|
+
def create
|
8
|
+
File.open(@settings[:eye_tor_config_path], "w") do |file|
|
9
|
+
file.puts read_eye_tor_config_template_and_substitute_keywords
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def read_eye_tor_config_template_and_substitute_keywords
|
16
|
+
text = File.read(@settings[:eye_tor_config_template])
|
17
|
+
eye_tor_config_template_substitution_keywords.each do |keyword|
|
18
|
+
text = text.gsub(/\[\[\[#{keyword}\]\]\]/, @settings[keyword.to_sym].to_s)
|
19
|
+
end
|
20
|
+
text
|
21
|
+
end
|
22
|
+
|
23
|
+
def eye_tor_config_template_substitution_keywords
|
24
|
+
@settings.keys.map(&:to_s)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
require 'rest-client'
|
2
2
|
|
3
3
|
module TorManager
|
4
|
+
TorUnavailable = Class.new(StandardError)
|
5
|
+
|
4
6
|
class IpAddressControl
|
5
7
|
attr_accessor :ip
|
6
8
|
|
@@ -24,7 +26,7 @@ module TorManager
|
|
24
26
|
private
|
25
27
|
|
26
28
|
def ensure_tor_is_available
|
27
|
-
raise "Cannot proceed, Tor is not running on port " +
|
29
|
+
raise TorUnavailable, "Cannot proceed, Tor is not running on port " +
|
28
30
|
"#{@tor_process.settings[:tor_port]}" unless
|
29
31
|
TorProcess.tor_running_on? port: @tor_process.settings[:tor_port],
|
30
32
|
parent_pid: @tor_process.settings[:parent_pid]
|
@@ -70,7 +72,7 @@ module TorManager
|
|
70
72
|
|
71
73
|
def tor_switch_endpoint
|
72
74
|
Tor::Controller.connect(:port => @tor_process.settings[:control_port]) do |tor|
|
73
|
-
tor.authenticate(
|
75
|
+
tor.authenticate(@tor_process.settings[:control_password])
|
74
76
|
tor.signal("newnym")
|
75
77
|
sleep 10
|
76
78
|
end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
require 'socket'
|
2
2
|
|
3
3
|
module TorManager
|
4
|
+
CannotKillProcess = Class.new(StandardError)
|
5
|
+
|
4
6
|
class ProcessHelper
|
5
7
|
class << self
|
6
8
|
def query_process query
|
@@ -12,14 +14,14 @@ module TorManager
|
|
12
14
|
|
13
15
|
def kill_process pids
|
14
16
|
to_array(pids).each do |pid|
|
15
|
-
try_to_kill pid: pid, attempts: 5
|
17
|
+
try_to_kill pid: Integer(pid), attempts: 5
|
16
18
|
end
|
17
19
|
end
|
18
20
|
|
19
21
|
def process_pid_running? pid
|
20
22
|
begin
|
21
23
|
return false if pid.to_s == ''.freeze
|
22
|
-
ipid = pid
|
24
|
+
ipid = Integer(pid)
|
23
25
|
return false if ipid <= 0
|
24
26
|
Process.kill(0, ipid)
|
25
27
|
return true
|
@@ -63,12 +65,12 @@ module TorManager
|
|
63
65
|
def try_to_kill params={}
|
64
66
|
pid = params.fetch(:pid, nil)
|
65
67
|
return unless pid && process_pid_running?(pid)
|
66
|
-
params.fetch(:attempts, 5).times do |
|
67
|
-
|
68
|
+
params.fetch(:attempts, 5).times do |i|
|
69
|
+
i < 3 ? Process.kill('TERM', pid) :
|
68
70
|
Process.kill('KILL', pid)
|
69
71
|
sleep 0.5
|
70
72
|
break unless process_pid_running? pid
|
71
|
-
raise "Couldnt kill pid: #{pid}" if
|
73
|
+
raise CannotKillProcess, "Couldnt kill pid: #{pid}" if i >= 4
|
72
74
|
end
|
73
75
|
end
|
74
76
|
end
|
@@ -4,6 +4,12 @@ require 'fileutils'
|
|
4
4
|
require 'securerandom'
|
5
5
|
|
6
6
|
module TorManager
|
7
|
+
Error = Class.new(StandardError)
|
8
|
+
TorPortInUse = Class.new(Error)
|
9
|
+
TorControlPortInUse = Class.new(Error)
|
10
|
+
TorFailedToStart = Class.new(Error)
|
11
|
+
TorFailedToStop = Class.new(Error)
|
12
|
+
|
7
13
|
class TorProcess
|
8
14
|
attr_accessor :settings
|
9
15
|
|
@@ -88,31 +94,29 @@ module TorManager
|
|
88
94
|
end
|
89
95
|
|
90
96
|
def tor_port_is_open?
|
91
|
-
raise "Cannot spawn Tor process as port " +
|
97
|
+
raise TorPortInUse, "Cannot spawn Tor process as port " +
|
92
98
|
"#{@settings[:tor_port]} is in use" unless
|
93
99
|
ProcessHelper.port_is_open?(@settings[:tor_port])
|
94
100
|
true
|
95
101
|
end
|
96
102
|
|
97
103
|
def control_port_is_open?
|
98
|
-
raise "Cannot spawn Tor process as control port " +
|
104
|
+
raise TorControlPortInUse, "Cannot spawn Tor process as control port " +
|
99
105
|
"#{@settings[:control_port]} is in use" unless
|
100
106
|
ProcessHelper.port_is_open?(@settings[:control_port])
|
101
107
|
true
|
102
108
|
end
|
103
109
|
|
104
110
|
def prepare_tor_start_and_monitor
|
105
|
-
build_eye_config_from_template
|
111
|
+
#build_eye_config_from_template
|
112
|
+
eye_config = CreateEyeConfig.new(
|
113
|
+
@settings.merge(
|
114
|
+
eye_tor_config_path: eye_config_filename))
|
115
|
+
eye_config.create
|
106
116
|
make_dirs
|
107
117
|
start_tor_and_monitor
|
108
118
|
end
|
109
119
|
|
110
|
-
def build_eye_config_from_template
|
111
|
-
File.open(eye_config_filename, "w") do |file|
|
112
|
-
file.puts read_eye_tor_config_template_and_substitute_keywords
|
113
|
-
end
|
114
|
-
end
|
115
|
-
|
116
120
|
def eye_config_filename
|
117
121
|
@eye_config_filename || File.join(@settings[:log_dir],
|
118
122
|
"tormanager.tor.#{@settings[:tor_port]}.#{Process.pid}.eye.rb")
|
@@ -122,23 +126,6 @@ module TorManager
|
|
122
126
|
@eye_app_name || "tormanager-tor-#{@settings[:tor_port]}-#{Process.pid}"
|
123
127
|
end
|
124
128
|
|
125
|
-
def read_eye_tor_config_template_and_substitute_keywords
|
126
|
-
text = File.read(@settings[:eye_tor_config_template])
|
127
|
-
eye_tor_config_template_substitution_keywords.each do |keyword|
|
128
|
-
text = text.gsub(/\[\[\[#{keyword}\]\]\]/, @settings[keyword.to_sym].to_s)
|
129
|
-
end
|
130
|
-
text
|
131
|
-
end
|
132
|
-
|
133
|
-
def eye_tor_config_template_substitution_keywords
|
134
|
-
remove_settings_that_are_not_eye_tor_config_template_keywords(
|
135
|
-
@settings.keys.map(&:to_s))
|
136
|
-
end
|
137
|
-
|
138
|
-
def remove_settings_that_are_not_eye_tor_config_template_keywords keywords
|
139
|
-
keywords - ['eye_tor_config_template', 'control_password', 'dont_remove_tor_config']
|
140
|
-
end
|
141
|
-
|
142
129
|
def make_dirs
|
143
130
|
[@settings[:log_dir], @settings[:pid_dir],
|
144
131
|
@settings[:tor_data_dir]].each do |path|
|
@@ -159,7 +146,7 @@ module TorManager
|
|
159
146
|
application: eye_app_name,
|
160
147
|
process: 'tor') == 'up'
|
161
148
|
sleep 2
|
162
|
-
raise "Tor didnt start up after 20 seconds! See log: " +
|
149
|
+
raise TorFailedToStart, "Tor didnt start up after 20 seconds! See log: " +
|
163
150
|
"#{File.join(@settings[:log_dir],
|
164
151
|
eye_app_name + ".log")}" if i >= 9
|
165
152
|
end
|
@@ -172,7 +159,8 @@ module TorManager
|
|
172
159
|
process: 'tor')
|
173
160
|
break if ['unknown','unmonitored'].include?(tor_status)
|
174
161
|
sleep 2
|
175
|
-
raise
|
162
|
+
raise TorFailedToStop,
|
163
|
+
"Tor didnt stop after 20 seconds! Last status: #{tor_status} See log: " +
|
176
164
|
"#{File.join(@settings[:log_dir],
|
177
165
|
eye_app_name + ".log")}" if i >= 9
|
178
166
|
end
|
data/lib/tormanager/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tormanager
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- joshweir
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-08-
|
11
|
+
date: 2017-08-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -155,9 +155,9 @@ files:
|
|
155
155
|
- bin/setup
|
156
156
|
- lib/tormanager.rb
|
157
157
|
- lib/tormanager/control.rb
|
158
|
+
- lib/tormanager/create_eye_config.rb
|
158
159
|
- lib/tormanager/eye/eye.tor.test.rb
|
159
160
|
- lib/tormanager/eye/sugar.rb
|
160
|
-
- lib/tormanager/eye/tor.god.rb
|
161
161
|
- lib/tormanager/eye/tor.template.eye.rb
|
162
162
|
- lib/tormanager/ip_address_control.rb
|
163
163
|
- lib/tormanager/process_helper.rb
|
@@ -1,105 +0,0 @@
|
|
1
|
-
require 'fileutils'
|
2
|
-
|
3
|
-
opts = {}
|
4
|
-
opts[:parent_id] = ARGV[0]
|
5
|
-
opts[:tor_port] = ARGV[1] || 9050
|
6
|
-
opts[:control_port] = ARGV[2] || 50500
|
7
|
-
opts[:pid_dir] = ARGV[3] || "/tmp"
|
8
|
-
opts[:log_dir] = ARGV[4] || "/tmp"
|
9
|
-
opts[:tor_data_dir] = ARGV[5] || "/tmp/tor_data/"
|
10
|
-
opts[:tor_new_circuit_period] = ARGV[6] || 60
|
11
|
-
opts[:max_tor_memory_usage_mb] = ARGV[7] || 200
|
12
|
-
opts[:max_tor_cpu_percentage] = ARGV[8] || 10
|
13
|
-
opts[:max_tor_memory_usage_times] = [3,5]
|
14
|
-
opts[:max_tor_cpu_percentage_times] = [3,5]
|
15
|
-
|
16
|
-
raise 'parent_id is required' unless opts[:parent_id]
|
17
|
-
|
18
|
-
module God
|
19
|
-
module Behaviors
|
20
|
-
class WaitBehavior < Behavior
|
21
|
-
attr_accessor :delay
|
22
|
-
|
23
|
-
def after_start
|
24
|
-
sleep delay.to_i if delay.to_i > 0
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
God.watch do |w|
|
31
|
-
the_name = "tormanager-tor-#{opts[:tor_port]}-#{opts[:parent_id]}"
|
32
|
-
w.name = the_name
|
33
|
-
w.start = "tor --SocksPort #{opts[:tor_port]} --ControlPort #{opts[:control_port]} " +
|
34
|
-
"--CookieAuthentication 0 --HashedControlPassword \"16:3E49D6163CCA95F2605B339" +
|
35
|
-
"E07F753C8F567DE4200E33FDF4CC6B84E44\" --NewCircuitPeriod " +
|
36
|
-
"#{opts[:tor_new_circuit_period]} --DataDirectory " +
|
37
|
-
File.join(opts[:tor_data_dir], opts[:tor_port]) + " --Log \"notice syslog\""
|
38
|
-
#w.pid_file = File.join(opts[:pid_dir], "#{the_name}.pid")
|
39
|
-
#w.log = File.join(opts[:log_dir], "#{the_name}.log") if opts[:log_dir].length > 0
|
40
|
-
w.keepalive
|
41
|
-
|
42
|
-
# clean pid files before start if necessary
|
43
|
-
w.behavior(:clean_pid_file)
|
44
|
-
w.behavior(:wait_behavior) do |b|
|
45
|
-
b.delay = 10
|
46
|
-
end
|
47
|
-
|
48
|
-
=begin
|
49
|
-
# determine the state on startup
|
50
|
-
w.transition(:init, { true => :up, false => :start }) do |on|
|
51
|
-
sleep 5
|
52
|
-
on.condition(:process_running) do |c|
|
53
|
-
c.interval = 5
|
54
|
-
c.running = true
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
# determine when process has finished starting
|
59
|
-
w.transition([:start, :restart], :up) do |on|
|
60
|
-
on.condition(:process_running) do |c|
|
61
|
-
c.interval = 20
|
62
|
-
c.running = true
|
63
|
-
end
|
64
|
-
|
65
|
-
# failsafe
|
66
|
-
on.condition(:tries) do |c|
|
67
|
-
c.interval = 20
|
68
|
-
c.times = 5
|
69
|
-
c.transition = :start
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
# start if process is not running
|
74
|
-
#w.transition(:up, :start) do |on|
|
75
|
-
# on.condition(:process_exits) do |c|
|
76
|
-
# c.interval = 20
|
77
|
-
# end
|
78
|
-
#end
|
79
|
-
|
80
|
-
# restart if memory or cpu is too high
|
81
|
-
w.transition(:up, :restart) do |on|
|
82
|
-
on.condition(:memory_usage) do |c|
|
83
|
-
c.interval = 20
|
84
|
-
c.above = opts[:max_tor_memory_usage_mb]
|
85
|
-
c.times = opts[:max_tor_memory_usage_times]
|
86
|
-
end
|
87
|
-
|
88
|
-
on.condition(:cpu_usage) do |c|
|
89
|
-
c.interval = 10
|
90
|
-
c.above = opts[:max_tor_cpu_percentage]
|
91
|
-
c.times = opts[:max_tor_cpu_percentage_times]
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
# lifecycle
|
96
|
-
w.lifecycle do |on|
|
97
|
-
on.condition(:flapping) do |c|
|
98
|
-
c.to_state = [:start, :restart]
|
99
|
-
c.times = 5
|
100
|
-
c.within = 5.minute
|
101
|
-
c.transition = :unmonitored
|
102
|
-
end
|
103
|
-
end
|
104
|
-
=end
|
105
|
-
end
|