Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion lib/cloud_controller/config_schemas/api_schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,13 @@ class ApiSchema < VCAP::Config
insecure_docker_registry_list: [String],
docker_staging_stack: String,
optional(:temporary_oci_buildpack_mode) => enum('oci-phase-1', NilClass),
enable_declarative_asset_downloads: bool
enable_declarative_asset_downloads: bool,
optional(:sshd) => {
optional(:allowed_ciphers) => String,
optional(:allowed_host_key_algorithms) => String,
optional(:allowed_key_exchanges) => String,
optional(:allowed_macs) => String
}
},

app_log_revision: bool,
Expand Down
8 changes: 7 additions & 1 deletion lib/cloud_controller/config_schemas/clock_schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,13 @@ class ClockSchema < VCAP::Config
use_privileged_containers_for_running: bool,
use_privileged_containers_for_staging: bool,
optional(:temporary_oci_buildpack_mode) => enum('oci-phase-1', NilClass),
enable_declarative_asset_downloads: bool
enable_declarative_asset_downloads: bool,
optional(:sshd) => {
optional(:allowed_ciphers) => String,
optional(:allowed_host_key_algorithms) => String,
optional(:allowed_key_exchanges) => String,
optional(:allowed_macs) => String
}
},

app_log_revision: bool,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,13 @@ class DeploymentUpdaterSchema < VCAP::Config
use_privileged_containers_for_running: bool,
use_privileged_containers_for_staging: bool,
optional(:temporary_oci_buildpack_mode) => enum('oci-phase-1', NilClass),
enable_declarative_asset_downloads: bool
enable_declarative_asset_downloads: bool,
optional(:sshd) => {
optional(:allowed_ciphers) => String,
optional(:allowed_host_key_algorithms) => String,
optional(:allowed_key_exchanges) => String,
optional(:allowed_macs) => String
}
},

app_log_revision: bool,
Expand Down
8 changes: 7 additions & 1 deletion lib/cloud_controller/config_schemas/worker_schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,13 @@ class WorkerSchema < VCAP::Config
use_privileged_containers_for_running: bool,
use_privileged_containers_for_staging: bool,
optional(:temporary_oci_buildpack_mode) => enum('oci-phase-1', NilClass),
enable_declarative_asset_downloads: bool
enable_declarative_asset_downloads: bool,
optional(:sshd) => {
optional(:allowed_ciphers) => String,
optional(:allowed_host_key_algorithms) => String,
optional(:allowed_key_exchanges) => String,
optional(:allowed_macs) => String
}
},

app_log_revision: bool,
Expand Down
27 changes: 20 additions & 7 deletions lib/cloud_controller/diego/main_lrp_action_builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -100,21 +100,34 @@ def generate_sidecar_actions(user)
end

def generate_ssh_action(user, environment_variables)
sshd_args = [
"-address=#{sprintf('0.0.0.0:%<port>d', port: DEFAULT_SSH_PORT)}",
"-hostKey=#{ssh_key.private_key}",
"-authorizedKey=#{ssh_key.authorized_key}",
'-inheritDaemonEnv',
'-logLevel=fatal'
]
add_allowed_ssh_algorithms(sshd_args)

action(::Diego::Bbs::Models::RunAction.new(
user: user,
path: '/tmp/lifecycle/diego-sshd',
args: [
"-address=#{sprintf('0.0.0.0:%<port>d', port: DEFAULT_SSH_PORT)}",
"-hostKey=#{ssh_key.private_key}",
"-authorizedKey=#{ssh_key.authorized_key}",
'-inheritDaemonEnv',
'-logLevel=fatal'
],
args: sshd_args,
env: environment_variables,
resource_limits: ::Diego::Bbs::Models::ResourceLimits.new(nofile: process.file_descriptors),
log_source: SSHD_LOG_SOURCE
))
end

def add_allowed_ssh_algorithms(args)
sshd_config = VCAP::CloudController::Config.config.get(:diego, :sshd)
return if sshd_config.nil?

