simple_proxies_deploying 1.1.1

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: c3086b055abad44698b019d6cb917ef2b55f2ed8
4
+ data.tar.gz: d6c6cce616fa968f9a18f3ab2f34ad476ff07aea
5
+ SHA512:
6
+ metadata.gz: 1a215ad874f5704357045c0543b6c208ccda56fc242fc42afe4255f67750c84ce6350a10ef8ef6150ebe95b83e6774ddf230ccedfde443a5cb620c14de3a26ec
7
+ data.tar.gz: 3ba545757c18b259035a866e7f28814f720a2f4273a2d51423e6a4404beab3589cf79988a145a46f0991e43af5496d62a6ed6ecdad2cd55b127859e8b0bfb766
data/lib/remotehost.rb ADDED
@@ -0,0 +1,476 @@
1
+ # TODO: replace RemoteHost class in SimpleHostsMonitoring library by this code
2
+ class RemoteHost
3
+ # TODO: this must be defined at class RemoteHost in the SimpleHostMonitoring library
4
+ attr_accessor :cpu_architecture, :cpu_speed, :cpu_load_average, :cpu_model, :cpu_type, :cpu_number, :mem_total, :mem_free, :disk_total, :disk_free, :net_hostname, :net_remote_ip, :net_mac_address
5
+ attr_accessor :stealth_browser_technology_code, :ssh_username, :ssh_password, :ssh_port, :ipv6_subnet_48
6
+ attr_accessor :ssh # this is the ssh connection
7
+ attr_accessor :logger
8
+
9
+ def initialize(the_logger=nil)
10
+ self.logger=the_logger
11
+ self.logger = BlackStack::DummyLogger.new(nil) if self.logger.nil? # assign a dummy logger that just generate output on the screen
12
+ end
13
+
14
+ # TODO: mover esto al modulo BaseHost de SimpleHostMonitoring
15
+ def self.valid_port_number?(n)
16
+ return false if !n.is_a?(Numeric)
17
+ return false if n < 1 || n > 65535
18
+ true
19
+ end
20
+
21
+ # return the same hash as the class poll() method, but connecting the server via SSH.
22
+ # we are assuming the server is a Linux server.
23
+ # TODO: write the list of software packages that server must have installed.
24
+ def poll_thru_ssh()
25
+ # TODO: code me!
26
+ end
27
+
28
+ # TODO: this must be defined at module BaseHost in the SimpleHostMonitoring library
29
+ def parse(h)
30
+ # parameters regarding the current status of the host
31
+ self.cpu_architecture = h[:cpu_architecture]
32
+ self.cpu_speed = h[:cpu_speed]
33
+ self.cpu_load_average = h[:cpu_load_average]
34
+ self.cpu_model = h[:cpu_model]
35
+ self.cpu_type = h[:cpu_type]
36
+ self.cpu_number = h[:cpu_number]
37
+ self.mem_total = h[:mem_total]
38
+ self.mem_free = h[:mem_free]
39
+ self.disk_total = h[:disk_total]
40
+ self.disk_free = h[:disk_free]
41
+ self.net_hostname = h[:net_hostname]
42
+ self.net_mac_address = h[:net_mac_address]
43
+
44
+ # parameters regarding the remote controling of the server
45
+ self.net_remote_ip = h[:net_remote_ip]
46
+ self.ssh_username = h[:ssh_username]
47
+ self.ssh_password = h[:ssh_password]
48
+ self.ssh_port = h[:ssh_port]
49
+
50
+ # StealthBrowserAutomation monkey-patch add-on: parameters regarding the usage of stealth browser for automation
51
+ self.stealth_browser_technology_code = h[:stealth_browser_technology_code]
52
+
53
+ # SimpleProxyServer monkey-patch add-on: paremeters regarding the installation of proxies
54
+ self.ipv6_subnet_48 = h[:ipv6_subnet_48]
55
+ end
56
+
57
+ def self.parse(h, logger=nil)
58
+ o = RemoteHost.new(logger)
59
+ o.parse(h)
60
+ o
61
+ end
62
+
63
+ # TODO: this must be defined at module BaseHost in the SimpleHostMonitoring library
64
+ def to_hash
65
+ {
66
+ # parameters regarding the current status of the host
67
+ :cpu_architecture => self.cpu_architecture,
68
+ :cpu_speed => self.cpu_speed,
69
+ :cpu_load_average => self.cpu_load_average,
70
+ :cpu_model => self.cpu_model,
71
+ :cpu_type => self.cpu_type,
72
+ :cpu_number => self.cpu_number,
73
+ :mem_total => self.mem_total,
74
+ :mem_free => self.mem_free,
75
+ :disk_total => self.disk_total,
76
+ :disk_free => self.disk_free,
77
+ :net_hostname => self.net_hostname,
78
+ :net_remote_ip => self.net_remote_ip,
79
+ :net_mac_address => self.net_mac_address,
80
+
81
+ # parameters regarding the remote controling of the server
82
+ :ssh_username => self.ssh_username,
83
+ :ssh_password => self.ssh_password,
84
+ :ssh_port => self.ssh_port,
85
+
86
+ # StealthBrowserAutomation monkey-patch add-on: parameters regarding the usage of stealth browser for automation
87
+ :stealth_browser_technology_code => self.stealth_browser_technology_code,
88
+
89
+ # SimpleProxyServer monkey-patch add-on: paremeters regarding the installation of proxies
90
+ :ipv6_subnet_48 => self.ipv6_subnet_48,
91
+ }
92
+ end
93
+
94
+
95
+ def ssh_parameters?
96
+ self.net_remote_ip && self.ssh_username && self.ssh_password
97
+ end
98
+
99
+ def get_ssh_port()
100
+ self.ssh_port.nil? ? 22 : self.ssh_port
101
+ end
102
+
103
+ def ssh_connect()
104
+ # validation: this host must have ssh parameters
105
+ raise SimpleProxiesDeployingException.new(1) if !self.ssh_parameters?
106
+
107
+ # connect
108
+ self.ssh = Net::SSH.start(self.net_remote_ip, self.ssh_username, :password => self.ssh_password, :port => self.get_ssh_port)
109
+
110
+ # validation: the connection must be established
111
+ raise SimpleProxiesDeployingException.new(4) if !self.ssh
112
+ end
113
+
114
+ # Parse the file /usr/local/etc/3proxy/cfg/3proxy.cfg
115
+ # Return an array of hash descriptors like this: {:port=>"3130", :external_ip=>"185.165.34.31"}
116
+ def get_ipv4_proxies()
117
+ # TODO: Code Me!
118
+ end
119
+
120
+ # Parse the file /usr/local/etc/3proxy/cfg/3proxy.cfg
121
+ # Return an array of hash descriptors like this: {:port=>"4248", :external_ip=>"2602:fed2:770f:df10:8dc9:556f:dfba:8ee3", :subnet64=>"2602:fed2:770f:df10"}
122
+ def get_ipv6_proxies()
123
+ # validation: this host must have defined an ipv6 subnet 48
124
+ raise SimpleProxiesDeployingException.new(5) if !self.ipv6_subnet_48
125
+
126
+ # validation: this host must have ssh connection
127
+ raise SimpleProxiesDeployingException.new(3) if !self.ssh
128
+
129
+ results = []
130
+ stdout = ssh.exec!("echo '#{self.ssh_password.gsub("'", "\\'")}' | sudo -S su root -c 'grep \"proxy -p\" /usr/local/etc/3proxy/cfg/3proxy.cfg'")
131
+ a = stdout.split("\n") # stdout.scan(MATCH_IPV6_STANDARD)
132
+ a.select { |x|
133
+ # filter all the IPv6 proxies
134
+ x.include?('-6')
135
+ }.each { |x|
136
+ # example: proxy -p4245 -6 -a -n -i0.0.0.0 -e2602:fed2:770f:e75c:dc88:fab6:7623:1f47
137
+ port = x.scan(MATCH_PORT_IN_3PROXY_CONF)[0].gsub(/\-p/, '')
138
+ external_ip = x.scan(MATCH_IPV6_STANDARD)[0]
139
+ subnet64 = external_ip.scan(MATCH_IPV6_64_SUBNET_STANDARD)[0]
140
+ results << { :port => port.to_i, :external_ip => external_ip.to_s, :subnet64 => subnet64.to_s }
141
+ }
142
+ results
143
+ end
144
+
145
+
146
+ # check a list of port numbers and return the list of ports that are missconfigured
147
+ # return an array of errors.
148
+ def check_all_ipv4_proxies()
149
+ # TODO: Code Me!
150
+ end
151
+
152
+ # check a list of port numbers and return the list of ports that are missconfigured
153
+ # return an array of errors.
154
+ # validate if there is more than one external ip address belonging the same /64 subnet.
155
+ # validate that each batch of 50 ports is all configured.
156
+ # raise an exception if there are ports outside the range
157
+ # raise an exception proxy_port_to is not higher than proxy_port_from.
158
+ def check_all_ipv6_proxies(proxy_port_from=DEFAULT_PROXY_PORT_FROM, proxy_port_to=DEFAULT_PROXY_PORT_TO)
159
+ #raise SimpleProxiesDeployingException.new(9, "#{proxy_port_from}") if proxy_port_from != DEFAULT_PROXY_PORT_FROM
160
+ raise SimpleProxiesDeployingException.new(10, "#{proxy_port_from} and #{proxy_port_to}") if proxy_port_from > proxy_port_to
161
+ #raise SimpleProxiesDeployingException.new(11, "from #{proxy_port_from} to #{proxy_port_to}") if (proxy_port_to-proxy_port_from+1) % DEFAULT_PROXY_PORTS_BATCH_SIZE != 0
162
+
163
+ # return this array with the list of glitches found
164
+ errors = []
165
+
166
+ # record all the /64 subnets of each external ip address, to check if there is more than one external ip address belonging the same /64 subnet
167
+ # records all the extenral ips of each port, to check that each batch of 50 ports is all configured, or it is empty
168
+ results = self.get_ipv6_proxies
169
+
170
+ # validate there is not ports outside the range
171
+ a = results.select { |x|
172
+ x[:port]<proxy_port_from || x[:port]>proxy_port_to
173
+ }.map { |x|
174
+ x[:port]
175
+ }
176
+ raise SimpleProxiesDeployingException.new(14, a.join(', ')) if a.size > 1
177
+
178
+ port = proxy_port_from
179
+ while port <= proxy_port_to
180
+ # map the external IPs to the port
181
+ a = results.select { |x| x[:port] == port }.map { |x| x[:external_ip] }
182
+
183
+ # validation: there is no extenral IP defined for this port
184
+ # raise SimpleProxiesDeployingException.new(8) if a.size == 0
185
+
186
+ if a.size > 0
187
+ # validation: there is no more than 1 extenral IP defined for this host
188
+ if a.size > 1
189
+ e = SimpleProxiesDeployingException.new(7, "#{port.to_s} - #{a.join(', ')}")
190
+ errors << { :proxy_port=>port, :code=>e.code, :description=>e.description, :simple_description=>e.simple_description }
191
+ end
192
+
193
+ # validation: the external ip must be belonging the subnet defined at ipv6 subnet 48
194
+ if !a[0].include?(self.ipv6_subnet_48)
195
+ e = SimpleProxiesDeployingException.new(6, "#{a[0]} and #{self.ipv6_subnet_48}")
196
+ errors << { :proxy_port=>port, :code=>e.code, :description=>e.description, :simple_description=>e.simple_description }
197
+ end
198
+ end # if a.size > 0
199
+
200
+ port += 1
201
+ end
202
+
203
+ # validation: there is more than one external ip address belonging the same /64 subnet.
204
+ self.logger.logs 'Check duplicated /64 subnets... '
205
+ i = 0
206
+ results.each { |r|
207
+ if !r[:external_ip].nil?
208
+ b = results.select { |s| s[:port]!=r[:port] && s[:subnet64]==r[:subnet64] }
209
+ if b.size > 1
210
+ e = SimpleProxiesDeployingException.new(12, b.join(', '))
211
+ errors << { :proxy_port=>r[:port], :code=>e.code, :description=>e.description, :simple_description=>e.simple_description }
212
+ i += 1
213
+ end
214
+ end # if !r[:external_ip].nil?
215
+ }
216
+ self.logger.logf "done (#{i.to_s} errors)"
217
+
218
+ # return
219
+ errors
220
+ end # def check_all_ipv6_proxies
221
+
222
+
223
+ # run linux command to get the interface name
224
+ # TODO: validate outout
225
+ def get_interface_name()
226
+ # validation: this host must have ssh connection
227
+ raise SimpleProxiesDeployingException.new(3) if !self.ssh
228
+ ssh.exec!("ip -o -4 route show to default | awk '{print $5}' | sed 1'!d'").strip
229
+ end
230
+
231
+ # run linux command to stop the proxy server
232
+ # TODO: validate outout
233
+ def stop_proxies()
234
+ # validation: this host must have ssh connection
235
+ raise SimpleProxiesDeployingException.new(3) if !self.ssh
236
+ ssh.exec!("sh /usr/local/etc/3proxy/scripts/rc.d/proxy.sh stop > /dev/null 2>&1")
237
+ end
238
+
239
+ # run linux command to stop the proxy server
240
+ # TODO: get this working
241
+ # TODO: validate outout
242
+ def start_proxies()
243
+ # validation: this host must have ssh connection
244
+ raise SimpleProxiesDeployingException.new(3) if !self.ssh
245
+ ssh.exec!("echo '#{self.ssh_password.gsub("'", "\\'")}' | sudo -S su root -c 'sh /usr/local/etc/3proxy/scripts/rc.d/proxy.sh start > /dev/null 2>&1'")
246
+ end
247
+
248
+
249
+ # setup custom IP authorization for a proxy
250
+ def setup_custom_ip_auth(port)
251
+ # TODO: Code Me!
252
+ end
253
+
254
+ # setup custom user/pass authorization for a proxy
255
+ def setup_custom_pass_auth(port)
256
+ # TODO: Code Me!
257
+ end
258
+
259
+
260
+ # install ipv4 proxies
261
+ def install4(username, password, port=3130)
262
+ #raise SimpleProxiesDeployingException.new(9, "#{proxy_port_from}") if proxy_port_from != DEFAULT_PROXY_PORT_FROM
263
+ #raise SimpleProxiesDeployingException.new(10, "#{proxy_port_from} and #{proxy_port_to}") if proxy_port_from > proxy_port_to
264
+ #raise SimpleProxiesDeployingException.new(11, "from #{proxy_port_from} to #{proxy_port_to}") if (proxy_port_to-proxy_port_from+1) % DEFAULT_PROXY_PORTS_BATCH_SIZE != 0
265
+
266
+ # TODO: validate the output
267
+ logger.logs "Get interface name... "
268
+ interface = self.get_interface_name
269
+ logger.done #logf "done (#{interface})"
270
+
271
+ logger.logs "Get server main ip from configuration... "
272
+ mainip = self.net_remote_ip
273
+ logger.done #logf "done (#{mainip})"
274
+
275
+ # TODO: validate the output
276
+ logger.logs "Install packages... "
277
+ stdout = ssh.exec!("echo '#{self.ssh_password.gsub("'", "\\'")}' | sudo -S su root -c '
278
+ apt-get install nano
279
+ apt-get update
280
+ apt-get autoremove -y
281
+ apt-get autoclean -y
282
+ apt-get clean -y
283
+ apt-get install fail2ban software-properties-common -y
284
+ apt-get install build-essential libevent-dev libssl-dev -y
285
+ apt-get install ethtool -y
286
+ apt-get install curl -y
287
+ '")
288
+ logger.done #logf "done (#{stdout})"
289
+
290
+ # TODO: validate the output
291
+ logger.logs "Install 3proxy... "
292
+ stdout = ssh.exec!("echo '#{self.ssh_password.gsub("'", "\\'")}' | sudo -S su root -c '
293
+ cd /usr/local/etc
294
+ wget https://github.com/z3APA3A/3proxy/archive/0.8.12.tar.gz
295
+ tar zxvf 0.8.12.tar.gz
296
+ rm 0.8.12.tar.gz
297
+ mv 3proxy-0.8.12 3proxy
298
+ cd 3proxy
299
+ make -f Makefile.Linux
300
+ make -f Makefile.Linux install
301
+ mkdir log
302
+ cd cfg
303
+ '")
304
+ logger.done #logf "done (#{stdout})"
305
+
306
+ # TODO: validate the output
307
+ logger.logs "Setup 3proxy.cfg... "
308
+ stdout = ssh.exec!("echo '#{self.ssh_password.gsub("'", "\\'")}' | sudo -S su root -c '
309
+ echo \"#!/usr/local/bin/3proxy
310
+ daemon
311
+ pidfile /usr/local/etc/3proxy/3proxy.pid
312
+ nserver 1.1.1.1
313
+ nserver 1.0.0.1
314
+ nscache 65536
315
+ timeouts 1 5 30 60 180 1800 15 60
316
+ log /usr/local/etc/3proxy/log/3proxy.log D
317
+ logformat \\\"- +_L%t.%. %N.%p %E %U %C:%c %R:%r %O %I %h %T\\\"
318
+ archiver rar rar a -df -inul %A %F
319
+ rotate 30
320
+ internal 0.0.0.0
321
+ external 0.0.0.0
322
+ authcache ip 60
323
+ users #{username}:CL:#{password}
324
+
325
+ auth strong
326
+ allow #{username}
327
+ proxy -p#{port} -a -n
328
+ \" > /usr/local/etc/3proxy/cfg/3proxy.cfg'")
329
+ logger.done #logf "done (#{stdout})"
330
+
331
+ logger.logs "Start proxy service... "
332
+ self.start_proxies
333
+ logger.done
334
+
335
+ end # def install_3proxy
336
+
337
+ # install ipv6 proxies
338
+ # raise an exception proxy_port_to is not higher than proxy_port_from.
339
+ def install6(proxy_port_from=DEFAULT_PROXY_PORT_FROM, proxy_port_to=DEFAULT_PROXY_PORT_TO)
340
+ #raise SimpleProxiesDeployingException.new(9, "#{proxy_port_from}") if proxy_port_from != DEFAULT_PROXY_PORT_FROM
341
+ raise SimpleProxiesDeployingException.new(10, "#{proxy_port_from} and #{proxy_port_to}") if proxy_port_from > proxy_port_to
342
+ #raise SimpleProxiesDeployingException.new(11, "from #{proxy_port_from} to #{proxy_port_to}") if (proxy_port_to-proxy_port_from+1) % DEFAULT_PROXY_PORTS_BATCH_SIZE != 0
343
+
344
+ # TODO: validate the output
345
+ logger.logs "Get interface name... "
346
+ interface = self.get_interface_name
347
+ logger.logf "done (#{interface})"
348
+
349
+ logger.logs "Get server main ip from configuration... "
350
+ mainip = self.net_remote_ip
351
+ logger.logf "done (#{mainip})"
352
+
353
+ logger.logs "Install ethtool... "
354
+ stdout = ssh.exec!("echo '#{self.ssh_password.gsub("'", "\\'")}' | sudo -S su root -c 'apt-get install ethtool'")
355
+ logger.done
356
+
357
+ # get list of 4-hex-digits subnets
358
+ logger.logs "Initialize list of 4-hex-digit numbers... "
359
+ hex4digits = []
360
+ "123456789ABCDEF".split('').each { |a| # don't inclulude codes with leading 0, in order to get codes that are 4 digits even in STANDARD notation
361
+ "0123456789ABCDEF".split('').each { |b|
362
+ "0123456789ABCDEF".split('').each { |c|
363
+ "0123456789ABCDEF".split('').each { |d|
364
+ hex4digits << "#{a}#{b}#{c}#{d}".downcase
365
+ }
366
+ }
367
+ }
368
+ }
369
+ logger.logf "done (#{hex4digits.size} numbers)"
370
+
371
+ logger.logs "Shuffle list of 4-hex-digit numbers... "
372
+ hex4digits.shuffle!
373
+ logger.logf "done (#{hex4digits[0]}, #{hex4digits[1]}, #{hex4digits[2]}, ...)"
374
+
375
+ logger.logs "Initialize list proxies... "
376
+ results = get_ipv6_proxies
377
+ logger.logf "done (#{results.size} ports)"
378
+
379
+ # TODO: validate the output
380
+ logger.logs "Install ethtool... "
381
+ stdout = ssh.exec!("echo '#{self.ssh_password.gsub("'", "\\'")}' | sudo -S su root -c 'apt-get install ethtool'")
382
+ logger.done
383
+
384
+ # TODO: validate the output
385
+ logger.logs "Install curl... "
386
+ stdout = ssh.exec!("echo '#{self.ssh_password.gsub("'", "\\'")}' | sudo -S su root -c 'apt-get install curl'")
387
+ logger.done
388
+
389
+ logger.logs "Stop proxy server... "
390
+ stdout = self.stop_proxies
391
+ logger.done #logf "done (#{stdout})"
392
+
393
+ # TODO: validate this output
394
+ logger.logs "Add /48 subnet to interface... "
395
+ stdout = ssh.exec!("echo '#{self.ssh_password.gsub("'", "\\'")}' | sudo -S su root -c 'ifconfig #{interface} add #{self.ipv6_subnet_48}::/48'")
396
+ logger.done #logf "done (#{stdout})"
397
+
398
+ # TODO: validate this output
399
+ logger.logs "Add default route for IPv6... "
400
+ stdout = ssh.exec!("echo '#{self.ssh_password.gsub("'", "\\'")}' | sudo -S su root -c 'ip -6 route add default via #{self.ipv6_subnet_48}::1'")
401
+ logger.done #logf "done (#{stdout})"
402
+
403
+ # TODO: validate this output
404
+ logger.logs "Setup /etc/network.conf... "
405
+ stdout = ssh.exec!("echo '#{self.ssh_password.gsub("'", "\\'")}' | sudo -S su root -c 'echo \"ifconfig #{interface} add #{self.ipv6_subnet_48}::/48
406
+ ip -6 route add default via #{self.ipv6_subnet_48}::1\" >> /etc/network.conf'")
407
+ logger.done #.logf "done (#{stdout})"
408
+
409
+ # TODO: validate this output
410
+ logger.logs "Remove exit 0 FROM rc.local... "
411
+ stdout = ssh.exec!("echo '#{self.ssh_password.gsub("'", "\\'")}' | sudo -S su root -c \"sed -i '/exit 0/d' /etc/rc.local\"")
412
+ logger.done #.logf "done (#{stdout})"
413
+
414
+ # TODO: validate this output
415
+ logger.logs "Remove exit 0 FROM rc.local... "
416
+ stdout = ssh.exec!("echo '#{self.ssh_password.gsub("'", "\\'")}' | sudo -S su root -c 'echo \"bash /etc/network.conf\" >> /etc/rc.local'")
417
+ logger.done #.logf "done (#{stdout})"
418
+
419
+ logger.logs "Remove not available /64 subnets... "
420
+ available_hex4digits = hex4digits.reject { |hex|
421
+ results.map { |result|
422
+ result[:subnet64]
423
+ }.include?("#{self.ipv6_subnet_48}:#{hex}")
424
+ }
425
+ logger.logf("done (#{available_hex4digits.size})")
426
+
427
+ logger.logs "Iterate ports... "
428
+ port = proxy_port_from
429
+ while port<=proxy_port_to
430
+ logger.logs "Checking port #{port}... "
431
+ if results.map { |result| result[:port].to_i }.include?(port)
432
+ logger.logf "done (already installed)"
433
+ else
434
+ #logger.logs "Get an available subnet64... "
435
+ hex = available_hex4digits[0]
436
+ subnet64 = "#{self.ipv6_subnet_48}:#{hex}"
437
+ #logger.logf "done (#{subnet64})"
438
+
439
+ #logger.logs "Remove #{subnet64} from list of available subnets64... "
440
+ available_hex4digits.reject! { |x| x == hex }
441
+ #logger.logf("done (#{available_hex4digits.size})")
442
+
443
+ #logger.logs "Build random IPv6... "
444
+ ipv6 = "#{subnet64}:#{hex4digits.shuffle[0]}:#{hex4digits.shuffle[0]}:#{hex4digits.shuffle[0]}:#{hex4digits.shuffle[0]}"
445
+ #logger.logf("done (#{ipv6})")
446
+
447
+ #logger.logs "Add record to configuration file... "
448
+ stdout = ssh.exec!("echo '#{self.ssh_password.gsub("'", "\\'")}' | sudo -S su root -c 'echo proxy -p#{port} -6 -a -n -i0.0.0.0 -e#{ipv6} >> /usr/local/etc/3proxy/cfg/3proxy.cfg'")
449
+ #logger.logf("done (#{stdout})")
450
+
451
+ #logger.logs "Add IPv6 address... "
452
+ stdout = ssh.exec!("echo '#{self.ssh_password.gsub("'", "\\'")}' | sudo -S su root -c 'ip address add #{ipv6} dev #{interface} > /dev/null 2>&1'")
453
+ #logger.logf("done (#{stdout})")
454
+
455
+ logger.logf('done (installed)')
456
+ end
457
+ port += 1
458
+ end
459
+
460
+ # TODO: validate this output
461
+ logger.logs "Start proxy server... "
462
+ stdout = self.start_proxies
463
+ logger.done #logf "done (#{stdout})"
464
+
465
+ # TODO: validate this output
466
+ logger.logs "Add exit 0 TO rc.local... "
467
+ stdout = ssh.exec!("echo '#{self.ssh_password.gsub("'", "\\'")}' | sudo -S su root -c 'echo \"exit 0\" >> /etc/rc.local'")
468
+ logger.logf "done (#{stdout})"
469
+
470
+ end
471
+
472
+ def ssh_disconnect()
473
+ self.ssh.close
474
+ end
475
+
476
+ end # class RemoteHost
@@ -0,0 +1,26 @@
1
+ require 'net/ssh'
2
+ require 'blackstack_commons'
3
+ require 'simple_cloud_logging'
4
+ require 'simple_command_line_parser'
5
+
6
+ # TODO: design the proxy server managment as an addon of SimpleHostMonitoring
7
+
8
+ # matching ipv6 addresses with standard notation (not compact. not mixed.)
9
+ MATCH_PORT_IN_3PROXY_CONF = /\-p[0-9][0-9][0-9][0-9]/
10
+
11
+ # Regular expressions to match IPv6 addresses in the 3proxy config file.
12
+ # reference: https://www.oreilly.com/library/view/regular-expressions-cookbook/9781449327453/ch08s17.html
13
+ #
14
+ # TODO: Research: which ipv6 notation use the 3cproxy configuration file? Is it standard or mixed or compresed?
15
+ #
16
+ MATCH_IPV6_STANDARD = /(?:[A-F0-9]{1,4}:){7}[A-F0-9]{1,4}/i
17
+ MATCH_IPV6_64_SUBNET_STANDARD = /^[A-F0-9]{1,4}:[A-F0-9]{1,4}:[A-F0-9]{1,4}:[A-F0-9]{1,4}/i # TODO: this is not supporting leading zeros
18
+
19
+ #
20
+ DEFAULT_PROXY_PORT_FROM = 4000
21
+ DEFAULT_PROXY_PORT_TO = 4499
22
+ DEFAULT_PROXY_PORTS_BATCH_SIZE = 50
23
+
24
+ #
25
+ require_relative './simpleproxiesdeployingexception.rb'
26
+ require_relative './remotehost.rb'
@@ -0,0 +1,42 @@
1
+ class SimpleProxiesDeployingException < StandardError
2
+ attr_accessor :code, :custom_description
3
+
4
+ ERROR_CODES = [
5
+ { :code => 1, :description => 'Host has not SSH parameters' },
6
+ { :code => 2, :description => 'Proxy port is not a valid port' },
7
+ { :code => 3, :description => 'No SSH connection' },
8
+ { :code => 4, :description => 'SSH connection failed' },
9
+ { :code => 5, :description => 'IPv6 subnet /48 is not defined for this host' },
10
+ { :code => 6, :description => 'Extenral IP is not belonging the IPv6 subnet /48 defined for this host' },
11
+ { :code => 7, :description => 'More than 1 external IP defined for this proxy port' },
12
+ { :code => 8, :description => 'There is not external IP defined for this proxy port' },
13
+
14
+ # ports batch validations
15
+ { :code => 9, :description => "By now proxy_port_from must be #{DEFAULT_PROXY_PORT_FROM}" },
16
+ { :code => 10, :description => "proxy_port_to must be higher than proxy_port_from" },
17
+ { :code => 11, :description => "[proxy_port_from..proxy_port_to] must be mod of batch size #{DEFAULT_PROXY_PORTS_BATCH_SIZE}" },
18
+ { :code => 12, :description => "Other proxies are belonging the same /64 subnet" },
19
+ { :code => 13, :description => "Each batch of 50 ports must be all configured or all empty" },
20
+ { :code => 14, :description => "Ports outside the range found" },
21
+ ]
22
+
23
+ def self.description(code)
24
+ ERROR_CODES.each do |error_code|
25
+ return error_code[:description] if error_code[:code] == code
26
+ end
27
+ return 'Unknown error code'
28
+ end
29
+
30
+ def simple_description
31
+ self.class.description(self.code)
32
+ end
33
+
34
+ def description
35
+ self.custom_description.nil? ? self.simple_description : self.custom_description
36
+ end
37
+
38
+ def initialize(the_code, the_custom_description = nil)
39
+ self.code = the_code
40
+ self.custom_description = the_custom_description.nil? ? nil : "#{SimpleProxiesDeployingException.description(self.code)}: #{the_custom_description}"
41
+ end
42
+ end
metadata ADDED
@@ -0,0 +1,146 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: simple_proxies_deploying
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Leandro Daniel Sardi
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2022-04-02 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: websocket
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 1.2.8
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 1.2.8
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: 1.2.8
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 1.2.8
33
+ - !ruby/object:Gem::Dependency
34
+ name: json
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: 1.8.1
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: 1.8.1
43
+ type: :runtime
44
+ prerelease: false
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - "~>"
48
+ - !ruby/object:Gem::Version
49
+ version: 1.8.1
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: 1.8.1
53
+ - !ruby/object:Gem::Dependency
54
+ name: blackstack_commons
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - "~>"
58
+ - !ruby/object:Gem::Version
59
+ version: 1.1.50
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: 1.1.50
63
+ type: :runtime
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: 1.1.50
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: 1.1.50
73
+ - !ruby/object:Gem::Dependency
74
+ name: simple_command_line_parser
75
+ requirement: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - "~>"
78
+ - !ruby/object:Gem::Version
79
+ version: 1.1.2
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: 1.1.2
83
+ type: :runtime
84
+ prerelease: false
85
+ version_requirements: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 1.1.2
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: 1.1.2
93
+ - !ruby/object:Gem::Dependency
94
+ name: simple_cloud_logging
95
+ requirement: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - "~>"
98
+ - !ruby/object:Gem::Version
99
+ version: 1.1.28
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: 1.1.28
103
+ type: :runtime
104
+ prerelease: false
105
+ version_requirements: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - "~>"
108
+ - !ruby/object:Gem::Version
109
+ version: 1.1.28
110
+ - - ">="
111
+ - !ruby/object:Gem::Version
112
+ version: 1.1.28
113
+ description: 'Find documentation here: https://github.com/leandrosardi/simple_proxies_deploying.'
114
+ email: leandro.sardi@expandedventure.com
115
+ executables: []
116
+ extensions: []
117
+ extra_rdoc_files: []
118
+ files:
119
+ - lib/remotehost.rb
120
+ - lib/simple_proxies_deploying.rb
121
+ - lib/simpleproxiesdeployingexception.rb
122
+ homepage: https://rubygems.org/gems/simple_proxies_deploying
123
+ licenses:
124
+ - MIT
125
+ metadata: {}
126
+ post_install_message:
127
+ rdoc_options: []
128
+ require_paths:
129
+ - lib
130
+ required_ruby_version: !ruby/object:Gem::Requirement
131
+ requirements:
132
+ - - ">="
133
+ - !ruby/object:Gem::Version
134
+ version: '0'
135
+ required_rubygems_version: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - ">="
138
+ - !ruby/object:Gem::Version
139
+ version: '0'
140
+ requirements: []
141
+ rubyforge_project:
142
+ rubygems_version: 2.4.5.1
143
+ signing_key:
144
+ specification_version: 4
145
+ summary: Install, monitor, and check configurations of proxy servers.
146
+ test_files: []