nub 0.0.125 → 0.0.128
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.
- checksums.yaml +4 -4
- data/lib/nub/config.rb +1 -1
- metadata +2 -3
- data/lib/nub/:w +0 -374
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bc495fbfdb92d3b2cbd5f8b34373e4ffd7ccfc5f9ddfede0140d1e52c8a2e89a
|
4
|
+
data.tar.gz: 27067ccd9364da31e08077f0cedce3fcf46594c6f2522a115695e5d310e908bf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c16bb3b7b76f1d2c80a3bcc05044eb81105fa1014e33c15c82bfb1930b739cede6a40dd27606ee56bfcb846efdbb805bc574bdd4395f867994fcb21ccd9079ec
|
7
|
+
data.tar.gz: fb633b15decdf82c281d235a8e0fe1c1db04c30175cbef81a5680522d528cd87329b821525bced89e25aecc75681b6adace6438282038c5a511a4955d7a73158
|
data/lib/nub/config.rb
CHANGED
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.128
|
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-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: colorize
|
@@ -89,7 +89,6 @@ files:
|
|
89
89
|
- LICENSE
|
90
90
|
- README.md
|
91
91
|
- lib/nub.rb
|
92
|
-
- lib/nub/:w
|
93
92
|
- lib/nub/commander.rb
|
94
93
|
- lib/nub/config.rb
|
95
94
|
- lib/nub/core.rb
|
data/lib/nub/:w
DELETED
@@ -1,374 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
#MIT License
|
3
|
-
#Copyright (c) 2018 phR0ze
|
4
|
-
#
|
5
|
-
#Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
-
#of this software and associated documentation files (the "Software"), to deal
|
7
|
-
#in the Software without restriction, including without limitation the rights
|
8
|
-
#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
-
#copies of the Software, and to permit persons to whom the Software is
|
10
|
-
#furnished to do so, subject to the following conditions:
|
11
|
-
#
|
12
|
-
#The above copyright notice and this permission notice shall be included in all
|
13
|
-
#copies or substantial portions of the Software.
|
14
|
-
#
|
15
|
-
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
-
#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
-
#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
-
#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
-
#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
-
#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
-
#SOFTWARE.
|
22
|
-
|
23
|
-
require 'ostruct'
|
24
|
-
require 'ipaddr'
|
25
|
-
require_relative 'log'
|
26
|
-
require_relative 'sys'
|
27
|
-
require_relative 'module'
|
28
|
-
|
29
|
-
# Collection of network related helpers
|
30
|
-
module Net
|
31
|
-
extend self
|
32
|
-
mattr_accessor(:agents)
|
33
|
-
mattr_accessor(:namespace_subnet, :namespce_cidr)
|
34
|
-
|
35
|
-
@@namespace_cidr = "24"
|
36
|
-
@@namespace_subnet = "192.168.100.0"
|
37
|
-
|
38
|
-
@@agents = OpenStruct.new({
|
39
|
-
windows_ie_6: 'Windows IE 6',
|
40
|
-
windows_ie_7: 'Windows IE 7',
|
41
|
-
windows_mozilla: 'Windows Mozilla',
|
42
|
-
mac_safari: 'Mac Safari',
|
43
|
-
mac_firefox: 'Mac FireFox',
|
44
|
-
mac_mozilla: 'Mac Mozilla',
|
45
|
-
linux_mozilla: 'Linux Mozilla',
|
46
|
-
linux_firefox: 'Linux Firefox',
|
47
|
-
linux_konqueror: 'Linux Konqueror',
|
48
|
-
iphone: 'iPhone'
|
49
|
-
})
|
50
|
-
|
51
|
-
# Get fresh proxy from environment
|
52
|
-
def proxy
|
53
|
-
return OpenStruct.new({
|
54
|
-
ftp: ENV['ftp_proxy'],
|
55
|
-
http: ENV['http_proxy'],
|
56
|
-
https: ENV['https_proxy'],
|
57
|
-
no: ENV['no_proxy'],
|
58
|
-
uri: ENV['http_proxy'] ? ENV['http_proxy'].split(':')[0..-2] * ":" : nil,
|
59
|
-
port: ENV['http_proxy'] ? ENV['http_proxy'].split(':').last : nil
|
60
|
-
})
|
61
|
-
end
|
62
|
-
|
63
|
-
# Check if a proxy is set
|
64
|
-
def proxy?
|
65
|
-
return !self.proxy.http.nil?
|
66
|
-
end
|
67
|
-
|
68
|
-
# Get a shell export string for proxies
|
69
|
-
# @param proxy [String] to use rather than default
|
70
|
-
def proxy_export(*args)
|
71
|
-
proxy = args.any? ? args.first.to_s : nil
|
72
|
-
if proxy
|
73
|
-
({'ftp_proxy' => proxy,
|
74
|
-
'http_proxy' => proxy,
|
75
|
-
'https_proxy' => proxy
|
76
|
-
}.map{|k,v| "export #{k}=#{v}"} * ';') + ";"
|
77
|
-
elsif self.proxy?
|
78
|
-
(self.proxy.to_h.map{|k,v| (![:uri, :port].include?(k) && v) ? "export #{k}_proxy=#{v}" : nil}.compact * ';') + ";"
|
79
|
-
else
|
80
|
-
return nil
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
# Check if the system is configured for the kernel to forward ip traffic
|
85
|
-
def ip_forward?
|
86
|
-
return File.read('/proc/sys/net/ipv4/ip_forward').include?('1')
|
87
|
-
end
|
88
|
-
|
89
|
-
# Determine the primary nic on the machine
|
90
|
-
# based off default routing to google.com
|
91
|
-
# @returns [String] nic identified as primary
|
92
|
-
def primary_nic
|
93
|
-
out = `ip route`
|
94
|
-
return out[/default via.*dev (.*) proto/, 1]
|
95
|
-
end
|
96
|
-
|
97
|
-
# Increment the given ip address
|
98
|
-
# @param ip [String] ip address to increment
|
99
|
-
# @param i [int] optionally increment by given number
|
100
|
-
# @returns [String] incremented ip
|
101
|
-
def ipinc(ip, *args)
|
102
|
-
i = args.any? ? args.first.to_i : 1
|
103
|
-
ip_i = IPAddr.new(ip).to_i + i
|
104
|
-
return [24, 16, 8, 0].collect{|x| (ip_i >> x) & 255}.join('.')
|
105
|
-
end
|
106
|
-
|
107
|
-
# Decrement the given ip address
|
108
|
-
# @param ip [String] ip address to decrement
|
109
|
-
# @param i [int] optionally decrement by given number
|
110
|
-
# @returns [String] decremented ip
|
111
|
-
def ipdec(ip, *args)
|
112
|
-
i = args.any? ? args.first.to_i : 1
|
113
|
-
ip_i = IPAddr.new(ip).to_i - i
|
114
|
-
return [24, 16, 8, 0].collect{|x| (ip_i >> x) & 255}.join('.')
|
115
|
-
end
|
116
|
-
|
117
|
-
# ----------------------------------------------------------------------------
|
118
|
-
# Namespace related helpers
|
119
|
-
# ----------------------------------------------------------------------------
|
120
|
-
|
121
|
-
# Virtual Ethernet NIC object
|
122
|
-
# @param name [String] of the veth e.g. veth1
|
123
|
-
# @param ip [String] of the veth e.g. 192.168.100.1
|
124
|
-
Veth = Struct.new(:name, :ip)
|
125
|
-
|
126
|
-
# Network object
|
127
|
-
# @param subnet [String] of the network e.g. 192.168.100.0
|
128
|
-
# @param cidr [String] of the network
|
129
|
-
# @param nic [String] to use for NAT etc...
|
130
|
-
# @param nameservers [Array[String]] to optionally use for new network else uses hosts
|
131
|
-
Network = Struct.new(:subnet, :cidr, :nic, :nameservers)
|
132
|
-
|
133
|
-
# Get all namespaces
|
134
|
-
# @returns [Array] of namespace names
|
135
|
-
def namespaces
|
136
|
-
return Dir[File.join("/var/run/netns", "*")].map{|x| File.basename(x)}
|
137
|
-
end
|
138
|
-
|
139
|
-
# Get the current nameservers in use
|
140
|
-
# @param filename [String] to use instead of /etc/resolv.conf
|
141
|
-
# @returns [Array] of name server ips
|
142
|
-
def nameservers(*args)
|
143
|
-
filename = args.any? ? args.first.to_s : '/etc/resolv.conf'
|
144
|
-
|
145
|
-
result = []
|
146
|
-
if File.file?(filename)
|
147
|
-
File.readlines(filename).each{|line|
|
148
|
-
if line[/nameserver/]
|
149
|
-
result << line[/nameserver\s+(.*)/, 1]
|
150
|
-
end
|
151
|
-
}
|
152
|
-
end
|
153
|
-
return result
|
154
|
-
end
|
155
|
-
|
156
|
-
# Check that the namespace has connectivity to the outside world
|
157
|
-
# using a simple curl on google
|
158
|
-
# @param namespace [String] name to use when creating it
|
159
|
-
# @param target [String] ip or dns name to use for check
|
160
|
-
# @param proxy [String] to use rather than default
|
161
|
-
def namespace_connectivity?(namespace, target, *args)
|
162
|
-
success = false
|
163
|
-
proxy = args.any? ? args.first.to_s : nil
|
164
|
-
Log.info("Checking namespace #{namespace.colorize(:cyan)} for connectivity to #{target}", newline:false)
|
165
|
-
|
166
|
-
if self.namespaces.include?(namespace)
|
167
|
-
ping = "curl -m 3 -sL -w \"%{http_code}\" #{target} -o /dev/null"
|
168
|
-
return Sys.exec_status("ip netns exec #{namespace} bash -c '#{self.proxy_export(proxy)}#{ping}'", die:false, check:"200")
|
169
|
-
else
|
170
|
-
Sys.exec_status(":", die:false, check:"200")
|
171
|
-
Log.warn("Namespace #{namespace} doesn't exist!")
|
172
|
-
end
|
173
|
-
end
|
174
|
-
|
175
|
-
# Get namespace details using defaults for missing arguments
|
176
|
-
# veth names are generated incrementally using the '<ns>_vethN' naming pattern
|
177
|
-
# veth ips are generated based off @@namespace_subnet/@@namespace_cidr incrementally
|
178
|
-
# network subnet and cidr default and namespaces and nic are looked up
|
179
|
-
# @param namespace [String] name to use when creating it
|
180
|
-
# @returns [host_veth, guest_veth, network]
|
181
|
-
def namespace_details(namespace, *args)
|
182
|
-
host_veth, guest_veth = Veth.new, Veth.new
|
183
|
-
network = Network.new(@@namespace_subnet, @@namespace_cidr, true)
|
184
|
-
|
185
|
-
# Rebuild namespace objects from disk where possible
|
186
|
-
if self.namespaces.include?(namespace)
|
187
|
-
|
188
|
-
# Rebuild veths from guest
|
189
|
-
out = `ip netns exec #{namespace} ip a show type veth`
|
190
|
-
if hostif = out[/([\d]+):\s+.*@if[\d]+/, 1] ? "if" + out[/([\d]+):\s+.*@if[\d]+/, 1] : nil
|
191
|
-
guest_veth.name = out[/ (.*)@if[\d]+/, 1]
|
192
|
-
guest_veth.ip = out[/inet\s+([\d]+\.[\d]+\.[\d]+\.[\d]+).*/, 1]
|
193
|
-
host_veth.name = out[/ (.*)@#{hostif}/, 1]
|
194
|
-
host_veth.ip = self.ipdec(guest_veth.ip)
|
195
|
-
|
196
|
-
# Rebuild veths from host
|
197
|
-
else
|
198
|
-
# out = `ip a show type veth`
|
199
|
-
# host_str = out[/inet(.*)#{host_veth.name}/, 1]
|
200
|
-
# host_ip = host_str[/\s*([\d]+\.[\d]+\.[\d]+\.[\d]+\/[\d]+).*/, 1] if host_str
|
201
|
-
# host_veth.ip = host_ip[/(.*)\/[\d]+/, 1] if host_ip
|
202
|
-
end
|
203
|
-
|
204
|
-
# Rebuild network object
|
205
|
-
namespace_conf = File.join("/etc/netns", namespace, "resolv.conf")
|
206
|
-
network.nameservers = self.nameservers(namespace_conf) if File.exists?(namespace_conf)
|
207
|
-
network.cidr = host_ip[/\/([\d]+)/, 1] if host_ip
|
208
|
-
network.subnet = IPAddr.new(host_veth.ip).mask(network.cidr).to_s
|
209
|
-
out = `iptables -S`
|
210
|
-
if out.include?(host_veth.name)
|
211
|
-
network.nic = out[/-A FORWARD -i #{host_veth.name} -o (.*) -j ACCEPT/, 1]
|
212
|
-
end
|
213
|
-
|
214
|
-
# Handle args as either as positional or named
|
215
|
-
else
|
216
|
-
if args.size == 1 && args.first.is_a?(Hash)
|
217
|
-
network = args.first[:network] if args.first.key?(:network)
|
218
|
-
host_veth = args.first[:host_veth] if args.first.key?(:host_veth)
|
219
|
-
guest_veth = args.first[:guest_veth] if args.first.key?(:guest_veth)
|
220
|
-
elsif args.size > 1
|
221
|
-
host_veth = args.shift
|
222
|
-
guest_veth = args.shift if args.any?
|
223
|
-
network = args.shift if args.any?
|
224
|
-
end
|
225
|
-
end
|
226
|
-
|
227
|
-
# Populate missing information
|
228
|
-
nss = self.namespaces
|
229
|
-
i = (nss.include?(namespace) ? nss.size - 1 : nss.size) * 2 + 1
|
230
|
-
host_veth.name = "#{namespace}_veth#{i}" if !host_veth.name
|
231
|
-
host_veth.ip = self.ipinc(@@namespace_subnet, i) if !host_veth.ip
|
232
|
-
guest_veth.name = "#{namespace}_veth#{i + 1}" if !guest_veth.name
|
233
|
-
guest_veth.ip = "#{self.ipinc(host_veth.ip)}" if !guest_veth.ip
|
234
|
-
network.nic = self.primary_nic if network.nic == true
|
235
|
-
network.nameservers = self.nameservers if not network.nameservers
|
236
|
-
|
237
|
-
return host_veth, guest_veth, network
|
238
|
-
end
|
239
|
-
|
240
|
-
# Create a network namespace with the given name
|
241
|
-
# Params can be given as ordered positional args or named args
|
242
|
-
#
|
243
|
-
# @param namespace [String] name to use when creating it
|
244
|
-
# @param host_veth [Veth] describes the veth to create for the host side
|
245
|
-
# @param guest_veth [Veth] describes the veth to create for the guest side
|
246
|
-
# @param network [Network] describes the network to share.
|
247
|
-
# If the nic param is nil NAT is not enabled. If nic is true then the primary nic is dynamically
|
248
|
-
# looked up else use user given If nameservers are not given the host nameservers will be used
|
249
|
-
#def create_namespace(namespace, host_veth, guest_veth, network)
|
250
|
-
def create_namespace(namespace, *args)
|
251
|
-
host_veth, guest_veth, network = self.namespace_details(namespace, args)
|
252
|
-
|
253
|
-
# Ensure namespace i.e. /var/run/netns/<namespace> exists
|
254
|
-
if !self.namespaces.include?(namespace)
|
255
|
-
Log.info("Creating Network Namespace #{namespace.colorize(:cyan)}", newline:false)
|
256
|
-
Sys.exec_status("ip netns add #{namespace}")
|
257
|
-
end
|
258
|
-
|
259
|
-
# Ensure loopback device is running inside the pnamespace
|
260
|
-
if `ip netns exec #{namespace} ip a`.include?("state DOWN")
|
261
|
-
Log.info("Start loopback interface in namespace", newline:false)
|
262
|
-
Sys.exec_status("ip netns exec #{namespace} ip link set lo up")
|
263
|
-
end
|
264
|
-
|
265
|
-
# Create a virtual ethernet pair to communicate across namespaces
|
266
|
-
# by default they will both be in the root namespace until one is assigned to another
|
267
|
-
# e.g. host:192.168.100.1 and guest:192.168.100.2 communicating in network:192.168.100.0
|
268
|
-
if !`ip a`.include?(host_veth.name)
|
269
|
-
msg = "Create namespace veths #{host_veth.name.colorize(:cyan)} for #{'root'.colorize(:cyan)} "
|
270
|
-
msg += "and #{guest_veth.name.colorize(:cyan)} for #{namespace.colorize(:cyan)}"
|
271
|
-
Log.info(msg, newline:false)
|
272
|
-
Sys.exec_status("ip link add #{host_veth.name} type veth peer name #{guest_veth.name}")
|
273
|
-
Log.info("Assign veth #{guest_veth.name.colorize(:cyan)} to namespace #{namespace.colorize(:cyan)}", newline:false)
|
274
|
-
Sys.exec_status("ip link set #{guest_veth.name} netns #{namespace}")
|
275
|
-
end
|
276
|
-
|
277
|
-
# Assign IPv4 addresses and start up the new veth interfaces
|
278
|
-
# sudo ping #{host_veth.ip} and sudo netns exec #{namespace} ping #{guest_veth.ip} should work now
|
279
|
-
if !`ip a`.include?(host_veth.ip)
|
280
|
-
Log.info("Assign ip #{host_veth.ip.colorize(:cyan)} and start #{host_veth.name.colorize(:cyan)}", newline:false)
|
281
|
-
Sys.exec_status("ifconfig #{host_veth.name} #{File.join(host_veth.ip, network.cidr)} up")
|
282
|
-
end
|
283
|
-
if !`ip netns exec #{namespace} ip a`.include?(guest_veth.ip)
|
284
|
-
Log.info("Assign ip #{guest_veth.ip.colorize(:cyan)} and start #{guest_veth.name.colorize(:cyan)}", newline:false)
|
285
|
-
Sys.exec_status("ip netns exec #{namespace} ifconfig #{guest_veth.name} #{File.join(guest_veth.ip, network.cidr)} up")
|
286
|
-
end
|
287
|
-
|
288
|
-
# Configure host veth as guest's default route leaving namespace
|
289
|
-
if !`ip netns exec #{namespace} ip route`.include?('default')
|
290
|
-
Log.info("Set default route for traffic leaving namespace #{namespace.colorize(:cyan)} to #{host_veth.ip.colorize(:cyan)}", newline:false)
|
291
|
-
Sys.exec_status("ip netns exec #{namespace} ip route add default via #{host_veth.ip} dev #{guest_veth.name}")
|
292
|
-
end
|
293
|
-
|
294
|
-
# NAT guest veth behind host veth to share internet access on host with guest
|
295
|
-
# Note: to see current forward rules use: sudo iptables -S
|
296
|
-
if network.nic
|
297
|
-
if !`iptables -t nat -S`.include?(File.join(network.subnet, network.cidr))
|
298
|
-
Log.info("Enable NAT on host for namespace #{File.join(network.subnet, network.cidr).colorize(:cyan)}", newline:false)
|
299
|
-
Sys.exec_status("iptables -t nat -A POSTROUTING -s #{File.join(network.subnet, network.cidr)} -o #{network.nic} -j MASQUERADE")
|
300
|
-
end
|
301
|
-
if !`iptables -S`.include?("-A FORWARD -i #{network.nic}")
|
302
|
-
Log.info("Allow forwarding to #{namespace.colorize(:cyan)} from #{network.nic.colorize(:cyan)}", newline:false)
|
303
|
-
Sys.exec_status("iptables -A FORWARD -i #{network.nic} -o #{host_veth.name} -j ACCEPT")
|
304
|
-
end
|
305
|
-
if !`iptables -S`.include?("-A FORWARD -i #{host_veth.name}")
|
306
|
-
Log.info("Allow forwarding from #{namespace.colorize(:cyan)} to #{network.nic.colorize(:cyan)}", newline:false)
|
307
|
-
Sys.exec_status("iptables -A FORWARD -i #{host_veth.name} -o #{network.nic} -j ACCEPT")
|
308
|
-
end
|
309
|
-
end
|
310
|
-
|
311
|
-
# Configure nameserver to use in Network namespace
|
312
|
-
namespace_conf = File.join("/etc/netns", namespace)
|
313
|
-
if !File.exists?(namespace_conf) && network.nameservers
|
314
|
-
Log.info("Creating nameserver config #{namespace_conf}", newline:false)
|
315
|
-
Sys.exec_status("mkdir -p #{namespace_conf}")
|
316
|
-
network.nameservers.each{|x|
|
317
|
-
Log.info("Adding nameserver #{x.colorize(:cyan)} to config", newline:false)
|
318
|
-
Sys.exec_status("echo 'nameserver #{x}' >> /etc/netns/#{namespace}/resolv.conf")
|
319
|
-
}
|
320
|
-
end
|
321
|
-
end
|
322
|
-
|
323
|
-
# Delete the given network namespace
|
324
|
-
# @param namespace [String] name to use when creating it
|
325
|
-
def delete_namespace(namespace)
|
326
|
-
host_veth, guest_veth, network = self.namespace_details(namespace)
|
327
|
-
|
328
|
-
# Remove nameserver config for network namespace
|
329
|
-
namespace_conf = File.join("/etc/netns", namespace)
|
330
|
-
if File.exists?(namespace_conf)
|
331
|
-
Log.info("Removing nameserver config #{namespace_conf.colorize(:cyan)}", newline:false)
|
332
|
-
Sys.exec_status("rm -rf #{namespace_conf}")
|
333
|
-
end
|
334
|
-
|
335
|
-
# Remove NAT and iptables forwarding allowances
|
336
|
-
if network.nic
|
337
|
-
if `iptables -t nat -S`.include?(File.join(network.subnet, network.cidr))
|
338
|
-
Log.info("Removing NAT on host for namespace #{File.join(network.subnet, network.cidr).colorize(:cyan)}", newline:false)
|
339
|
-
Sys.exec_status("iptables -t nat -D POSTROUTING -s #{File.join(network.subnet, network.cidr)} -o #{network.nic} -j MASQUERADE")
|
340
|
-
end
|
341
|
-
if `iptables -S`.include?("-A FORWARD -i #{network.nic}")
|
342
|
-
Log.info("Remove forwarding to #{namespace.colorize(:cyan)} from #{host_veth.ip.colorize(:cyan)}", newline:false)
|
343
|
-
Sys.exec_status("iptables -D FORWARD -i #{network.nic} -o #{host_veth.name} -j ACCEPT")
|
344
|
-
end
|
345
|
-
if `iptables -S`.include?("-A FORWARD -i #{host_veth.name}")
|
346
|
-
Log.info("Remove forwarding from #{namespace.colorize(:cyan)} to #{host_veth.ip.colorize(:cyan)}", newline:false)
|
347
|
-
Sys.exec_status("iptables -D FORWARD -i #{host_veth.name} -o #{network.nic} -j ACCEPT")
|
348
|
-
end
|
349
|
-
end
|
350
|
-
|
351
|
-
# Remove veths (virtual ethernet interfaces)
|
352
|
-
if `ip a`.include?(host_veth.name)
|
353
|
-
Log.info("Removing veth interface #{host_veth.name.colorize(:cyan)} for namespace", newline:false)
|
354
|
-
Sys.exec_status("ip link delete #{host_veth.name}")
|
355
|
-
end
|
356
|
-
|
357
|
-
# Remove namespace
|
358
|
-
if self.namespaces.include?(namespace)
|
359
|
-
Log.info("Removing namespace #{namespace.colorize(:cyan)}", newline:false)
|
360
|
-
Sys.exec_status("ip netns delete #{namespace}")
|
361
|
-
end
|
362
|
-
end
|
363
|
-
|
364
|
-
# Execute in the namespace
|
365
|
-
# @param namespace [String] to execut within
|
366
|
-
# @param cmd [String] command to execute
|
367
|
-
# @param proxy [String] to use rather than default
|
368
|
-
def namespace_exec(namespace, cmd, *args)
|
369
|
-
proxy = args.any? ? args.first.to_s : nil
|
370
|
-
return `ip netns exec #{namespace} bash -c '#{self.proxy_export(proxy)}#{cmd}'`
|
371
|
-
end
|
372
|
-
end
|
373
|
-
|
374
|
-
# vim: ft=ruby:ts=2:sw=2:sts=2
|