You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficcontrol.apache.org by zr...@apache.org on 2021/09/21 22:08:58 UTC
[trafficcontrol] 07/09: Le regex fix (#6184)
This is an automated email from the ASF dual-hosted git repository.
zrhoffman pushed a commit to branch 6.0.x
in repository https://gitbox.apache.org/repos/asf/trafficcontrol.git
commit 675de0795e06af90d9dacf3de6561d1a232fb1d4
Author: mattjackson220 <33...@users.noreply.github.com>
AuthorDate: Mon Sep 20 16:11:38 2021 -0600
Le regex fix (#6184)
* Lets Encrypt updated for domains that don't contain the xmlid
* updated changelog
(cherry picked from commit 14d8d8ecc1660c183afc36678cc55d73dc9a9aa6)
---
CHANGELOG.md | 1 +
...21090914220900_le_dns_challenge_xml_id.down.sql | 18 +++++++++
...2021090914220900_le_dns_challenge_xml_id.up.sql | 18 +++++++++
.../traffic_ops_golang/deliveryservice/acme.go | 12 +++---
.../deliveryservice/acme_renew.go | 2 +-
.../deliveryservice/letsencrypt_dns_challenge.go | 5 ++-
.../core/ds/LetsEncryptDnsChallenge.java | 16 +++++++-
.../core/ds/LetsEncryptDnsChallengeWatcher.java | 45 +++++++++++-----------
8 files changed, 84 insertions(+), 33 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0e01602..1fd6704 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -106,6 +106,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
- Fixed Federations IMS so TR federations watcher will get updates.
- [#5129](https://github.com/apache/trafficcontrol/issues/5129) - Updated TM so that it returns a 404 if the endpoint is not supported.
- Fixed Traffic Router crs/stats to prevent overflow and to correctly record the time used in averages.
+- [#6093](https://github.com/apache/trafficcontrol/issues/6093) - Fixed Let's Encrypt to work for delivery services where the domain does not contain the XMLID.
### Changed
- Migrated completely off of bower in favor of npm
diff --git a/traffic_ops/app/db/migrations/2021090914220900_le_dns_challenge_xml_id.down.sql b/traffic_ops/app/db/migrations/2021090914220900_le_dns_challenge_xml_id.down.sql
new file mode 100644
index 0000000..d2e7e61
--- /dev/null
+++ b/traffic_ops/app/db/migrations/2021090914220900_le_dns_challenge_xml_id.down.sql
@@ -0,0 +1,18 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+ALTER TABLE dnschallenges DROP COLUMN IF EXISTS xml_id;
diff --git a/traffic_ops/app/db/migrations/2021090914220900_le_dns_challenge_xml_id.up.sql b/traffic_ops/app/db/migrations/2021090914220900_le_dns_challenge_xml_id.up.sql
new file mode 100644
index 0000000..64df6a0
--- /dev/null
+++ b/traffic_ops/app/db/migrations/2021090914220900_le_dns_challenge_xml_id.up.sql
@@ -0,0 +1,18 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+ALTER TABLE dnschallenges ADD COLUMN xml_id text NOT NULL;
diff --git a/traffic_ops/traffic_ops_golang/deliveryservice/acme.go b/traffic_ops/traffic_ops_golang/deliveryservice/acme.go
index 044a466..e89b8e6 100644
--- a/traffic_ops/traffic_ops_golang/deliveryservice/acme.go
+++ b/traffic_ops/traffic_ops_golang/deliveryservice/acme.go
@@ -82,7 +82,8 @@ func (u *MyUser) GetPrivateKey() crypto.PrivateKey {
// DNSProviderTrafficRouter is used in the lego library and contains a database in order to store the DNS challenges for ACME protocol.
type DNSProviderTrafficRouter struct {
- db *sqlx.DB
+ db *sqlx.DB
+ xmlId *string
}
// NewDNSProviderTrafficRouter returns a new DNSProviderTrafficRouter object.
@@ -100,8 +101,8 @@ func (d *DNSProviderTrafficRouter) Present(domain, token, keyAuth string) error
tx, err := d.db.Begin()
fqdn, value := dns01.GetRecord(domain, keyAuth)
- q := `INSERT INTO dnschallenges (fqdn, record) VALUES ($1, $2)`
- response, err := tx.Exec(q, fqdn, value)
+ q := `INSERT INTO dnschallenges (fqdn, record, xml_id) VALUES ($1, $2, $3)`
+ response, err := tx.Exec(q, fqdn, value, *d.xmlId)
tx.Commit()
if err != nil {
log.Errorf("Inserting dns txt record for fqdn '" + fqdn + "' record '" + value + "': " + err.Error())
@@ -439,7 +440,7 @@ func GetAcmeCertificates(cfg *config.Config, req tc.DeliveryServiceAcmeSSLKeysRe
account = acmeAccount
}
- client, err := GetAcmeClient(account, userTx, db)
+ client, err := GetAcmeClient(account, userTx, db, req.Key)
if err != nil {
log.Errorf("acme: getting acme client for provider %s: %v", provider, err)
api.CreateChangeLogRawTx(api.ApiChange, "DS: "+*req.DeliveryService+", ID: "+strconv.Itoa(dsID)+", ACTION: FAILED to add SSL keys with "+provider, currentUser, logTx)
@@ -560,7 +561,7 @@ func GetAcmeAccountConfig(cfg *config.Config, acmeProvider string) *config.Confi
}
// GetAcmeClient uses the ACME account information in either cdn.conf or the database to create and register an ACME client.
-func GetAcmeClient(acmeAccount *config.ConfigAcmeAccount, userTx *sql.Tx, db *sqlx.DB) (*lego.Client, error) {
+func GetAcmeClient(acmeAccount *config.ConfigAcmeAccount, userTx *sql.Tx, db *sqlx.DB, xmlId *string) (*lego.Client, error) {
if acmeAccount.UserEmail == "" {
log.Errorf("An email address must be provided to use ACME with %v", acmeAccount.AcmeProvider)
return nil, errors.New("An email address must be provided to use ACME with " + acmeAccount.AcmeProvider)
@@ -610,6 +611,7 @@ func GetAcmeClient(acmeAccount *config.ConfigAcmeAccount, userTx *sql.Tx, db *sq
client.Challenge.Remove(challenge.TLSALPN01)
trafficRouterDns := NewDNSProviderTrafficRouter()
trafficRouterDns.db = db
+ trafficRouterDns.xmlId = xmlId
if err != nil {
log.Errorf("Error creating Traffic Router DNS provider: %s", err.Error())
return nil, err
diff --git a/traffic_ops/traffic_ops_golang/deliveryservice/acme_renew.go b/traffic_ops/traffic_ops_golang/deliveryservice/acme_renew.go
index 7b92526..eb7c78a 100644
--- a/traffic_ops/traffic_ops_golang/deliveryservice/acme_renew.go
+++ b/traffic_ops/traffic_ops_golang/deliveryservice/acme_renew.go
@@ -145,7 +145,7 @@ func renewAcmeCerts(cfg *config.Config, dsName string, ctx context.Context, http
return nil, errors.New("No acme account information in cdn.conf for " + keyObj.AuthType), http.StatusInternalServerError
}
- client, err := GetAcmeClient(acmeAccount, userTx, db)
+ client, err := GetAcmeClient(acmeAccount, userTx, db, &dsName)
if err != nil {
api.CreateChangeLogRawTx(api.ApiChange, "DS: "+dsName+", ID: "+strconv.Itoa(*dsID)+", ACTION: FAILED to add SSL keys with "+acmeAccount.AcmeProvider, currentUser, logTx)
return nil, errors.New("getting acme client: " + err.Error()), http.StatusInternalServerError
diff --git a/traffic_ops/traffic_ops_golang/deliveryservice/letsencrypt_dns_challenge.go b/traffic_ops/traffic_ops_golang/deliveryservice/letsencrypt_dns_challenge.go
index 45fb560..a9af8cd 100644
--- a/traffic_ops/traffic_ops_golang/deliveryservice/letsencrypt_dns_challenge.go
+++ b/traffic_ops/traffic_ops_golang/deliveryservice/letsencrypt_dns_challenge.go
@@ -33,6 +33,7 @@ import (
type DnsRecord struct {
Fqdn *string `json:"fqdn" db:"fqdn"`
Record *string `json:"record" db:"record"`
+ XmlId *string `json:"xmlId" db:"xml_id"`
}
func GetDnsChallengeRecords(w http.ResponseWriter, r *http.Request) {
@@ -43,7 +44,7 @@ func GetDnsChallengeRecords(w http.ResponseWriter, r *http.Request) {
}
defer inf.Close()
- getQuery := `SELECT fqdn, record FROM dnschallenges`
+ getQuery := `SELECT fqdn, record, xml_id FROM dnschallenges`
queryParamsToQueryCols := map[string]dbhelpers.WhereColumnInfo{
"fqdn": dbhelpers.WhereColumnInfo{Column: "fqdn"},
@@ -73,7 +74,7 @@ func getDnsRecords(tx *sqlx.Tx, getQuery string, queryValues map[string]interfac
defer rows.Close()
for rows.Next() {
record := DnsRecord{}
- if err := rows.Scan(&record.Fqdn, &record.Record); err != nil {
+ if err := rows.Scan(&record.Fqdn, &record.Record, &record.XmlId); err != nil {
return nil, errors.New("scanning dns challenge records: " + err.Error())
}
records = append(records, record)
diff --git a/traffic_router/core/src/main/java/org/apache/traffic_control/traffic_router/core/ds/LetsEncryptDnsChallenge.java b/traffic_router/core/src/main/java/org/apache/traffic_control/traffic_router/core/ds/LetsEncryptDnsChallenge.java
index 8261ba0..2260825 100644
--- a/traffic_router/core/src/main/java/org/apache/traffic_control/traffic_router/core/ds/LetsEncryptDnsChallenge.java
+++ b/traffic_router/core/src/main/java/org/apache/traffic_control/traffic_router/core/ds/LetsEncryptDnsChallenge.java
@@ -26,6 +26,9 @@ public class LetsEncryptDnsChallenge {
@JsonProperty
private String record;
+ @JsonProperty
+ private String xmlId;
+
public String getFqdn() {
return fqdn;
}
@@ -42,6 +45,14 @@ public class LetsEncryptDnsChallenge {
this.record = record;
}
+ public String getXmlId() {
+ return xmlId;
+ }
+
+ public void setXmlId(final String xmlId) {
+ this.xmlId = xmlId;
+ }
+
@Override
public boolean equals(final Object o) {
if (this == o) {
@@ -52,11 +63,12 @@ public class LetsEncryptDnsChallenge {
}
final LetsEncryptDnsChallenge that = (LetsEncryptDnsChallenge) o;
return fqdn.equals(that.fqdn) &&
- record.equals(that.record);
+ record.equals(that.record) &&
+ xmlId.equals(that.xmlId);
}
@Override
public int hashCode() {
- return Objects.hash(fqdn, record);
+ return Objects.hash(fqdn, record, xmlId);
}
}
diff --git a/traffic_router/core/src/main/java/org/apache/traffic_control/traffic_router/core/ds/LetsEncryptDnsChallengeWatcher.java b/traffic_router/core/src/main/java/org/apache/traffic_control/traffic_router/core/ds/LetsEncryptDnsChallengeWatcher.java
index 957bf06..5ebc89c 100644
--- a/traffic_router/core/src/main/java/org/apache/traffic_control/traffic_router/core/ds/LetsEncryptDnsChallengeWatcher.java
+++ b/traffic_router/core/src/main/java/org/apache/traffic_control/traffic_router/core/ds/LetsEncryptDnsChallengeWatcher.java
@@ -31,6 +31,7 @@ import org.apache.log4j.Logger;
import java.io.*;
import java.time.Instant;
import java.util.HashMap;
+import java.util.Iterator;
import java.util.List;
public class LetsEncryptDnsChallengeWatcher extends AbstractResourceWatcher {
@@ -57,35 +58,33 @@ public class LetsEncryptDnsChallengeWatcher extends AbstractResourceWatcher {
challengeList.forEach(challenge -> {
- final StringBuilder sb = new StringBuilder();
- sb.append(challenge.getFqdn());
- if (!challenge.getFqdn().endsWith(".")) {
- sb.append('.');
+ final ObjectNode deliveryServiceConfig = (ObjectNode) deliveryServicesNode.get(challenge.getXmlId());
+ if (deliveryServiceConfig == null) {
+ LOGGER.error("finding deliveryservice in cr-config for " + challenge.getXmlId());
+ return;
}
- final String challengeDomain = sb.toString();
- final String fqdn = challengeDomain.substring(0, challengeDomain.length() - 1).replace("_acme-challenge.", "");
-
- ObjectNode deliveryServiceConfig = null;
- String dsLabel = "";
- final StringBuilder nameSb = new StringBuilder();
- nameSb.append("_acme-challenge");
- for (final String label : fqdn.split("\\.")) {
- deliveryServiceConfig = (ObjectNode) deliveryServicesNode.get(label);
- if (deliveryServiceConfig != null) {
- dsLabel = label;
- break;
- } else {
- nameSb.append('.');
- nameSb.append(label);
- }
+
+ String staticEntryString = challenge.getFqdn();
+ final ArrayNode domains = (ArrayNode) deliveryServiceConfig.get("domains");
+ if (domains == null || domains.size() == 0) {
+ LOGGER.error("no domains found in cr-config for deliveryservice " + challenge.getXmlId());
+ return;
+ }
+
+ final Iterator<JsonNode> domainIter = domains.iterator();
+ while(domainIter.hasNext()) {
+ final JsonNode domainNode = domainIter.next();
+ staticEntryString = staticEntryString.replace(domainNode.asText() + ".", "");
}
- final String name = nameSb.toString();
+ if (staticEntryString.endsWith(".")) {
+ staticEntryString = staticEntryString.substring(0, staticEntryString.length() - 1);
+ }
- final ArrayNode staticDnsEntriesNode = updateStaticEntries(challenge, name, mapper, deliveryServiceConfig);
+ final ArrayNode staticDnsEntriesNode = updateStaticEntries(challenge, staticEntryString, mapper, deliveryServiceConfig);
deliveryServiceConfig.set("staticDnsEntries", staticDnsEntriesNode);
- deliveryServicesNode.set(dsLabel, deliveryServiceConfig);
+ deliveryServicesNode.set(challenge.getXmlId(), deliveryServiceConfig);
});