Skip to content

Commit

Permalink
Add mTLS to opi clients
Browse files Browse the repository at this point in the history
Signed-off-by: Kalai Wei <[email protected]>
Co-authored-by: Kalai Wei <[email protected]>
  • Loading branch information
2 people authored and monamohebbi committed May 31, 2019
1 parent 32572a4 commit 2068e57
Show file tree
Hide file tree
Showing 5 changed files with 176 additions and 0 deletions.
8 changes: 8 additions & 0 deletions lib/cloud_controller/opi/base_client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,14 @@ class BaseClient
def initialize(config)
@config = config
@client = HTTPClient.new(base_url: url)
opi_config = config.get(:opi)
client_cert_file = opi_config[:client_cert_file]
client_key_file = opi_config[:client_key_file]
ca_file = opi_config[:ca_file]
if client_cert_file && client_key_file && ca_file
client.ssl_config.add_trust_ca(ca_file)
client.ssl_config.set_client_cert_file(client_cert_file, client_key_file)
end
end

private
Expand Down
17 changes: 17 additions & 0 deletions spec/fixtures/certs/opi_client.crt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
-----BEGIN CERTIFICATE-----
MIICpjCCAY4CCQDBHE4Oe2sSWTANBgkqhkiG9w0BAQsFADAUMRIwEAYDVQQDDAls
b2NhbGhvc3QwIBcNMTkwNTI4MjM0NDQ0WhgPMjExOTA1MDQyMzQ0NDRaMBQxEjAQ
BgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
ALEZDdlz4/Y3hxbkCeFO+ryZXLSXy1URO6RL74eDIAI2232194W9Is6ty1th2urT
7IJFdPdgPxZp57OTv6qJCpyySocrQKdWVOD3UodN0vSY0ThfBAlkWyUmi8ERV+s8
0qCsTlFUP8c6POyQ0E7PNnxtK6HmTDJONnVsXEL4c3C56c/TYnS3ATjrbpLFutFO
P2twG4RxA/m6mFp6Z3Ygd0ZsdmZVn2JArwE6/+VwjoZsmvECzK4xAgW9Z5KOpWh/
g5bJHL737hUkT72BbQ5VCeyQb1I8HJPrMCcnbprorR+Hexcgd9TIuMZ7VtlFvpw/
xgVmf4OWb1eke7R7UG68EDECAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAb5bNoNCa
37LHrSe/Aw+3mF0JCflAb0vZfEHtfbGgK2LDi0tvY6kVmnc2EnCzr3AEID6DaZa9
Ntb7mPXIVB1JhM30TOSEekhMUhsSk8oguuof+NtMT4T30pDgSsXqxGRiEDFqBCir
mmDyetLZzxtZ7Qpact/RZ65ZkGpA1BT6ZJj3lkJ/R1W8faxGMpGxuza4BuHXDZoB
9rzHdhvEmz41hA1mhaPh/boHEMmod9RP4APtlzKAjjwxWhtFsFEBkEKAaXRDYtqm
7DvvMizTR1P8Hihz2Sj0L1ziPLmXDN1vaFZJtQySRruwVpZ7RQ6J/9/1BbUuzAdl
bUnPBdscC9Abfg==
-----END CERTIFICATE-----
28 changes: 28 additions & 0 deletions spec/fixtures/certs/opi_client.key
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCxGQ3Zc+P2N4cW
5AnhTvq8mVy0l8tVETukS++HgyACNtt9tfeFvSLOrctbYdrq0+yCRXT3YD8Waeez
k7+qiQqcskqHK0CnVlTg91KHTdL0mNE4XwQJZFslJovBEVfrPNKgrE5RVD/HOjzs
kNBOzzZ8bSuh5kwyTjZ1bFxC+HNwuenP02J0twE4626SxbrRTj9rcBuEcQP5upha
emd2IHdGbHZmVZ9iQK8BOv/lcI6GbJrxAsyuMQIFvWeSjqVof4OWyRy+9+4VJE+9
gW0OVQnskG9SPByT6zAnJ26a6K0fh3sXIHfUyLjGe1bZRb6cP8YFZn+Dlm9XpHu0
e1BuvBAxAgMBAAECggEAHJez8bjRRE5gxCRbKAJNXyfPnOSpEnnuzC7qZFGaWGEs
/NXlObV4qi/LFlztMF6436uBH/NtHBxLKWYgWtM3YGc0uzAThzDcEVo8+9Vnys/l
b5l/mFiYkp3vkGNRc4xlYUWQe3cDuRHBBly3FRJFdL9XfRMmmDSifEDbgICGett0
VH9toDD+ZjIejTY8fxjBSynPwuFlCEoV8Ypyud8rwK8eSLJ05Ig6kt8xiIjzZmn+
rXCVcMrXkoRg6FnHjftNiTgJ0hwZNTn0EN04itbVyT6j1HAudej4M88W5deVhsk7
hm37nm6mPZGfZsdQ9UO9YXcwlnHgc+xt/u0gqQgcAQKBgQDnM8uR2jeqAJtsIEiB
ZuA0b/R3l+p5zkeDXYEKczyayxqjnMHg/55+/0whSlOEuggZf3S6A3r/mAP0L+IM
hvGhvNkoFDefAb8JDzDkzrconIx5NFOX3JFZfv7HdEhks5E+53KFmVsDBlUQoaBc
TWcFBAv6QUJAV5M8Qsqdoo+y8QKBgQDEF7GI8vw3qn9EZJUipA37Zze6jZVTFkCh
lyF4lca3WNJYJqJ86m7qzzQIAkpbFRxz6I96pRdPZ/3Wd7sXhRZG+I2tb3Pxp1cE
wX5lEYqnm3FqJp4yKbsxlZ5wHEiR0Xys5Dq1Iae2LkkKz4VCpdUiI/Y73MYqXBr5
1BXjl/exQQKBgGzLU7SrYdwucvR7cILr3P7v27LXGq/8oGwxeMJpHZCdmEh7QERX
JMcP7UwRBKIFREBzWIMblipl5x5l1dIdQeDg07LnaJD7KmDh9BkHKOsEV5nFRLzG
PuNFPjCvCE3SrbtS//HcCxauSSMNWz9z8NFMaTJ2uO08CH2n1F4/G62RAoGBALC/
qoaGflCunYhIISTYOsIgh1rfw3jg1eDRGJpYZoVcyjwqlsuBg/iiS4PsjJkMrljL
hohFxn0MfwCRa1IH48yUvR9XFmr7KrRetE7lQNVShyfnJzCP7OsEsYrb8418BaTR
Exmw/Dp5/dyAsN0iHLppL8lFdlk4LBiD0jcTA3ABAoGANIbOtNqIYZq5bgwBTKSc
JlkzY8ZSK5iChktpEDvFrF/V7F2xtkLctbbpojYqcx785RPUsI8ASzcIyYBot1YH
f0kYu2lv67uEZnJyYFd8gD1QS+CKrH7akqiwjP4WIJU8FIKZlCFBEaJ6dOghUgq/
DQyOfHRiQ5eI63tgAcm6Cp8=
-----END PRIVATE KEY-----
17 changes: 17 additions & 0 deletions spec/fixtures/config/opi_kube.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
apiVersion: v1
clusters:
- cluster:
server: http://fake.cluster
name: fake-cluster
contexts:
- context:
cluster: fake-cluster
user: fake-user
name: fake-cluster
current-context: fake-cluster
kind: Config
preferences: {}
users:
- name: fake-user
user:
token: token
106 changes: 106 additions & 0 deletions spec/integration/opi_base_client_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
require 'spec_helper'
require 'socket'

