knife-bastion 1.0.0

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,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: cde0ad1420a7e4754cbd8a540b711217f7547382
4
+ data.tar.gz: e99a6bad8478a5ea09b294dbbe882e62dac8ccbe
5
+ SHA512:
6
+ metadata.gz: 0b21d9651473242ddfed9b7de693057020b3b4e2253b317eacab1e22ea9963783adc53eb1f567a119ca64d02dce244b336a4c7a63f29b6e8b2af55ef60f7d19b
7
+ data.tar.gz: 6bd170228b796ee6195706d30817c86277314818dd753262161595612c94ea1290b5617884f8548295b7f0c487fa72be381be9da3a8043f333dcc78c764fd7c4
@@ -0,0 +1,2 @@
1
+ a�Q �c�U�^_��Pt�HRWVˢ#���ļ�t����z0�1��<K��4E�S"7�X�Uա�(�\�0#��*7H�a��f��<��oE}�׏�����`������T&F�
2
+ ,� ��х�����f��C��f��R�$2������� �T)Jo��
Binary file
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+
11
+ *.gem
12
+
13
+ .ruby-gemset
14
+ .ruby-version
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in knife-bastion.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013-2016 Eligible
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,98 @@
1
+ # knife-bastion
2
+
3
+ This plugin allows Knife to access Chef server over a secure SSH connection,
4
+ without exposing Chef server port to your VPN network.
5
+
6
+ ## Installation
7
+
8
+ Add this line to your Chef repository's Gemfile:
9
+
10
+ ```ruby
11
+ gem 'knife-bastion'
12
+ ```
13
+
14
+ And then execute:
15
+
16
+ $ bundle
17
+
18
+ Or install it yourself as:
19
+
20
+ $ gem install knife-bastion
21
+
22
+ ## Usage
23
+
24
+ Configure your bastion server in `.chef/knife.rb` (at the bottom):
25
+
26
+ ```ruby
27
+ # ...
28
+ # your knife configurations goes here
29
+ # ...
30
+
31
+ # Bastion host SSH settings
32
+ knife[:bastion_host] = "bastion.mycorp.net"
33
+ knife[:bastion_user] = ENV["MYCORP_USER"] || ENV["CHEF_USER"] || ENV["USER"]
34
+
35
+ # If you have multiple networks, that require different MFA tokens, specify
36
+ # each network name here. (This configuration is referenced to clarify the
37
+ # token a user should employ.)
38
+ # knife[:bastion_network] = "mynet"
39
+
40
+ # By default, the proxy server is created on port 4443. You may configure the
41
+ # local bastion port here:
42
+ # knife[:bastion_local_port] = 4443
43
+
44
+ require "knife-bastion/activate"
45
+ ```
46
+
47
+ Now, your workflow will look like this:
48
+
49
+ 1. Run `knife bastion start` - this command will establish SSH connection to
50
+ bastion box for 10 minutes, and create a SOCKS proxy on port `4443`, that
51
+ will forward all Chef requests to Chef server via bastion box.
52
+ 2. Use Chef to do your work.
53
+ 3. At any time you can use `knife bastion status` - which will verify the proxy
54
+ and make sure everything works as expected.
55
+ 4. After you finished, run `knife bastion stop` to shutdown the connection
56
+ and turn off the proxy. If you forget to do this, it will die automatically
57
+ after 10 minutes.
58
+
59
+ Sometimes when you work on a big change, default timeout of 10 minutes is too short.
60
+ You can increase timeout with `--timeout` flag:
61
+
62
+ ```
63
+ knife bastion start --timeout 1800
64
+ ```
65
+
66
+ Maximum timeout is 3600 (1 hour) for security reasons. You can re-establish bastion
67
+ connection by executing `knife bastion start` (if the connection is currently active,
68
+ it will be forcibly closed.)
69
+
70
+ ### Bastion troubleshooting
71
+
72
+ If something is not right, you need to ensure you have access to bastion box.
73
+ Try connecting to `bastion.mycorp.net` via SSH:
74
+
75
+ ```bash
76
+ ssh ${MYCORP_USER-$USER}@bastion.mycorp.net
77
+ ```
78
+
79
+ Check current bastion connection status (it will tell you if there is anything
80
+ wrong with your box):
81
+
82
+ ```
83
+ knife bastion status
84
+ ```
85
+
86
+ ## Contributing
87
+
88
+ 1. Fork it
89
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
90
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
91
+ 4. Push to the branch (`git push origin my-new-feature`)
92
+ 5. Create new Pull Request
93
+
94
+ Bug reports and pull requests are welcome on GitHub at https://github.com/eligible/knife-bastion.
95
+
96
+ ## License
97
+
98
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,21 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIDfDCCAmSgAwIBAgIBATANBgkqhkiG9w0BAQUFADBCMREwDwYDVQQDDAhzZWN1
3
+ cml0eTEYMBYGCgmSJomT8ixkARkWCGVsaWdpYmxlMRMwEQYKCZImiZPyLGQBGRYD
4
+ Y29tMB4XDTE2MDgyMjIxNTI0NVoXDTE3MDgyMjIxNTI0NVowQjERMA8GA1UEAwwI
5
+ c2VjdXJpdHkxGDAWBgoJkiaJk/IsZAEZFghlbGlnaWJsZTETMBEGCgmSJomT8ixk
6
+ ARkWA2NvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKyXvxbyCjdJ
7
+ eUPxJzt0cBv+fk9xnXq1Gu+EiFLayUAoADC9KtNDPRLe8Gd0yK5UmQD8F0wL89D4
8
+ y8vEXOm5hfHpgG7qQ01S11SRM7ksgId8OM0MyZkBTBcvpPqTyU06dbyRSy7Ir4Tn
9
+ Ro4Qb5+iOfZk3gcE9+StsJYn7l8mQFRHOZVgf8kVaAVTR8FWMLr3PMgKHsHiFJnn
10
+ Jm7eFlvQPQ8Mf56WnX4fPCO/caNqM4RFRHTjW+LYan3KsA7mg/FAt7LstONfS422
11
+ sUv0EhwprWRF1483e7b6KBcXhrk8RK447JRyKzqfw9jPONl/d5XodFGGesZ/XNHK
12
+ d0vvWDsmRSUCAwEAAaN9MHswCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAwHQYDVR0O
13
+ BBYEFGKTLK26F60J6VzTer7W4T/gMN2SMCAGA1UdEQQZMBeBFXNlY3VyaXR5QGVs
14
+ aWdpYmxlLmNvbTAgBgNVHRIEGTAXgRVzZWN1cml0eUBlbGlnaWJsZS5jb20wDQYJ
15
+ KoZIhvcNAQEFBQADggEBAF6VvkLEzKE9CPmQ4UXS0aHlRNwCVhSOpYeBfXWVVQqJ
16
+ ez7ftmxXLFGZ8N1wHxM7gEBFKCOB3Cu80F1uioxVMEPJAg1TT7t17GWNorG0aP7g
17
+ W5iMS2bfdLMFv8Z9Cljvn12ba+2tTn7hrzplf8gW/sxlaP3Q1lK/2cpiKqFVHLNJ
18
+ AR7q+NSrOmenHnTiKB4wTD3bRw0lv8iMVOnL97EQ/j8zp7m7dR3bJaGf5xLYeYkc
19
+ DHSQkPQADqf52XlDQ7I6fBAn6E2bH38Wvwpu593AvE02KRKqaK8XEtBBldE4d/It
20
+ 2ysZ/sPJras9LFb2MpjJNRCdXr3z2ed6QwuLnsyEfuk=
21
+ -----END CERTIFICATE-----
@@ -0,0 +1,31 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'knife-bastion/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "knife-bastion"
8
+ spec.version = Knife::Bastion::VERSION
9
+ spec.authors = ["Dmytro Shteflyuk"]
10
+ spec.email = ["dmytro@eligible.com"]
11
+
12
+ spec.summary = %q{Access Chef securely via bastion server.}
13
+ spec.description = %q{Protect your Chef server by restricting direct access to Chef HTTPS port to be only accessible from your internal network.}
14
+ spec.homepage = "https://github.com/eligible/knife-bastion"
15
+ spec.license = "MIT"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
+ spec.bindir = "exe"
19
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.cert_chain = ['certs/eligible.pem']
23
+ spec.signing_key = File.expand_path("~/.ssh/gem-eligible.pem") if $0 =~ /gem\z/
24
+
25
+ spec.add_runtime_dependency 'chef'
26
+ spec.add_runtime_dependency 'highline'
27
+ spec.add_runtime_dependency 'socksify'
28
+
29
+ spec.add_development_dependency "bundler", "~> 1.12"
30
+ spec.add_development_dependency "rake", "~> 10.0"
31
+ end
@@ -0,0 +1,75 @@
1
+ require 'chef/knife'
2
+
3
+ class Chef
4
+ class Knife
5
+ class BastionBase < Knife
6
+ include Chef::Mixin::ShellOut
7
+
8
+ def initialize_params
9
+ @bastion_user = Chef::Config[:knife][:bastion_user] || ENV['CHEF_USER'] || ENV['USER']
10
+ @bastion_host = Chef::Config[:knife][:bastion_host]
11
+ @bastion_network = Chef::Config[:knife][:bastion_network]
12
+ @chef_host = URI.parse(Chef::Config[:chef_server_url]).host
13
+ @local_port = Chef::Config[:knife][:bastion_local_port] || 4443
14
+ end
15
+
16
+ def tunnel_pid(local_port, raise_on_closed_port = true)
17
+ # Check if local port is open, get proxy process PID
18
+ pid_result = shell_out("lsof -nPt -i4TCP:#{local_port} -sTCP:LISTEN")
19
+ unless pid_result.status.success?
20
+ if raise_on_closed_port
21
+ ui.fatal "Tunnel is not open on port #{local_port}"
22
+ abort
23
+ end
24
+ return nil
25
+ end
26
+ proxy_pid = pid_result.stdout.chomp
27
+
28
+ # Verify tunnel destination
29
+ bastion_ip_addr = Resolv.getaddress(@bastion_host)
30
+ dest_result = shell_out("lsof -an -p #{proxy_pid} -i4@#{bastion_ip_addr}:ssh")
31
+ unless dest_result.status.success?
32
+ ui.fatal "There is a process with PID #{proxy_pid} listening on port #{local_port}, but it does not look like a tunnel"
33
+ abort
34
+ end
35
+
36
+ proxy_pid
37
+ end
38
+
39
+ def print_tunnel_info(header, timeout: nil, pid: nil)
40
+ ui.info <<-INFO
41
+ #{header}
42
+ * Bastion host: #{ui.color "#{@bastion_user}@#{@bastion_host}", [:bold, :white]}
43
+ * Chef host: #{ui.color @chef_host, [:bold, :white]}
44
+ * Local port: #{ui.color @local_port.to_s, [:bold, :white]}
45
+ INFO
46
+ if timeout
47
+ ui.info <<-INFO
48
+ * Timeout: #{ui.color timeout.to_s, [:bold, :white]} seconds
49
+ INFO
50
+ end
51
+ if pid
52
+ ui.info <<-INFO
53
+ * Proxy PID: #{ui.color pid.to_s, [:bold, :white]}
54
+ INFO
55
+ end
56
+ end
57
+
58
+ def run
59
+ initialize_params
60
+
61
+ # Retrieve proxy process PID. Raises an error if something is wrong
62
+ proxy_pid = tunnel_pid(@local_port)
63
+ print_tunnel_info("Found an esablished tunnel:", pid: proxy_pid)
64
+
65
+ require 'socksify'
66
+ TCPSocket::socks_server = "127.0.0.1"
67
+ TCPSocket::socks_port = @local_port
68
+
69
+ # This line will raise an exception if tunnel is broken
70
+ rest.get_rest("/policies")
71
+ ui.info ui.color("OK: ", :green) + "The tunnel is up and running"
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,83 @@
1
+ require_relative 'bastion_base'
2
+
3
+ class Chef
4
+ class Knife
5
+ class BastionStart < BastionBase
6
+ option :timeout,
7
+ long: "--timeout SECONDS",
8
+ description: "Sets the tunnel life time, in seconds (10 minutes by default)",
9
+ default: 600,
10
+ proc: lambda { |s| s.to_i }
11
+
12
+ deps do
13
+ require 'shellwords'
14
+ end
15
+
16
+ banner "knife bastion start (options)"
17
+ category "bastion"
18
+
19
+ def initialize_params
20
+ super
21
+
22
+ @timeout = config[:timeout]
23
+ @timeout = 600 if @timeout < 1 # timeout should be greater than 0
24
+ @timeout = 3600 if @timeout > 3600 # timeout should be less than 1 hour
25
+ end
26
+
27
+ def run
28
+ initialize_params
29
+
30
+ # Check if proxy is already running and restart it
31
+ kill_proxy_if_running
32
+
33
+ print_tunnel_info("Creating a tunnel to Chef server:", timeout: @timeout)
34
+
35
+ ui.info "Establishing connection to #{ui.color @bastion_host, [:bold, :white]}"
36
+ ui.warn "Please make sure to use your #{ui.color @bastion_network, [:bold, :magenta]} token" if @bastion_network
37
+
38
+ start_proxy
39
+ end
40
+
41
+ def kill_proxy_if_running
42
+ proxy_pid = tunnel_pid(@local_port, false)
43
+ if proxy_pid
44
+ ui.warn "Proxy on #{@local_port} is up and running. Restarting it"
45
+ shell_out!("kill -9 '#{proxy_pid}'")
46
+ end
47
+ end
48
+
49
+ def start_proxy
50
+ # Not using shell_out! here because it disables tty via Process.setsid,
51
+ # so it will not be possible to enter password/token for bastion host.
52
+ system ssh_proxy_command(@timeout)
53
+
54
+ if $?.exitstatus == 0
55
+ ui.info ui.color("OK: ", :green) + "Successfully started proxy on port #{@local_port}"
56
+ else
57
+ ui.fatal "Failed to start proxy"
58
+ end
59
+ end
60
+
61
+ def ssh_proxy_command(timeout)
62
+ cmd = [
63
+ "/usr/bin/ssh",
64
+ # go to background just before command execution
65
+ "-f",
66
+ # prevent reading from stdin
67
+ "-n",
68
+ # application-level port forwarding (SOCKS proxy)
69
+ "-D", "127.0.0.1:#{@local_port}",
70
+ # wait for all remote port forwards to be successfully established
71
+ "-o", "ExitOnForwardFailure=yes",
72
+ # Disable sharing of multiple connections
73
+ "-o", "ControlPath=none",
74
+ # SSH host to connect to
75
+ "#{@bastion_user}@#{@bastion_host}",
76
+ # Enforce tunnel timeout
77
+ "sleep #{timeout}"
78
+ ]
79
+ Shellwords.join(cmd)
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,28 @@
1
+ require_relative 'bastion_base'
2
+
3
+ class Chef
4
+ class Knife
5
+ class BastionStatus < BastionBase
6
+ include Chef::Mixin::ShellOut
7
+
8
+ banner "knife bastion status (options)"
9
+ category "bastion"
10
+
11
+ def run
12
+ initialize_params
13
+
14
+ # Retrieve proxy process PID. Raises an error if something is wrong
15
+ proxy_pid = tunnel_pid(@local_port)
16
+ print_tunnel_info("Found an esablished tunnel:", pid: proxy_pid)
17
+
18
+ require 'socksify'
19
+ TCPSocket::socks_server = "127.0.0.1"
20
+ TCPSocket::socks_port = @local_port
21
+
22
+ # This line will raise an exception if tunnel is broken
23
+ rest.get_rest("/policies")
24
+ ui.info ui.color("OK: ", :green) + "The tunnel is up and running"
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,23 @@
1
+ require_relative 'bastion_base'
2
+
3
+ class Chef
4
+ class Knife
5
+ class BastionStop < BastionBase
6
+ include Chef::Mixin::ShellOut
7
+
8
+ banner "knife bastion stop (options)"
9
+ category "bastion"
10
+
11
+ def run
12
+ initialize_params
13
+
14
+ # Retrieve proxy process PID. Raises an error if something is wrong
15
+ pid = tunnel_pid(@local_port)
16
+
17
+ shell_out!("kill -9 '#{pid}'")
18
+
19
+ ui.info ui.color("OK: ", :green) + "Tunnel closed, you're safe now"
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,4 @@
1
+ # Only activate socks proxy for Knife
2
+ if defined?(Chef::Application::Knife)
3
+ require_relative 'chef_socks_proxy'
4
+ end
@@ -0,0 +1,62 @@
1
+ # Load socksify gem, required to make Chef work with SOCKS proxy
2
+ begin
3
+ require 'socksify'
4
+ rescue LoadError
5
+ puts HighLine.color("FATAL:", [:bold, :red]) + " Failed to load #{HighLine.color("socksify", [:bold, :magenta])} gem. Please run #{HighLine.color("bundle install", [:bold, :magenta])} to continue"
6
+ # Hard exit to skip Chef exception reporting
7
+ exit! 1
8
+ end
9
+
10
+ # Simple class, that delegates all the calls to the base client object, except
11
+ # for `request`. The latter is overwritten to first configure SOCKS proxy,
12
+ # and if connection fails - show warning about the bastion setup.
13
+ class BastionChefClientProxy < BasicObject
14
+ NETWORK_ERRORS = [
15
+ ::SocketError,
16
+ ::Errno::ETIMEDOUT,
17
+ ::Errno::ECONNRESET,
18
+ ::Errno::ECONNREFUSED,
19
+ ::Timeout::Error,
20
+ ::OpenSSL::SSL::SSLError,
21
+ ]
22
+
23
+ def initialize(client)
24
+ @client = client
25
+ end
26
+
27
+ def request(*args, &block)
28
+ with_socks_proxy do
29
+ @client.request(*args, &block)
30
+ end
31
+ end
32
+
33
+ def method_missing(method, *args, &block)
34
+ @client.send(method, *args, &block)
35
+ end
36
+
37
+ def with_socks_proxy
38
+ old_socks_server, old_socks_port = ::TCPSocket::socks_server, ::TCPSocket::socks_port
39
+ ::TCPSocket::socks_server, ::TCPSocket::socks_port = '127.0.0.1', ::Chef::Config[:knife][:bastion_local_port] || 4443
40
+ yield
41
+ rescue *NETWORK_ERRORS
42
+ puts ::HighLine.color("WARNING:", [:bold, :red]) + " Failed to contact Chef server!"
43
+ puts "You might need to start bastion connection with #{::HighLine.color("knife bastion start", [:bold, :magenta])} to access Chef."
44
+ puts
45
+ raise
46
+ ensure
47
+ ::TCPSocket::socks_server, ::TCPSocket::socks_port = old_socks_server, old_socks_port
48
+ end
49
+ end
50
+
51
+ # Override `http_client` method in `Chef::HTTP` to return proxy object instead
52
+ # of normal client object.
53
+ Chef::HTTP.class_eval do
54
+ alias_method :http_client_without_bastion, :http_client
55
+ protected :http_client_without_bastion
56
+
57
+ protected
58
+
59
+ def http_client(*args)
60
+ BastionChefClientProxy.new(http_client_without_bastion(*args))
61
+ end
62
+ end
@@ -0,0 +1,6 @@
1
+ module Knife
2
+ module Bastion
3
+ VERSION = "1.0.0"
4
+ MAJOR, MINOR, TINY = VERSION.split('.')
5
+ end
6
+ end
metadata ADDED
@@ -0,0 +1,151 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: knife-bastion
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Dmytro Shteflyuk
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain:
11
+ - |
12
+ -----BEGIN CERTIFICATE-----
13
+ MIIDfDCCAmSgAwIBAgIBATANBgkqhkiG9w0BAQUFADBCMREwDwYDVQQDDAhzZWN1
14
+ cml0eTEYMBYGCgmSJomT8ixkARkWCGVsaWdpYmxlMRMwEQYKCZImiZPyLGQBGRYD
15
+ Y29tMB4XDTE2MDgyMjIxNTI0NVoXDTE3MDgyMjIxNTI0NVowQjERMA8GA1UEAwwI
16
+ c2VjdXJpdHkxGDAWBgoJkiaJk/IsZAEZFghlbGlnaWJsZTETMBEGCgmSJomT8ixk
17
+ ARkWA2NvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKyXvxbyCjdJ
18
+ eUPxJzt0cBv+fk9xnXq1Gu+EiFLayUAoADC9KtNDPRLe8Gd0yK5UmQD8F0wL89D4
19
+ y8vEXOm5hfHpgG7qQ01S11SRM7ksgId8OM0MyZkBTBcvpPqTyU06dbyRSy7Ir4Tn
20
+ Ro4Qb5+iOfZk3gcE9+StsJYn7l8mQFRHOZVgf8kVaAVTR8FWMLr3PMgKHsHiFJnn
21
+ Jm7eFlvQPQ8Mf56WnX4fPCO/caNqM4RFRHTjW+LYan3KsA7mg/FAt7LstONfS422
22
+ sUv0EhwprWRF1483e7b6KBcXhrk8RK447JRyKzqfw9jPONl/d5XodFGGesZ/XNHK
23
+ d0vvWDsmRSUCAwEAAaN9MHswCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAwHQYDVR0O
24
+ BBYEFGKTLK26F60J6VzTer7W4T/gMN2SMCAGA1UdEQQZMBeBFXNlY3VyaXR5QGVs
25
+ aWdpYmxlLmNvbTAgBgNVHRIEGTAXgRVzZWN1cml0eUBlbGlnaWJsZS5jb20wDQYJ
26
+ KoZIhvcNAQEFBQADggEBAF6VvkLEzKE9CPmQ4UXS0aHlRNwCVhSOpYeBfXWVVQqJ
27
+ ez7ftmxXLFGZ8N1wHxM7gEBFKCOB3Cu80F1uioxVMEPJAg1TT7t17GWNorG0aP7g
28
+ W5iMS2bfdLMFv8Z9Cljvn12ba+2tTn7hrzplf8gW/sxlaP3Q1lK/2cpiKqFVHLNJ
29
+ AR7q+NSrOmenHnTiKB4wTD3bRw0lv8iMVOnL97EQ/j8zp7m7dR3bJaGf5xLYeYkc
30
+ DHSQkPQADqf52XlDQ7I6fBAn6E2bH38Wvwpu593AvE02KRKqaK8XEtBBldE4d/It
31
+ 2ysZ/sPJras9LFb2MpjJNRCdXr3z2ed6QwuLnsyEfuk=
32
+ -----END CERTIFICATE-----
33
+ date: 2016-08-22 00:00:00.000000000 Z
34
+ dependencies:
35
+ - !ruby/object:Gem::Dependency
36
+ name: chef
37
+ requirement: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ type: :runtime
43
+ prerelease: false
44
+ version_requirements: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ - !ruby/object:Gem::Dependency
50
+ name: highline
51
+ requirement: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ type: :runtime
57
+ prerelease: false
58
+ version_requirements: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ - !ruby/object:Gem::Dependency
64
+ name: socksify
65
+ requirement: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :runtime
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ - !ruby/object:Gem::Dependency
78
+ name: bundler
79
+ requirement: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - "~>"
82
+ - !ruby/object:Gem::Version
83
+ version: '1.12'
84
+ type: :development
85
+ prerelease: false
86
+ version_requirements: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - "~>"
89
+ - !ruby/object:Gem::Version
90
+ version: '1.12'
91
+ - !ruby/object:Gem::Dependency
92
+ name: rake
93
+ requirement: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - "~>"
96
+ - !ruby/object:Gem::Version
97
+ version: '10.0'
98
+ type: :development
99
+ prerelease: false
100
+ version_requirements: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - "~>"
103
+ - !ruby/object:Gem::Version
104
+ version: '10.0'
105
+ description: Protect your Chef server by restricting direct access to Chef HTTPS port
106
+ to be only accessible from your internal network.
107
+ email:
108
+ - dmytro@eligible.com
109
+ executables: []
110
+ extensions: []
111
+ extra_rdoc_files: []
112
+ files:
113
+ - ".gitignore"
114
+ - Gemfile
115
+ - LICENSE.txt
116
+ - README.md
117
+ - Rakefile
118
+ - certs/eligible.pem
119
+ - knife-bastion.gemspec
120
+ - lib/chef/knife/bastion_base.rb
121
+ - lib/chef/knife/bastion_start.rb
122
+ - lib/chef/knife/bastion_status.rb
123
+ - lib/chef/knife/bastion_stop.rb
124
+ - lib/knife-bastion/activate.rb
125
+ - lib/knife-bastion/chef_socks_proxy.rb
126
+ - lib/knife-bastion/version.rb
127
+ homepage: https://github.com/eligible/knife-bastion
128
+ licenses:
129
+ - MIT
130
+ metadata: {}
131
+ post_install_message:
132
+ rdoc_options: []
133
+ require_paths:
134
+ - lib
135
+ required_ruby_version: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - ">="
138
+ - !ruby/object:Gem::Version
139
+ version: '0'
140
+ required_rubygems_version: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - ">="
143
+ - !ruby/object:Gem::Version
144
+ version: '0'
145
+ requirements: []
146
+ rubyforge_project:
147
+ rubygems_version: 2.4.5.1
148
+ signing_key:
149
+ specification_version: 4
150
+ summary: Access Chef securely via bastion server.
151
+ test_files: []
Binary file