nub 0.0.119 → 0.0.125

Sign up to get free protection for your applications and to get access to all the features.
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