nub 0.0.119 → 0.0.125
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +0 -32
- data/lib/nub/net.rb +78 -16
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fe85adf0021df868b46e1b8f36f38d6b9f3deb42edc9721629bf6a2b915b3701
|
4
|
+
data.tar.gz: 5988cdcaca7111a76b345f8c434f963a9730a37aac57dc9bb2a3e3818d381ff5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 11ff5cd8004bca05799bd22dff24780fb06174fbe30f2292c550480b485da23125d92eedea4d8719094e19abbbb912d914dbfcd972b105758a133e4dded008aa
|
7
|
+
data.tar.gz: 0995e0bc2ba7f9e02e391e3cea2cc2a8771396934b3b82ad1aafa34b375acc8fb5e384787e28fa32c1165af51e4ab08c6a687dda969152dcf693a54231b2d5a5
|
data/README.md
CHANGED
@@ -33,7 +33,6 @@ Collection of ruby utils I've used in several of my projects and wanted re-usabl
|
|
33
33
|
* [Module Extensions](#module-extensions)
|
34
34
|
* [Net Module](#net-module)
|
35
35
|
* [Network Namespaces](#network-namespaces)
|
36
|
-
* [Teamviewer Example](#teamviewer-example)
|
37
36
|
* [PIA VPN Example](#pia-vpn-example)
|
38
37
|
* [Network Proxy](#network-proxy)
|
39
38
|
* [Pacman Module](#pacman-module)
|
@@ -459,37 +458,6 @@ sudo ip netns exec foo ping www.google.com
|
|
459
458
|
In the following sub sections I'll show you how to automated this complicated setup using the
|
460
459
|
***Net*** ruby module.
|
461
460
|
|
462
|
-
#### TeamViewer Example <a name="teamviewer-example"></a>
|
463
|
-
In this example I'll be showing you how to isolate Teamviewer such that Teamviewer is only able to
|
464
|
-
bind to the veth IPv4 address that we create for it rather than all network interfaces on the host.
|
465
|
-
This will allow you to have a local Teamviewer instance running and accessible from your network
|
466
|
-
facing IP but also to be able to SSH port forward other Teamviewer instances to your veth addresses.
|
467
|
-
|
468
|
-
```bash
|
469
|
-
require_relative '../lib/nub/net'
|
470
|
-
require_relative '../lib/nub/user'
|
471
|
-
!puts("Must be root to execute") and exit if not User.root?
|
472
|
-
|
473
|
-
if ARGV.size > 0
|
474
|
-
cmd = ARGV[0]
|
475
|
-
app = ARGV[1]
|
476
|
-
namespace = "foo"
|
477
|
-
host_veth = Net::Veth.new("veth1", "192.168.100.1")
|
478
|
-
guest_veth = Net::Veth.new("veth2", "192.168.100.2")
|
479
|
-
network = Net::Network.new("192.168.100.0", "24")
|
480
|
-
if cmd == "isolate"
|
481
|
-
Net.create_namespace(namespace, host_veth, guest_veth, network, "enp+")
|
482
|
-
Net.namespace_connectivity?(namespace, "google.com")
|
483
|
-
Net.namespace_exec(namespace, "lxterminal")
|
484
|
-
elsif cmd == "destroy"
|
485
|
-
Net.delete_namespace(namespace, host_veth, network, "enp+")
|
486
|
-
end
|
487
|
-
else
|
488
|
-
puts("Isolate: #{$0} isolate <app>")
|
489
|
-
puts("Destroy: #{$0} destroy")
|
490
|
-
end
|
491
|
-
```
|
492
|
-
|
493
461
|
#### PIA VPN Example <a name="pia-vpn-example"></a>
|
494
462
|
```ruby
|
495
463
|
WIP
|
data/lib/nub/net.rb
CHANGED
@@ -22,6 +22,8 @@
|
|
22
22
|
|
23
23
|
require 'ostruct'
|
24
24
|
require 'ipaddr'
|
25
|
+
require 'socket'
|
26
|
+
require 'timeout'
|
25
27
|
require_relative 'log'
|
26
28
|
require_relative 'sys'
|
27
29
|
require_relative 'module'
|
@@ -114,6 +116,24 @@ module Net
|
|
114
116
|
return [24, 16, 8, 0].collect{|x| (ip_i >> x) & 255}.join('.')
|
115
117
|
end
|
116
118
|
|
119
|
+
# Check if the given ip:port is open
|
120
|
+
# @param ip [String] to check
|
121
|
+
# @param port [Int] to check
|
122
|
+
# @param timeout [Int] to wait when dead
|
123
|
+
def port_open?(ip, port, *args)
|
124
|
+
sec = args.any? ? args.first.to_i : 0.1
|
125
|
+
Timeout::timeout(sec){
|
126
|
+
begin
|
127
|
+
TCPSocket.new(ip, port).close
|
128
|
+
true
|
129
|
+
rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH
|
130
|
+
false
|
131
|
+
end
|
132
|
+
}
|
133
|
+
rescue Timeout::Error
|
134
|
+
false
|
135
|
+
end
|
136
|
+
|
117
137
|
# ----------------------------------------------------------------------------
|
118
138
|
# Namespace related helpers
|
119
139
|
# ----------------------------------------------------------------------------
|
@@ -172,36 +192,78 @@ module Net
|
|
172
192
|
end
|
173
193
|
end
|
174
194
|
|
195
|
+
# Get veths for namespace
|
196
|
+
# @param namespace [String] name to use for lookup
|
197
|
+
# @returns [host_veth, guest_veth]
|
198
|
+
def namespace_veths(namespace)
|
199
|
+
host, guest = Veth.new, Veth.new
|
200
|
+
if self.namespaces.include?(namespace)
|
201
|
+
|
202
|
+
# Lookup guest side
|
203
|
+
out = `ip netns exec #{namespace} ip a show type veth`
|
204
|
+
host_i = out[/([\d]+):\s+.*@if[\d]+/, 1]
|
205
|
+
if host_i
|
206
|
+
guest.name = out[/ (.*)@if[\d]+/, 1]
|
207
|
+
guest.ip = out[/inet\s+([\d]+\.[\d]+\.[\d]+\.[\d]+).*/, 1]
|
208
|
+
|
209
|
+
# Lookup host side
|
210
|
+
out = `ip a show type veth`
|
211
|
+
host.name = out[/ (.*)@if#{host_i}/, 1]
|
212
|
+
host_ip = out[/inet(.*)#{host.name}/, 1][/\s*([\d]+\.[\d]+\.[\d]+\.[\d]+\/[\d]+).*/, 1]
|
213
|
+
host.ip = host_ip[/(.*)\/[\d]+/, 1]
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
return host, guest
|
218
|
+
end
|
219
|
+
|
220
|
+
# Get next available pair of veth ips
|
221
|
+
# @returns ips [Array] of next available ips
|
222
|
+
def namespace_next_veth_ips
|
223
|
+
used = []
|
224
|
+
self.namespaces.each{|ns|
|
225
|
+
used += self.namespace_veths(ns).select{|x| x.ip}.map{|x| x.ip.split('.').last.to_i}
|
226
|
+
}
|
227
|
+
return ((1..255).to_a - used)[0..1].map{|x| self.ipinc(@@namespace_subnet, x)}
|
228
|
+
end
|
229
|
+
|
175
230
|
# Get namespace details using defaults for missing arguments
|
176
231
|
# veth names are generated using the '<ns>_<type>' naming pattern
|
177
232
|
# veth ips are generated based off @@namespace_subnet/@@namespace_cidr incrementally
|
178
233
|
# network subnet and cidr default and namespaces and nic are looked up
|
179
|
-
# @param namespace [String] name to use
|
234
|
+
# @param namespace [String] name to use for details
|
180
235
|
# @returns [host_veth, guest_veth, network]
|
181
236
|
def namespace_details(namespace, *args)
|
182
237
|
host_veth, guest_veth = Veth.new, Veth.new
|
183
238
|
network = Network.new(@@namespace_subnet, @@namespace_cidr, true)
|
184
239
|
|
240
|
+
# Pull from existing namespace first
|
241
|
+
if self.namespaces.include?(namespace)
|
242
|
+
host_veth, guest_veth = self.namespace_veths(namespace)
|
243
|
+
|
185
244
|
# Handle args as either as positional or named
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
245
|
+
else
|
246
|
+
if args.size == 1 && args.first.is_a?(Hash)
|
247
|
+
network = args.first[:network] if args.first.key?(:network)
|
248
|
+
host_veth = args.first[:host_veth] if args.first.key?(:host_veth)
|
249
|
+
guest_veth = args.first[:guest_veth] if args.first.key?(:guest_veth)
|
250
|
+
elsif args.size > 1
|
251
|
+
host_veth = args.shift
|
252
|
+
guest_veth = args.shift if args.any?
|
253
|
+
network = args.shift if args.any?
|
254
|
+
end
|
194
255
|
end
|
195
256
|
|
196
257
|
# Populate missing information
|
197
|
-
nss = self.namespaces
|
198
|
-
i = (nss.include?(namespace) ? nss.size - 1 : nss.size) * 2 + 1
|
199
258
|
host_veth.name = "#{namespace}_host" if !host_veth.name
|
200
|
-
host_veth.ip = self.ipinc(@@namespace_subnet, i) if !host_veth.ip
|
201
259
|
guest_veth.name = "#{namespace}_guest" if !guest_veth.name
|
202
|
-
guest_veth.ip = "#{self.ipinc(host_veth.ip)}" if !guest_veth.ip
|
203
260
|
network.nic = self.primary_nic if network.nic == true
|
204
|
-
network.nameservers = self.nameservers if
|
261
|
+
network.nameservers = self.nameservers if !network.nameservers
|
262
|
+
if !host_veth.ip or !guest_veth.ip
|
263
|
+
host_ip, guest_ip = self.namespace_next_veth_ips
|
264
|
+
host_veth.ip = host_ip if !host_veth.ip
|
265
|
+
guest_veth.ip = guest_ip if !guest_veth.ip
|
266
|
+
end
|
205
267
|
|
206
268
|
return host_veth, guest_veth, network
|
207
269
|
end
|
@@ -313,11 +375,11 @@ module Net
|
|
313
375
|
Log.info("Removing NAT on host for namespace #{File.join(network.subnet, network.cidr).colorize(:cyan)}", newline:false)
|
314
376
|
Sys.exec_status("iptables -t nat -D POSTROUTING -s #{File.join(network.subnet, network.cidr)} -o #{network.nic} -j MASQUERADE")
|
315
377
|
end
|
316
|
-
if `iptables -S`.include?("-A FORWARD -i #{network.nic}")
|
378
|
+
if `iptables -S`.include?("-A FORWARD -i #{network.nic} -o #{host_veth.name}")
|
317
379
|
Log.info("Remove forwarding to #{namespace.colorize(:cyan)} from #{host_veth.ip.colorize(:cyan)}", newline:false)
|
318
380
|
Sys.exec_status("iptables -D FORWARD -i #{network.nic} -o #{host_veth.name} -j ACCEPT")
|
319
381
|
end
|
320
|
-
if `iptables -S`.include?("-A FORWARD -i #{host_veth.name}")
|
382
|
+
if `iptables -S`.include?("-A FORWARD -i #{host_veth.name} -o #{network.nic}")
|
321
383
|
Log.info("Remove forwarding from #{namespace.colorize(:cyan)} to #{host_veth.ip.colorize(:cyan)}", newline:false)
|
322
384
|
Sys.exec_status("iptables -D FORWARD -i #{host_veth.name} -o #{network.nic} -j ACCEPT")
|
323
385
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nub
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.125
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Patrick Crummett
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-08-
|
11
|
+
date: 2018-08-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: colorize
|