WL#12012: TLS endpoint for routing connections
Motivation
MySQL Router currently forwards data as is as soon as a (classic and xproto) connection upgrades to TLS (and as of MySQL 5.7 communication between client and server is encrypted with TLS by default).
Client ssl-mode=verify-identity
Adding any TCP-layer router/load-balancer/... between client and backend breaks the 'verify-identity' part of TLS.
If the client validates the certificate (check the cert's subject) it would detect that the identity of the certificate (the server) doesn't match the host it connected to (the router):
- Client connects to Router
IP=10.0.0.1
. - Router connects to Server
IP=10.0.0.2
and presents cert withsubject=10.0.0.2
. - Client checks if cert's subject matches the hostname/ip it connected to.
- As they don't match: Bad Certificate Error.
That means to support 'verify-identity' with the Router it must present the router's hostname/ip in the certificate the client receives. As router and server are on different hosts, the router needs its own certificate.
Protocol aware Routing
Given that Router can present its own certificate, it can't forward the bytes as is anymore and must decrypt and encrypt the TLS payload for the communication with the server.
That's opens the door to support use-cases that are currently disabled with TLS connections in the router:
- prevent max-connect-errors by completing the protocol
- track error-messages like "super-read-only" when PRIMARY becomes SECONDARY
TLS offloading
Scenario: Router and Application are on the same host, Server's are remote.
Given that Router can encrypt the payload between Router and Server the connection between client and router can be unencrypted if the connection itself is secure (like unix-sockets and shared memory).
User Stories
- As Router I want inject expectations (gr-role, last-gtid, ...) into the protocol stream between router and server to ensure client sees the GR cluster as a single server.
- As Router I want to detect connect-errors that increment max_connect_errors even client enabled encryption to prevent Router from being blocked by the server.
- As Router I want to detect "super-read-only" message in case a server became read-only due to a PRIMARY to SECONDARY role change.
- As a application developer I want to have a fast communication with a local router which encrypts the traffic to the server.
- As a application developer I want to be able to successfully verify the certificates of the connection with the router.
Insight into User Stories
User Stories 1 to 3 all require protocol awareness, while the 4th User Story is about offloading the encryption work to the router.
Security implications
Security of TLS connections is based on:
- strong encryption primitives
- knowledge of the private key
- chain-of-trust of certificates
If Router wants to decrypt encrypted TLS traffic it needs to have to access to the private key of the certificate that is presented to the client at connect-time.
If Router has a valid certificate the client can verify that its communication with the Router is secure (chain-of-trust can be checked, subject matches, cert isn't out-dated, ...).
Limitations
client certificates
The MySQL Server allows clients to authenticate with TLS certificates.
Clients present the server with a certificate at connect time, that the server verifies and checks against its auth-database.
In case if TLS endpoints, the router would receive the clients certificate and could verify it, but forwarding the certificate to the server would fail.
Goal
- allow Router to see the unencrypted protocol exchanged between client and server.
- allow to encrypt router-server communication of client-router is unencrypted
- allow to unencrypted router-server communication of client-router is encrypted.
Requirements
Precedence
- PredecendeR1
-
if a known ssl option exists in the
routing
section, the routing plugin MUST use it. - PrecedenceR2
-
if a known ssl option is not found in the
routing
section, the routing plugin MUST use the value from theDEFAULT
section if it exists. - PrecedenceR3
-
if a known ssl option is not found in the
routing
section nor theDEFAULT
section, a default value MAY be used.
Client-side TLS
- ClientR1
-
if
client_ssl_mode
is not specified and eitherclient_ssl_key
orclient_ssl_cert
are set,client_ssl_mode
MUST default toPREFERRED
. - ClientR1.1
-
if
client_ssl_mode
is not specified andclient_ssl_key
andclient_ssl_cert
are not set,client_ssl_mode
MUST default toPASSTHROUGH
. - ClientR2
-
if
client_ssl_mode
is set, it MUST case-insensitively match one ofPREFERRED
,DISABLED
,REQUIRED
orPASSTHROUGH
. - ClientR3
-
if
client_ssl_mode
is DISABLED, communication with the client MUST be unencrypted. - ClientR3.1
-
if
client_ssl_mode
is PASSTHROUGH, router MUST delegate the decision if an TLS connection shall be established to the server. - ClientR3.2
-
if
client_ssl_mode
is PASSTHROUGH, router MUST fail ifserver_ssl_mode
is notAS_CLIENT
.
client TLS endpoint
If client_ssl_mode
is not DISABLED nor PASSTHROUGH,
- ClientR4
-
router MUST read certificate from
client_ssl_cert=<filename>
and private key fromclient_ssl_key=<filename>
specified in configuration. - ClientR4.1
-
router MUST present new TLS connections with certificate generated from
client_ssl_cert
andclient_ssl_key
. - ClientR5
-
router MUST use a secure default list of ciphers for
client_ssl_cipher
, ifclient_ssl_cipher
is not set. - ClientR5.1
-
router MUST fail to start, if
client_ssl_cipher
is invalid. - ClientR5.2
-
router MUST only negotiate ciphers with clients that match the
client_ssl_cipher
- ClientR6
-
router MUST use a secure default list curves for
client_ssl_curves
, ifclient_ssl_curves
is not set. - ClientR6.1
-
router MUST fail to start, if
client_ssl_curves
is invalid. - ClientR6.2
-
router MUST only negotiate curves with clients that match the
client_ssl_curves
- ClientR7
-
router MUST read the DH params set in the
client_ssl_dh_params
file. - ClientR7.1
- router MUST fail to start, if reading the DH params fails.
- ClientR7.2
-
router MUST use default DH params if
client_ssl_dh_params
is not set. - ClientR8
-
router MUST fail unencrypted connections from clients if
client_ssl_mode
is REQUIRED. - ClientR8.1
-
router MUST encrypt connections with clients if
client_ssl_mode
is PREFERRED and the client supports it. - ClientR8.2
-
router MUST allow unencrypted connections with clients if
client_ssl_mode
is PREFERRED and the client does not supports TLS.
Server-side TLS
- ServerR1
-
if
server_ssl_mode
is not specified,server_ssl_mode
MUST default toAS_CLIENT
- ServerR1.1
-
if
server_ssl_mode
is set, it MUST match one ofPREFERRED
,DISABLED
,REQUIRED
orAS_CLIENT
case-insensitive. - ServerR2
-
if
server_ssl_verify
is not set,server_ssl_verify
MUST default toDISABLED
. - ServerR2.1
-
if
server_ssl_verify
is set, it MUST match one ofDISABLED
,VERIFY_IDENTITY
orVERIFY_CA
case-insensitive. - ServerR3
-
router MUST use a secure default list ciphers for
server_ssl_cipher
, ifserver_ssl_cipher
is not set. - ServerR3.1
-
router MUST fail to start, if
server_ssl_cipher
is invalid. - ServerR3.2
-
router MUST only negotiate ciphers with servers that match the
server_ssl_cipher
- ServerR4
-
router MUST use a secure default list elliptic curves for
server_ssl_curves
, ifserver_ssl_curves
is not set. - ServerR4.1
-
router MUST fail to start, if
server_ssl_curves
can't be used. - ServerR4.2
-
router MUST only negotiate elliptic curves with servers that match the
server_ssl_curves
- ServerR5
-
router MUST fail unencrypted connections to servers if
server_ssl_mode
is REQUIRED. - ServerR5.1
-
router MUST use encrypted connections with servers if
server_ssl_mode
is PREFERRED and the server supports TLS. - ServerR5.2
-
router MUST use unencrypted connections with servers if
server_ssl_mode
is PREFERRED and the server does not support TLS. - ServerR5.3
-
router MUST use encrypted connections to servers if
server_ssl_mode
isAS_CLIENT
and the client-side connection is encrypted. - ServerR5.4
-
router MUST use unencrypted connections to servers if
server_ssl_mode
isAS_CLIENT
and the client-side connection is unencrypted. - ServerR6
-
router MUST use unencrypted connections to server is
server_ssl_mode
isDISABLED
. - ServerR7
-
if the connection to the server is encrypted, router MUST verify the servers certificate signature if
server_ssl_verify
isVERIFY_CA
orVERIFY_IDENTITY
. - ServerR7.1
-
if the connection to the server is encrypted, router MUST verify the servers certificate identity if
server_ssl_verify
isVERIFY_IDENTITY
. - ServerR8
-
if the server's certificate is verified, router MUST validate against the CAs provided by
server_ssl_ca
andserver_ssl_capath
. - ServerR9
-
if
server_ssl_crl
orserver_ssl_crlpath
are set, router MUST load the CRLs from those locations and use them to check for revoked certificates when the server's certificate is verified.
Auditing
- AuditR1
- if the client connection is via IP, router MUST set the client's IP address and TCP source port in the connection attributes of the server side connection.
Bootstrap
If mysqlrouter
is called with --bootstrap
,
- BootstrapR1
-
if
--client-ssl-mode
is specified with a supported value, its value MUST be written to the generated configuration file's[DEFAULT]
section asclient_ssl_mode
. - BootstrapR1.1
-
if
--client-ssl-mode
is specified with an unsupported value, it MUST fail to bootstrap. - BootstrapR1.2
-
if
--client-ssl-mode
is not specified,PREFERRED
value MUST be written to the generated configuration file's[DEFAULT]
section asclient_ssl_mode
. - BootstrapR2
-
if
--client-ssl-cipher
is specified with non-empty value, its value MUST be written to the generated configuration file's[DEFAULT]
section asclient_ssl_cipher
. - BootstrapR2.1
-
if
--client-ssl-cipher
is specified with an empty value, it MUST fail to bootstrap. - BootstrapR3
-
if
--client-ssl-curves
is specified with non-empty value, its value MUST be written to the generated configuration file's[DEFAULT]
section asclient_ssl_curves
. - BootstrapR3.1
-
if
--client-ssl-curves
is specified with an empty value, it MUST fail to bootstrap. - BootstrapR4
-
if
--client-ssl-cert
is specified with non-empty value and--client-ssl-key
is specified with a non-empty value, the value of--client-ssl-cert
MUST be written to the generated configuration file's[DEFAULT]
section asclient_ssl_cert
. - BootstrapR4.1
-
if
--client-ssl-cert
is specified with an empty value, it MUST fail to bootstrap. - BootstrapR4.2
-
if
--client-ssl-cert
is not specified and--client-ssl-key
is not specified,${datadir}/router-cert.pem
MUST be written to the generated configuration file's[DEFAULT]
section asclient_ssl_cert
. - BootstrapR4.3
-
if
--client-ssl-cert
is specified with a non-empty value and--client-ssl-key
is NOT specified with a non-empty value, bootstrap MUST fail. - BootstrapR5
-
if
--client-ssl-key
is specified with non-empty value and--client-ssl-cert
is specified with a non-empty value, the value of--client-ssl-key
MUST be written to the generated configuration file's[DEFAULT]
section asclient_ssl_key
. - BootstrapR5.1
-
if
--client-ssl-key
is specified with an empty value, it MUST fail to bootstrap. - BootstrapR5.2
-
if
--client-ssl-key
is not specified and--client-ssl-cert
is not specified,${datadir}/router-key.pem
MUST be written to the generated configuration file's[DEFAULT]
section asclient_ssl_key
. - BootstrapR5.3
-
if
--client-ssl-key
is specified with a non-empty value and--client-ssl-cert
is NOT specified with a non-empty value, bootstrap MUST fail. - BootstrapR6
-
if
--client-ssl-dh-params
is specified with non-empty value, its value MUST be written to the generated configuration file's[DEFAULT]
section asclient_ssl_dh_params
. - BootstrapR6.1
-
if
--client-ssl-dh-params
is specified with an empty value, it MUST fail to bootstrap. - BootstrapR7
-
if
--server-ssl-mode
is specified with a supported value, its value MUST be written to the generated configuration file's[DEFAULT]
section asserver_ssl_mode
. - BootstrapR7.1
-
if
--server-ssl-mode
is specified with an unsupported value, it MUST fail to bootstrap. - BootstrapR7.2
-
if
--server-ssl-mode
is not specified,AS_CLIENT
value MUST be written to the generated configuration file's[DEFAULT]
section asserver_ssl_mode
. - BootstrapR8
-
if
--server-ssl-cipher
is specified with non-empty value, its value MUST be written to the generated configuration file's[DEFAULT]
section asserver_ssl_cipher
. - BootstrapR8.1
-
if
--server-ssl-cipher
is specified with an empty value, it MUST fail to bootstrap. - BootstrapR9
-
if
--server-ssl-curves
is specified with non-empty value, its value MUST be written to the generated configuration file's[DEFAULT]
section asserver_ssl_curves
. - BootstrapR9.1
-
if
--server-ssl-curves
is specified with an empty value, it MUST fail to bootstrap. - BootstrapR10
-
if
--server-ssl-ca
is specified with non-empty value, its value MUST be written to the generated configuration file's[DEFAULT]
section asserver_ssl_ca
. - BootstrapR10.1
-
if
--server-ssl-ca
is specified with an empty value, it MUST fail to bootstrap. - BootstrapR11
-
if
--server-ssl-capath
is specified with non-empty value, its value MUST be written to the generated configuration file's[DEFAULT]
section asserver_ssl_capath
. - BootstrapR11.1
-
if
--server-ssl-capath
is specified with an empty value, it MUST fail to bootstrap. - BootstrapR12
-
if
--server-ssl-crl
is specified with non-empty value, its value MUST be written to the generated configuration file's[DEFAULT]
section asserver_ssl_crl
. - BootstrapR12.1
-
if
--server-ssl-crl
is specified with an empty value, it MUST fail to bootstrap. - BootstrapR13
-
if
--server-ssl-crlpath
is specified with non-empty value, its value MUST be written to the generated configuration file's[DEFAULT]
section asserver_ssl_crlpath
. - BootstrapR13.1
-
if
--server-ssl-crlpath
is specified with an empty value, it MUST fail to bootstrap. - BootstrapR14
-
if
--server-ssl-verify
is specified with supported value, its value MUST be written to the generated configuration file's[DEFAULT]
section asserver_ssl_verify
. - BootstrapR14.1
-
if
--server-ssl-verify
is specified with an unsupported value, it MUST fail to bootstrap. - BootstrapR14.2
-
if
--server-ssl-verify
is not specified,DISABLED
value MUST be written to the generated configuration file's[DEFAULT]
section asserver_ssl_verify
. - BootstrapR15
-
if
--client-ssl-mode
isPASSTHROUGH
and--server-ssl-mode
is specified and notAS_CLIENT
, bootstrap MUST fail. - BootstrapR16
-
if
--client-ssl-mode
is notDISABLED
norPASSTHROUGH
and neither--client-ssl-cert
nor--client-ssl-key
are specified, bootstrap MUST try to create self-signed certificate and write their filenames to theDEFAULT
section'sclient_ssl_cert
andclient_ssl_key
. - BootstrapR16.1
- if generation of certificates fails, bootstrap MUST fail.
Specification
Bootstrap
The mysqlrouter
executable gets new command line options:
--client-ssl-mode
--client-ssl-cipher
--client-ssl-curves
--client-ssl-cert
--client-ssl-dh-params
--client-ssl-key
--server-ssl-mode
--server-ssl-cipher
--server-ssl-curves
--server-ssl-ca
--server-ssl-capath
--server-ssl-crl
--server-ssl-crlpath
--server-ssl-verify
--client-ssl-mode
Sets client_ssl_mode
used by all [routing]
used by default.
--client-ssl-cipher
Sets client_ssl_cipher
used by all [routing]
used by default.
--client-ssl-curves
Sets client_ssl_curves
used by all [routing]
used by default.
--client-ssl-cert
Sets client_ssl_cert
used by all [routing]
used by default.
--client-ssl-dh-params
Sets client_ssl_dh_params
used by all [routing]
used by default.
--client-ssl-key
Sets client_ssl_key
used by all [routing]
used by default.
--server-ssl-mode
Sets server_ssl_mode
used by all [routing]
used by default.
--server-ssl-cipher
Sets server_ssl_cipher
used by all [routing]
used by default.
--server-ssl-curves
Sets server_ssl_curves
used by all [routing]
used by default.
--server-ssl-ca
Sets server_ssl_ca
used by all [routing]
used by default.
--server-ssl-capath
Sets server_ssl_capath
used by all [routing]
used by default.
--server-ssl-crl
Sets server_ssl_crl
used by all [routing]
used by default.
--server-ssl-crlpath
Sets server_ssl_crlpath
used by all [routing]
used by default.
--server-ssl-verify
Sets server_ssl_verify
used by all [routing]
used by default.
Configuration
The configuration file's [DEFAULT]
section and [routing]
section get new options:
client_ssl_mode
client_ssl_cipher
client_ssl_curves
client_ssl_cert
client_ssl_key
server_ssl_mode
server_ssl_verify
server_ssl_cipher
server_ssl_curves
server_ssl_ca
server_ssl_capath
server_ssl_crl
server_ssl_crlpath
client_ssl_key
The path name of the SSL private key file in PEM format used to encrypt client-to-router connections.
- type
- file name
- default
- not set
client_ssl_cert
The path name of the SSL public key certificate file in PEM format used to encrypt client-to-router connections.
- type
- file name
- default
- not set
client_ssl_mode
Controls if connections from client to router must be encrypted.
- type
- string (case-insensitive)
- allowed values
-
DISABLED
,PREFERRED
,REQUIRED
,PASSTHROUGH
- default
-
PREFERRED
ifclient_ssl_cert
orclient_ssl_key
are set,PASSTHROUGH
otherwise
client_ssl_cipher
The list of permissible encryption ciphers for connections that use TLS protocols up through TLSv1.2. If no cipher in the list is supported, encrypted connections that use these TLS protocols will not work.
(taken from https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_ssl_cipher)
- type
- string
- format
- a list of one or more cipher names, separated by colons
- default
- a secure list of ssl ciphers
Exact behaviour depends on SSL library used.
- OpenSSL supports the syntax for specifying ciphers described in the OpenSSL documentation at https://www.openssl.org/docs/man1.1.1/man1/ciphers.html.
client_ssl_curves
Which elliptic curves are allowed between client and router.
The list of permissible curves used by elliptic curve ciphers and signatures for connections that use TLS protocols up through TLSv1.2.
If no curve in the list is supported, elliptic curves algorithms will not work.
- type
- string
- format
- a colon separated list of curve NIDs or names, for example "P-521:P-384:P-256".
- default
- a secure list of ssl curves
client_ssl_dh_params
Filename of the a DH parameter file. If specified and non-empty the DH params from the file are used instead of internal default DH params.
- type
- filename
- format
- a DH param file in PEM format.
- default
- not set
server_ssl_mode
Controls if connections from router to server must be encrypted.
- type
- string (case-insensitive)
- allowed values
-
DISABLED
,PREFERRED
,REQUIRED
,AS_CLIENT
- default
-
AS_CLIENT
server_ssl_verify
Verification of the SSL certificates presented to the router by the server.
- type
- string (case-insensitive)
- allowed values
-
DISABLED
,VERIFY_CA
,VERIFY_IDENTITY
- default
-
DISABLED
DISABLED
: connection fails, if server doesn't provide a certificate at handshakeVERIFY_CA
: connection fails, if server's certificate doesn't match any of the CAs the router trusts.VERIFY_IDENTITY
: connection fails, if server's certificate doesn't match any of the CAs the router trusts or the server's certificate subject doesn't match the hostname/ip the router connected to.
See server_ssl_ca
and server_ssl_capath
about how the router trusts the CAs.
server_ssl_ca
The path name of the Certificate Authority (CA) certificate file in PEM format. The file contains a list of trusted SSL Certificate Authorities.
- type
- filename
- default
- none
server_ssl_capath
The path name of the directory that contains trusted SSL Certificate Authority (CA) certificate files in PEM format.
- type
- directory name
- default
- none
server_ssl_cipher
- type
- string
- format
- a list of one or more cipher names, separated by colons
- default
- a secure list of ssl ciphers
server_ssl_crl
The path name of the file containing certificate revocation lists in PEM format.
- type
- file name
- default
- not set
server_ssl_crlpath
The path of the directory that contains certificate revocation-list files in PEM format.
- type
- directory name
- default
- not set
server_ssl_curves
- type
- string
- format
- colon separated list of curve names
- default
- a secure list of ssl curves
client_ssl_mode
+ server_ssl_mode
The client_ssl_mode
and server_ssl_mode
allow to control how encryption
between client-router and router-server are negotiated.
client-router
If the client-router connection ssl::client
can be encrypted depends on:
- the router's configuration for
client_ssl_mode
andserver_ssl_mode
- the client's and server's TLS capability.
For client_ssl_mode
DISABLED
- router will not announce the TLS capability to the client. The client may continue with a PLAIN connection to the router or abort the connection.
PREFERRED
-
router will announce the TLS capability to the client if
server_ssl_mode
is notAS_CLIENT
. Ifserver_ssl_mode
isAS_CLIENT
and the server does not support TLS, the TLS capability will not be announced. The client may continue with a PLAIN connection or switch the connection with the router to TLS. REQUIRED
-
router will open a TLS endpoint and will announce the TLS capability
to the client if
server_ssl_mode
is notAS_CLIENT
. Ifserver_ssl_mode
isAS_CLIENT
and the server does not support TLS, the TLS capability will not be announced. If the client does not switch the client-router connection to TLS before authentication, the authentication will fail. PASSTHROUGH
- router will announce the server's TLS capability to the client as is. The client may continue with a PLAIN connection or switch to TLS. The TLS connection will be established between client and server and the router will not be able to decrypt the TLS traffic.
client_ssl_mode |
server_ssl_mode |
ssl-cap::client | ssl-cap::server | ssl::client |
---|---|---|---|---|
DISABLED |
any | any | any | PLAIN |
PREFERRED |
any | [ ] |
any | PLAIN |
PREFERRED |
any | [x] |
any | SSL |
REQUIRED |
any | [ ] |
any | FAIL |
REQUIRED |
any | [x] |
any | SSL |
PASSTHROUGH |
AS_CLIENT |
any | [ ] |
PLAIN |
PASSTHROUGH |
AS_CLIENT |
[ ] |
[x] |
PLAIN |
PASSTHROUGH |
AS_CLIENT |
[x] |
[x] |
(SSL) |
* PLAIN
: connection unencrypted
* SSL
: connection encrypted, TLS endpoint
* (SSL)
: connection encrypted, no TLS endpoint
* FAIL
: connection fails
router-server
If the router-server connection ssl::server
can be encrypted depends on:
- the router's configuration for
client_ssl_mode
andserver_ssl_mode
- the client's and server's TLS capability.
For server_ssl_mode
DISABLED
- The router will connect to the server with a PLAIN connection. The server MAY fail authentication if the connection is not encrypted.
PREFERRED
- The router will connect to the server with a TLS connection if the server supports it, and use PLAIN connection if not.
REQUIRED
- The router will connect to the server with a TLS connection if the server supports it, and send an error to the client and close the connection if not.
AS_CLIENT
-
The router will forward the server's TLS capability to the client if the
client_ssl_mode
is notDISABLED
and switch to TLS if the server supports it and the client switched to TLS.
client_ssl_mode |
server_ssl_mode |
ssl-cap::client | ssl-cap::server | ssl::server |
---|---|---|---|---|
any | DISABLED |
any | any | PLAIN |
any | PREFERRED |
any | [ ] |
PLAIN |
any | PREFERRED |
any | [x] |
SSL |
any | REQUIRED |
any | [ ] |
FAIL |
any | REQUIRED |
any | [x] |
SSL |
PASSTHROUGH |
AS_CLIENT |
any | [ ] |
PLAIN |
PASSTHROUGH |
AS_CLIENT |
[ ] |
[x] |
PLAIN |
PASSTHROUGH |
AS_CLIENT |
[x] |
[x] |
(SSL) |
DISABLED |
AS_CLIENT |
any | any | PLAIN |
PREFERRED |
AS_CLIENT |
[ ] |
[x] |
PLAIN |
PREFERRED |
AS_CLIENT |
any | [ ] |
PLAIN |
PREFERRED |
AS_CLIENT |
[x] |
[x] |
SSL |
REQUIRED |
AS_CLIENT |
[ ] |
[x] |
PLAIN |
REQUIRED |
AS_CLIENT |
any | [ ] |
FAIL |
REQUIRED |
AS_CLIENT |
[x] |
[x] |
SSL |
* PLAIN
: connection unencrypted
* SSL
: connection encrypted, TLS endpoint
* (SSL)
: connection encrypted, no TLS endpoint
* FAIL
: connection fails
Expected performance impact
Given that the
- openssl overhead
- TLS handshake impact
- TLS encrypt/decrypt impact
TLS handshake impact
As the router has to do both sides of the handshake, and both handshakes are costly, it must ensure that:
- TLS session resumption
can be utilized to avoid the cost of a full handshake.
The cost of a TLS handshake (without network latency) is:
- 6ms TLS full handshake.
- 2ms TLS session resumption.
Adding network latency on top the extra round-trips of a full handshake are even more costly.
ECDSA vs RSA
The server must sign, and the client must verify the signature in the full handshake. The cost of both operations differs depending on the public key algorithm used:
$ openssl speed rsa2048 ecdsap256
sign | verify | sign/s | verify/s | |
---|---|---|---|---|
rsa 2048 bits | 0.000482s | 0.000014s | 2073.1 | 71423.2 |
256 bits ecdsa (nistp256) | 0.0000s | 0.0001s | 58837.8 | 18614.0 |
Using ECDSA certificates would allow to free the router from a part of the handshake cost and move that cost to the client. Given that many clients are expected to connect to the router, it makes sense to allow to move more CPU time to the client.
TLS encrypt/decrypt impact
Using openssl speed
to check the most used block cipher:
$ openssl speed aes-256-cbc
byte/s
16 bytes 145390.02k
64 bytes 154363.69k
256 bytes 156149.76k
1024 bytes 314356.39k
8192 bytes 316304.04k
16384 bytes 319307.17k
A single core (~4GHz) can encrypt 1Gbit/s - 2.5Gbit/s without AES-NI.
$ openssl speed -evp aes-256-cbc
byte/s
16 1052149.54k
64 1192553.41k
256 1227219.54k
1024 1239889.92k
8192 1242598.06k
16384 1246625.13k
Enabling AES-NI brings up the single core encryption rate to 8-10GBit/s which brings is nicely to the limit of the expected network.
Using TLS 1.2/1.3 we have AES-256-GCM available which brings:
$ openssl speed -evp aes-256-gcm
16 625809.02k
64 1672981.31k
256 3027140.69k
1024 4145966.08k
8192 4812051.80k
16384 4839724.37k
... ~38Gbit/s on a single core.
If aes-128-gcm is secure enough, the throughput for 16k blocks would reach 52Mbyte/s ... 41Gbit/s on a single core.
Utilizing all 12 cores:
$ openssl speed -multi 12 -evp aes-256-gcm
16 6493659.75k
64 18142276.05k
256 32883796.57k
1024 45086758.57k
8192 52438436.52k
16384 52724700.50k
gives ~11 times throughput improvement which shows nice scalability.
The impact of symmetric encryption/decryption should be therefore ignorable if the network is the limiting factor.
Implementation Tasks
- integrate with openssl socket io
- store key to private key in router's keyring
- configuration
- client-tls: disabled, preferred, required
- backend-tls: disabled, preferred, required