Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Traffic Router default certificate configuration for port 443 #7089

Closed
mkrug1981 opened this issue Sep 27, 2022 · 1 comment · Fixed by #7135
Closed

Traffic Router default certificate configuration for port 443 #7089

mkrug1981 opened this issue Sep 27, 2022 · 1 comment · Fixed by #7135
Assignees
Labels
improvement The functionality exists but it could be improved in some way.

Comments

@mkrug1981
Copy link

mkrug1981 commented Sep 27, 2022

This Improvement request (usability, performance, tech debt, etc.) affects these Traffic Control components:

  • Traffic Router

Current behavior:

Currently it seems not possible to configure the default TLS certificate or use a custom one.

private static HandshakeData createDefaultSsl() {
try {
final KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(2048);
final KeyPair keyPair = keyPairGenerator.generateKeyPair();
//Generate self signed certificate
final X509Certificate[] chain = new X509Certificate[1];
// Select provider
Security.addProvider(new BouncyCastleProvider());
// Generate cert details
final long now = System.currentTimeMillis();
final Date startDate = new Date(System.currentTimeMillis());
final X500Name dnName = new X500Name("C=US; ST=CO; L=Denver; " +
"O=Apache Traffic Control; OU=Apache Foundation; OU=Hosted by Traffic Control; " +
"OU=CDNDefault; CN="+DEFAULT_SSL_KEY);
final BigInteger certSerialNumber = new BigInteger(Long.toString(now));
final Calendar calendar = Calendar.getInstance();
calendar.setTime(startDate);
calendar.add(Calendar.YEAR, 3);
final Date endDate = calendar.getTime();
// Build certificate
final ContentSigner contentSigner = new JcaContentSignerBuilder("SHA1WithRSA").build(keyPair.getPrivate());
final JcaX509v3CertificateBuilder certBuilder = new JcaX509v3CertificateBuilder(dnName, certSerialNumber, startDate, endDate, dnName, keyPair.getPublic());
// Attach extensions
certBuilder.addExtension(Extension.basicConstraints, true, new BasicConstraints(true));
certBuilder.addExtension(Extension.keyUsage, true, new KeyUsage(KeyUsage.digitalSignature | KeyUsage.keyEncipherment | KeyUsage.keyCertSign));
certBuilder.addExtension(Extension.extendedKeyUsage, true, new ExtendedKeyUsage(new KeyPurposeId[] {
KeyPurposeId.id_kp_clientAuth,
KeyPurposeId.id_kp_serverAuth
}));
// Generate final certificate
final X509CertificateHolder certHolder = certBuilder.build(contentSigner);
final JcaX509CertificateConverter converter = new JcaX509CertificateConverter();
converter.setProvider(new BouncyCastleProvider());
chain[0] = converter.getCertificate(certHolder);
return new HandshakeData(DEFAULT_SSL_KEY, DEFAULT_SSL_KEY, chain, keyPair.getPrivate());
}

It always uses as Example SHA1WithRSA as sigalg. Would be nice to use SHA256WithRSA instead.

Further more it looks like it is unclear how to provide a Default certificate via TO, Following code

// Check to see if a Default cert has been provided by Traffic Ops
if (!master.containsKey(DEFAULT_SSL_KEY)){
// Check to see if a Default cert has been provided/created previously
if (handshakeDataMap.containsKey(DEFAULT_SSL_KEY)) {
master.put(DEFAULT_SSL_KEY, handshakeDataMap.get(DEFAULT_SSL_KEY));
}else{
// create a new default certificate
final HandshakeData defaultHd = createDefaultSsl();
if (defaultHd == null){
log.error("Failed to initialize the CertificateRegistry because of a problem with the 'default' " +
"certificate. Returning the Certificate Registry without a default.");
return;
}
master.put(DEFAULT_SSL_KEY, defaultHd);
}
}

New behavior:

Please make the default certificate configurable or at least allow to set values like sigalg via a configuration file.
Besides it would be nice if a custom default certificate could be used rather than the build in methodology from TR

@mkrug1981 mkrug1981 added the improvement The functionality exists but it could be improved in some way. label Sep 27, 2022
@mkrug1981
Copy link
Author

mkrug1981 commented Sep 27, 2022

What I have tried already is to try and set a certificate via keyStore file with CN=default.invalid which the java code looks for


Your keystore contains 1 entry

Alias name: sn-tr0001-blstg
Creation date: 26 Sep 2022
Entry type: PrivateKeyEntry
Certificate chain length: 1
Certificate[1]:
Owner: CN=default.invalid, OU=APIDefault, O=Apache Traffic Control, L=Denver, ST=Colorado, C=US
Issuer: CN=default.invalid, OU=APIDefault, O=Apache Traffic Control, L=Denver, ST=Colorado, C=US
Serial number: 7816ef6f
Valid from: Mon Sep 26 19:55:54 UTC 2022 until: Thu Sep 23 19:55:54 UTC 2032
Certificate fingerprints:
         SHA1: A7:8A:35:BE:9F:76:3E:C8:36:98:3A:A8:74:63:2E:78:24:34:30:00
         SHA256: 9A:F3:0A:13:3E:33:FE:5F:B5:38:C4:ED:27:A8:81:BC:70:6F:A9:6C:9C:A8:82:06:A7:F4:01:F4:05:2B:51:5D
Signature algorithm name: SHA256withRSA
Subject Public Key Algorithm: 2048-bit RSA key
Version: 3```

Unfortunately I still get the certificate back which the java code generates during TR startup
[trafficcontrol/traffic_router/connector/src/main/java/org/apache/traffic_control/traffic_router/secure/CertificateRegistry.java](https://github.com/apache/trafficcontrol/blob/070df30363152ce63aa4111e7ad7678ca6c1d280/traffic_router/connector/src/main/java/org/apache/traffic_control/traffic_router/secure/CertificateRegistry.java#L81-L129)

**curl Examples:**
--- 1st the CN from the certificate
```$ curl -vv -o /dev/null https://sn-tr0001-blstg/check --resolve sn-tr0001-blstg:443:176.xx.xx.xx -k          
* Added sn-tr0001-blstg:443:176.xx.xx.xx to DNS cache
* Hostname sn-tr0001-blstg was found in DNS cache
*   Trying 176.255.213.70:443...
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0* Connected to sn-tr0001-blstg (176.255.213.70) port 443 (#0)
* ALPN: offers h2
* ALPN: offers http/1.1
} [5 bytes data]
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
} [512 bytes data]
* TLSv1.3 (IN), TLS handshake, Server hello (2):
{ [61 bytes data]
* TLSv1.2 (IN), TLS handshake, Certificate (11):
{ [975 bytes data]
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
{ [333 bytes data]
* TLSv1.2 (IN), TLS handshake, Server finished (14):
{ [4 bytes data]
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
} [70 bytes data]
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
} [1 bytes data]
* TLSv1.2 (OUT), TLS handshake, Finished (20):
} [16 bytes data]
* TLSv1.2 (IN), TLS handshake, Finished (20):
{ [16 bytes data]
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
* ALPN: server did not agree on a protocol. Uses default.
* Server certificate:
*  subject: C=US; ST=Colorado; L=Denver; O=Apache Traffic Control; OU=APIDefault; CN=default.invalid
*  start date: Sep 26 19:55:54 2022 GMT
*  expire date: Sep 23 19:55:54 2032 GMT
*  issuer: C=US; ST=Colorado; L=Denver; O=Apache Traffic Control; OU=APIDefault; CN=default.invalid
*  SSL certificate verify result: self signed certificate (18), continuing anyway.
} [5 bytes data]
> GET /check HTTP/1.1
> Host: sn-tr0001-blstg
> User-Agent: curl/7.85.0
> Accept: */*
> 
{ [5 bytes data]
* Mark bundle as not supporting multi```

--- 2nd try with a not defined hostname
```curl -vv -o /dev/null https://www.cdn99.skycdp.com/check --resolve www.cdn99.skycdp.com:443:176.255.213.70 -k
* Added www.cdn99.skycdp.com:443:176.xx.xx.xx to DNS cache
* Hostname www.cdn99.skycdp.com was found in DNS cache
*   Trying 176.xx.xx.xx:443...
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0* Connected to www.cdn99.skycdp.com (176.255.213.70) port 443 (#0)
* ALPN: offers h2
* ALPN: offers http/1.1
} [5 bytes data]
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
} [512 bytes data]
* TLSv1.3 (IN), TLS handshake, Server hello (2):
{ [61 bytes data]
* TLSv1.2 (IN), TLS handshake, Certificate (11):
{ [757 bytes data]
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
{ [333 bytes data]
* TLSv1.2 (IN), TLS handshake, Server finished (14):
{ [4 bytes data]
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
} [70 bytes data]
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
} [1 bytes data]
* TLSv1.2 (OUT), TLS handshake, Finished (20):
} [16 bytes data]
* TLSv1.2 (IN), TLS handshake, Finished (20):
{ [16 bytes data]
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
* ALPN: server did not agree on a protocol. Uses default.
* Server certificate:
*  subject: C=US; ST
*  start date: Sep 26 19:56:35 2022 GMT
*  expire date: Sep 26 19:56:35 2025 GMT
*  issuer: C=US; ST
*  SSL certificate verify result: self signed certificate (18), continuing anyway.
} [5 bytes data]
> GET /check HTTP/1.1```

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
improvement The functionality exists but it could be improved in some way.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants