Bug 1473816
| Summary: | Hardening Satellite 6.2+ network security by disabling vulnerable ciphers and enabling new secure ones | ||
|---|---|---|---|
| Product: | Red Hat Satellite | Reporter: | Pablo Hess <phess> |
| Component: | Security | Assignee: | satellite6-bugs <satellite6-bugs> |
| Status: | CLOSED DUPLICATE | QA Contact: | Katello QA List <katello-qa-list> |
| Severity: | medium | Docs Contact: | |
| Priority: | unspecified | ||
| Version: | 6.2.10 | CC: | lzap, mhulan, phess, tbrisker |
| Target Milestone: | Unspecified | ||
| Target Release: | Unused | ||
| Hardware: | All | ||
| OS: | Unspecified | ||
| Whiteboard: | |||
| Fixed In Version: | Doc Type: | If docs needed, set a value | |
| Doc Text: | Story Points: | --- | |
| Clone Of: | Environment: | ||
| Last Closed: | 2017-07-24 14:46:58 UTC | Type: | Bug |
| Regression: | --- | Mount Type: | --- |
| Documentation: | --- | CRM: | |
| Verified Versions: | Category: | --- | |
| oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |
| Cloudforms Team: | --- | Target Upstream Version: | |
| Embargoed: | |||
I have some configuration issues with the WEBricks serving https on the following ports:
- tcp/9090
- tcp/8008
For the WEBrick running on tcp/9090 (aka. "foreman-proxy") there is at least some kind of configuration option which allows to reduce the ciphers ("/etc/foreman-proxy/settings.yml"):
# Use this option only if you need to disable certain cipher suites.
# Note: we use the OpenSSL suite name, take a look at:
# https://www.openssl.org/docs/manmaster/apps/ciphers.html#CIPHER-SUITE-NAMES
# for more information.
:ssl_disabled_ciphers: [DHE-RSA-CAMELLIA256-SHA, DHE-DSS-CAMELLIA256-SHA,
ECDH-RSA-AES256-SHA, ECDH-ECDSA-AES256-SHA, AES256-SHA, CAMELLIA256-SHA,
PSK-AES256-CBC-SHA, ECDHE-RSA-AES128-SHA, ECDHE-ECDSA-AES128-SHA,
DHE-RSA-AES128-SHA, DHE-DSS-AES128-SHA, DHE-RSA-SEED-SHA,
DHE-DSS-SEED-SHA, DHE-RSA-CAMELLIA128-SHA, DHE-DSS-CAMELLIA128-SHA,
ECDH-RSA-AES128-SHA, ECDH-ECDSA-AES128-SHA, AES128-SHA, SEED-SHA,
CAMELLIA128-SHA, PSK-AES128-CBC-SHA, ECDHE-RSA-DES-CBC3-SHA,
ECDHE-ECDSA-DES-CBC3-SHA, EDH-RSA-DES-CBC3-SHA, EDH-DSS-DES-CBC3-SHA,
ECDH-RSA-DES-CBC3-SHA, ECDH-ECDSA-DES-CBC3-SHA, DES-CBC3-SHA,
IDEA-CBC-SHA, PSK-3DES-EDE-CBC-SHA, KRB5-IDEA-CBC-SHA,
KRB5-DES-CBC3-SHA, KRB5-IDEA-CBC-MD5, KRB5-DES-CBC3-MD5,
ECDHE-RSA-RC4-SHA, ECDHE-ECDSA-RC4-SHA, ECDH-RSA-RC4-SHA,
ECDH-ECDSA-RC4-SHA, RC4-SHA, RC4-MD5, PSK-RC4-SHA, KRB5-RC4-SHA,
KRB5-RC4-MD5]
This is not available for the other WEBrick running on tcp/8008 (aka. "smart_proxy_dynflow_core").
So I patched the service myself to get rid of "TLSv1.1" and all those "Medium grade encryption" and triple DES ciphers.
Patches were modified from https://github.com/theforeman/smart_proxy_dynflow/blob/master/lib/smart_proxy_dynflow_core/webrick-patch.rb and were applied as files:
/opt/theforeman/tfm/root/usr/share/gems/gems/smart_proxy_dynflow_core-0.1.3.1/lib/smart_proxy_dynflow_core/launcher.rb
and
/opt/theforeman/tfm/root/usr/share/gems/gems/smart_proxy_dynflow_core-0.1.3.1/lib/smart_proxy_dynflow_core/webrick-patch.rb
Scan results against port 9090 of the internal capsule BEFORE the patches:
-------------------------------------------------------------------------
Testing protocols (via sockets except TLS 1.2, SPDY+HTTP2)
SSLv2 not offered (OK)
SSLv3 not offered (OK)
TLS 1 not offered
TLS 1.1 not offered
TLS 1.2 offered (OK)
Version tolerance downgraded to TLSv1.2 (OK)
SPDY/NPN not offered
HTTP2/ALPN Local problem: /bin/openssl doesn't support HTTP2/ALPN
Testing ~standard cipher lists
Null Ciphers not offered (OK)
Anonymous NULL Ciphers not offered (OK)
Anonymous DH Ciphers not offered (OK)
40 Bit encryption not offered (OK)
56 Bit export ciphers Local problem: No 56 Bit export ciphers configured in /bin/openssl
Export Ciphers (general) not offered (OK)
Low (<=64 Bit) not offered (OK)
DES Ciphers not offered (OK)
"Medium" grade encryption not offered (OK)
Triple DES Ciphers not offered (OK)
High grade encryption offered (OK)
Testing robust (perfect) forward secrecy, (P)FS -- omitting Null Authentication/Encryption, 3DES, RC4
No ciphers supporting Forward Secrecy offered
Testing server preferences
Has server cipher order? yes (OK)
Negotiated protocol TLSv1.2
Negotiated cipher AES128-GCM-SHA256 (openssl cannot show DH bits)
Cipher order
TLSv1.2: AES128-GCM-SHA256 AES256-GCM-SHA384 AES128-SHA256 AES256-SHA256 AES128-SHA AES256-SHA
Testing vulnerabilities
Heartbleed (CVE-2014-0160) not vulnerable (OK), timed out
CCS (CVE-2014-0224) not vulnerable (OK)
Secure Renegotiation (CVE-2009-3555) not vulnerable (OK)
Secure Client-Initiated Renegotiation VULNERABLE (NOT ok), DoS threat
CRIME, TLS (CVE-2012-4929) not vulnerable (OK)
BREACH (CVE-2013-3587) no HTTP compression (OK) - only supplied "/" tested
POODLE, SSL (CVE-2014-3566) not vulnerable (OK)
TLS_FALLBACK_SCSV (RFC 7507), No fallback possible, TLS 1.2 is the only protocol (OK)
FREAK (CVE-2015-0204) not vulnerable (OK) (tested with 4/9 ciphers)
DROWN (2016-0800, CVE-2016-0703) not vulnerable on this port (OK)
LOGJAM (CVE-2015-4000), experimental not vulnerable (OK) (tested w/ 2/4 ciphers only!), common primes not checked.
BEAST (CVE-2011-3389) no SSL3 or TLS1 (OK)
RC4 (CVE-2013-2566, CVE-2015-2808) no RC4 ciphers detected (OK)
Scan results against port 8008 of the internal capsule BEFORE the patches:
-------------------------------------------------------------------------
Testing protocols (via sockets except TLS 1.2, SPDY+HTTP2)
SSLv2 not offered (OK)
SSLv3 not offered (OK)
TLS 1 not offered
TLS 1.1 offered
TLS 1.2 offered (OK)
Version tolerance downgraded to TLSv1.2 (OK)
SPDY/NPN not offered
HTTP2/ALPN Local problem: /bin/openssl doesn't support HTTP2/ALPN
Testing ~standard cipher lists
Null Ciphers not offered (OK)
Anonymous NULL Ciphers not offered (OK)
Anonymous DH Ciphers not offered (OK)
40 Bit encryption not offered (OK)
56 Bit export ciphers Local problem: No 56 Bit export ciphers configured in /bin/openssl
Export Ciphers (general) not offered (OK)
Low (<=64 Bit) not offered (OK)
DES Ciphers not offered (OK)
"Medium" grade encryption offered (NOT ok)
Triple DES Ciphers offered
High grade encryption offered (OK)
Testing robust (perfect) forward secrecy, (P)FS -- omitting Null Authentication/Encryption, 3DES, RC4
PFS is offered (OK) DHE-RSA-AES128-GCM-SHA256 DHE-RSA-AES128-SHA256 DHE-RSA-AES128-SHA DHE-RSA-AES256-GCM-SHA384 DHE-RSA-AES256-SHA256 DHE-RSA-AES256-SHA DHE-RSA-CAMELLIA128-SHA DHE-RSA-CAMELLIA256-SHA
DHE-RSA-SEED-SHA
Testing server preferences
Has server cipher order? yes (OK)
Negotiated protocol TLSv1.2
Negotiated cipher DHE-RSA-AES256-GCM-SHA384, 1024 bit DH
Cipher order
TLSv1.1: DHE-RSA-AES256-SHA DHE-RSA-CAMELLIA256-SHA AES256-SHA CAMELLIA256-SHA DHE-RSA-AES128-SHA DHE-RSA-SEED-SHA DHE-RSA-CAMELLIA128-SHA AES128-SHA SEED-SHA CAMELLIA128-SHA EDH-RSA-DES-CBC3-SHA DES-CBC3-
SHA IDEA-CBC-SHA RC4-SHA RC4-MD5
TLSv1.2: DHE-RSA-AES256-GCM-SHA384 DHE-RSA-AES256-SHA256 DHE-RSA-AES256-SHA DHE-RSA-CAMELLIA256-SHA AES256-GCM-SHA384 AES256-SHA256 AES256-SHA CAMELLIA256-SHA DHE-RSA-AES128-GCM-SHA256 DHE-RSA-AES128-SHA25
6 DHE-RSA-AES128-SHA DHE-RSA-SEED-SHA DHE-RSA-CAMELLIA128-SHA AES128-GCM-SHA256 AES128-SHA256 AES128-SHA SEED-SHA CAMELLIA128-SHA EDH-RSA-DES-CBC3-SHA DES-CBC3-SHA IDEA-CBC-SHA RC4-SHA RC4-MD5
Patch applied as:
/opt/theforeman/tfm/root/usr/share/gems/gems/smart_proxy_dynflow_core-0.1.3.1/lib/smart_proxy_dynflow_core/webrick-patch.rb
------------------------------------------------------------
require 'webrick/https'
CIPHERS = ['ECDHE-RSA-AES128-GCM-SHA256','ECDHE-RSA-AES256-GCM-SHA384',
'ECDHE-RSA-AES128-CBC-SHA256','ECDHE-RSA-AES256-CBC-SHA384',
'ECDHE-RSA-AES128-GCM-SHA256','ECDHE-RSA-AES256-GCM-SHA256',
'AES256-GCM-SHA384','AES128-GCM-SHA256','AES128-SHA256',
'AES256-SHA256','DHE-RSA-AES256-GCM-SHA384','DHE-RSA-AES128-GCM-SHA256',
'DHE-RSA-AES128-SHA256','DHE-RSA-AES256-SHA256']
module WEBrick
class GenericServer
def setup_ssl_context(config) # :nodoc:
unless config[:SSLCertificate]
cn = config[:SSLCertName]
comment = config[:SSLCertComment]
cert, key = Utils::create_self_signed_cert(1024, cn, comment)
config[:SSLCertificate] = cert
config[:SSLPrivateKey] = key
end
ctx = OpenSSL::SSL::SSLContext.new
ctx.set_params
ctx.ciphers = (CIPHERS).join(':')
ctx.key = config[:SSLPrivateKey]
ctx.cert = config[:SSLCertificate]
ctx.client_ca = config[:SSLClientCA]
ctx.extra_chain_cert = config[:SSLExtraChainCert]
ctx.ca_file = config[:SSLCACertificateFile]
ctx.ca_path = config[:SSLCACertificatePath]
ctx.cert_store = config[:SSLCertificateStore]
ctx.tmp_dh_callback = config[:SSLTmpDhCallback]
ctx.verify_mode = config[:SSLVerifyClient]
ctx.verify_depth = config[:SSLVerifyDepth]
ctx.verify_callback = config[:SSLVerifyCallback]
ctx.timeout = config[:SSLTimeout]
ctx.options |= config[:SSLOptions] unless config[:SSLOptions].nil?
ctx
end
end
end
Patch applied as /opt/theforeman/tfm/root/usr/share/gems/gems/smart_proxy_dynflow_core-0.1.3.1/lib/smart_proxy_dynflow_core/webrick-patch.rb
------------------------------------------------------------
require 'webrick/https'
require 'smart_proxy_dynflow_core/bundler_helper'
require 'smart_proxy_dynflow_core/settings'
require 'smart_proxy_dynflow_core/webrick-patch'
module SmartProxyDynflowCore
class Launcher
def self.launch!(options)
self.new.start options
end
def start(options)
load_settings!(options)
Settings.instance.standalone = true
Rack::Server.new(rack_settings).start
end
def load_settings!(options = {})
config_dir, one_config = options.values_at(:config_dir, :one_config)
possible_config_dirs = [
'/etc/smart_proxy_dynflow_core',
File.expand_path('~/.config/smart_proxy_dynflow_core'),
File.join(File.dirname(__FILE__), '..', '..', 'config'),
]
possible_config_dirs << config_dir if config_dir
BundlerHelper.require_groups(:default)
possible_config_dirs.reverse! if one_config
possible_config_dirs.select { |config_dir| File.directory? config_dir }.each do |config_dir|
break if load_config_dir(config_dir) && one_config
end
Settings.instance.daemonize = options[:daemonize] if options.key?(:daemonize)
Settings.instance.pid_file = options[:pid_file] if options.key?(:pid_file)
Settings.loaded!
end
def self.route_mapping(rack_builder)
rack_builder.map '/console' do
run Core.web_console
end
rack_builder.map '/' do
run Api
end
end
private
def rack_settings
settings = if https_enabled?
Log.instance.debug "Using HTTPS"
https_app
else
Log.instance.debug "Using HTTP"
{}
end
settings.merge(base_settings)
end
def app
Rack::Builder.new do
SmartProxyDynflowCore::Launcher.route_mapping(self)
end
end
def base_settings
{
:app => app,
:Host => Settings.instance.listen,
:Port => Settings.instance.port,
:AccessLog => [[Log.log_file, WEBrick::AccessLog::COMMON_LOG_FORMAT]],
:Logger => Log.instance,
:daemonize => Settings.instance.daemonize,
:pid => Settings.instance.pid_file
}
end
def https_app
ssl_options = OpenSSL::SSL::SSLContext::DEFAULT_PARAMS[:options]
ssl_options |= OpenSSL::SSL::OP_CIPHER_SERVER_PREFERENCE if defined?(OpenSSL::SSL::OP_CIPHER_SERVER_PREFERENCE)
# This is required to disable SSLv3 on Ruby 1.8.7
ssl_options |= OpenSSL::SSL::OP_NO_SSLv2 if defined?(OpenSSL::SSL::OP_NO_SSLv2)
ssl_options |= OpenSSL::SSL::OP_NO_SSLv3 if defined?(OpenSSL::SSL::OP_NO_SSLv3)
ssl_options |= OpenSSL::SSL::OP_NO_TLSv1 if defined?(OpenSSL::SSL::OP_NO_TLSv1)
ssl_options |= OpenSSL::SSL::OP_NO_TLSv1_1 if defined?(OpenSSL::SSL::OP_NO_TLSv1_1)
{
:SSLEnable => true,
:SSLVerifyClient => OpenSSL::SSL::VERIFY_PEER,
:SSLPrivateKey => ssl_private_key,
:SSLCertificate => ssl_certificate,
:SSLCACertificateFile => Settings.instance.ssl_ca_file,
:SSLOptions => ssl_options
}
end
def https_enabled?
Settings.instance.use_https
end
def ssl_private_key
OpenSSL::PKey::RSA.new(File.read(Settings.instance.ssl_private_key))
rescue Exception => e
Log.instance.fatal "Unable to load private SSL key. Are the values correct in settings.yml and do permissions allow reading?: #{e}"
raise e
end
def ssl_certificate
OpenSSL::X509::Certificate.new(File.read(Settings.instance.ssl_certificate))
rescue Exception => e
Log.instance.fatal "Unable to load SSL certificate. Are the values correct in settings.yml and do permissions allow reading?: #{e}"
raise e
end
def load_config_dir(dir)
settings_yml = File.join(dir, 'settings.yml')
if File.exist? settings_yml
Log.instance.debug "Loading settings from #{dir}"
Settings.load_global_settings settings_yml
Dir[File.join(dir, 'settings.d', '*.yml')].each { |path| Settings.load_plugin_settings(path) }
true
end
end
end
end
|
Description of problem: Pentest showed weak ciphers used by Satellite. In addition to disabling such ciphers there is the need to add new ones, mainly ECDHE-based ciphers. Version-Release number of selected component (if applicable): 6.2.x (preferable) or 6.3.0 How reproducible: n.a. Steps to Reproduce: n.a. Actual results: Testing all 121 locally available ciphers against the server, ordered by encryption strength Hexcode Cipher Suite Name (OpenSSL) KeyExch. Encryption Bits ------------------------------------------------------------------------ x9f DHE-RSA-AES256-GCM-SHA384 DH 2048 AESGCM 256 x6b DHE-RSA-AES256-SHA256 DH 2048 AES 256 x39 DHE-RSA-AES256-SHA DH 2048 AES 256 x88 DHE-RSA-CAMELLIA256-SHA DH 2048 Camellia 256 x9d AES256-GCM-SHA384 RSA AESGCM 256 x3d AES256-SHA256 RSA AES 256 x35 AES256-SHA RSA AES 256 x84 CAMELLIA256-SHA RSA Camellia 256 x9e DHE-RSA-AES128-GCM-SHA256 DH 2048 AESGCM 128 x67 DHE-RSA-AES128-SHA256 DH 2048 AES 128 x33 DHE-RSA-AES128-SHA DH 2048 AES 128 x9a DHE-RSA-SEED-SHA DH 2048 SEED 128 x45 DHE-RSA-CAMELLIA128-SHA DH 2048 Camellia 128 x9c AES128-GCM-SHA256 RSA AESGCM 128 x3c AES128-SHA256 RSA AES 128 x2f AES128-SHA RSA AES 128 x96 SEED-SHA RSA SEED 128 x41 CAMELLIA128-SHA RSA Camellia 128 x16 EDH-RSA-DES-CBC3-SHA DH 2048 3DES 168 x0a DES-CBC3-SHA RSA 3DES 168 x07 IDEA-CBC-SHA RSA IDEA 128 x05 RC4-SHA RSA RC4 128 x04 RC4-MD5 RSA RC4 128 x15 EDH-RSA-DES-CBC-SHA DH 2048 DES 56 x09 DES-CBC-SHA RSA DES 56 So the service might be vulnerable to BEAST: TLS1: IDEA-CBC-SHA DES-CBC-SHA DES-CBC3-SHA EDH-RSA-DES-CBC-SHA EDH-RSA-DES-CBC3-SHA AES128-SHA DHE-RSA-AES128-SHA AES256-SHA DHE-RSA-AES256-SHA CAMELLIA128-SHA DHE-RSA-CAMELLIA128-SHA CAMELLIA256-SHA DHE-RSA-CAMELLIA256-SHA SEED-SHA DHE-RSA-SEED-SHA Expected results: We need a configuration option where we can limit the ciphers / TLS versions just like in Apache (where the defaults as of Satellite 6.2.10 are really bad as well): ~~~ SSLProtocol -ALL +TLSv1.2 SSLCipherSuite ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:!ECDH+3DES:!DH+3DES:RSA+AEGCM:RSA+AES:!RSA+3DES:!aNULL:!MD5:!DSS:!SHA SSLHonorCipherOrder on ~~~ Additional info: The next few messages on this BZ detail how this customer is working to disable weak ciphers and implement ECDHE in all Red Hat Satellite 6.2.10 components.