spior 0.2.8 → 0.3.5
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 +0 -0
- data/.github/workflows/rubocop-analysis.yml +2 -2
- data/CHANGELOG.md +7 -0
- data/Rakefile +1 -1
- data/bin/spior +1 -0
- data/lib/auth.rb +46 -0
- data/lib/spior/dep.rb +7 -14
- data/lib/spior/helpers.rb +3 -6
- data/lib/spior/iptables/root.rb +2 -1
- data/lib/spior/iptables/rules.rb +15 -15
- data/lib/spior/iptables/tor.rb +1 -3
- data/lib/spior/iptables.rb +1 -0
- data/lib/spior/ipv6.rb +35 -0
- data/lib/spior/menu.rb +6 -5
- data/lib/spior/msg.rb +13 -5
- data/lib/spior/options.rb +8 -7
- data/lib/spior/service/enable.rb +45 -42
- data/lib/spior/service/restart.rb +2 -1
- data/lib/spior/service/start.rb +3 -1
- data/lib/spior/service/stop.rb +5 -3
- data/lib/spior/status.rb +4 -4
- data/lib/spior/tor/config.rb +53 -16
- data/lib/spior/tor/data.rb +1 -1
- data/lib/spior/tor/start.rb +41 -35
- data/lib/spior/tor/stop.rb +34 -13
- data/lib/spior/tor.rb +0 -1
- data/lib/spior/version.rb +1 -1
- data/lib/spior.rb +2 -0
- data/spior.gemspec +1 -1
- data.tar.gz.sig +0 -0
- metadata +26 -24
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ecae8f75479fb87d8b09a28ea74c86728923802feb7b6c495af0c6e455dfc986
|
4
|
+
data.tar.gz: 442c8fbf6ea54e45b6b48abc4ba5de582ae09ae73bd71c1fce497ea082c929c1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fe92411f967699b8cd29129f174030bb44a0d6ea2616fa5ff579e0879da63dfce83ce7bfeadfbed7e536141a882ff118315f730d3a26e45d8756bf9aed416130
|
7
|
+
data.tar.gz: 2195a94c764fcdecc221d2cea1688ca241901ac948cb02fb285b2c4c234b2f73335b2c44bd227014e795e32621b8221616dcaaecada2e95e779fad543d21ffff
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
## 0.3.5, release 2023-10-26
|
2
|
+
* Better code style, only 11 alerts from rubocop.
|
3
|
+
* spior -t also block ipv6 traffic, no need to reboot.
|
4
|
+
* Config is written at /etc/torrc.d/spior.conf and loaded with the native daemon.
|
5
|
+
* Only '%include /etc/torrc.d/*.conf' is now added to /etc/tor/torrc.
|
6
|
+
* Certificate update `certs/szorfein.pem`.
|
7
|
+
|
1
8
|
## 0.2.8, release 2022-09-16
|
2
9
|
* Spior used with `--clearnet` try to restore iptables rules found on your system, e.g: `/etc/iptables/iptables.rules` and `/etc/iptables/iptables.rules-backup` for Archlinux or use `Spior::Iptables::Default`.
|
3
10
|
* Stdout enhanced.
|
data/Rakefile
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
# https://github.com/seattlerb/minitest#running-your-tests-
|
4
4
|
require 'rake/testtask'
|
5
5
|
require 'rdoc/task'
|
6
|
-
require File.dirname(__FILE__)
|
6
|
+
require "#{File.dirname(__FILE__)}/lib/spior/version"
|
7
7
|
|
8
8
|
# rake rdoc
|
9
9
|
Rake::RDocTask.new('rdoc') do |rdoc|
|
data/bin/spior
CHANGED
data/lib/auth.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
# lib/auth.rb
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'open3'
|
5
|
+
|
6
|
+
# When action require privilege, Auth search on the system for sudo or doas.
|
7
|
+
class Auth
|
8
|
+
def initialize
|
9
|
+
@auth = search_app
|
10
|
+
end
|
11
|
+
|
12
|
+
def mkdir(path)
|
13
|
+
return unless File.exist?(path)
|
14
|
+
|
15
|
+
x("mkdir -p #{path}")
|
16
|
+
end
|
17
|
+
|
18
|
+
def sysctl(flag, value)
|
19
|
+
return if flag.nil?
|
20
|
+
|
21
|
+
x("sysctl -w #{flag}=#{value}")
|
22
|
+
end
|
23
|
+
|
24
|
+
protected
|
25
|
+
|
26
|
+
def search_app
|
27
|
+
if File.exist?('/usr/bin/doas') || File.exist?('/bin/doas')
|
28
|
+
'doas'
|
29
|
+
elsif File.exist?('/usr/bin/sudo') || File.exist?('/bin/sudo')
|
30
|
+
'sudo'
|
31
|
+
else
|
32
|
+
warn 'No auth program found, Spior need few privileges.'
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def x(args)
|
39
|
+
Open3.popen2e("#{@auth} #{args}") do |_, stdout, wait_thr|
|
40
|
+
puts stdout.gets while stdout.gets
|
41
|
+
|
42
|
+
exit_status = wait_thr.value
|
43
|
+
raise "An error expected with #{@auth} #{args}" unless exit_status.success?
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/lib/spior/dep.rb
CHANGED
@@ -6,38 +6,31 @@ require 'tty-which'
|
|
6
6
|
module Spior
|
7
7
|
# Dep: install all dependencies for Spior
|
8
8
|
module Dep
|
9
|
-
|
9
|
+
module_function
|
10
10
|
|
11
11
|
def looking
|
12
12
|
case Nomansland.distro?
|
13
13
|
when :archlinux
|
14
|
-
|
15
|
-
installing_deps(%w[iptables tor])
|
14
|
+
installing_deps('Arch', %w[iptables tor])
|
16
15
|
when :debian
|
17
|
-
|
18
|
-
installing_deps(%w[iptables tor])
|
16
|
+
installing_deps('Debian', %w[iptables tor])
|
19
17
|
when :gentoo
|
20
|
-
|
21
|
-
installing_deps(%w[iptables tor])
|
18
|
+
installing_deps('Gentoo', %w[iptables tor])
|
22
19
|
when :void
|
23
|
-
|
24
|
-
installing_deps(%w[iptables tor])
|
20
|
+
installing_deps('Void', %w[iptables tor])
|
25
21
|
else
|
26
22
|
Msg.report 'Install for your distro is not yet supported.'
|
27
23
|
end
|
28
24
|
end
|
29
25
|
|
30
|
-
|
31
|
-
|
32
|
-
def installing_deps(names)
|
26
|
+
def installing_deps(distro, names)
|
33
27
|
names.map do |n|
|
28
|
+
Msg.p "Search #{n} for #{distro}..."
|
34
29
|
install(n) unless search_dep(n)
|
35
30
|
end
|
36
|
-
Msg.p 'Dependencies are OK.'
|
37
31
|
end
|
38
32
|
|
39
33
|
def install(name)
|
40
|
-
Msg.p "Installing #{name}..."
|
41
34
|
case Nomansland.installer?
|
42
35
|
when :apt_get
|
43
36
|
Helpers::Exec.new('apt-get').run("install #{name}")
|
data/lib/spior/helpers.rb
CHANGED
@@ -5,6 +5,7 @@ require 'tempfile'
|
|
5
5
|
require 'open3'
|
6
6
|
|
7
7
|
module Helpers
|
8
|
+
# Execute program using sudo when permission is required
|
8
9
|
class Exec
|
9
10
|
def initialize(name)
|
10
11
|
@search_uid = Process::Sys.getuid
|
@@ -14,14 +15,10 @@ module Helpers
|
|
14
15
|
def run(args)
|
15
16
|
cmd = (@search_uid == '0' ? @name : "sudo #{@name}")
|
16
17
|
Open3.popen2e("#{cmd} #{args}") do |_, stdout_err, wait_thr|
|
17
|
-
|
18
|
-
puts line
|
19
|
-
end
|
18
|
+
puts stdout_err.gets while stdout_err.gets
|
20
19
|
|
21
20
|
exit_status = wait_thr.value
|
22
|
-
unless exit_status.success?
|
23
|
-
raise "Error, Running #{cmd} #{args}"
|
24
|
-
end
|
21
|
+
raise "Error, Running #{cmd} #{args}" unless exit_status.success?
|
25
22
|
end
|
26
23
|
end
|
27
24
|
end
|
data/lib/spior/iptables/root.rb
CHANGED
@@ -4,6 +4,7 @@ require 'interfacez'
|
|
4
4
|
|
5
5
|
module Spior
|
6
6
|
module Iptables
|
7
|
+
# Base class for iptables
|
7
8
|
class Root
|
8
9
|
def initialize
|
9
10
|
@lo = Interfacez.loopback
|
@@ -36,7 +37,7 @@ module Spior
|
|
36
37
|
private
|
37
38
|
|
38
39
|
def ipt(line)
|
39
|
-
@i.run(
|
40
|
+
@i.run(line.to_s)
|
40
41
|
puts "Added - iptables #{line}" if @debug
|
41
42
|
end
|
42
43
|
|
data/lib/spior/iptables/rules.rb
CHANGED
@@ -6,24 +6,26 @@ require 'nomansland'
|
|
6
6
|
|
7
7
|
module Spior
|
8
8
|
module Iptables
|
9
|
+
# Iptables::Rules, used to save or restore iptables rules
|
9
10
|
class Rules
|
10
11
|
def initialize
|
11
12
|
@tmp_iptables_rules = Tempfile.new('iptables_rules')
|
12
13
|
@tmp_spior_rules = Tempfile.new('spior_rules')
|
13
|
-
@
|
14
|
+
@save_path = search_iptables_config
|
14
15
|
end
|
15
16
|
|
16
|
-
def
|
17
|
+
def save
|
17
18
|
save_rules(@tmp_iptables_rules)
|
18
19
|
insert_comment(@tmp_spior_rules, @tmp_iptables_rules)
|
19
|
-
create_file(@tmp_spior_rules, @
|
20
|
+
create_file(@tmp_spior_rules, @save_path)
|
21
|
+
Msg.p "Iptables rules saved at #{@save_path}"
|
20
22
|
end
|
21
23
|
|
22
24
|
def restore
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
25
|
+
return if restoring_older_rules(@save_path)
|
26
|
+
|
27
|
+
Msg.p 'Adding clearnet navigation...'
|
28
|
+
Iptables::Default.new.run!
|
27
29
|
end
|
28
30
|
|
29
31
|
protected
|
@@ -70,16 +72,14 @@ module Spior
|
|
70
72
|
end
|
71
73
|
|
72
74
|
def restoring_older_rules(filename)
|
73
|
-
files = %W[#{filename} #{filename}
|
75
|
+
files = %W[#{filename}-backup #{filename}]
|
74
76
|
files.each do |f|
|
75
|
-
next unless File.exist? f
|
77
|
+
next unless File.exist?(f) || search_for_comment(f)
|
76
78
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
return true
|
82
|
-
end
|
79
|
+
Iptables::Root.new.stop!
|
80
|
+
Msg.p "Found older rules #{f}, restoring..."
|
81
|
+
Helpers::Exec.new('iptables-restore').run(f)
|
82
|
+
return true
|
83
83
|
end
|
84
84
|
false
|
85
85
|
end
|
data/lib/spior/iptables/tor.rb
CHANGED
@@ -35,9 +35,7 @@ module Spior
|
|
35
35
|
ipt "-t #{table} -A OUTPUT -d #{CONFIG.virt_addr} -p tcp -j #{target}"
|
36
36
|
|
37
37
|
target = 'RETURN' if table == 'nat'
|
38
|
-
@non_tor.each { |ip|
|
39
|
-
ipt "-t #{table} -A OUTPUT -d #{ip} -j #{target}"
|
40
|
-
}
|
38
|
+
@non_tor.each { |ip| ipt "-t #{table} -A OUTPUT -d #{ip} -j #{target}" }
|
41
39
|
|
42
40
|
target = "REDIRECT --to-ports #{CONFIG.trans_port}" if table == 'nat'
|
43
41
|
ipt "-t #{table} -A OUTPUT -p tcp -j #{target}"
|
data/lib/spior/iptables.rb
CHANGED
data/lib/spior/ipv6.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
# lib/ipv6.rb
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'auth'
|
5
|
+
|
6
|
+
module Spior
|
7
|
+
# Block or Allow ipv6 traffic with sysctl
|
8
|
+
class Ipv6
|
9
|
+
def initialize
|
10
|
+
@changed = false
|
11
|
+
end
|
12
|
+
|
13
|
+
def allow
|
14
|
+
apply_option('net.ipv6.conf.all.disable_ipv6', '0')
|
15
|
+
apply_option('net.ipv6.conf.default.disable_ipv6', '0')
|
16
|
+
Msg.p 'ipv6 allowed' if @changed
|
17
|
+
end
|
18
|
+
|
19
|
+
def block
|
20
|
+
apply_option('net.ipv6.conf.all.disable_ipv6', '1')
|
21
|
+
apply_option('net.ipv6.conf.default.disable_ipv6', '1')
|
22
|
+
Msg.p 'ipv6 blocked' if @changed
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def apply_option(flag, value)
|
28
|
+
flag_path = flag.gsub('.', '/')
|
29
|
+
return unless File.exist?("/proc/sys/#{flag_path}")
|
30
|
+
|
31
|
+
Auth.new.sysctl(flag, value)
|
32
|
+
@changed = true
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/lib/spior/menu.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Spior
|
4
|
+
# Build an interactive menu for spior
|
4
5
|
module Menu
|
5
6
|
def self.run
|
6
7
|
loop do
|
@@ -18,15 +19,15 @@ module Spior
|
|
18
19
|
print '>> '
|
19
20
|
case gets.chomp
|
20
21
|
when '1'
|
21
|
-
|
22
|
+
Service.start
|
22
23
|
when '2'
|
23
|
-
|
24
|
+
Service.restart
|
24
25
|
when '3'
|
25
|
-
|
26
|
+
Service.stop
|
26
27
|
when '4'
|
27
|
-
|
28
|
+
Status.info
|
28
29
|
when '5'
|
29
|
-
|
30
|
+
Dep.looking
|
30
31
|
else
|
31
32
|
exit
|
32
33
|
end
|
data/lib/spior/msg.rb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'rainbow'
|
4
4
|
|
5
|
+
# Used to display various message
|
5
6
|
module Msg
|
6
7
|
module_function
|
7
8
|
|
@@ -19,17 +20,24 @@ module Msg
|
|
19
20
|
end
|
20
21
|
|
21
22
|
def p(text)
|
22
|
-
|
23
|
+
opn = Rainbow('[').cyan
|
24
|
+
msg = Rainbow('+').white
|
25
|
+
cls = Rainbow(']').cyan
|
26
|
+
puts "#{opn}#{msg}#{cls} #{text}"
|
23
27
|
end
|
24
28
|
|
25
29
|
def err(text)
|
26
|
-
|
30
|
+
opn = Rainbow('[').red
|
31
|
+
msg = Rainbow('-').white
|
32
|
+
cls = Rainbow(']').red
|
33
|
+
puts "#{opn}#{msg}#{cls} #{text}"
|
27
34
|
end
|
28
35
|
|
29
36
|
def info(text)
|
30
|
-
|
31
|
-
|
32
|
-
|
37
|
+
one = Rainbow('_').blue
|
38
|
+
two = Rainbow('-').white
|
39
|
+
thr = Rainbow('_').blue
|
40
|
+
puts "#{one}#{two}#{thr} #{text} #{one}#{two}#{thr}"
|
33
41
|
end
|
34
42
|
|
35
43
|
def report(text)
|
data/lib/spior/options.rb
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
require 'optparse'
|
4
4
|
|
5
5
|
module Spior
|
6
|
+
# Options for the CLI
|
6
7
|
class Options
|
7
8
|
def initialize(argv)
|
8
9
|
parse(argv)
|
@@ -13,33 +14,33 @@ module Spior
|
|
13
14
|
def parse(argv)
|
14
15
|
OptionParser.new do |opts|
|
15
16
|
opts.on('-i', '--install', 'Install the dependencies.') do
|
16
|
-
|
17
|
+
Dep.looking
|
17
18
|
end
|
18
19
|
|
19
20
|
opts.on('-t', '--tor', 'Redirect traffic through TOR.') do
|
20
|
-
|
21
|
+
Service.start
|
21
22
|
end
|
22
23
|
|
23
24
|
opts.on('-r', '--reload', 'Reload TOR to change your IP.') do
|
24
|
-
|
25
|
+
Service.restart
|
25
26
|
exit
|
26
27
|
end
|
27
28
|
|
28
29
|
opts.on('-c', '--clearnet', 'Reset iptables and return to clearnet navigation.') do
|
29
|
-
|
30
|
+
Service.stop
|
30
31
|
end
|
31
32
|
|
32
33
|
opts.on('-s', '--status', 'Look infos about your current IP.') do
|
33
|
-
|
34
|
+
Status.info
|
34
35
|
exit
|
35
36
|
end
|
36
37
|
|
37
38
|
opts.on('-p', '--persist', 'Active Spior at every boot.') do
|
38
|
-
|
39
|
+
Service::Enable.new
|
39
40
|
end
|
40
41
|
|
41
42
|
opts.on('-m', '--menu', 'Display an interactive menu.') do
|
42
|
-
|
43
|
+
Menu.run
|
43
44
|
end
|
44
45
|
|
45
46
|
opts.on('-h', '--help', 'Show this message.') do
|
data/lib/spior/service/enable.rb
CHANGED
@@ -3,60 +3,63 @@
|
|
3
3
|
require 'nomansland'
|
4
4
|
|
5
5
|
module Spior
|
6
|
+
# Service make Spior persistent using services on system like iptables and tor
|
6
7
|
module Service
|
7
|
-
|
8
|
-
|
9
|
-
# enable the Tor redirection when you boot your system
|
8
|
+
# Enable the Tor redirection when you boot your system
|
10
9
|
#
|
11
10
|
# It should use and enable the services:
|
12
11
|
# + tor
|
13
12
|
# + iptables
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
13
|
+
class Enable
|
14
|
+
def initialize
|
15
|
+
case Nomansland.distro?
|
16
|
+
when :gentoo
|
17
|
+
for_gentoo
|
18
|
+
when :archlinux
|
19
|
+
for_arch
|
20
|
+
else
|
21
|
+
Msg.report 'Your distro is not yet supported.'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
protected
|
26
|
+
|
27
|
+
def for_gentoo
|
28
|
+
Iptables::Rules.new.save
|
29
|
+
case Nomansland.init?
|
30
|
+
when :systemd
|
31
|
+
systemd_enable('iptables-restore', 'tor')
|
32
|
+
when :openrc
|
33
|
+
rc_upd = Helpers::Exec.new('rc-update')
|
34
|
+
rc_upd.run('rc-update add iptables boot')
|
35
|
+
rc_upd.run('rc-update add tor')
|
36
|
+
rc_upd.run('rc-update add tor default')
|
37
|
+
else
|
38
|
+
Msg.report 'Init no yet supported for start Iptables at boot'
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def for_arch
|
43
|
+
Iptables::Rules.new.save
|
20
44
|
Tor::Config.new(Tempfile.new('torrc')).backup
|
21
|
-
|
45
|
+
systemd_enable('iptables', 'tor')
|
22
46
|
Msg.p 'Services enabled for Archlinux...'
|
23
|
-
else
|
24
|
-
Msg.report 'Your distro is not yet supported.'
|
25
47
|
end
|
26
|
-
end
|
27
48
|
|
28
|
-
|
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
|
49
|
+
private
|
46
50
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
51
|
+
def systemd_enable(*services)
|
52
|
+
systemctl = Helpers::Exec.new('systemctl')
|
53
|
+
services.each do |s|
|
54
|
+
Msg.p "Search for service #{s}..."
|
55
|
+
systemctl.run("enable #{s}") unless system("systemctl is-enabled #{s}")
|
56
|
+
end
|
52
57
|
end
|
53
|
-
end
|
54
58
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
systemctl.run("start #{service}")
|
59
|
+
def systemd_start(service)
|
60
|
+
systemctl = Helpers::Exec.new('systemctl')
|
61
|
+
Msg.p "Search for service #{service}..."
|
62
|
+
systemctl.run("start #{service}") unless system("systemctl is-active #{service}")
|
60
63
|
end
|
61
64
|
end
|
62
65
|
end
|
data/lib/spior/service/start.rb
CHANGED
@@ -1,14 +1,16 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Spior
|
4
|
+
# Interact with Spior::Tor and Spior::Iptables
|
4
5
|
module Service
|
5
6
|
module_function
|
6
7
|
|
7
8
|
# Service.start should start Tor if not alrealy running
|
8
9
|
# And start to redirect the local traffic with Iptables
|
9
10
|
def start
|
10
|
-
Tor.
|
11
|
+
Tor::Start.new
|
11
12
|
Iptables::Tor.new.run!
|
13
|
+
Ipv6.new.block
|
12
14
|
end
|
13
15
|
end
|
14
16
|
end
|
data/lib/spior/service/stop.rb
CHANGED
@@ -1,12 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Spior
|
4
|
+
# Interact with Spior::Tor and Spior::Iptables
|
4
5
|
module Service
|
5
6
|
module_function
|
6
7
|
|
7
|
-
def stop
|
8
|
-
Tor.
|
9
|
-
Iptables::Rules.new.restore
|
8
|
+
def stop(clean: true)
|
9
|
+
Tor::Stop.new
|
10
|
+
Iptables::Rules.new.restore if clean
|
11
|
+
Ipv6.new.allow if clean
|
10
12
|
end
|
11
13
|
end
|
12
14
|
end
|
data/lib/spior/status.rb
CHANGED
@@ -17,8 +17,8 @@ module Spior
|
|
17
17
|
status = 'Enable' if hash['IsTor'] == true
|
18
18
|
end
|
19
19
|
status
|
20
|
-
rescue OpenURI::HTTPError =>
|
21
|
-
res =
|
20
|
+
rescue OpenURI::HTTPError => e
|
21
|
+
res = e.io
|
22
22
|
puts "Fail to join server #{res.status}"
|
23
23
|
end
|
24
24
|
|
@@ -38,8 +38,8 @@ module Spior
|
|
38
38
|
puts " Timezone ===> #{hash['time_zone']}"
|
39
39
|
end
|
40
40
|
puts " Status ===> #{enable}"
|
41
|
-
rescue OpenURI::HTTPError =>
|
42
|
-
res =
|
41
|
+
rescue OpenURI::HTTPError => e
|
42
|
+
res = e.io
|
43
43
|
puts "Fail to join server #{res.status}"
|
44
44
|
end
|
45
45
|
end
|
data/lib/spior/tor/config.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'digest'
|
4
|
+
require 'tempfile'
|
5
|
+
require 'auth'
|
4
6
|
|
5
7
|
module Spior
|
6
8
|
module Tor
|
@@ -12,37 +14,70 @@ module Spior
|
|
12
14
|
#
|
13
15
|
def initialize(filename)
|
14
16
|
@filename = filename
|
15
|
-
@
|
16
|
-
|
17
|
+
@config_torrc = '/etc/tor/torrc'
|
18
|
+
@config_dir = '/etc/torrc.d'
|
19
|
+
@config_spiorrc = "#{@config_dir}/spior.conf"
|
20
|
+
@content = ['# Generated by Spior, don\'t edit.']
|
17
21
|
@content_torrc = []
|
18
22
|
end
|
19
23
|
|
20
24
|
# Generate a `torrc` compatible file for Spior
|
21
25
|
# Use value from Spior::CONFIG
|
22
26
|
def generate
|
27
|
+
create_config_dir
|
28
|
+
configure_torrc
|
23
29
|
generate_content(@content)
|
24
|
-
return if @content.length ==
|
30
|
+
return if @content.length == 1
|
25
31
|
|
26
|
-
|
27
|
-
|
32
|
+
cn = @content.join("\n")
|
33
|
+
File.write(@filename.path, "#{cn}\n")
|
34
|
+
Msg.p "Generating #{@config_spiorrc}..."
|
35
|
+
move(@filename.path, @config_spiorrc)
|
36
|
+
end
|
37
|
+
|
38
|
+
def write_file(content, file, mode = 'a')
|
39
|
+
return if content.nil?
|
40
|
+
|
41
|
+
File.open(file, mode) do |f|
|
42
|
+
if content.is_a?(Array)
|
43
|
+
f.puts(content.join('\n'))
|
44
|
+
else
|
45
|
+
f.puts(content)
|
46
|
+
end
|
47
|
+
# f.chmod(644)
|
48
|
+
end
|
28
49
|
end
|
29
50
|
|
30
51
|
# Save current Tor options (Spior::CONFIG) in /etc/tor/torrc
|
31
52
|
# Only if theses options are not alrealy present
|
32
53
|
def backup
|
33
54
|
generate_content(@content_torrc)
|
34
|
-
|
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
|
55
|
+
write_file @content_torrc, @filename.path, 'w'
|
39
56
|
|
40
57
|
Msg.p 'Saving Tor options...'
|
41
|
-
move(@filename.path,
|
58
|
+
move(@filename.path, @config_spiorrc)
|
42
59
|
end
|
43
60
|
|
44
61
|
protected
|
45
62
|
|
63
|
+
def create_config_dir
|
64
|
+
return if Dir.exist? @config_dir
|
65
|
+
|
66
|
+
if Process::Sys.getuid == '0'
|
67
|
+
File.mkdir @config_dir
|
68
|
+
else
|
69
|
+
Auth.new.mkdir @config_dir
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def configure_torrc
|
74
|
+
temp = Tempfile.new('torrc')
|
75
|
+
content = File.read(@config_torrc)
|
76
|
+
adding content, "%include #{@config_dir}/*.conf"
|
77
|
+
write_file content, temp.path
|
78
|
+
move(temp.path, @config_torrc)
|
79
|
+
end
|
80
|
+
|
46
81
|
def generate_content(content)
|
47
82
|
adding content, 'AutomapHostsOnResolve 1'
|
48
83
|
adding content, "DNSPort #{CONFIG.dns_port}"
|
@@ -54,9 +89,9 @@ module Spior
|
|
54
89
|
private
|
55
90
|
|
56
91
|
def search(option_name)
|
57
|
-
File.open(
|
92
|
+
File.open(@config_torrc) do |f|
|
58
93
|
f.each do |line|
|
59
|
-
return Regexp.last_match(1) if line.match(
|
94
|
+
return Regexp.last_match(1) if line.match(%r{^#{option_name} ([a-z0-9./*]*)}i)
|
60
95
|
end
|
61
96
|
end
|
62
97
|
false
|
@@ -65,12 +100,14 @@ module Spior
|
|
65
100
|
def adding(content, option)
|
66
101
|
o = option.split(' ')
|
67
102
|
all = o[1..o.length].join(' ')
|
68
|
-
|
69
|
-
|
70
|
-
|
103
|
+
return if search(o[0])
|
104
|
+
|
105
|
+
content << "#{o[0]} #{all}"
|
71
106
|
end
|
72
107
|
|
73
108
|
def digest_match?(src, dest)
|
109
|
+
return unless File.exist?(dest)
|
110
|
+
|
74
111
|
md5_src = Digest::MD5.file src
|
75
112
|
md5_dest = Digest::MD5.file dest
|
76
113
|
md5_src == md5_dest
|
data/lib/spior/tor/data.rb
CHANGED
@@ -34,7 +34,7 @@ module Spior
|
|
34
34
|
def search(option_name)
|
35
35
|
File.open('/etc/tor/torrc') do |f|
|
36
36
|
f.each do |line|
|
37
|
-
return Regexp.last_match(1) if line.match(
|
37
|
+
return Regexp.last_match(1) if line.match(%r{#{option_name} ([a-z0-9./]*)}i)
|
38
38
|
end
|
39
39
|
end
|
40
40
|
false
|
data/lib/spior/tor/start.rb
CHANGED
@@ -4,56 +4,62 @@ require 'nomansland'
|
|
4
4
|
require 'tempfile'
|
5
5
|
|
6
6
|
module Spior
|
7
|
+
# Module Spior::Tor used to start/stop/restart Tor on the system.
|
7
8
|
module Tor
|
8
|
-
extend self
|
9
|
-
|
10
9
|
# start should start the Tor service on your distribution
|
11
|
-
|
12
|
-
|
10
|
+
class Start
|
11
|
+
def initialize
|
12
|
+
tmp_file = Tempfile.new('torrc')
|
13
13
|
|
14
|
-
|
14
|
+
Config.new(tmp_file).generate
|
15
15
|
|
16
|
-
|
17
|
-
|
16
|
+
nomansland
|
17
|
+
end
|
18
18
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
19
|
+
protected
|
20
|
+
|
21
|
+
def nomansland
|
22
|
+
case Nomansland.init?
|
23
|
+
when :systemd
|
24
|
+
start_systemd
|
25
|
+
when :openrc
|
26
|
+
start_openrc
|
27
|
+
when :runit
|
28
|
+
start_runit
|
29
|
+
else
|
30
|
+
Msg.report "Don't known yet how to start Tor for your system."
|
31
|
+
end
|
29
32
|
end
|
30
|
-
end
|
31
33
|
|
32
|
-
|
34
|
+
private
|
35
|
+
|
36
|
+
def start_systemd
|
37
|
+
state = `systemctl is-active tor`.chomp
|
38
|
+
return if state == 'active'
|
33
39
|
|
34
|
-
def start_systemd
|
35
|
-
state = `systemctl is-active tor`.chomp
|
36
|
-
unless state == 'active'
|
37
40
|
Msg.p 'Starting Tor with Systemd...'
|
38
41
|
Helpers::Exec.new('systemctl').run('start tor')
|
39
42
|
end
|
40
|
-
end
|
41
43
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
Helpers::Exec.new('sv').run('start tor')
|
46
|
-
else
|
47
|
-
Helpers::Exec.new('ln').run('-s /etc/sv/tor /var/service/tor')
|
44
|
+
def start_openrc
|
45
|
+
Msg.p 'Starting Tor with OpenRC...'
|
46
|
+
Helpers::Exec.new('/etc/init.d/tor').run('start')
|
48
47
|
end
|
49
|
-
end
|
50
48
|
|
51
|
-
|
49
|
+
def start_runit
|
50
|
+
Msg.p 'Starting Tor with Runit...'
|
51
|
+
if File.exist? '/var/service/tor'
|
52
|
+
Helpers::Exec.new('sv').run('start tor')
|
53
|
+
else
|
54
|
+
Helpers::Exec.new('ln').run('-s /etc/sv/tor /var/service/tor')
|
55
|
+
end
|
56
|
+
end
|
52
57
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
58
|
+
def x(arg)
|
59
|
+
auth = (Process::Sys.getuid == '0' ? '' : 'sudo')
|
60
|
+
pid = spawn("#{auth} #{arg}", out: '/dev/null') or raise 'Error'
|
61
|
+
Process.wait pid
|
62
|
+
end
|
57
63
|
end
|
58
64
|
end
|
59
65
|
end
|
data/lib/spior/tor/stop.rb
CHANGED
@@ -1,31 +1,52 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Spior
|
4
|
+
# Module Spior::Tor used to start/stop/restart Tor on the system.
|
4
5
|
module Tor
|
5
|
-
module_function
|
6
|
-
|
7
6
|
# Stop Tor service on your distribution (linux)
|
8
7
|
# It also kill previous instance run by Spior
|
9
|
-
|
10
|
-
|
8
|
+
class Stop
|
9
|
+
def initialize
|
10
|
+
old_pid = `pgrep -f "tor -f /tmp/torrc*"`.chomp
|
11
|
+
|
12
|
+
if old_pid != ''
|
13
|
+
Msg.p "Found old pid > #{old_pid}, killing it..."
|
14
|
+
Helpers::Exec.new('kill').run("-9 #{old_pid}")
|
15
|
+
end
|
16
|
+
|
17
|
+
nomansland
|
18
|
+
end
|
19
|
+
|
20
|
+
protected
|
11
21
|
|
12
|
-
|
13
|
-
|
14
|
-
|
22
|
+
def nomansland
|
23
|
+
case Nomansland.init?
|
24
|
+
when :systemd
|
25
|
+
stop_systemd
|
26
|
+
when :runit
|
27
|
+
stop_runit
|
28
|
+
when :openrc
|
29
|
+
stop_openrc
|
30
|
+
else
|
31
|
+
Msg.report 'Don\'t known how to stop Tor on your system.'
|
32
|
+
end
|
15
33
|
end
|
16
34
|
|
17
|
-
|
18
|
-
|
35
|
+
private
|
36
|
+
|
37
|
+
def stop_systemd
|
19
38
|
Msg.p 'Stopping Tor with Systemd...'
|
20
39
|
Helpers::Exec.new('systemctl').run('stop tor')
|
21
|
-
|
40
|
+
end
|
41
|
+
|
42
|
+
def stop_runit
|
22
43
|
Msg.p 'Stopping Tor with Runit...'
|
23
44
|
Helpers::Exec.new('sv').run('stop tor')
|
24
|
-
|
45
|
+
end
|
46
|
+
|
47
|
+
def stop_openrc
|
25
48
|
Msg.p 'Stopping Tor with Openrc...'
|
26
49
|
Helpers::Exec.new('/etc/init.d/tor').run('stop')
|
27
|
-
else
|
28
|
-
Msg.report 'Don\'t known how to stop Tor on your system.'
|
29
50
|
end
|
30
51
|
end
|
31
52
|
end
|
data/lib/spior/tor.rb
CHANGED
data/lib/spior/version.rb
CHANGED
data/lib/spior.rb
CHANGED
@@ -9,6 +9,7 @@ require_relative 'spior/tor'
|
|
9
9
|
require_relative 'spior/menu'
|
10
10
|
require_relative 'spior/service'
|
11
11
|
require_relative 'spior/helpers'
|
12
|
+
require_relative 'spior/ipv6'
|
12
13
|
|
13
14
|
module Spior
|
14
15
|
# Contain value of Tor::Data
|
@@ -21,6 +22,7 @@ module Spior
|
|
21
22
|
# Spior::CONFIG.virt_addr = '10.192.0.0/10'
|
22
23
|
CONFIG = Tor::Data.new
|
23
24
|
|
25
|
+
# Main for the CLI
|
24
26
|
class Main
|
25
27
|
def initialize(argv)
|
26
28
|
@argv = argv
|
data/spior.gemspec
CHANGED
data.tar.gz.sig
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: spior
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- szorfein
|
@@ -12,31 +12,31 @@ cert_chain:
|
|
12
12
|
-----BEGIN CERTIFICATE-----
|
13
13
|
MIIEhTCCAu2gAwIBAgIBATANBgkqhkiG9w0BAQsFADBEMREwDwYDVQQDDAhzem9y
|
14
14
|
ZmVpbjEaMBgGCgmSJomT8ixkARkWCnByb3Rvbm1haWwxEzARBgoJkiaJk/IsZAEZ
|
15
|
-
|
15
|
+
FgNjb20wHhcNMjMxMDIzMTcyMTA4WhcNMjQxMDIyMTcyMTA4WjBEMREwDwYDVQQD
|
16
16
|
DAhzem9yZmVpbjEaMBgGCgmSJomT8ixkARkWCnByb3Rvbm1haWwxEzARBgoJkiaJ
|
17
|
-
k/
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
AaOBgTB/
|
27
|
-
|
17
|
+
k/IsZAEZFgNjb20wggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQCqe1yx
|
18
|
+
EG2oM25jeHp08A8zkaDNmbI3MujjrRM/WPEYZX2dVwOxkIS20hQVuxcAsBBA4W/W
|
19
|
+
kuPbqRkvLboaGaxLrllkSEJw9HA/GesTdXLyCFYmNzSFqGh5BafNSkxoiDhTavxp
|
20
|
+
xvYzAkYR/3CzSOWSxJk73wIg+F7w/nWJPTt2tgJE9hgR8uuFY+EzPOlFZhkFTdCV
|
21
|
+
88sBGuZPMjq7ASQVBE3UA+Y1xJeXE3/FhIhYvLnjevkkDLSLFmox0ZQf6nx6abuL
|
22
|
+
KTOGRA1bfLfkW5HMh5X5JwViliwG3RWhqAukJUgHTUk+oKtejlzSDqupwOenKZf0
|
23
|
+
xI2/BnS8zOsS6Te08iLxqZfI/lsG8wcPduekSetRI4VIOZ5QoRK54PiQjrOBhbnD
|
24
|
+
OQBB/XF1C80imZtRtdUqh6bK9WeWI4RYZ2/KwXL1AScEbXkBkkOECWoVrD18WgRm
|
25
|
+
siuX6RkNIelhtb0En7f3bizgPqlO0qPQV+wPi9TSBxdVG12C0OmjCQYMQD0CAwEA
|
26
|
+
AaOBgTB/MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQWBBTlKnQ3qMUF
|
27
|
+
zydvZaKwdP+dnj2uajAiBgNVHREEGzAZgRdzem9yZmVpbkBwcm90b25tYWlsLmNv
|
28
28
|
bTAiBgNVHRIEGzAZgRdzem9yZmVpbkBwcm90b25tYWlsLmNvbTANBgkqhkiG9w0B
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
29
|
+
AQsFAAOCAYEAFjnBWWfaMeA8hP0Q76WmBCFckGN5I42X5RQkVYRRXIaeXIS1td/t
|
30
|
+
O1v1iQLo6ABfASMi6We7T16+ita68xwNOmSkMNHHXBr/fdGbHExxFSX7BXNRbwla
|
31
|
+
SS6Vy0bXKMDJbXcvkrmIolpYhEFm1218FCRCT6ogM1oWAJAfhfF9pMeRxrxjQYFn
|
32
|
+
ko8XgjIHxb83miOILgdq/lgJ4gfD7PsGfJtLCLiCKCcxIb4TtmKAzRwCDVpb6wqM
|
33
|
+
5xJZffAmHI7v8lVer53sPzm3INPu5xFZyfZ/SXYXPKKwln0efH63K5vuXYwEN7NI
|
34
|
+
SBSRTN03Hb65t86m6/r084SrNnLntQjCSqApzFBt1QwJ5cmiVilODN4V7y2hZpyK
|
35
|
+
hSk3b2VOotDPiWIm1p/IPXQDfm5x67Z5fJQPAlBTsse4jKyVyW1lZLmERSBuRZ2O
|
36
|
+
urXgRIzALxd/xazPCnoLSXPzfJSI6Y77S1EBvhPd9RaSO8IyH9RhPDP9mnTvW2Kl
|
37
|
+
NAUnoL+txK5a
|
38
38
|
-----END CERTIFICATE-----
|
39
|
-
date:
|
39
|
+
date: 2023-10-26 00:00:00.000000000 Z
|
40
40
|
dependencies:
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: interfacez
|
@@ -113,6 +113,7 @@ files:
|
|
113
113
|
- bin/spior
|
114
114
|
- ext/ipt_mod.conf
|
115
115
|
- ext/iptables.service
|
116
|
+
- lib/auth.rb
|
116
117
|
- lib/spior.rb
|
117
118
|
- lib/spior/dep.rb
|
118
119
|
- lib/spior/helpers.rb
|
@@ -121,6 +122,7 @@ files:
|
|
121
122
|
- lib/spior/iptables/root.rb
|
122
123
|
- lib/spior/iptables/rules.rb
|
123
124
|
- lib/spior/iptables/tor.rb
|
125
|
+
- lib/spior/ipv6.rb
|
124
126
|
- lib/spior/menu.rb
|
125
127
|
- lib/spior/msg.rb
|
126
128
|
- lib/spior/options.rb
|
@@ -166,7 +168,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
166
168
|
requirements:
|
167
169
|
- tor
|
168
170
|
- iptables
|
169
|
-
rubygems_version: 3.3.
|
171
|
+
rubygems_version: 3.3.25
|
170
172
|
signing_key:
|
171
173
|
specification_version: 4
|
172
174
|
summary: A tool to make TOR your default gateway
|
metadata.gz.sig
CHANGED
Binary file
|