nub 0.0.119 → 0.0.125

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.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +0 -32
  3. data/lib/nub/net.rb +78 -16
  4. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d7c15f5f66c73221685a124f105c3cca8205d41155603111823e8d580783aea7
4
- data.tar.gz: 5d1bbe7937d9befa92a78237d6554993490e3e492b2dd75c5721e4457c2e630e
3
+ metadata.gz: fe85adf0021df868b46e1b8f36f38d6b9f3deb42edc9721629bf6a2b915b3701
4
+ data.tar.gz: 5988cdcaca7111a76b345f8c434f963a9730a37aac57dc9bb2a3e3818d381ff5
5
5
  SHA512:
6
- metadata.gz: 4e2d6a2b5344de24c51ddb4913dd1225de0da8e6aeead3a527138bf124bfbe96a309f50ce5cd4b5b572a33bcdaf048da9cde1197c7a4dfb76f9a037e80b740d9
7
- data.tar.gz: 11bb6954b62eb0326ac9015cd517808edaaabfeed0ec3d220448a80bd91b5ad84a03c8a94deed1c63f29d00a80eae5e3b1fe87fcc43290d902566de35393f0c9
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 when creating it
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
- if args.size == 1 && args.first.is_a?(Hash)
187
- network = args.first[:network] if args.first.key?(:network)
188
- host_veth = args.first[:host_veth] if args.first.key?(:host_veth)
189
- guest_veth = args.first[:guest_veth] if args.first.key?(:guest_veth)
190
- elsif args.size > 1
191
- host_veth = args.shift
192
- guest_veth = args.shift if args.any?
193
- network = args.shift if args.any?
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 not network.nameservers
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.119
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-21 00:00:00.000000000 Z
11
+ date: 2018-08-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: colorize