spior 0.2.8 → 0.3.5
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 +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
|