Introduction
Enforcing strong and modern cipher is critical to ensure our deployment are well protected from old and weak cipher. Enforcing only strong and modern cipher will significantly reduced or not too bold to say removed the tendency to be victimized by crypt-analysis attack[1].
In this blog, we going to show how we can enforce those for below OCP components:
- masters
- etcd
- nodes
- router
There are two scenarios:
- Fresh Installation
- Running Cluster
Fresh Installation Scenario
Fresh installation is all about specifying correct Ansible variables in order to ensure selected cipher are in place. One might find example here for v3.11.
Note that for router, the variable to set cipher suite is not yet available during this blog written using openshift-ansible-playbooks-3.11.59-1.git.0.ba8e948.el7.noarch.
~~ TRUNCATED ~~
# Masters Cipher Suites
openshift_master_min_tls_version=VersionTLS12
openshift_master_cipher_suites=['TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256','TLS_RSA_WITH_AES_256_CBC_SHA']
# Nodes Cipher Suites
openshift_node_min_tls_version=VersionTLS12
openshift_node_cipher_suites=['TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256','TLS_RSA_WITH_AES_256_CBC_SHA'
# etcd Cipher Suites
etcd_cipher_suites="TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305"
~~ TRUNCATED ~~
Once the playbook ready, run the installation. However we need to still manually set the router cipher suite as per below guide (as this also can be configured using advanced Ansible variable of “openshift_hosted_router_edits”).
Running Cluster Scenario
In this scenario, we have running cluster and going to set proper cipher suite selection. We going to do it component by component.
Router
There are several built-in router cipher suite here. To set router cipher to modern, update the router dc environment.
Update router deploymentConfig environment:
[root@bastion 3.11]# oc set env dc/router ROUTER_CIPHERS=modern
deploymentconfig.apps.openshift.io/router updated
router deploymentConfig will execute an rolling update:
[root@bastion 3.11]# oc get pods
NAME READY STATUS RESTARTS AGE
docker-registry-1-gjqfb 1/1 Running 0 18h
registry-console-1-8g64s 1/1 Running 0 1d
router-2-8ldc2 1/1 Running 0 1m
router-3-deploy 0/1 ContainerCreating 0 2s
Once the new pod running inspect the pod environment:
[root@bastion 3.11]# oc rsh router-3-wtzxz env | grep CIPHERS
ROUTER_CIPHERS=modern
You can further check the haproxy.config:
[root@bastion ~]# oc rsh router-3-wtzxz cat /var/lib/haproxy/conf/haproxy.config | grep cipher
The default cipher suite can be selected from the three sets recommended by https://wiki.mozilla.org/Security/Server_Side_TLS,
By default when a cipher set is not provided, intermediate is used.
# Modern cipher suite (no legacy browser support) from https://wiki.mozilla.org/Security/Server_Side_TLS
ssl-default-bind-ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256
[root@bastion ~]#
etcd
For etcd this is only application for 3.10 and below. 3.11 are using containerized etcd. Also ensure etcd is at least at version 3.2.22.
Under systemd directory create etcd.service.d :
# mkdir -p /etc/systemd/system/etcd.service.d
Then, create a new systemd drop-in file for the etcd service with below content:
# cat /etc/systemd/system/etcd.service.d/10-ciphers.conf
[Service]
Environment=ETCD_CIPHER_SUITES=TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
Now reload systemd daemon and restart etcd, do this for all etcd nodes.
# systemctl daemon-reload
# systemctl restart etcd
Ensure etcd is healhty:
# etcdctl3 member list
# etcdctl3 endpoint health
Masters & Web-Console
Edit /etc/origin/master/master-config.yaml
~~ TRUNCATED ~~
servingInfo:
…
minTLSVersion: VersionTLS12
cipherSuites:
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
TLS_RSA_WITH_AES_256_CBC_SHA
~~ TRUNCATED ~~
For web-console, edit webconsole-config configMap
# oc edit cm webconsole-config -n openshift-web-console
… servingInfo:
…
minTLSVersion: VersionTLS12
cipherSuites:
- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
- TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
And now restart:
# systemctl restart atomic-openshift-master-api.service
# systemctl restart atomic-openshift-master-controllers.service
Verification
TLS Verify
Test with TLS1 will thrown Secure Renegotiation IS NOT supported.
# openssl s_client -connect "hostname"
:8443 -tls1
# openssl s_client -connect "router_route"
:443 -tls1
CONNECTED(00000003)
140586350237584:error:1409442E:SSL routines:ssl3_read_bytes:tlsv1 alert protocol version:s3_pkt.c:1493:SSL alert number 70
140586350237584:error:1409E0E5:SSL routines:ssl3_write_bytes:ssl handshake failure:s3_pkt.c:659:
no peer certificate available
No client certificate CA names sent
SSL handshake has read 7 bytes and written 0 bytes
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
Protocol : TLSv1
Cipher : 0000
Session-ID:
Session-ID-ctx:
Master-Key:
Key-Arg : None
Krb5 Principal: None
PSK identity: None
PSK identity hint: None
Start Time: 1539170928
Timeout : 7200 (sec)
Verify return code: 0 (ok)
Cipher Verify
Using nmap to list supported cipher:
[root@mzali-fedora ~]# nmap --script ssl-enum-ciphers -p 8443 ocp-con-prod.bytewise.com.my
Starting Nmap 7.70 ( https://nmap.org ) at 2018-12-03 16:38 +08
Nmap scan report for ocp-con-prod.bytewise.com.my (192.168.50.50)
Host is up (0.00015s latency).
rDNS record for 192.168.50.50: master01.bytewise.com.my
PORT STATE SERVICE
8443/tcp open https-alt
| ssl-enum-ciphers:
| TLSv1.2:
| ciphers:
| TLS_RSA_WITH_AES_128_GCM_SHA256 (rsa 2048) - A
| TLS_RSA_WITH_AES_256_GCM_SHA384 (rsa 2048) - A
| TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A
| TLS_RSA_WITH_AES_256_CBC_SHA (rsa 2048) - A
| compressors:
| NULL
| cipher preference: server
|_ least strength: A
MAC Address: 52:54:00:AD:E3:3D (QEMU virtual NIC)
Nmap done: 1 IP address (1 host up) scanned in 0.74 seconds
[root@mzali-fedora ~]#
Conclusion
While this is only small portion of hardening OCP platform from infra perspective. A thorough whitepaper of container security is a good place to understand how OCP security work.