Skip to content

Commit

Permalink
Fix: Getting TLS certificate through proxy & prometheus update (#4700)
Browse files Browse the repository at this point in the history
  • Loading branch information
chakflying authored Apr 24, 2024
1 parent add5c12 commit 1490443
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 30 deletions.
48 changes: 33 additions & 15 deletions server/model/monitor.js
Original file line number Diff line number Diff line change
Expand Up @@ -512,10 +512,16 @@ class Monitor extends BeanModel {
}
}

let tlsInfo;
// Store tlsInfo when key material is received
options.httpsAgent.on("keylog", (line, tlsSocket) => {
tlsInfo = checkCertificate(tlsSocket);
let tlsInfo = {};
// Store tlsInfo when secureConnect event is emitted
// The keylog event listener is a workaround to access the tlsSocket
options.httpsAgent.once("keylog", async (line, tlsSocket) => {
tlsSocket.once("secureConnect", async () => {
tlsInfo = checkCertificate(tlsSocket);
tlsInfo.valid = tlsSocket.authorized || false;

await this.handleTlsInfo(tlsInfo);
});
});

log.debug("monitor", `[${this.name}] Axios Options: ${JSON.stringify(options)}`);
Expand All @@ -527,19 +533,16 @@ class Monitor extends BeanModel {
bean.msg = `${res.status} - ${res.statusText}`;
bean.ping = dayjs().valueOf() - startTime;

// Store certificate and check for expiry if https is used
if (this.getUrl()?.protocol === "https:") {
// No way to listen for the `secureConnection` event, so we do it here
const tlssocket = res.request.res.socket;
// fallback for if kelog event is not emitted, but we may still have tlsInfo,
// e.g. if the connection is made through a proxy
if (this.getUrl()?.protocol === "https:" && tlsInfo.valid === undefined) {
const tlsSocket = res.request.res.socket;

if (tlssocket) {
tlsInfo.valid = tlssocket.authorized || false;
}
if (tlsSocket) {
tlsInfo = checkCertificate(tlsSocket);
tlsInfo.valid = tlsSocket.authorized || false;

await this.updateTlsInfo(tlsInfo);
if (!this.getIgnoreTls() && this.isEnabledExpiryNotification()) {
log.debug("monitor", `[${this.name}] call checkCertExpiryNotifications`);
await this.checkCertExpiryNotifications(tlsInfo);
await this.handleTlsInfo(tlsInfo);
}
}

Expand Down Expand Up @@ -1679,6 +1682,21 @@ class Monitor extends BeanModel {
const parentActive = await Monitor.isParentActive(parent.id);
return parent.active && parentActive;
}

/**
* Store TLS certificate information and check for expiry
* @param {Object} tlsInfo Information about the TLS connection
* @returns {Promise<void>}
*/
async handleTlsInfo(tlsInfo) {
await this.updateTlsInfo(tlsInfo);
this.prometheus?.update(null, tlsInfo);

if (!this.getIgnoreTls() && this.isEnabledExpiryNotification()) {
log.debug("monitor", `[${this.name}] call checkCertExpiryNotifications`);
await this.checkCertExpiryNotifications(tlsInfo);
}
}
}

module.exports = Monitor;
32 changes: 17 additions & 15 deletions server/prometheus.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,23 +79,25 @@ class Prometheus {
}
}

try {
monitorStatus.set(this.monitorLabelValues, heartbeat.status);
} catch (e) {
log.error("prometheus", "Caught error");
log.error("prometheus", e);
}
if (heartbeat) {
try {
monitorStatus.set(this.monitorLabelValues, heartbeat.status);
} catch (e) {
log.error("prometheus", "Caught error");
log.error("prometheus", e);
}

try {
if (typeof heartbeat.ping === "number") {
monitorResponseTime.set(this.monitorLabelValues, heartbeat.ping);
} else {
// Is it good?
monitorResponseTime.set(this.monitorLabelValues, -1);
try {
if (typeof heartbeat.ping === "number") {
monitorResponseTime.set(this.monitorLabelValues, heartbeat.ping);
} else {
// Is it good?
monitorResponseTime.set(this.monitorLabelValues, -1);
}
} catch (e) {
log.error("prometheus", "Caught error");
log.error("prometheus", e);
}
} catch (e) {
log.error("prometheus", "Caught error");
log.error("prometheus", e);
}
}

Expand Down

0 comments on commit 1490443

Please sign in to comment.