spior 0.1.2 → 0.1.6

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.
@@ -0,0 +1,59 @@
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
+ # Accept related
50
+ ipt "-A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT"
51
+ end
52
+
53
+ def all
54
+ ipt "-t filter -A OUTPUT -p udp -j REJECT"
55
+ ipt "-t filter -A OUTPUT -p icmp -j REJECT"
56
+ end
57
+ end
58
+ end
59
+ end
@@ -1,186 +1,8 @@
1
- require 'interfacez'
2
- require_relative 'tor'
3
- require_relative 'msg'
4
- require_relative 'helpers'
5
-
6
1
  module Spior
7
- class Iptables
8
-
9
- def self.tor(interface = false)
10
- initialize(interface)
11
- flush_rules
12
- bogus_tcp_flags
13
- bad_packets
14
- spoofing
15
- icmp
16
- dns
17
- nat
18
- input
19
- forward
20
- output
21
- drop_all
22
- end
23
-
24
- def self.flush_rules
25
- @i = Helpers::Exec.new("iptables")
26
- ipt "-F"
27
- ipt "-X"
28
- ipt "-t nat -F"
29
- ipt "-t nat -X"
30
- ipt "-t mangle -F"
31
- ipt "-t mangle -X"
32
- end
33
-
34
- private
35
-
36
- def self.initialize(interface)
37
- @lo = Interfacez.loopback
38
- @lo_addr = Interfacez.ipv4_address_of(@lo)
39
- @tor = Spior::Tor.new
40
- @non_tor = ["#{@lo_addr}/8", "10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"]
41
- @incoming = interface
42
- @incoming_addr = Interfacez.ipv4_address_of(@incoming)
43
- end
44
-
45
- def self.check_dep
46
- Spior::Copy::config_files
47
- end
48
-
49
- def self.ipt(line)
50
- @i.run("#{line}")
51
- #puts "added - #{@i} #{line}"
52
- end
53
-
54
- def self.drop_all
55
- ipt "-P INPUT DROP"
56
- ipt "-P FORWARD DROP"
57
- ipt "-P OUTPUT DROP"
58
- end
59
-
60
- def self.bogus_tcp_flags
61
- puts "bogus"
62
- ipt "-t mangle -A PREROUTING -p tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG NONE -j DROP"
63
- ipt "-t mangle -A PREROUTING -p tcp --tcp-flags FIN,SYN FIN,SYN -j DROP"
64
- ipt "-t mangle -A PREROUTING -p tcp --tcp-flags SYN,RST SYN,RST -j DROP"
65
- ipt "-t mangle -A PREROUTING -p tcp --tcp-flags FIN,RST FIN,RST -j DROP"
66
- ipt "-t mangle -A PREROUTING -p tcp --tcp-flags FIN,ACK FIN -j DROP"
67
- ipt "-t mangle -A PREROUTING -p tcp --tcp-flags ACK,URG URG -j DROP"
68
- ipt "-t mangle -A PREROUTING -p tcp --tcp-flags ACK,FIN FIN -j DROP"
69
- ipt "-t mangle -A PREROUTING -p tcp --tcp-flags ACK,PSH PSH -j DROP"
70
- ipt "-t mangle -A PREROUTING -p tcp --tcp-flags ALL ALL -j DROP"
71
- ipt "-t mangle -A PREROUTING -p tcp --tcp-flags ALL NONE -j DROP"
72
- ipt "-t mangle -A PREROUTING -p tcp --tcp-flags ALL FIN,PSH,URG -j DROP"
73
- ipt "-t mangle -A PREROUTING -p tcp --tcp-flags ALL SYN,FIN,PSH,URG -j DROP"
74
- ipt "-t mangle -A PREROUTING -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP"
75
- end
76
-
77
- def self.bad_packets
78
- puts "bad_packets"
79
- # new packet not syn
80
- ipt "-t mangle -A PREROUTING -p tcp ! --syn -m conntrack --ctstate NEW -j DROP"
81
- # fragment packet
82
- ipt "-A INPUT -f -j DROP"
83
- # XMAS
84
- ipt "-A INPUT -p tcp --tcp-flags ALL ALL -j DROP"
85
- # null packet
86
- ipt "-A INPUT -p tcp --tcp-flags ALL NONE -j DROP"
87
- end
88
-
89
- def self.spoofing
90
- 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"]
91
- subs.each do |sub|
92
- ipt "-t mangle -A PREROUTING -s #{sub} -j DROP"
93
- end
94
- ipt "-t mangle -A PREROUTING -s #{@lo_addr}/8 ! -i #{@lo} -j DROP"
95
- end
96
-
97
- def self.icmp
98
- puts "icmp"
99
- ipt "-N port-scanning"
100
- ipt "-A port-scanning -p tcp --tcp-flags SYN,ACK,FIN,RST RST -m limit --limit 1/s --limit-burst 2 -j RETURN"
101
- ipt "-A port-scanning -j DROP"
102
-
103
- ipt "-N syn_flood"
104
- ipt "-A INPUT -p tcp --syn -j syn_flood"
105
- ipt "-A syn_flood -m limit --limit 1/s --limit-burst 3 -j RETURN"
106
- ipt "-A syn_flood -j DROP"
107
-
108
- ipt "-A INPUT -p icmp -m limit --limit 1/s --limit-burst 1 -j ACCEPT"
109
- ipt "-A INPUT -p icmp -m limit --limit 1/s --limit-burst 1 -j LOG --log-prefix PING-DROP:"
110
- ipt "-A INPUT -p icmp -j DROP"
111
- ipt "-A OUTPUT -p icmp -j ACCEPT"
112
- end
113
-
114
- def self.dns
115
- puts "dns"
116
- ipt "-t nat -A PREROUTING ! -i #{@lo} -p udp -m udp --dport 53 -j REDIRECT --to-ports #{@tor.dns}"
117
- ipt "-t nat -A OUTPUT -p udp -m udp --dport 53 -j REDIRECT --to-ports #{@tor.dns}"
118
- ipt "-t nat -A OUTPUT -p tcp -m tcp --dport 53 -j REDIRECT --to-ports #{@tor.dns}"
119
- end
120
-
121
- def self.nat
122
- puts "nat"
123
- # nat .onion addresses
124
- ipt "-t nat -A OUTPUT -d #{@tor.virt_addr} -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -j REDIRECT --to-ports #{@tor.trans_port}"
125
-
126
- # Don't nat the Tor process, the loopback, or the local network
127
- ipt "-t nat -A OUTPUT -m owner --uid-owner #{@tor.uid} -j RETURN"
128
- ipt "-t nat -A OUTPUT -o #{@lo} -j RETURN"
129
-
130
- # Allow lan access for hosts in $non_tor
131
- @non_tor.each do |lan|
132
- ipt "-t nat -A OUTPUT -d #{lan} -j RETURN"
133
- end
134
-
135
- # Redirects all other pre-routing and output to Tor's TransPort
136
- ipt "-t nat -A OUTPUT -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -j REDIRECT --to-ports #{@tor.trans_port}"
137
-
138
- # Redirects all other pre-routing and output to Tor's TransPort
139
- ipt "-t nat -A OUTPUT -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -j REDIRECT --to-ports #{@tor.trans_port}"
140
- end
141
-
142
- def self.input
143
- puts "input"
144
- ipt "-A INPUT -i #{@incoming} -p tcp -s #{@incoming_addr} --dport 22 -m conntrack --ctstate NEW -j ACCEPT"
145
-
146
- # Allow loopback, rules
147
- ipt "-A INPUT -m state --state ESTABLISHED -j ACCEPT"
148
- ipt "-A INPUT -i #{@lo} -j ACCEPT"
149
-
150
- # Allow DNS lookups from connected clients and internet access through tor.
151
- ipt "-A INPUT -d #{@incoming_addr} -i #{@incoming} -p udp -m udp --dport #{@tor.dns} -j ACCEPT"
152
- ipt "-A INPUT -d #{@incoming_addr} -i #{@incoming} -p tcp -m tcp --dport #{@tor.trans_port} --tcp-flags FIN,SYN,RST,ACK SYN -j ACCEPT"
153
-
154
- # Default
155
- ipt "-A INPUT -j DROP"
156
- end
157
-
158
- def self.output
159
- puts "output"
160
- ipt "-A OUTPUT -m conntrack --ctstate INVALID -j LOG --log-prefix \"DROP INVALID \" --log-ip-options --log-tcp-options"
161
- ipt "-A OUTPUT -m conntrack --ctstate INVALID -j DROP"
162
- ipt "-A OUTPUT -m state --state ESTABLISHED -j ACCEPT"
163
-
164
- # output
165
- ipt "-A OUTPUT -m owner --uid-owner #{@tor.uid} -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -m state --state NEW -j ACCEPT"
166
-
167
- # Accept, allow loopback output
168
- ipt "-A OUTPUT -p tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT"
169
- ipt "-A OUTPUT -d #{@lo_addr}/32 -o #{@lo} -j ACCEPT"
170
-
171
- # tor transparent magic
172
- ipt "-A OUTPUT -d #{@lo_addr}/32 -p tcp -m tcp --dport #{@tor.trans_port} --tcp-flags FIN,SYN,RST,ACK SYN -j ACCEPT"
173
-
174
- ipt "-A OUTPUT -j DROP"
175
- end
176
-
177
- def self.forward
178
- puts "forward"
179
- ipt "-A FORWARD -m conntrack --ctstate INVALID -j LOG --log-prefix \"DROP INVALID \" --log-ip-options --log-tcp-options"
180
- ipt "-A FORWARD -m conntrack --ctstate INVALID -j DROP"
181
- ipt "-A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT"
182
- ipt "-A FORWARD -i #{@incoming} ! -s #{@incoming_addr} -j LOG --log-prefix \"SPOOFED PKT \""
183
- ipt "-A FORWARD -i #{@incoming} ! -s #{@incoming_addr} -j DROP"
184
- end
2
+ module Iptables
185
3
  end
