f5-appsvcs-extension
f5-appsvcs-extension copied to clipboard
Unable to add both ECC and RSA certificates for a single domain (Service_HTTPS, TLS_Server)
Environment
Application Services Version: 3.28.0
BIG-IP Version: 16.0.1.1
BIG-IQ Version: 8.0.0.1
Summary
Unable to add two certificates for the same domain to a single TLS_Server / client SSL profile
Steps To Reproduce
- Create a declaration using the Service_HTTPS class, a single TLS_Server object which in its turn references two certificate objects (one RSA and one ECC certificate).
- Deploy the application
- The result will be Virtual Server with two Client SSL profiles attached.
Expected behavior
In this specific case, the certificates should be added to a single Client SSL profile.
Defining multiple certificates in a TLS_Server object results in multiple client SSL profiles on the BIG-IP. For website using multiple domain names and SNI this works just fine.
But when we need to configure both Elliptic Curve Cryptography and RSA certificates on a single virtual server, these certificates should end up in one and the same client SSL profile on the BIG-IP.
Resulting config should probably look like:
ltm profile client-ssl webtest_443/webtest_certs-1- {
...
cert-key-chain {
set1 {
cert webtest_443/ecc_cert_1.crt
chain webtest_443/ecc_cert_1-bundle.crt
key webtest_443/ecc_cert_1.key
}
set0 {
cert webtest_443/rsa_cert_1.crt
chain webtest_443/rsa_cert_1-bundle.crt
key webtest_443/rsa_cert_1.key
}
}
...
}
I've encountered this exact issue on AS3 3.29, BIGIP 14.1.2.8
.
The problem can easily be simulated with the example declaration that is meant to clarify this exact functionality:
Using multiple SSL/TLS certificates in a single profile
Unlike the description in the Schema Reference, the example declaration description and our expectations the result is two clientSSL profiles ("webtls" and "webtls-1-"), completely in line with the behavior described by @PhobicShades
To clarify: this has nothing to do with these being different (RSA vs ECC) certificates, the issue is related to multiple certificates being specified.
The description on that example is incorrect. I am working with our technical writer to update it.
This is currently working as designed. I am changing this issue to a feature request to support the use case of multiple certificates types with a single domain.
Hello do you have any information when this feature may get implemented? Kind regards Artur
Also waiting for this feature.
Since I did not find the repository where the NodeJS of AS3 is stored, I built a diff file how this could look like. I'm adding an additional boolean field "hybrid" (optional, default: false) to TLS_Server in order to have all certificates added to a single clientssl profile - with the limitation that you must not have two or more certificates of the same type (RSA/ECDSA/...) assigned to the same TLS_Server. Likewise, you cannot have more than one clientssl profile assigned to a Service_HTTPS or similar, simply because that reference is not designed as a list and setting hybrid to true generates only a single clientssl profile.
Any dev feel free to pick it up and propose it in the right place to the right folks :smiley:
If you would like to test the diff, then you would need to apply it to /var/config/rest/iapps/f5-appsvcs
and run bigstart restart restnoded
. Note that the patch binary is missing on the BIG-IP so you would need to download the content of f5-appsvcs to a local directory and the run patch -ruN -d <local_location_of_f5-appvscs> -p 1 < hybrid_v2.patch
and upload the patched files lib/map_as3.js
, schema/latest/adc-schema.json
, schema/latest/as3-schema.json
and schema/latest/core-schema.json
, pay attention to file ownership and permissions.
Please see below the content of hybrid_v2.patch
:
diff '--color=auto' -ruN a/lib/map_as3.js b/lib/map_as3.js
--- a/lib/map_as3.js 2022-01-19 23:05:24.000000000 +0100
+++ b/lib/map_as3.js 2022-03-03 13:30:50.688761100 +0100
@@ -140,7 +140,10 @@
} else {
profName = i === 0 ? n : `${n}-${i}-`;
}
- item.profiles.push({ name: profName, context });
+
+ if (!(profileDef.hybrid || false) || i === 0) {
+ item.profiles.push({ name: profName, context });
+ }
});
}
} else {
@@ -1121,28 +1124,56 @@
updateTlsOptions(item, context);
- item.certificates.forEach((obj, index) => {
+ if (item.hybrid || false) {
const tlsItem = Object.create(item);
- let itemName;
- if (item.namingScheme === 'certificate') {
- itemName = obj.certificate.split('/').pop();
- } else {
- itemName = index === 0 ? itemId : `${itemId}-${index}-`;
- }
- const path = util.mcpPath(tenantId, appId, itemName);
+ let itemName = itemId;
- tlsItem.certificates = [];
- genCert(tlsItem, obj.certificate, 'SERVER');
- genCert(tlsItem, obj.proxyCertificate, 'CA');
+ tlsItem['sni-default'] = true;
+ tlsItem.matchToSNI = false;
+ tlsItem.mode = false;
- tlsItem['sni-default'] = index === 0;
- tlsItem.matchToSNI = obj.matchToSNI || 'none';
- tlsItem.mode = obj.enabled;
+ tlsItem.certificates = [];
+ item.certificates.forEach((obj, index) => {
+ genCert(tlsItem, obj.certificate, 'SERVER');
+ genCert(tlsItem, obj.proxyCertificate, 'CA');
+
+ if (item.namingScheme === 'certificate' && index === 0) {
+ itemName = obj.certificate.split('/').pop();
+ }
+ if (obj.matchToSNI && !tlsItem.matchToSNI) {
+ tlsItem.matchToSNI = obj.matchToSNI;
+ }
+ tlsItem.mode = tlsItem.mode || obj.enabled;
+ });
+ tlsItem.matchToSNI = tlsItem.matchToSNI || 'none';
+ const path = util.mcpPath(tenantId, appId, itemName);
configs.push(normalize.actionableMcp(context, tlsItem, 'ltm profile client-ssl', path));
- });
+ } else {
+ item.certificates.forEach((obj, index) => {
+ const tlsItem = Object.create(item);
+
+ let itemName;
+ if (item.namingScheme === 'certificate') {
+ itemName = obj.certificate.split('/').pop();
+ } else {
+ itemName = index === 0 ? itemId : `${itemId}-${index}-`;
+ }
+ const path = util.mcpPath(tenantId, appId, itemName);
+ tlsItem.certificates = [];
+ genCert(tlsItem, obj.certificate, 'SERVER');
+ genCert(tlsItem, obj.proxyCertificate, 'CA');
+
+ tlsItem['sni-default'] = index === 0;
+ tlsItem.matchToSNI = obj.matchToSNI || 'none';
+ tlsItem.mode = obj.enabled;
+
+ configs.push(normalize.actionableMcp(context, tlsItem, 'ltm profile client-ssl', path));
+ });
+ }
+
if (item.ldapStartTLS) {
const clientLdapProfile = {
activationMode: item.ldapStartTLS
diff '--color=auto' -ruN a/schema/latest/adc-schema.json b/schema/latest/adc-schema.json
--- a/schema/latest/adc-schema.json 2022-01-19 23:05:24.000000000 +0100
+++ b/schema/latest/adc-schema.json 2022-03-02 15:39:38.424597900 +0100
@@ -7889,6 +7889,12 @@
}
]
},
+ "hybrid": {
+ "title": "Hybrid Client-SSL Proflie",
+ "description": "Forces all certificates to be part of a single Client-SSL profile. Requires that all certificates are of different types (e.g. RSA, ECDSA).",
+ "type": "boolean",
+ "default": false
+ },
"ldapStartTLS": {
"title": "Client-LDAP Profile",
"description": "Creates a client LDAP profile with the specified activation mode STARTTLS.",
diff '--color=auto' -ruN a/schema/latest/as3-schema.json b/schema/latest/as3-schema.json
--- a/schema/latest/as3-schema.json 2022-01-19 23:05:24.000000000 +0100
+++ b/schema/latest/as3-schema.json 2022-03-02 15:39:17.921988400 +0100
@@ -8187,6 +8187,12 @@
}
]
},
+ "hybrid": {
+ "title": "Hybrid Client-SSL Proflie",
+ "description": "Forces all certificates to be part of a single Client-SSL profile. Requires that all certificates are of different types (e.g. RSA, ECDSA).",
+ "type": "boolean",
+ "default": false
+ },
"ldapStartTLS": {
"title": "Client-LDAP Profile",
"description": "Creates a client LDAP profile with the specified activation mode STARTTLS.",
diff '--color=auto' -ruN a/schema/latest/core-schema.json b/schema/latest/core-schema.json
--- a/schema/latest/core-schema.json 2022-01-19 23:05:24.000000000 +0100
+++ b/schema/latest/core-schema.json 2022-03-02 15:38:54.156155900 +0100
@@ -5394,6 +5394,12 @@
{ "$ref": "#/definitions/Pointer_Data_Group" }
]
},
+ "hybrid": {
+ "title": "Hybrid Client-SSL Proflie",
+ "description": "Forces all certificates to be part of a single Client-SSL profile. Requires that all certificates are of different types (e.g. RSA, ECDSA).",
+ "type": "boolean",
+ "default": false
+ },
"ldapStartTLS": {
"title": "Client-LDAP Profile",
"description": "Creates a client LDAP profile with the specified activation mode STARTTLS.",
Hi just want to ask if there is an update?
hi again
i saw that in f5-appsvcs-3.33.0-4.noarch the feature of adding two certificates was added. I used the feature and did a rollout. But i found out that it doesn't work as i thought. It creates two SSL-Profiles which is a problem is my environment.
I have a cipher list like this: so ECC certificate should be prefered
ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-CBC-SHA
But with the F5 implementation of AS3 there will be a SSL-profile with only a RSA certificate attached:
When F5 uses this SSL-Profile F5 will reply with a RSA cipher and not with a ECC-cipher.
see test with curl when i fix the ciphers to ECC certificates.
curl https://example.com/ -vI --ciphers ECDHE-ECDSA-AES256-GCM-SHA384
...................
- TCP_NODELAY set
- Connected to services.sg103.prd.sctv.ch (ip) port 443 (#0)
- ALPN, offering h2
- ALPN, offering http/1.1
- Cipher selection: ECDHE-ECDSA-AES256-GCM-SHA384
- successfully set certificate verify locations:
- CAfile: /etc/pki/tls/certs/ca-bundle.crt CApath: none
- TLSv1.3 (OUT), TLS handshake, Client hello (1):
- TLSv1.3 (IN), TLS alert, handshake failure (552):
- error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure
- Closing connection 0 curl: (35) error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure
So i want two actions from F5:
- Confirm is this is really implemented
- fix the implementation; best way would be to add two certificates into one SSL-Profile
If you are still looking for this feature, please reach out to us at [email protected] in order to prioritize
This issue has been automatically closed because there has been no response to our request for more information from the original author. With only the information that is currently in the issue, we don't have enough information to take action. Please reach out if you have or find the answers we need so that we can investigate further.