args << "-allowedCiphers=#{sshd_config[:allowed_ciphers]}" if sshd_config[:allowed_ciphers].present?
args << "-allowedHostKeyAlgorithms=#{sshd_config[:allowed_host_key_algorithms]}" if sshd_config[:allowed_host_key_algorithms].present?
args << "-allowedKeyExchanges=#{sshd_config[:allowed_key_exchanges]}" if sshd_config[:allowed_key_exchanges].present?
args << "-allowedMACs=#{sshd_config[:allowed_macs]}" if sshd_config[:allowed_macs].present?
end
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,99 @@ module Diego
)
)
end

context 'when SSH algorithm configuration is provided' do
before do
TestConfig.override(
diego: {
sshd: {
allowed_ciphers: 'cipher-1,cipher-2',
allowed_host_key_algorithms: 'hostkeyalg-1,hostkeyalg-2',
allowed_key_exchanges: 'kex-1,kex-2',
allowed_macs: 'mac-1,mac-2'
}
}
)
end

it 'includes SSH algorithm flags in the diego-sshd arguments' do
actions = MainLRPActionBuilder.build(process, lrp_builder, ssh_key).codependent_action.actions.map(&:run_action)
ssh_action = actions.find { |action| action.path == '/tmp/lifecycle/diego-sshd' }

expect(ssh_action.args).to include('-allowedCiphers=cipher-1,cipher-2')
expect(ssh_action.args).to include('-allowedHostKeyAlgorithms=hostkeyalg-1,hostkeyalg-2')
expect(ssh_action.args).to include('-allowedKeyExchanges=kex-1,kex-2')
expect(ssh_action.args).to include('-allowedMACs=mac-1,mac-2')
end
end

context 'when SSH algorithm configuration has empty strings' do
before do
TestConfig.override(
diego: {
sshd: {
allowed_ciphers: '',
allowed_host_key_algorithms: '',
allowed_key_exchanges: '',
allowed_macs: ''
}
}
)
end

it 'does not include SSH algorithm flags in the arguments' do
actions = MainLRPActionBuilder.build(process, lrp_builder, ssh_key).codependent_action.actions.map(&:run_action)
ssh_action = actions.find { |action| action.path == '/tmp/lifecycle/diego-sshd' }

expect(ssh_action.args).not_to include(match(/-allowedCiphers=/))
expect(ssh_action.args).not_to include(match(/-allowedHostKeyAlgorithms=/))
expect(ssh_action.args).not_to include(match(/-allowedKeyExchanges=/))
expect(ssh_action.args).not_to include(match(/-allowedMACs=/))
end
end

context 'when SSH algorithm configuration is partially provided' do
before do
TestConfig.override(
diego: {
sshd: {
allowed_ciphers: 'cipher-1',
allowed_host_key_algorithms: '',
}
}
)
end

it 'includes only the configured algorithm flags' do
actions = MainLRPActionBuilder.build(process, lrp_builder, ssh_key).codependent_action.actions.map(&:run_action)
ssh_action = actions.find { |action| action.path == '/tmp/lifecycle/diego-sshd' }

expect(ssh_action.args).to include('-allowedCiphers=cipher-1')
expect(ssh_action.args).not_to include(match(/-allowedHostKeyAlgorithms=/))
expect(ssh_action.args).not_to include(match(/-allowedKeyExchanges=/))
expect(ssh_action.args).not_to include(match(/-allowedMACs=/))
end
end

context 'when diego sshd configuration is missing' do
before do
TestConfig.override(diego: {})
end

it 'does not raise an error and excludes algorithm flags' do
expect do
MainLRPActionBuilder.build(process, lrp_builder, ssh_key)
end.not_to raise_error

actions = MainLRPActionBuilder.build(process, lrp_builder, ssh_key).codependent_action.actions.map(&:run_action)
ssh_action = actions.find { |action| action.path == '/tmp/lifecycle/diego-sshd' }

expect(ssh_action.args).not_to include(match(/-allowedCiphers=/))
expect(ssh_action.args).not_to include(match(/-allowedHostKeyAlgorithms=/))
expect(ssh_action.args).not_to include(match(/-allowedKeyExchanges=/))
expect(ssh_action.args).not_to include(match(/-allowedMACs=/))
end
end
end

describe 'VCAP_PLATFORM_OPTIONS' do
Expand Down
Loading