186
4
  end
5
+
6
+ require_relative 'iptables/root'
7
+ require_relative 'iptables/tor'
8
+ require_relative 'iptables/default'
data/lib/spior/menu.rb CHANGED
@@ -1,11 +1,3 @@
1
- require_relative 'msg'
2
- require_relative 'mac'
3
- require_relative 'iptables'
4
- require_relative 'network'
5
- require_relative 'reload'
6
- require_relative 'clear'
7
- require_relative 'status'
8
-
9
1
  module Spior
10
2
  module Menu
11
3
  extend self
@@ -16,30 +8,25 @@ module Spior
16
8
  Msg.head
17
9
  puts %q{Please select an option:
18
10
 
19
- 1. Forge a new MAC address
20
- 2. Redirect traffic through tor
21
- 3. Reload tor and change your ip
22
- 4. Clear and restore your files
23
- 5. Check info on your current ip
24
- 6. Quit}
11
+ 1. Redirect traffic through tor
12
+ 2. Reload tor and change your ip
13
+ 3. Clear and restore your files
14
+ 4. Check info on your current ip
15
+ 5. Quit}
25
16
 
26
17
  puts
27
18
  print ">> "
28
19
  case gets.chomp
29
- when '1'
30
- check_network
31
- Spior::MAC::randomize(@network.card)
32
- when '2'
33
- check_network
34
- Spior::Iptables::tor(@network.card)
35
- when '3'
36
- Spior::Reload::tor
37
- when '4'
38
- Spior::Clear::all
39
- when '5'
40
- Spior::Status::info
41
- when '6'
42
- exit
20
+ when '1'
21
+ Spior::Iptables::Tor.new.run!
22
+ when '2'
23
+ Spior::Serice.restart
24
+ when '3'
25
+ Spior::Clear.all
26
+ when '4'
27
+ Spior::Status.info
28
+ when '5'
29
+ exit
43
30
  end
