spior 0.1.4 → 0.1.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.tar.gz.sig +0 -0
- data/CHANGELOG.md +7 -0
- data/README.md +7 -4
- data/Rakefile +2 -1
- data/bin/spior +2 -3
- data/lib/spior.rb +42 -0
- data/lib/spior/clear.rb +13 -18
- data/lib/spior/copy.rb +63 -98
- data/lib/spior/helpers.rb +13 -7
- data/lib/spior/install.rb +0 -3
- data/lib/spior/iptables.rb +5 -183
- data/lib/spior/iptables/default.rb +38 -0
- data/lib/spior/iptables/root.rb +92 -0
- data/lib/spior/iptables/tor.rb +64 -0
- data/lib/spior/menu.rb +10 -24
- data/lib/spior/network.rb +0 -1
- data/lib/spior/options.rb +8 -15
- data/lib/spior/persist.rb +29 -62
- data/lib/spior/status.rb +30 -12
- data/lib/spior/tor.rb +4 -104
- data/lib/spior/tor/info.rb +113 -0
- data/lib/spior/{reload.rb → tor/restart.rb} +3 -4
- data/lib/spior/version.rb +3 -0
- data/spior.gemspec +3 -1
- metadata +11 -9
- metadata.gz.sig +0 -0
- data/ext/ssh.conf +0 -29
- data/ext/sshd.conf +0 -46
- data/ext/sshuttle.service +0 -11
- data/lib/spior/runner.rb +0 -34
@@ -0,0 +1,38 @@
|
|
1
|
+
module Spior
|
2
|
+
module Iptables
|
3
|
+
class Default < Iptables::Root
|
4
|
+
private
|
5
|
+
|
6
|
+
def input
|
7
|
+
# SSH
|
8
|
+
ipt "-A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT"
|
9
|
+
# Allow loopback, rules
|
10
|
+
ipt "-A INPUT -i #{@lo} -j ACCEPT"
|
11
|
+
# Accept related
|
12
|
+
ipt "-A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT"
|
13
|
+
end
|
14
|
+
|
15
|
+
def output
|
16
|
+
ipt "-A OUTPUT -m conntrack --ctstate INVALID -j DROP"
|
17
|
+
ipt "-A OUTPUT -m state --state ESTABLISHED -j ACCEPT"
|
18
|
+
|
19
|
+
# Allow SSH
|
20
|
+
ipt "-A OUTPUT -p tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT"
|
21
|
+
|
22
|
+
# Allow Loopback
|
23
|
+
ipt "-A OUTPUT -d #{@lo_addr}/8 -o #{@lo} -j ACCEPT"
|
24
|
+
|
25
|
+
# Default
|
26
|
+
ipt "-A OUTPUT -m conntrack --ctstate ESTABLISHED -j ACCEPT"
|
27
|
+
end
|
28
|
+
|
29
|
+
def all
|
30
|
+
ipt "-t filter -A OUTPUT -p udp -j ACCEPT"
|
31
|
+
ipt "-t filter -A OUTPUT -p icmp -j REJECT"
|
32
|
+
ipt "-P INPUT ACCEPT"
|
33
|
+
ipt "-P FORWARD ACCEPT"
|
34
|
+
ipt "-P OUTPUT ACCEPT"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
require 'interfacez'
|
2
|
+
|
3
|
+
module Spior
|
4
|
+
module Iptables
|
5
|
+
class Root
|
6
|
+
def initialize
|
7
|
+
@lo = Interfacez.loopback
|
8
|
+
@lo_addr = Interfacez.ipv4_address_of(@lo)
|
9
|
+
@i = Helpers::Exec.new("iptables")
|
10
|
+
Spior::Copy.new.save
|
11
|
+
end
|
12
|
+
|
13
|
+
def run!
|
14
|
+
bogus_tcp_flags
|
15
|
+
bad_packets
|
16
|
+
spoofing
|
17
|
+
redirect
|
18
|
+
input
|
19
|
+
output
|
20
|
+
all
|
21
|
+
end
|
22
|
+
|
23
|
+
def restart!
|
24
|
+
stop!
|
25
|
+
run!
|
26
|
+
end
|
27
|
+
|
28
|
+
def stop!
|
29
|
+
ipt "-F"
|
30
|
+
ipt "-X"
|
31
|
+
ipt "-t nat -F"
|
32
|
+
ipt "-t nat -X"
|
33
|
+
ipt "-t mangle -F"
|
34
|
+
ipt "-t mangle -X"
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def ipt(line)
|
40
|
+
@i.run("#{line}")
|
41
|
+
puts "added - #{@i} #{line}"
|
42
|
+
end
|
43
|
+
|
44
|
+
def redirect
|
45
|
+
end
|
46
|
+
|
47
|
+
def input
|
48
|
+
end
|
49
|
+
|
50
|
+
def output
|
51
|
+
end
|
52
|
+
|
53
|
+
def all
|
54
|
+
end
|
55
|
+
|
56
|
+
def bogus_tcp_flags
|
57
|
+
ipt "-t mangle -A PREROUTING -p tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG NONE -j DROP"
|
58
|
+
ipt "-t mangle -A PREROUTING -p tcp --tcp-flags FIN,SYN FIN,SYN -j DROP"
|
59
|
+
ipt "-t mangle -A PREROUTING -p tcp --tcp-flags SYN,RST SYN,RST -j DROP"
|
60
|
+
ipt "-t mangle -A PREROUTING -p tcp --tcp-flags FIN,RST FIN,RST -j DROP"
|
61
|
+
ipt "-t mangle -A PREROUTING -p tcp --tcp-flags FIN,ACK FIN -j DROP"
|
62
|
+
ipt "-t mangle -A PREROUTING -p tcp --tcp-flags ACK,URG URG -j DROP"
|
63
|
+
ipt "-t mangle -A PREROUTING -p tcp --tcp-flags ACK,FIN FIN -j DROP"
|
64
|
+
ipt "-t mangle -A PREROUTING -p tcp --tcp-flags ACK,PSH PSH -j DROP"
|
65
|
+
ipt "-t mangle -A PREROUTING -p tcp --tcp-flags ALL ALL -j DROP"
|
66
|
+
ipt "-t mangle -A PREROUTING -p tcp --tcp-flags ALL NONE -j DROP"
|
67
|
+
ipt "-t mangle -A PREROUTING -p tcp --tcp-flags ALL FIN,PSH,URG -j DROP"
|
68
|
+
ipt "-t mangle -A PREROUTING -p tcp --tcp-flags ALL SYN,FIN,PSH,URG -j DROP"
|
69
|
+
ipt "-t mangle -A PREROUTING -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP"
|
70
|
+
end
|
71
|
+
|
72
|
+
def bad_packets
|
73
|
+
# new packet not syn
|
74
|
+
ipt "-t mangle -A PREROUTING -p tcp ! --syn -m conntrack --ctstate NEW -j DROP"
|
75
|
+
# fragment packet
|
76
|
+
ipt "-A INPUT -f -j DROP"
|
77
|
+
# XMAS
|
78
|
+
ipt "-A INPUT -p tcp --tcp-flags ALL ALL -j DROP"
|
79
|
+
# null packet
|
80
|
+
ipt "-A INPUT -p tcp --tcp-flags ALL NONE -j DROP"
|
81
|
+
end
|
82
|
+
|
83
|
+
def spoofing
|
84
|
+
subs=["224.0.0.0/3", "169.254.0.0/16", "172.16.0.0/12", "192.0.2.0/24", "0.0.0.0/8", "240.0.0.0/5"]
|
85
|
+
subs.each do |sub|
|
86
|
+
ipt "-t mangle -A PREROUTING -s #{sub} -j DROP"
|
87
|
+
end
|
88
|
+
ipt "-t mangle -A PREROUTING -s #{@lo_addr}/8 ! -i #{@lo} -j DROP"
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module Spior
|
2
|
+
module Iptables
|
3
|
+
class Tor < Iptables::Root
|
4
|
+
def initialize
|
5
|
+
super
|
6
|
+
@tor = Spior::Tor::Info.new
|
7
|
+
@non_tor = ["#{@lo_addr}/8", "192.168.0.0/16", "172.16.0.0/12", "10.0.0.0/8"]
|
8
|
+
@tables = ["nat", "filter"]
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def redirect
|
14
|
+
@tables.each { |table|
|
15
|
+
target = "ACCEPT"
|
16
|
+
target = "RETURN" if table == "nat"
|
17
|
+
|
18
|
+
ipt "-t #{table} -F OUTPUT"
|
19
|
+
ipt "-t #{table} -A OUTPUT -m state --state ESTABLISHED -j #{target}"
|
20
|
+
ipt "-t #{table} -A OUTPUT -m owner --uid #{@tor.uid} -j #{target}"
|
21
|
+
|
22
|
+
match_dns_port = @tor.dns
|
23
|
+
if table == "nat"
|
24
|
+
target = "REDIRECT --to-ports #{@tor.dns}"
|
25
|
+
match_dns_port = "53"
|
26
|
+
end
|
27
|
+
|
28
|
+
ipt "-t #{table} -A OUTPUT -p udp --dport #{match_dns_port} -j #{target}"
|
29
|
+
ipt "-t #{table} -A OUTPUT -p tcp --dport #{match_dns_port} -j #{target}"
|
30
|
+
|
31
|
+
target = "REDIRECT --to-ports #{@tor.trans_port}" if table == "nat"
|
32
|
+
ipt "-t #{table} -A OUTPUT -d #{@tor.virt_addr} -p tcp -j #{target}"
|
33
|
+
|
34
|
+
target = "RETURN" if table == "nat"
|
35
|
+
@non_tor.each { |ip|
|
36
|
+
ipt "-t #{table} -A OUTPUT -d #{ip} -j #{target}"
|
37
|
+
}
|
38
|
+
|
39
|
+
target = "REDIRECT --to-ports #{@tor.trans_port}" if table == "nat"
|
40
|
+
ipt "-t #{table} -A OUTPUT -p tcp -j #{target}"
|
41
|
+
}
|
42
|
+
end
|
43
|
+
|
44
|
+
def input
|
45
|
+
# SSH
|
46
|
+
ipt "-A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT"
|
47
|
+
# Allow loopback
|
48
|
+
ipt "-A INPUT -i #{@lo} -j ACCEPT"
|
49
|
+
# Allow DNS lookups from connected clients and internet access through tor.
|
50
|
+
ipt "-A INPUT -p udp -m udp --dport #{@tor.dns} -j ACCEPT"
|
51
|
+
# Accept related
|
52
|
+
ipt "-A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT"
|
53
|
+
end
|
54
|
+
|
55
|
+
def all
|
56
|
+
ipt "-t filter -A OUTPUT -p udp -j REJECT"
|
57
|
+
ipt "-t filter -A OUTPUT -p icmp -j REJECT"
|
58
|
+
ipt "-P INPUT DROP"
|
59
|
+
ipt "-P FORWARD DROP"
|
60
|
+
ipt "-P OUTPUT DROP"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
data/lib/spior/menu.rb
CHANGED
@@ -1,10 +1,3 @@
|
|
1
|
-
require_relative 'msg'
|
2
|
-
require_relative 'iptables'
|
3
|
-
require_relative 'network'
|
4
|
-
require_relative 'reload'
|
5
|
-
require_relative 'clear'
|
6
|
-
require_relative 'status'
|
7
|
-
|
8
1
|
module Spior
|
9
2
|
module Menu
|
10
3
|
extend self
|
@@ -24,17 +17,16 @@ module Spior
|
|
24
17
|
puts
|
25
18
|
print ">> "
|
26
19
|
case gets.chomp
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
exit
|
20
|
+
when '1'
|
21
|
+
Spior::Iptables::Tor.new.run!
|
22
|
+
when '2'
|
23
|
+
Spior::Tor.restart
|
24
|
+
when '3'
|
25
|
+
Spior::Clear.all
|
26
|
+
when '4'
|
27
|
+
Spior::Status.info
|
28
|
+
when '5'
|
29
|
+
exit
|
38
30
|
end
|
39
31
|
end
|
40
32
|
end
|
@@ -47,11 +39,5 @@ module Spior
|
|
47
39
|
puts "┗━┛╹ ╹┗━┛╹┗╸"
|
48
40
|
# generated with toilet -F crop -f future spior
|
49
41
|
end
|
50
|
-
|
51
|
-
def check_network
|
52
|
-
if not @network
|
53
|
-
@network = Spior::Network.new
|
54
|
-
end
|
55
|
-
end
|
56
42
|
end
|
57
43
|
end
|
data/lib/spior/network.rb
CHANGED
data/lib/spior/options.rb
CHANGED
@@ -1,16 +1,11 @@
|
|
1
1
|
require 'optparse'
|
2
|
-
require_relative 'reload'
|
3
|
-
require_relative 'status'
|
4
|
-
require_relative 'clear'
|
5
|
-
require_relative 'menu'
|
6
2
|
|
7
3
|
module Spior
|
8
4
|
class Options
|
9
|
-
attr_reader :install , :
|
5
|
+
attr_reader :install , :tor , :persist
|
10
6
|
|
11
7
|
def initialize(argv)
|
12
8
|
@install = false
|
13
|
-
@mac = false
|
14
9
|
@tor = false
|
15
10
|
@persist = false
|
16
11
|
parse(argv)
|
@@ -24,24 +19,22 @@ module Spior
|
|
24
19
|
@install = true
|
25
20
|
end
|
26
21
|
|
27
|
-
opts.on("-n", "--net-card NAME", "The name of the target network card") do |net|
|
28
|
-
@interface = net
|
29
|
-
end
|
30
|
-
|
31
22
|
opts.on("-t", "--tor", "Redirect traffic through TOR") do
|
32
23
|
@tor = true
|
33
24
|
end
|
34
25
|
|
35
26
|
opts.on("-r", "--reload", "Reload TOR to change your ip") do
|
36
|
-
Spior::
|
27
|
+
Spior::Tor.restart
|
28
|
+
exit
|
37
29
|
end
|
38
30
|
|
39
|
-
opts.on("-c", "--
|
40
|
-
Spior::Clear
|
31
|
+
opts.on("-c", "--clearnet", "Reset iptables and return to clearnet navigation") do
|
32
|
+
Spior::Clear.all
|
41
33
|
end
|
42
34
|
|
43
35
|
opts.on("-s", "--status", "Look infos about your current ip") do
|
44
|
-
Spior::Status
|
36
|
+
Spior::Status.info
|
37
|
+
exit
|
45
38
|
end
|
46
39
|
|
47
40
|
opts.on("-p", "--persist", "Active Spior at every boot.") do
|
@@ -49,7 +42,7 @@ module Spior
|
|
49
42
|
end
|
50
43
|
|
51
44
|
opts.on("-m", "--menu", "Display an interactive menu") do
|
52
|
-
Spior::Menu
|
45
|
+
Spior::Menu.run
|
53
46
|
end
|
54
47
|
|
55
48
|
opts.on("-h", "--help", "Show this message") do
|
data/lib/spior/persist.rb
CHANGED
@@ -1,83 +1,50 @@
|
|
1
1
|
require 'nomansland'
|
2
2
|
require 'tty-which'
|
3
|
-
require_relative 'copy'
|
4
|
-
require_relative 'msg'
|
5
|
-
require_relative 'helpers'
|
6
3
|
|
7
4
|
module Spior
|
8
5
|
module Persist
|
9
6
|
extend self
|
10
7
|
|
11
|
-
def
|
12
|
-
@services=[ "tor", "iptables" ]
|
13
|
-
services
|
14
|
-
save_rules
|
15
|
-
search_for_systemd
|
16
|
-
end
|
17
|
-
|
18
|
-
private
|
19
|
-
|
20
|
-
# Install a systemd service where needed. TODO: test on more distrib
|
21
|
-
# no need on: archlinux
|
22
|
-
# need on: gentoo, debian,
|
23
|
-
def services
|
24
|
-
return if !TTY::Which.exist?('systemctl')
|
25
|
-
path_bin = "/sbin/iptables-restore"
|
26
|
-
path_rules = ""
|
8
|
+
def enable
|
27
9
|
case Nomansland::distro?
|
28
10
|
when :gentoo
|
29
|
-
|
30
|
-
|
31
|
-
|
11
|
+
for_gentoo
|
12
|
+
else
|
13
|
+
Msg.p "Your distro is not yet supported."
|
32
14
|
end
|
33
|
-
|
34
|
-
[Unit]
|
35
|
-
Description=IPv4 Packet Filtering Framework for Spior
|
36
|
-
Before=network-pre.target
|
37
|
-
Wants=network-pre.target
|
15
|
+
end
|
38
16
|
|
39
|
-
|
40
|
-
Type=oneshot
|
41
|
-
ExecStart=#{path_bin} #{path_rules}
|
42
|
-
ExecReload=#{path_bin} #{path_rules}
|
43
|
-
RemainAfterExit=yes
|
17
|
+
private
|
44
18
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
19
|
+
def for_gentoo
|
20
|
+
if TTY::Which.exist?('systemctl')
|
21
|
+
systemd_start("iptables-store")
|
22
|
+
systemd_enable("iptables-restore")
|
23
|
+
systemd_enable("tor")
|
24
|
+
else
|
25
|
+
system("sudo /etc/init.d/iptables save")
|
26
|
+
rc_upd = Helpers::Exec.new("rc-update")
|
27
|
+
rc_upd.run("rc-update add iptables boot")
|
28
|
+
rc_upd.run("rc-update add tor")
|
29
|
+
rc_upd.run("rc-update add tor default")
|
53
30
|
end
|
54
31
|
end
|
55
32
|
|
56
|
-
def
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
Msg.p "Search for service #{service}..."
|
63
|
-
`systemctl is-enabled #{service}`
|
64
|
-
if not $?.success? then
|
65
|
-
@systemctl.run("enable #{service}")
|
66
|
-
end
|
33
|
+
def systemd_enable(service)
|
34
|
+
systemctl = Helpers::Exec.new("systemctl")
|
35
|
+
Msg.p "Search for service #{service}..."
|
36
|
+
`systemctl is-enabled #{service}`
|
37
|
+
if not $?.success? then
|
38
|
+
systemctl.run("enable #{service}")
|
67
39
|
end
|
68
40
|
end
|
69
41
|
|
70
|
-
def
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
@systemctl.run("start iptables-store")
|
77
|
-
when :apt_get
|
78
|
-
@iptables_save.run("> /etc/iptables/rules.v4")
|
79
|
-
else
|
80
|
-
Msg.report "Fail for save iptables-rule, your system is not yet supported"
|
42
|
+
def systemd_start(service)
|
43
|
+
systemctl = Helpers::Exec.new("systemctl")
|
44
|
+
Msg.p "Search for service #{service}..."
|
45
|
+
`systemctl is-active #{service}`
|
46
|
+
if not $?.success? then
|
47
|
+
systemctl.run("start #{service}")
|
81
48
|
end
|
82
49
|
end
|
83
50
|
end
|
data/lib/spior/status.rb
CHANGED
@@ -1,20 +1,38 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
1
|
require 'open-uri'
|
2
|
+
require 'json'
|
4
3
|
|
5
4
|
module Spior
|
6
|
-
|
5
|
+
module Status
|
6
|
+
def self.enable
|
7
|
+
begin
|
8
|
+
status = "Disable"
|
9
|
+
api_check = "https://check.torproject.org/api/ip"
|
10
|
+
URI.open(api_check) do |l|
|
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}"
|
18
|
+
end
|
19
|
+
end
|
7
20
|
|
8
|
-
# TODO: if someone want help, i have trouble to make JSON.parse() work here
|
9
|
-
# the output is very very ugly !
|
10
21
|
def self.info
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
22
|
+
begin
|
23
|
+
api_check = "https://ipleak.net/json"
|
24
|
+
URI.open(api_check) do |l|
|
25
|
+
hash = JSON.parse l.read
|
26
|
+
puts
|
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}"
|
35
|
+
end
|
17
36
|
end
|
18
|
-
|
19
37
|
end
|
20
38
|
end
|