spior 0.1.4 → 0.1.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.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
|