44
31
  end
45
32
  end
@@ -52,11 +39,5 @@ module Spior
52
39
  puts "┗━┛╹ ╹┗━┛╹┗╸"
53
40
  # generated with toilet -F crop -f future spior
54
41
  end
55
-
56
- def check_network
57
- if not @network
58
- @network = Spior::Network.new
59
- end
60
- end
61
42
  end
62
43
  end
data/lib/spior/msg.rb CHANGED
@@ -1,30 +1,28 @@
1
1
  require 'rainbow'
2
2
 
3
3
  module Msg
4
- def self.head
4
+ extend self
5
+
6
+ def head
5
7
  puts Rainbow("------------------------------------------------").cyan
6
8
  end
7
9
 
8
- def self.p(text)
10
+ def p(text)
9
11
  puts Rainbow("[").cyan + Rainbow("+").white + Rainbow("]").cyan + " " + text
10
12
  end
11
13
 
12
- def self.err(text)
14
+ def err(text)
13
15
  puts Rainbow("[").red + Rainbow("-").white + Rainbow("]").red + " " + text
14
16
  end
15
17
 
16
- def self.info(text)
18
+ def info(text)
17
19
  puts Rainbow("-").blue + Rainbow("-").white + Rainbow("-").blue + " " + text + " " + Rainbow("-").blue + Rainbow("-").white + Rainbow("-").blue
18
20
  end
19
21
 
20
- def self.report(text)
22
+ def report(text)
21
23
  puts ""
22
24
  info text
23
25
  puts "Please, report this issue at https://github.com/szorfein/spior/issues"
24
26
  puts ""
25
27
  end
26
-
27
- def self.for_no_systemd
28
- puts "Init system is not yet supported. You can contribute to add it."
29
- end
30
28
  end
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 , :mac , :interface , :tor , :persist
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)
@@ -20,32 +15,26 @@ module Spior
20
15
 
21
16
  def parse(argv)
22
17
  OptionParser.new do |opts|
23
- opts.on("-i", "--install", "Install and update dependencies") do
18
+ opts.on("-i", "--install", "Install the dependencies") do
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
- opts.on("-m", "--mac", "Change your mac") do
32
- @mac = true
33
- end
34
-
35
22
  opts.on("-t", "--tor", "Redirect traffic through TOR") do
