From 9f34e0d6db9aa1050987ce1286ecf8c5db872a93 Mon Sep 17 00:00:00 2001 From: Trent Mick Date: Thu, 8 Dec 2022 12:00:36 -0800 Subject: [PATCH] fix: avoid IPv4 vs IPv6 ambiguity in default 'serverUrl' by using '127.0.0.1' rather than 'localhost' (#3049) Starting in node v17 the defaults for DNS resolution order was changed (https://github.com/nodejs/node/pull/39987) such that `dns.lookup()` no longer sorted IPv4 addresses first. This impacts usage of the *default* APM Server URL (the `serverUrl` config var), 'http://localhost:8200', when using node >=17 because the APM server only binds to the IPv4 address by default (https://github.com/elastic/apm-server/issues/1405). Fixes: #3045 Refs: https://github.com/elastic/apm/pull/727 --- docs/configuration.asciidoc | 4 ++-- docs/custom-stack.asciidoc | 2 +- docs/express.asciidoc | 2 +- docs/fastify.asciidoc | 2 +- docs/hapi.asciidoc | 2 +- docs/koa.asciidoc | 2 +- docs/opentracing.asciidoc | 2 +- docs/restify.asciidoc | 2 +- docs/setup.asciidoc | 2 +- lib/agent.js | 22 +++++++++++----------- lib/config.js | 4 ++-- package-lock.json | 14 +++++++------- package.json | 2 +- test/config.test.js | 2 +- 14 files changed, 32 insertions(+), 32 deletions(-) diff --git a/docs/configuration.asciidoc b/docs/configuration.asciidoc index 9fd9f2d180..9a3397f5bd 100644 --- a/docs/configuration.asciidoc +++ b/docs/configuration.asciidoc @@ -72,7 +72,7 @@ WARNING: The API key is sent as plain-text in every request to the server, so yo ==== `serverUrl` * *Type:* String -* *Default:* `http://localhost:8200` +* *Default:* `http://127.0.0.1:8200` * *Env:* `ELASTIC_APM_SERVER_URL` The URL to where the APM Server is deployed. @@ -1146,7 +1146,7 @@ module.exports = { // Use if APM Server requires a token secretToken: '', - // Set custom APM Server URL (default: http://localhost:8200) + // Set custom APM Server URL (default: http://127.0.0.1:8200) serverUrl: '' } ---- diff --git a/docs/custom-stack.asciidoc b/docs/custom-stack.asciidoc index d8b1d0c783..52f97fd6a3 100644 --- a/docs/custom-stack.asciidoc +++ b/docs/custom-stack.asciidoc @@ -51,7 +51,7 @@ var apm = require('elastic-apm-node').start({ // Use if APM Server uses API keys for authentication apiKey: '', - // Set custom APM Server URL (default: http://localhost:8200) + // Set custom APM Server URL (default: http://127.0.0.1:8200) serverUrl: '', }) ---- diff --git a/docs/express.asciidoc b/docs/express.asciidoc index 564853e548..a4693529c8 100644 --- a/docs/express.asciidoc +++ b/docs/express.asciidoc @@ -49,7 +49,7 @@ const apm = require('elastic-apm-node').start({ // Use if APM Server uses API keys for authentication apiKey: '', - // Set custom APM Server URL (default: http://localhost:8200) + // Set custom APM Server URL (default: http://127.0.0.1:8200) serverUrl: '', }) diff --git a/docs/fastify.asciidoc b/docs/fastify.asciidoc index 0e5e9f26df..fd322a49e5 100644 --- a/docs/fastify.asciidoc +++ b/docs/fastify.asciidoc @@ -50,7 +50,7 @@ var apm = require('elastic-apm-node').start({ // Use if APM Server uses API keys for authentication apiKey: '', - // Set custom APM Server URL (default: http://localhost:8200) + // Set custom APM Server URL (default: http://127.0.0.1:8200) serverUrl: '', }) diff --git a/docs/hapi.asciidoc b/docs/hapi.asciidoc index fc263fbb9d..06b70ce7ec 100644 --- a/docs/hapi.asciidoc +++ b/docs/hapi.asciidoc @@ -46,7 +46,7 @@ const apm = require('elastic-apm-node').start({ // Use if APM Server uses API keys for authentication apiKey: '', - // Set custom APM Server URL (default: http://localhost:8200) + // Set custom APM Server URL (default: http://127.0.0.1:8200) serverUrl: '', }) diff --git a/docs/koa.asciidoc b/docs/koa.asciidoc index f963ab1e37..6153c4b484 100644 --- a/docs/koa.asciidoc +++ b/docs/koa.asciidoc @@ -54,7 +54,7 @@ const apm = require('elastic-apm-node').start({ // Use if APM Server uses API keys for authentication apiKey: '', - // Set custom APM Server URL (default: http://localhost:8200) + // Set custom APM Server URL (default: http://127.0.0.1:8200) serverUrl: '', }) diff --git a/docs/opentracing.asciidoc b/docs/opentracing.asciidoc index 3972b0e9e9..a59c06b972 100644 --- a/docs/opentracing.asciidoc +++ b/docs/opentracing.asciidoc @@ -75,7 +75,7 @@ const agent = require('elastic-apm-node').start({ // Use if APM Server uses API keys for authentication apiKey: '', - // Set custom APM Server URL (default: http://localhost:8200) + // Set custom APM Server URL (default: http://127.0.0.1:8200) serverUrl: '', }) diff --git a/docs/restify.asciidoc b/docs/restify.asciidoc index 341b80abcc..bbc7b4b845 100644 --- a/docs/restify.asciidoc +++ b/docs/restify.asciidoc @@ -46,7 +46,7 @@ const apm = require('elastic-apm-node').start({ // Use if APM Server uses API keys for authentication apiKey: '', - // Set custom APM Server URL (default: http://localhost:8200) + // Set custom APM Server URL (default: http://127.0.0.1:8200) serverUrl: '', }) diff --git a/docs/setup.asciidoc b/docs/setup.asciidoc index 907e713b0c..e595ebb2b4 100644 --- a/docs/setup.asciidoc +++ b/docs/setup.asciidoc @@ -70,7 +70,7 @@ require('elastic-apm-node').start({ // Use if APM Server uses API keys for authentication apiKey: '', - // Set custom APM Server URL (default: http://localhost:8200) + // Set custom APM Server URL (default: http://127.0.0.1:8200) serverUrl: '', // Only activate the agent if it's running in production diff --git a/lib/agent.js b/lib/agent.js index c9df001974..c7cf72512b 100644 --- a/lib/agent.js +++ b/lib/agent.js @@ -198,15 +198,6 @@ Agent.prototype.setSpanOutcome = function (outcome) { Agent.prototype._config = function (opts) { this._conf = config.createConfig(opts, this.logger) this.logger = this._conf.logger - - const { host, port, protocol } = this._conf.serverUrl - ? parsers.parseUrl(this._conf.serverUrl) - : { host: 'localhost:8200', port: '8200' } - - this._conf.serverHost = host - this._conf.serverPort = port === '' - ? (protocol === 'https:' ? 443 : 80) - : parseInt(port, 10) } Agent.prototype.isStarted = function () { @@ -225,6 +216,7 @@ Agent.prototype.start = function (opts) { this.addFilter(require('./filters/http-headers')) } + // Check cases where we do *not* start. if (!this._conf.active) { this.logger.debug('Elastic APM agent disabled (`active` is false)') return this @@ -232,11 +224,19 @@ Agent.prototype.start = function (opts) { this.logger.error('Elastic APM is incorrectly configured: Missing serviceName (APM will be disabled)') this._conf.active = false return this - } else if (!(this._conf.serverPort >= 1 && this._conf.serverPort <= 65535)) { + } + // Sanity check the port from `serverUrl`. + const parsedUrl = parsers.parseUrl(this._conf.serverUrl) + const serverPort = (parsedUrl.port + ? Number(parsedUrl.port) + : (parsedUrl.protocol === 'https:' ? 443 : 80)) + if (!(serverPort >= 1 && serverPort <= 65535)) { this.logger.error('Elastic APM is incorrectly configured: serverUrl "%s" contains an invalid port! (allowed: 1-65535)', this._conf.serverUrl) this._conf.active = false return this - } else if (this._conf.logLevel === 'trace') { + } + + if (this._conf.logLevel === 'trace') { var stackObj = {} Error.captureStackTrace(stackObj) diff --git a/lib/config.js b/lib/config.js index dd03f925c6..d242323021 100644 --- a/lib/config.js +++ b/lib/config.js @@ -90,6 +90,7 @@ var DEFAULTS = { ], serviceNodeName: undefined, serverTimeout: '30s', + serverUrl: 'http://127.0.0.1:8200', sourceLinesErrorAppFrames: 5, sourceLinesErrorLibraryFrames: 5, sourceLinesSpanAppFrames: 0, @@ -541,8 +542,7 @@ class Config { const REDACT_FIELDS = { apiKey: true, secretToken: true, - serverUrl: true, - serverHost: true + serverUrl: true } const NICE_REGEXPS_FIELDS = { ignoreUrlRegExp: true, diff --git a/package-lock.json b/package-lock.json index 7f3ce03afb..fe11a9ba99 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,7 +17,7 @@ "basic-auth": "^2.0.1", "cookie": "^0.5.0", "core-util-is": "^1.0.2", - "elastic-apm-http-client": "11.0.3", + "elastic-apm-http-client": "11.0.4", "end-of-stream": "^1.4.4", "error-callsites": "^2.0.4", "error-stack-parser": "^2.0.6", @@ -6155,9 +6155,9 @@ "dev": true }, "node_modules/elastic-apm-http-client": { - "version": "11.0.3", - "resolved": "https://registry.npmjs.org/elastic-apm-http-client/-/elastic-apm-http-client-11.0.3.tgz", - "integrity": "sha512-y+P9ByvfxjZbnLejgGaCAnwEe+FWMVshoMmjeLEEEVlQTLiFUHy7vhYyCQVqgbZzQ6zpaGPqPU2woKglKW4RHw==", + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/elastic-apm-http-client/-/elastic-apm-http-client-11.0.4.tgz", + "integrity": "sha512-449Qj/STi9hgnIk2KQ7719E7lpM3/i4Afs7NUhSOX8wV3sxn/+ItIHx9kKJthzhDDezxIfQcH83v83AF67GspQ==", "dependencies": { "agentkeepalive": "^4.2.1", "breadth-filter": "^2.0.0", @@ -20134,9 +20134,9 @@ "dev": true }, "elastic-apm-http-client": { - "version": "11.0.3", - "resolved": "https://registry.npmjs.org/elastic-apm-http-client/-/elastic-apm-http-client-11.0.3.tgz", - "integrity": "sha512-y+P9ByvfxjZbnLejgGaCAnwEe+FWMVshoMmjeLEEEVlQTLiFUHy7vhYyCQVqgbZzQ6zpaGPqPU2woKglKW4RHw==", + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/elastic-apm-http-client/-/elastic-apm-http-client-11.0.4.tgz", + "integrity": "sha512-449Qj/STi9hgnIk2KQ7719E7lpM3/i4Afs7NUhSOX8wV3sxn/+ItIHx9kKJthzhDDezxIfQcH83v83AF67GspQ==", "requires": { "agentkeepalive": "^4.2.1", "breadth-filter": "^2.0.0", diff --git a/package.json b/package.json index 3d6701d615..8425a15d89 100644 --- a/package.json +++ b/package.json @@ -93,7 +93,7 @@ "basic-auth": "^2.0.1", "cookie": "^0.5.0", "core-util-is": "^1.0.2", - "elastic-apm-http-client": "11.0.3", + "elastic-apm-http-client": "11.0.4", "end-of-stream": "^1.4.4", "error-callsites": "^2.0.4", "error-stack-parser": "^2.0.6", diff --git a/test/config.test.js b/test/config.test.js index f2c35489ea..d66950babd 100644 --- a/test/config.test.js +++ b/test/config.test.js @@ -148,7 +148,7 @@ var optionFixtures = [ ['secretToken', 'SECRET_TOKEN'], ['serverCaCertFile', 'SERVER_CA_CERT_FILE'], ['serverTimeout', 'SERVER_TIMEOUT', 30], - ['serverUrl', 'SERVER_URL'], + ['serverUrl', 'SERVER_URL', 'http://127.0.0.1:8200'], ['serviceName', 'SERVICE_NAME', apmName], ['serviceNodeName', 'SERVICE_NODE_NAME'], ['serviceVersion', 'SERVICE_VERSION', apmVersion],