spior 0.1.6 → 0.2.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +3 -3
- data/.github/workflows/rubocop-analysis.yml +47 -0
- data/.gitignore +1 -0
- data/CHANGELOG.md +14 -0
- data/Gemfile +5 -0
- data/README.md +13 -3
- data/Rakefile +20 -9
- data/lib/spior/dep.rb +45 -23
- data/lib/spior/helpers.rb +19 -19
- data/lib/spior/iptables/default.rb +19 -13
- data/lib/spior/iptables/root.rb +35 -36
- data/lib/spior/iptables/rules.rb +103 -0
- data/lib/spior/iptables/tor.rb +23 -20
- data/lib/spior/iptables.rb +3 -0
- data/lib/spior/menu.rb +16 -23
- data/lib/spior/msg.rb +22 -8
- data/lib/spior/options.rb +16 -19
- data/lib/spior/service/enable.rb +63 -0
- data/lib/spior/service/restart.rb +4 -12
- data/lib/spior/service/start.rb +5 -17
- data/lib/spior/service/stop.rb +12 -0
- data/lib/spior/service.rb +5 -0
- data/lib/spior/status.rb +32 -24
- data/lib/spior/tor/config.rb +100 -0
- data/lib/spior/tor/data.rb +53 -0
- data/lib/spior/tor/start.rb +59 -0
- data/lib/spior/tor/stop.rb +32 -0
- data/lib/spior/tor.rb +8 -1
- data/lib/spior/version.rb +3 -1
- data/lib/spior.rb +16 -23
- data/spior.gemspec +24 -21
- data/test/test_install.rb +2 -2
- data/test/test_options.rb +2 -0
- data.tar.gz.sig +0 -0
- metadata +57 -51
- metadata.gz.sig +0 -0
- data/lib/spior/clear.rb +0 -35
- data/lib/spior/copy.rb +0 -84
- data/lib/spior/persist.rb +0 -51
- data/lib/spior/tor/info.rb +0 -96
data/lib/spior/iptables/tor.rb
CHANGED
@@ -1,58 +1,61 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Spior
|
2
4
|
module Iptables
|
5
|
+
# Make Local Redirection Through Tor.
|
3
6
|
class Tor < Iptables::Root
|
4
7
|
def initialize
|
5
8
|
super
|
6
|
-
@
|
7
|
-
@
|
8
|
-
@tables = ["nat", "filter"]
|
9
|
+
@non_tor = %W[#{@lo_addr}/8 192.168.0.0/16 172.16.0.0/12 10.0.0.0/8]
|
10
|
+
@tables = %w[nat filter]
|
9
11
|
end
|
10
12
|
|
11
13
|
private
|
12
14
|
|
13
15
|
def redirect
|
14
|
-
|
15
|
-
|
16
|
-
target =
|
16
|
+
Msg.p 'Redirecting local traffic though Tor...'
|
17
|
+
@tables.map do |table|
|
18
|
+
target = 'ACCEPT'
|
19
|
+
target = 'RETURN' if table == 'nat'
|
17
20
|
|
18
21
|
ipt "-t #{table} -F OUTPUT"
|
19
22
|
ipt "-t #{table} -A OUTPUT -m state --state ESTABLISHED -j #{target}"
|
20
|
-
ipt "-t #{table} -A OUTPUT -m owner --uid #{
|
23
|
+
ipt "-t #{table} -A OUTPUT -m owner --uid #{CONFIG.uid} -j #{target}"
|
21
24
|
|
22
|
-
match_dns_port =
|
23
|
-
if table ==
|
24
|
-
target = "REDIRECT --to-ports #{
|
25
|
-
match_dns_port =
|
25
|
+
match_dns_port = CONFIG.dns_port
|
26
|
+
if table == 'nat'
|
27
|
+
target = "REDIRECT --to-ports #{CONFIG.dns_port}"
|
28
|
+
match_dns_port = '53'
|
26
29
|
end
|
27
30
|
|
28
31
|
ipt "-t #{table} -A OUTPUT -p udp --dport #{match_dns_port} -j #{target}"
|
29
32
|
ipt "-t #{table} -A OUTPUT -p tcp --dport #{match_dns_port} -j #{target}"
|
30
33
|
|
31
|
-
target = "REDIRECT --to-ports #{
|
32
|
-
ipt "-t #{table} -A OUTPUT -d #{
|
34
|
+
target = "REDIRECT --to-ports #{CONFIG.trans_port}" if table == 'nat'
|
35
|
+
ipt "-t #{table} -A OUTPUT -d #{CONFIG.virt_addr} -p tcp -j #{target}"
|
33
36
|
|
34
|
-
target =
|
37
|
+
target = 'RETURN' if table == 'nat'
|
35
38
|
@non_tor.each { |ip|
|
36
39
|
ipt "-t #{table} -A OUTPUT -d #{ip} -j #{target}"
|
37
40
|
}
|
38
41
|
|
39
|
-
target = "REDIRECT --to-ports #{
|
42
|
+
target = "REDIRECT --to-ports #{CONFIG.trans_port}" if table == 'nat'
|
40
43
|
ipt "-t #{table} -A OUTPUT -p tcp -j #{target}"
|
41
|
-
|
44
|
+
end
|
42
45
|
end
|
43
46
|
|
44
47
|
def input
|
45
48
|
# SSH
|
46
|
-
ipt
|
49
|
+
ipt '-A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT'
|
47
50
|
# Allow loopback
|
48
51
|
ipt "-A INPUT -i #{@lo} -j ACCEPT"
|
49
52
|
# Accept related
|
50
|
-
ipt
|
53
|
+
ipt '-A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT'
|
51
54
|
end
|
52
55
|
|
53
56
|
def all
|
54
|
-
ipt
|
55
|
-
ipt
|
57
|
+
ipt '-t filter -A OUTPUT -p udp -j REJECT'
|
58
|
+
ipt '-t filter -A OUTPUT -p icmp -j REJECT'
|
56
59
|
end
|
57
60
|
end
|
58
61
|
end
|
data/lib/spior/iptables.rb
CHANGED
data/lib/spior/menu.rb
CHANGED
@@ -1,43 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Spior
|
2
4
|
module Menu
|
3
|
-
|
4
|
-
|
5
|
-
def run
|
6
|
-
banner
|
5
|
+
def self.run
|
7
6
|
loop do
|
8
7
|
Msg.head
|
9
|
-
puts
|
8
|
+
puts 'Please select an option:
|
10
9
|
|
11
|
-
1. Redirect traffic through
|
12
|
-
2. Reload
|
13
|
-
3.
|
14
|
-
4. Check info on your current
|
15
|
-
5.
|
10
|
+
1. Redirect traffic through Tor
|
11
|
+
2. Reload Spior and change your IP
|
12
|
+
3. Stop Tor and use a clearnet navigation
|
13
|
+
4. Check info on your current IP
|
14
|
+
5. Install all the dependencies
|
15
|
+
6. Quit'
|
16
16
|
|
17
17
|
puts
|
18
|
-
print
|
18
|
+
print '>> '
|
19
19
|
case gets.chomp
|
20
20
|
when '1'
|
21
|
-
Spior::
|
21
|
+
Spior::Service.start
|
22
22
|
when '2'
|
23
|
-
Spior::
|
23
|
+
Spior::Service.restart
|
24
24
|
when '3'
|
25
|
-
Spior::
|
25
|
+
Spior::Service.stop
|
26
26
|
when '4'
|
27
27
|
Spior::Status.info
|
28
28
|
when '5'
|
29
|
+
Spior::Dep.looking
|
30
|
+
else
|
29
31
|
exit
|
30
32
|
end
|
31
33
|
end
|
32
34
|
end
|
33
|
-
|
34
|
-
private
|
35
|
-
|
36
|
-
def banner
|
37
|
-
puts "┏━┓┏━┓╻┏━┓┏━┓"
|
38
|
-
puts "┗━┓┣━┛┃┃ ┃┣┳┛"
|
39
|
-
puts "┗━┛╹ ╹┗━┛╹┗╸"
|
40
|
-
# generated with toilet -F crop -f future spior
|
41
|
-
end
|
42
35
|
end
|
43
36
|
end
|
data/lib/spior/msg.rb
CHANGED
@@ -1,28 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'rainbow'
|
2
4
|
|
3
5
|
module Msg
|
4
|
-
|
6
|
+
module_function
|
7
|
+
|
8
|
+
def banner
|
9
|
+
puts
|
10
|
+
puts '┏━┓┏━┓╻┏━┓┏━┓'
|
11
|
+
puts '┗━┓┣━┛┃┃ ┃┣┳┛'
|
12
|
+
puts '┗━┛╹ ╹┗━┛╹┗╸'
|
13
|
+
puts
|
14
|
+
# generated with toilet -F crop -f future spior
|
15
|
+
end
|
5
16
|
|
6
17
|
def head
|
7
|
-
puts Rainbow(
|
18
|
+
puts Rainbow('------------------------------------------------').cyan
|
8
19
|
end
|
9
20
|
|
10
21
|
def p(text)
|
11
|
-
puts Rainbow(
|
22
|
+
puts Rainbow('[').cyan + Rainbow('+').white + Rainbow(']').cyan + ' ' + text
|
12
23
|
end
|
13
24
|
|
14
25
|
def err(text)
|
15
|
-
puts Rainbow(
|
26
|
+
puts Rainbow('[').red + Rainbow('-').white + Rainbow(']').red + ' ' + text
|
16
27
|
end
|
17
28
|
|
18
29
|
def info(text)
|
19
|
-
|
30
|
+
print Rainbow('-').blue + Rainbow('-').white + Rainbow('-').blue
|
31
|
+
print " #{text} "
|
32
|
+
print Rainbow('-').blue + Rainbow('-').white + Rainbow('-').blue + "\n"
|
20
33
|
end
|
21
34
|
|
22
35
|
def report(text)
|
23
|
-
puts
|
36
|
+
puts
|
24
37
|
info text
|
25
|
-
puts
|
26
|
-
puts
|
38
|
+
puts 'Please, report this issue at https://github.com/szorfein/spior/issues'
|
39
|
+
puts
|
40
|
+
exit 1
|
27
41
|
end
|
28
42
|
end
|
data/lib/spior/options.rb
CHANGED
@@ -1,13 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'optparse'
|
2
4
|
|
3
5
|
module Spior
|
4
6
|
class Options
|
5
|
-
attr_reader :install , :tor , :persist
|
6
|
-
|
7
7
|
def initialize(argv)
|
8
|
-
@install = false
|
9
|
-
@tor = false
|
10
|
-
@persist = false
|
11
8
|
parse(argv)
|
12
9
|
end
|
13
10
|
|
@@ -15,46 +12,46 @@ module Spior
|
|
15
12
|
|
16
13
|
def parse(argv)
|
17
14
|
OptionParser.new do |opts|
|
18
|
-
opts.on(
|
19
|
-
|
15
|
+
opts.on('-i', '--install', 'Install the dependencies.') do
|
16
|
+
Spior::Dep.looking
|
20
17
|
end
|
21
18
|
|
22
|
-
opts.on(
|
23
|
-
|
19
|
+
opts.on('-t', '--tor', 'Redirect traffic through TOR.') do
|
20
|
+
Spior::Service.start
|
24
21
|
end
|
25
22
|
|
26
|
-
opts.on(
|
23
|
+
opts.on('-r', '--reload', 'Reload TOR to change your IP.') do
|
27
24
|
Spior::Service.restart
|
28
25
|
exit
|
29
26
|
end
|
30
27
|
|
31
|
-
opts.on(
|
32
|
-
Spior::
|
28
|
+
opts.on('-c', '--clearnet', 'Reset iptables and return to clearnet navigation.') do
|
29
|
+
Spior::Service.stop
|
33
30
|
end
|
34
31
|
|
35
|
-
opts.on(
|
32
|
+
opts.on('-s', '--status', 'Look infos about your current IP.') do
|
36
33
|
Spior::Status.info
|
37
34
|
exit
|
38
35
|
end
|
39
36
|
|
40
|
-
opts.on(
|
41
|
-
|
37
|
+
opts.on('-p', '--persist', 'Active Spior at every boot.') do
|
38
|
+
Spior::Service.enable
|
42
39
|
end
|
43
40
|
|
44
|
-
opts.on(
|
41
|
+
opts.on('-m', '--menu', 'Display an interactive menu.') do
|
45
42
|
Spior::Menu.run
|
46
43
|
end
|
47
44
|
|
48
|
-
opts.on(
|
45
|
+
opts.on('-h', '--help', 'Show this message.') do
|
49
46
|
puts opts
|
50
47
|
exit
|
51
48
|
end
|
52
49
|
|
53
50
|
begin
|
54
|
-
argv = [
|
51
|
+
argv = ['-m'] if argv.empty?
|
55
52
|
opts.parse!(argv)
|
56
53
|
rescue OptionParser::ParseError => e
|
57
|
-
|
54
|
+
warn e.message, "\n", opts
|
58
55
|
exit(-1)
|
59
56
|
end
|
60
57
|
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'nomansland'
|
4
|
+
|
5
|
+
module Spior
|
6
|
+
module Service
|
7
|
+
extend self
|
8
|
+
|
9
|
+
# enable the Tor redirection when you boot your system
|
10
|
+
#
|
11
|
+
# It should use and enable the services:
|
12
|
+
# + tor
|
13
|
+
# + iptables
|
14
|
+
def enable
|
15
|
+
case Nomansland.distro?
|
16
|
+
when :gentoo
|
17
|
+
for_gentoo
|
18
|
+
when :archlinux
|
19
|
+
Iptables::Rules.new.backup
|
20
|
+
Tor::Config.new(Tempfile.new('torrc')).backup
|
21
|
+
Helpers::Exec.new('systemctl').run('enable iptables tor')
|
22
|
+
Msg.p 'Services enabled for Archlinux...'
|
23
|
+
else
|
24
|
+
Msg.report 'Your distro is not yet supported.'
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def for_gentoo
|
31
|
+
case Nomansland.init?
|
32
|
+
when :systemd
|
33
|
+
systemd_start('iptables-store')
|
34
|
+
systemd_enable('iptables-restore')
|
35
|
+
systemd_enable('tor')
|
36
|
+
when :openrc
|
37
|
+
system('sudo /etc/init.d/iptables save')
|
38
|
+
rc_upd = Helpers::Exec.new('rc-update')
|
39
|
+
rc_upd.run('rc-update add iptables boot')
|
40
|
+
rc_upd.run('rc-update add tor')
|
41
|
+
rc_upd.run('rc-update add tor default')
|
42
|
+
else
|
43
|
+
Msg.report 'Init no yet supported for start Iptables at boot'
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def systemd_enable(service)
|
48
|
+
systemctl = Helpers::Exec.new('systemctl')
|
49
|
+
Msg.p "Search for service #{service}..."
|
50
|
+
unless system("systemctl is-enabled #{service}")
|
51
|
+
systemctl.run("enable #{service}")
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def systemd_start(service)
|
56
|
+
systemctl = Helpers::Exec.new('systemctl')
|
57
|
+
Msg.p "Search for service #{service}..."
|
58
|
+
unless system("systemctl is-active #{service}")
|
59
|
+
systemctl.run("start #{service}")
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -1,21 +1,13 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Spior
|
4
4
|
module Service
|
5
5
|
module_function
|
6
6
|
|
7
7
|
def restart
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
elsif TTY::Which.exist? 'sv'
|
12
|
-
Helpers::Exec.new('sv').run('restart tor')
|
13
|
-
Msg.p 'ip changed.'
|
14
|
-
elsif File.exist? '/etc/init.d/tor'
|
15
|
-
Helpers::Exec.new('/etc/init.d/tor').run('restart')
|
16
|
-
else
|
17
|
-
Msg.report "Don't known yet how to restart Tor for your system."
|
18
|
-
end
|
8
|
+
Service.stop
|
9
|
+
Service.start
|
10
|
+
Msg.p 'ip changed.'
|
19
11
|
end
|
20
12
|
end
|
21
13
|
end
|
data/lib/spior/service/start.rb
CHANGED
@@ -1,26 +1,14 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Spior
|
4
4
|
module Service
|
5
5
|
module_function
|
6
6
|
|
7
|
+
# Service.start should start Tor if not alrealy running
|
8
|
+
# And start to redirect the local traffic with Iptables
|
7
9
|
def start
|
8
|
-
|
9
|
-
|
10
|
-
unless state == 'active'
|
11
|
-
Helpers::Exec.new("systemctl").run("start tor")
|
12
|
-
Msg.p "TOR started."
|
13
|
-
end
|
14
|
-
elsif TTY::Which.exist? 'sv'
|
15
|
-
unless File.exist? '/var/service/tor'
|
16
|
-
Helpers::Exec.new('ln').run('-s /etc/sv/tor /var/service/tor')
|
17
|
-
Msg.p "TOR started."
|
18
|
-
end
|
19
|
-
elsif File.exist? '/etc/init.d/tor'
|
20
|
-
Helpers::Exec.new('/etc/init.d/tor').run('start')
|
21
|
-
else
|
22
|
-
Msg.report "Don't known yet how to start Tor for your system."
|
23
|
-
end
|
10
|
+
Tor.start
|
11
|
+
Iptables::Tor.new.run!
|
24
12
|
end
|
25
13
|
end
|
26
14
|
end
|
data/lib/spior/service.rb
CHANGED
@@ -1,7 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Spior
|
4
|
+
# Service should start/stop/restart Tor and Iptable.
|
2
5
|
module Service
|
3
6
|
end
|
4
7
|
end
|
5
8
|
|
6
9
|
require_relative 'service/start'
|
10
|
+
require_relative 'service/stop'
|
7
11
|
require_relative 'service/restart'
|
12
|
+
require_relative 'service/enable'
|
data/lib/spior/status.rb
CHANGED
@@ -1,38 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'open-uri'
|
2
4
|
require 'json'
|
3
5
|
|
4
6
|
module Spior
|
7
|
+
# Status display information on your current IP addresse
|
8
|
+
#
|
9
|
+
# If you use an IPV6 address, it should fail to display a Tor IP...
|
5
10
|
module Status
|
11
|
+
# Check on https://check.torproject.org/api/ip if Tor is enable or not
|
12
|
+
# and display the result.
|
6
13
|
def self.enable
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
hash = JSON.parse l.read
|
12
|
-
status = "Enable" if hash["IsTor"] == true
|
13
|
-
end
|
14
|
-
status
|
15
|
-
rescue OpenURI::HTTPError => error
|
16
|
-
res = error.io
|
17
|
-
puts "Fail to join server #{res.status}"
|
14
|
+
status = 'Disable'
|
15
|
+
URI.open('https://check.torproject.org/api/ip') do |l|
|
16
|
+
hash = JSON.parse l.read
|
17
|
+
status = 'Enable' if hash['IsTor'] == true
|
18
18
|
end
|
19
|
+
status
|
20
|
+
rescue OpenURI::HTTPError => error
|
21
|
+
res = error.io
|
22
|
+
puts "Fail to join server #{res.status}"
|
19
23
|
end
|
20
24
|
|
25
|
+
# info check and display information from https://ipleak.net/json
|
26
|
+
#
|
27
|
+
# Check for:
|
28
|
+
# * +ip+
|
29
|
+
# * +continent_name+
|
30
|
+
# * +time_zone+
|
31
|
+
#
|
32
|
+
# We can add later info on City/Region or other things.
|
21
33
|
def self.info
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
puts " Current ip ===> #{hash["ip"]}"
|
28
|
-
puts " Continent ===> #{hash["continent_name"]}"
|
29
|
-
puts " Timezone ===> #{hash["time_zone"]}"
|
30
|
-
end
|
31
|
-
puts " Status ===> #{enable}"
|
32
|
-
rescue OpenURI::HTTPError => error
|
33
|
-
res = error.io
|
34
|
-
puts "Fail to join server #{res.status}"
|
34
|
+
URI.open('https://ipleak.net/json') do |l|
|
35
|
+
hash = JSON.parse l.read
|
36
|
+
puts " Current ip ===> #{hash['ip']}"
|
37
|
+
puts " Continent ===> #{hash['continent_name']}"
|
38
|
+
puts " Timezone ===> #{hash['time_zone']}"
|
35
39
|
end
|
40
|
+
puts " Status ===> #{enable}"
|
41
|
+
rescue OpenURI::HTTPError => error
|
42
|
+
res = error.io
|
43
|
+
puts "Fail to join server #{res.status}"
|
36
44
|
end
|
37
45
|
end
|
38
46
|
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'digest'
|
4
|
+
|
5
|
+
module Spior
|
6
|
+
module Tor
|
7
|
+
# Generate a config file (torrc) for Spior
|
8
|
+
class Config
|
9
|
+
# ==== Attributes
|
10
|
+
#
|
11
|
+
# * +filename+ - A reference to a tempfile like filename=Tempfile.new('foo')
|
12
|
+
#
|
13
|
+
def initialize(filename)
|
14
|
+
@filename = filename
|
15
|
+
@content = ['# Generated by Spior, don\'t edit.', 'RunAsDaemon 1',
|
16
|
+
'ClientOnly 1', 'SocksPort 0']
|
17
|
+
@content_torrc = []
|
18
|
+
end
|
19
|
+
|
20
|
+
# Generate a `torrc` compatible file for Spior
|
21
|
+
# Use value from Spior::CONFIG
|
22
|
+
def generate
|
23
|
+
generate_content(@content)
|
24
|
+
return if @content.length == 4
|
25
|
+
|
26
|
+
File.write @filename.path, @content.join("\n") + "\n"
|
27
|
+
Msg.p 'Generating Tor config...'
|
28
|
+
end
|
29
|
+
|
30
|
+
# Save current Tor options (Spior::CONFIG) in /etc/tor/torrc
|
31
|
+
# Only if theses options are not alrealy present
|
32
|
+
def backup
|
33
|
+
generate_content(@content_torrc)
|
34
|
+
outfile = File.open(@filename.path, 'w')
|
35
|
+
outfile.puts(File.read('/etc/tor/torrc'))
|
36
|
+
outfile.puts(@content_torrc.join("\n")) if @content_torrc != []
|
37
|
+
outfile.chmod(0644)
|
38
|
+
outfile.close
|
39
|
+
|
40
|
+
Msg.p 'Saving Tor options...'
|
41
|
+
move(@filename.path, '/etc/tor/torrc')
|
42
|
+
end
|
43
|
+
|
44
|
+
protected
|
45
|
+
|
46
|
+
def generate_content(content)
|
47
|
+
adding content, 'AutomapHostsOnResolve 1'
|
48
|
+
adding content, "DNSPort #{CONFIG.dns_port}"
|
49
|
+
adding content, "VirtualAddrNetworkIpv4 #{CONFIG.virt_addr}"
|
50
|
+
adding content, "TransPort #{CONFIG.trans_port} IsolateClientAddr
|
51
|
+
IsolateClientProtocol IsolateDestAddr IsolateDestPort"
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def search(option_name)
|
57
|
+
File.open('/etc/tor/torrc') do |f|
|
58
|
+
f.each do |line|
|
59
|
+
return Regexp.last_match(1) if line.match(/#{option_name} ([a-z0-9]*)/i)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
false
|
63
|
+
end
|
64
|
+
|
65
|
+
def adding(content, option)
|
66
|
+
o = option.split(' ')
|
67
|
+
all = o[1..o.length].join(' ')
|
68
|
+
unless search(o[0])
|
69
|
+
content << "#{o[0]} #{all}"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def digest_match?(src, dest)
|
74
|
+
md5_src = Digest::MD5.file src
|
75
|
+
md5_dest = Digest::MD5.file dest
|
76
|
+
md5_src == md5_dest
|
77
|
+
end
|
78
|
+
|
79
|
+
# Permission for Archlinux on a torrc are chmod 644, chown root:root
|
80
|
+
def fix_perm(file)
|
81
|
+
if Process::Sys.getuid == '0'
|
82
|
+
file.chown(0, 0)
|
83
|
+
else
|
84
|
+
Helpers::Exec.new('chown').run("root:root #{file}")
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def move(src, dest)
|
89
|
+
return if digest_match? src, dest
|
90
|
+
|
91
|
+
fix_perm(@filename.path)
|
92
|
+
if Process::Sys.getuid == '0'
|
93
|
+
FileUtils.mv(src, dest)
|
94
|
+
else
|
95
|
+
Helpers::Exec.new('mv').run("#{src} #{dest}")
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'nomansland'
|
4
|
+
|
5
|
+
module Spior
|
6
|
+
module Tor
|
7
|
+
##
|
8
|
+
# Data
|
9
|
+
# Fill Spior::CONFIG with data found on `/etc/tor/torrc` or set default.
|
10
|
+
#
|
11
|
+
# ==== Attributes
|
12
|
+
#
|
13
|
+
# * +user+ - Username used by Tor on your distro, e.g 'tor' on Archlinux
|
14
|
+
# * +dns_port+ - Open this port to listen for UDP DNS requests, and resolve them anonymously
|
15
|
+
# * +uid+ - The uid value from the user attribute.
|
16
|
+
# * +trans_port+ - Port to open to listen for transparent proxy connections.
|
17
|
+
# * +virt_addr+ - Default use '10.192.0.0/10'.
|
18
|
+
#
|
19
|
+
class Data
|
20
|
+
attr_accessor :user, :dns_port, :trans_port, :virt_addr, :uid
|
21
|
+
|
22
|
+
def initialize
|
23
|
+
@user = search('User') || 'tor'
|
24
|
+
@dns_port = search('DNSPort') || '9061'
|
25
|
+
@trans_port = search('TransPort') || '9040'
|
26
|
+
@virt_addr = search('VirtualAddrNetworkIPv4') || '10.192.0.0/10'
|
27
|
+
@uid = search_uid || 0
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
# Search value of option_name in the /etc/tor/torrc
|
33
|
+
# Return false by default
|
34
|
+
def search(option_name)
|
35
|
+
File.open('/etc/tor/torrc') do |f|
|
36
|
+
f.each do |line|
|
37
|
+
return Regexp.last_match(1) if line.match(/#{option_name} ([a-z0-9.\/]*)/i)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
false
|
41
|
+
end
|
42
|
+
|
43
|
+
def search_uid
|
44
|
+
case Nomansland.distro?
|
45
|
+
when :debian || :ubuntu
|
46
|
+
`id -u debian-tor`.chomp
|
47
|
+
else
|
48
|
+
`id -u #{@user}`.chomp
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|