spior 0.1.6 → 0.2.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|