spior 0.1.6 → 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 +47 -0
- data/.gitignore +1 -0
- data/CHANGELOG.md +21 -0
- data/Gemfile +5 -0
- data/README.md +13 -3
- data/Rakefile +20 -9
- data/bin/spior +1 -0
- data/lib/auth.rb +46 -0
- data/lib/spior/dep.rb +38 -23
- data/lib/spior/helpers.rb +22 -25
- data/lib/spior/iptables/default.rb +19 -13
- data/lib/spior/iptables/root.rb +37 -37
- data/lib/spior/iptables/rules.rb +103 -0
- data/lib/spior/iptables/tor.rb +24 -23
- data/lib/spior/iptables.rb +4 -0
- data/lib/spior/ipv6.rb +35 -0
- data/lib/spior/menu.rb +18 -24
- data/lib/spior/msg.rb +30 -8
- data/lib/spior/options.rb +20 -22
- data/lib/spior/service/enable.rb +66 -0
- data/lib/spior/service/restart.rb +5 -12
- data/lib/spior/service/start.rb +7 -17
- data/lib/spior/service/stop.rb +14 -0
- data/lib/spior/service.rb +5 -0
- data/lib/spior/status.rb +32 -24
- data/lib/spior/tor/config.rb +137 -0
- data/lib/spior/tor/data.rb +53 -0
- data/lib/spior/tor/start.rb +65 -0
- data/lib/spior/tor/stop.rb +53 -0
- data/lib/spior/tor.rb +7 -1
- data/lib/spior/version.rb +3 -1
- data/lib/spior.rb +18 -23
- data/spior.gemspec +24 -21
- data/test/test_install.rb +2 -2
- data/test/test_options.rb +2 -0
- data.tar.gz.sig +2 -2
- metadata +59 -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
@@ -0,0 +1,137 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'digest'
|
4
|
+
require 'tempfile'
|
5
|
+
require 'auth'
|
6
|
+
|
7
|
+
module Spior
|
8
|
+
module Tor
|
9
|
+
# Generate a config file (torrc) for Spior
|
10
|
+
class Config
|
11
|
+
# ==== Attributes
|
12
|
+
#
|
13
|
+
# * +filename+ - A reference to a tempfile like filename=Tempfile.new('foo')
|
14
|
+
#
|
15
|
+
def initialize(filename)
|
16
|
+
@filename = filename
|
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.']
|
21
|
+
@content_torrc = []
|
22
|
+
end
|
23
|
+
|
24
|
+
# Generate a `torrc` compatible file for Spior
|
25
|
+
# Use value from Spior::CONFIG
|
26
|
+
def generate
|
27
|
+
create_config_dir
|
28
|
+
configure_torrc
|
29
|
+
generate_content(@content)
|
30
|
+
return if @content.length == 1
|
31
|
+
|
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
|
49
|
+
end
|
50
|
+
|
51
|
+
# Save current Tor options (Spior::CONFIG) in /etc/tor/torrc
|
52
|
+
# Only if theses options are not alrealy present
|
53
|
+
def backup
|
54
|
+
generate_content(@content_torrc)
|
55
|
+
write_file @content_torrc, @filename.path, 'w'
|
56
|
+
|
57
|
+
Msg.p 'Saving Tor options...'
|
58
|
+
move(@filename.path, @config_spiorrc)
|
59
|
+
end
|
60
|
+
|
61
|
+
protected
|
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
|
+
|
81
|
+
def generate_content(content)
|
82
|
+
adding content, 'AutomapHostsOnResolve 1'
|
83
|
+
adding content, "DNSPort #{CONFIG.dns_port}"
|
84
|
+
adding content, "VirtualAddrNetworkIpv4 #{CONFIG.virt_addr}"
|
85
|
+
adding content, "TransPort #{CONFIG.trans_port} IsolateClientAddr
|
86
|
+
IsolateClientProtocol IsolateDestAddr IsolateDestPort"
|
87
|
+
end
|
88
|
+
|
89
|
+
private
|
90
|
+
|
91
|
+
def search(option_name)
|
92
|
+
File.open(@config_torrc) do |f|
|
93
|
+
f.each do |line|
|
94
|
+
return Regexp.last_match(1) if line.match(%r{^#{option_name} ([a-z0-9./*]*)}i)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
false
|
98
|
+
end
|
99
|
+
|
100
|
+
def adding(content, option)
|
101
|
+
o = option.split(' ')
|
102
|
+
all = o[1..o.length].join(' ')
|
103
|
+
return if search(o[0])
|
104
|
+
|
105
|
+
content << "#{o[0]} #{all}"
|
106
|
+
end
|
107
|
+
|
108
|
+
def digest_match?(src, dest)
|
109
|
+
return unless File.exist?(dest)
|
110
|
+
|
111
|
+
md5_src = Digest::MD5.file src
|
112
|
+
md5_dest = Digest::MD5.file dest
|
113
|
+
md5_src == md5_dest
|
114
|
+
end
|
115
|
+
|
116
|
+
# Permission for Archlinux on a torrc are chmod 644, chown root:root
|
117
|
+
def fix_perm(file)
|
118
|
+
if Process::Sys.getuid == '0'
|
119
|
+
file.chown(0, 0)
|
120
|
+
else
|
121
|
+
Helpers::Exec.new('chown').run("root:root #{file}")
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def move(src, dest)
|
126
|
+
return if digest_match? src, dest
|
127
|
+
|
128
|
+
fix_perm(@filename.path)
|
129
|
+
if Process::Sys.getuid == '0'
|
130
|
+
FileUtils.mv(src, dest)
|
131
|
+
else
|
132
|
+
Helpers::Exec.new('mv').run("#{src} #{dest}")
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
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(%r{#{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
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'nomansland'
|
4
|
+
require 'tempfile'
|
5
|
+
|
6
|
+
module Spior
|
7
|
+
# Module Spior::Tor used to start/stop/restart Tor on the system.
|
8
|
+
module Tor
|
9
|
+
# start should start the Tor service on your distribution
|
10
|
+
class Start
|
11
|
+
def initialize
|
12
|
+
tmp_file = Tempfile.new('torrc')
|
13
|
+
|
14
|
+
Config.new(tmp_file).generate
|
15
|
+
|
16
|
+
nomansland
|
17
|
+
end
|
18
|
+
|
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
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def start_systemd
|
37
|
+
state = `systemctl is-active tor`.chomp
|
38
|
+
return if state == 'active'
|
39
|
+
|
40
|
+
Msg.p 'Starting Tor with Systemd...'
|
41
|
+
Helpers::Exec.new('systemctl').run('start tor')
|
42
|
+
end
|
43
|
+
|
44
|
+
def start_openrc
|
45
|
+
Msg.p 'Starting Tor with OpenRC...'
|
46
|
+
Helpers::Exec.new('/etc/init.d/tor').run('start')
|
47
|
+
end
|
48
|
+
|
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
|
57
|
+
|
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
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Spior
|
4
|
+
# Module Spior::Tor used to start/stop/restart Tor on the system.
|
5
|
+
module Tor
|
6
|
+
# Stop Tor service on your distribution (linux)
|
7
|
+
# It also kill previous instance run by Spior
|
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
|
21
|
+
|
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
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def stop_systemd
|
38
|
+
Msg.p 'Stopping Tor with Systemd...'
|
39
|
+
Helpers::Exec.new('systemctl').run('stop tor')
|
40
|
+
end
|
41
|
+
|
42
|
+
def stop_runit
|
43
|
+
Msg.p 'Stopping Tor with Runit...'
|
44
|
+
Helpers::Exec.new('sv').run('stop tor')
|
45
|
+
end
|
46
|
+
|
47
|
+
def stop_openrc
|
48
|
+
Msg.p 'Stopping Tor with Openrc...'
|
49
|
+
Helpers::Exec.new('/etc/init.d/tor').run('stop')
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
data/lib/spior/tor.rb
CHANGED
@@ -1,6 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Spior
|
4
|
+
# The module Tor interract with Tor on your system.
|
2
5
|
module Tor
|
3
6
|
end
|
4
7
|
end
|
5
8
|
|
6
|
-
require_relative 'tor/
|
9
|
+
require_relative 'tor/data'
|
10
|
+
require_relative 'tor/config'
|
11
|
+
require_relative 'tor/start'
|
12
|
+
require_relative 'tor/stop'
|
data/lib/spior/version.rb
CHANGED
data/lib/spior.rb
CHANGED
@@ -1,44 +1,39 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
3
|
require_relative 'spior/dep'
|
4
4
|
require_relative 'spior/iptables'
|
5
5
|
require_relative 'spior/msg'
|
6
6
|
require_relative 'spior/options'
|
7
7
|
require_relative 'spior/status'
|
8
8
|
require_relative 'spior/tor'
|
9
|
-
require_relative 'spior/persist'
|
10
9
|
require_relative 'spior/menu'
|
11
10
|
require_relative 'spior/service'
|
12
11
|
require_relative 'spior/helpers'
|
12
|
+
require_relative 'spior/ipv6'
|
13
13
|
|
14
14
|
module Spior
|
15
|
+
# Contain value of Tor::Data
|
16
|
+
# Can be customized, e.g:
|
17
|
+
#
|
18
|
+
# Spior::CONFIG.dns_port = '5353'
|
19
|
+
# Spior::CONFIG.trans_port = '8888'
|
20
|
+
# Spior::CONFIG.uid = '666'
|
21
|
+
# Spior::CONFIG.user = 'Tor-User-System'
|
22
|
+
# Spior::CONFIG.virt_addr = '10.192.0.0/10'
|
23
|
+
CONFIG = Tor::Data.new
|
24
|
+
|
25
|
+
# Main for the CLI
|
15
26
|
class Main
|
16
27
|
def initialize(argv)
|
17
28
|
@argv = argv
|
18
|
-
|
29
|
+
x
|
19
30
|
end
|
20
31
|
|
21
32
|
private
|
22
33
|
|
23
|
-
def
|
24
|
-
|
25
|
-
|
26
|
-
if options.install
|
27
|
-
Msg.head
|
28
|
-
Dep.install
|
29
|
-
Copy.new.save
|
30
|
-
end
|
31
|
-
|
32
|
-
Dep.check
|
33
|
-
|
34
|
-
if options.tor
|
35
|
-
Msg.head
|
36
|
-
Iptables::Tor.new.run!
|
37
|
-
end
|
38
|
-
|
39
|
-
if options.persist
|
40
|
-
Persist.enable
|
41
|
-
end
|
34
|
+
def x
|
35
|
+
Msg.banner
|
36
|
+
Options.new(@argv)
|
42
37
|
end
|
43
38
|
end
|
44
39
|
end
|
data/spior.gemspec
CHANGED
@@ -1,18 +1,20 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "#{File.dirname(__FILE__)}/lib/spior/version"
|
2
4
|
|
3
5
|
Gem::Specification.new do |s|
|
4
|
-
s.name =
|
6
|
+
s.name = 'spior'
|
5
7
|
s.version = Spior::VERSION
|
6
|
-
s.summary =
|
7
|
-
s.description = <<-
|
8
|
+
s.summary = 'A tool to make TOR your default gateway'
|
9
|
+
s.description = <<-DESC
|
8
10
|
A tool to make TOR your default gateway
|
9
|
-
|
11
|
+
DESC
|
10
12
|
s.metadata = {
|
11
|
-
|
12
|
-
|
13
|
-
|
13
|
+
'changelog_uri' => 'https://github.com/szorfein/spior/blob/master/CHANGELOG.md',
|
14
|
+
'bug_tracker_uri' => 'https://github.com/szorfein/spior/issues',
|
15
|
+
'wiki_uri' => 'https://github.com/szorfein/spior'
|
14
16
|
}
|
15
|
-
s.author =
|
17
|
+
s.author = 'szorfein'
|
16
18
|
|
17
19
|
s.platform = Gem::Platform::RUBY
|
18
20
|
|
@@ -20,24 +22,25 @@ Gem::Specification.new do |s|
|
|
20
22
|
s.email = 'szorfein@protonmail.com'
|
21
23
|
s.homepage = 'https://github.com/szorfein/spior'
|
22
24
|
|
23
|
-
s.files = `git ls-files`.split(
|
24
|
-
s.files.reject! { |fn| fn.include?
|
25
|
-
s.files.reject! { |fn| fn.include?
|
26
|
-
s.executables = [
|
25
|
+
s.files = `git ls-files`.split(' ')
|
26
|
+
s.files.reject! { |fn| fn.include? 'certs' }
|
27
|
+
s.files.reject! { |fn| fn.include? 'test' }
|
28
|
+
s.executables = ['spior']
|
29
|
+
|
30
|
+
s.extra_rdoc_files = Dir['README.md', 'CHANGELOG.md', 'LICENSE.txt']
|
27
31
|
|
28
|
-
s.
|
32
|
+
s.test_files = Dir['test/test_*.rb']
|
29
33
|
|
30
|
-
s.test_files = Dir["test/test_*.rb"]
|
31
34
|
s.cert_chain = ['certs/szorfein.pem']
|
32
|
-
s.signing_key = File.expand_path(
|
35
|
+
s.signing_key = File.expand_path('~/.ssh/gem-private_key.pem')
|
33
36
|
|
34
37
|
s.requirements << 'tor'
|
35
38
|
s.requirements << 'iptables'
|
36
39
|
|
37
|
-
s.required_ruby_version = '>=2.
|
40
|
+
s.required_ruby_version = '>= 2.6'
|
38
41
|
|
39
|
-
s.add_runtime_dependency('
|
40
|
-
s.add_runtime_dependency('
|
41
|
-
s.add_runtime_dependency('
|
42
|
-
s.add_runtime_dependency('tty-which', '0.
|
42
|
+
s.add_runtime_dependency('interfacez', '~> 1.0')
|
43
|
+
s.add_runtime_dependency('nomansland', '~> 0.0')
|
44
|
+
s.add_runtime_dependency('rainbow', '~> 3.1')
|
45
|
+
s.add_runtime_dependency('tty-which', '~> 0.5')
|
43
46
|
end
|
data/test/test_install.rb
CHANGED
@@ -1,12 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'minitest/autorun'
|
2
4
|
require_relative '../lib/spior/install'
|
3
5
|
require 'pathname'
|
4
6
|
|
5
7
|
class TestInstall < Minitest::Test
|
6
|
-
|
7
8
|
def test_sudo_is_installed
|
8
9
|
sudo = `which sudo`
|
9
10
|
assert_match(/sudo/, sudo, "sudo isn't installed?")
|
10
11
|
end
|
11
|
-
|
12
12
|
end
|
data/test/test_options.rb
CHANGED
data.tar.gz.sig
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
A��@������s���D�.�뿹���;��������V}9���Jv�FX�Q.֬ڸK������S�(���v(��:&��]�}xoR�G)4F㎓��u�X ��F�1֠5���Rt��]�[�)р�==y~�r��S��KZ���LtM���j�F�V*����ƽC��o6��.�w��Nf�'kA��9�p�Z���)��2�X��:Q�Q���)�H�V�ߛ���)��=��}��k��H��k��OtH9zq�dB��P�}��;�����h�F
|
2
|
+
�}f�,�u�naKia����tQj�C�\^:�^�x@�s�jS(��.�@���z0���|!x�R�t��9�}�E��}�<o��evq䗎��ч�����7/de�
|