36
23
  @tor = true
37
24
  end
38
25
 
39
26
  opts.on("-r", "--reload", "Reload TOR to change your ip") do
40
- Spior::Reload::tor
27
+ Spior::Service.restart
28
+ exit
41
29
  end
42
30
 
43
- opts.on("-c", "--clear", "Clear iptables rules and restore files") do
44
- Spior::Clear::all
31
+ opts.on("-c", "--clearnet", "Reset iptables and return to clearnet navigation") do
32
+ Spior::Clear.all
45
33
  end
46
34
 
47
35
  opts.on("-s", "--status", "Look infos about your current ip") do
48
- Spior::Status::info
36
+ Spior::Status.info
37
+ exit
49
38
  end
50
39
 
51
40
  opts.on("-p", "--persist", "Active Spior at every boot.") do
@@ -53,7 +42,7 @@ module Spior
53
42
  end
54
43
 
55
44
  opts.on("-m", "--menu", "Display an interactive menu") do
56
- Spior::Menu::run
45
+ Spior::Menu.run
57
46
  end
58
47
 
59
48
  opts.on("-h", "--help", "Show this message") do
data/lib/spior/persist.rb CHANGED
@@ -1,46 +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 all(card_name)
12
- @card_name = card_name
13
- @services=[ "tor", "iptables", "deceitmac@" + @card_name ]
14
- search_for_systemd
8
+ def enable
9
+ case Nomansland::distro?
10
+ when :gentoo
11
+ for_gentoo
12
+ else
13
+ Msg.p "Your distro is not yet supported."
14
+ end
15
15
  end
16
16
 
17
17
  private
18
18
 
19
- def search_for_systemd
20
- return if !TTY::Which.exist?('systemctl')
21
- @systemctl = Helpers::Exec.new("systemctl")
22
- @iptables_save = Helpers::Exec.new("iptables-save")
23
- Spior::Copy::systemd_services
24
- @services.each do |service|
25
- Msg.p "Search for service #{service}..."
26
- `systemctl is-enabled #{service}`
27
- if not $?.success? then
28
- @systemctl.run("enable #{service}")
29
- end
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")
30
30
  end
31
- iptables_systemd
32
31
  end
33
32
 
34
- def iptables_systemd
35
- case Nomansland::installer?
36
- when :pacman
37
- @iptables_save.run("-f /etc/iptables/iptables.rules")
38
- when :emerge
39
- @systemctl.run("start iptables-store")
40
- when :apt_get
41
- @iptables_save.run("> /etc/iptables/rules.v4")
42
- else
43
- Msg.report "Fail for save iptables-rule, your system is not yet supported"
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}")
39
+ end
40
+ end
41
+
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}")
44
48
  end
45
49
  end
46
50
  end
@@ -0,0 +1,21 @@
1
+ require 'tty-which'
2
+
3
+ module Spior
4
+ module Service
5
+ module_function
6
+
7
+ def restart
8
+ if TTY::Which.exist?('systemctl')
9
+ Helpers::Exec.new("systemctl").run("restart tor")
10
+ Msg.p "ip changed."
11
+ elsif TTY::Which.exist? 'sv'
12
+ Helpers::Exec.new('sv').run('restart tor')
13
+ Msg.p 'ip changed.'
14
+ elsif File.exist? '/etc/init.d/tor'
15
+ Helpers::Exec.new('/etc/init.d/tor').run('restart')
16
+ else
17
+ Msg.report "Don't known yet how to restart Tor for your system."
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,26 @@
1
+ require 'tty-which'
2
+
3
+ module Spior
4
+ module Service
5
+ module_function
6
+
7
+ def start
8
+ if TTY::Which.exist?('systemctl')
9
+ state = `systemctl is-active tor`.chomp
10
+ unless state == 'active'
11
+ Helpers::Exec.new("systemctl").run("start tor")
12
+ Msg.p "TOR started."
13
+ end
14
+ elsif TTY::Which.exist? 'sv'
15
+ unless File.exist? '/var/service/tor'
16
+ Helpers::Exec.new('ln').run('-s /etc/sv/tor /var/service/tor')
17
+ Msg.p "TOR started."
18
+ end
19
+ elsif File.exist? '/etc/init.d/tor'
20
+ Helpers::Exec.new('/etc/init.d/tor').run('start')
21
+ else
22
+ Msg.report "Don't known yet how to start Tor for your system."
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,7 @@
1
+ module Spior
2
+ module Service
3
+ end
4
+ end
5
+
6
+ require_relative 'service/start'
7
+ require_relative 'service/restart'
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
- class Status
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
- uri = URI.parse("https://ipleak.net/json")
12
- uri.open {|f|
13
- f.each_line {|line|
14
- p line.chomp.delete("/\",{}")
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