$LOAD_PATH.unshift('app')

require 'cloud_controller/opi/base_client'

# This spec requires the OPI binary and `nats-server` to be in $PATH
skip_opi_tests = ENV['CF_RUN_OPI_SPECS'] != 'true'

RSpec.describe(OPI::BaseClient, opi: skip_opi_tests) do
let(:tls_port) { 8484 }
let(:opi_url) { "https://localhost:#{tls_port}" }
let(:ca_cert_file) { File.join(Paths::FIXTURES, 'certs/opi_client.crt') }
let(:client_cert_file) { File.join(Paths::FIXTURES, 'certs/opi_client.crt') }
let(:client_key_file) { File.join(Paths::FIXTURES, 'certs/opi_client.key') }
let(:config) do
VCAP::CloudController::Config.new(
opi: {
url: opi_url,
client_cert_file: client_cert_file,
client_key_file: client_key_file,
ca_file: ca_cert_file
},
)
end
subject(:client) { described_class.new(config) }
let(:process) { double(guid: 'jeff', version: '0.1.0') }

before :all do
WebMock.disable_net_connect!(allow_localhost: true)
end

def client
client = HTTPClient.new
client.ssl_config.set_trust_ca(ca_cert_file)
client.ssl_config.set_client_cert_file(client_cert_file, client_key_file)
client
end

def up?(url)
client.get(url)
rescue OpenSSL::SSL::SSLError
true
rescue Errno::ECONNREFUSED
false
end

def nats_up?
TCPSocket.new 'localhost', 4222
rescue Errno::ECONNREFUSED
false
end

before do
@nats_pid = Process.spawn('nats-server --user nats --pass nats')
wait_for { nats_up? }.to be_truthy

@file = Tempfile.new('opi_config.yml')
@file.write({
'opi' => {
'kube_config_path' => File.join(Paths::FIXTURES, 'config/opi_kube.conf'),
'cc_ca_path' => ca_cert_file,
'cc_cert_path' => client_cert_file,
'cc_key_path' => client_key_file,
'nats_ip' => '127.0.0.1',
'nats_port' => 4222,
'nats_password' => 'nats',
'loggregator_ca_path' => ca_cert_file,
'loggregator_cert_path' => client_cert_file,
'loggregator_key_path' => client_key_file,
'tls_port' => tls_port,
'client_ca_path' => ca_cert_file,
'server_cert_path' => client_cert_file,
'server_key_path' => client_key_file
}
}.to_yaml)
@file.close

@opi_pid = Process.spawn('opi', 'connect', '-c', @file.path)

wait_for { up?(opi_url) }.to be_truthy
end

after do
Process.kill('SIGTERM', @opi_pid)
Process.kill('SIGTERM', @nats_pid)
end

context 'OPI system tests' do
context 'when connecting to OPI with a valid client cert' do
it 'connects successfully' do
expect(up?(opi_url)).to_not be_nil
end
end

context 'when connecting to OPI with an invalid client cert' do
let(:client_cert_file) { File.join(Paths::FIXTURES, 'certs/dea_client.crt') }
let(:client_key_file) { File.join(Paths::FIXTURES, 'certs/dea_client.key') }

it 'returns a TLS error' do
expect { client.get(opi_url) }.to raise_error(OpenSSL::SSL::SSLError)
end
end
end
end

0 comments on commit 2068e57

Please sign in to comment.