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

feat(dashmate): validate external IP #2183

Merged
merged 2 commits into from
Sep 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 48 additions & 12 deletions packages/dashmate/src/doctor/analyse/analyseConfigFactory.js
Original file line number Diff line number Diff line change
Expand Up @@ -160,13 +160,25 @@ and revoke the previous certificate in the ZeroSSL dashboard`,
if (coreP2pPort && coreP2pPort !== 'OPEN') {
const port = config.get('core.p2p.port');
const externalIp = config.get('externalIp');
const problem = new Problem(
'Core P2P port is unavailable for incoming connections.',
chalk`Please ensure that port ${port} on your public IP address ${externalIp} is open

let solution = chalk`Please ensure that port ${port} on your public IP address ${externalIp} is open
for incoming connections. You may need to configure your firewall to
ensure this port is accessible from the public internet. If you are using
Network Address Translation (NAT), please enable port forwarding for port 80
and all Dash service ports listed above.`;
if (externalIp) {
solution = chalk`Please ensure your configured IP address ${externalIp} is your public IP.
You can change it using {bold.cyanBright dashmate config set externalIp [IP]}.
Also, ensure that port ${port} on your public IP address is open
for incoming connections. You may need to configure your firewall to
ensure this port is accessible from the public internet. If you are using
Network Address Translation (NAT), please enable port forwarding for port 80
and all Dash service ports listed above.`,
and all Dash service ports listed above.`;
}

const problem = new Problem(
'Core P2P port is unavailable for incoming connections.',
solution,
SEVERITY.HIGH,
);

Expand All @@ -178,13 +190,25 @@ and all Dash service ports listed above.`,
if (gatewayHttpPort && gatewayHttpPort !== 'OPEN') {
const port = config.get('platform.gateway.listeners.dapiAndDrive.port');
const externalIp = config.get('externalIp');
const problem = new Problem(
'Gateway HTTP port is unavailable for incoming connections.',
chalk`Please ensure that port ${port} on your public IP address ${externalIp} is open

let solution = chalk`Please ensure that port ${port} on your public IP address ${externalIp} is open
for incoming connections. You may need to configure your firewall to
ensure this port is accessible from the public internet. If you are using
Network Address Translation (NAT), please enable port forwarding for port 80
and all Dash service ports listed above.`;
if (externalIp) {
solution = chalk`Please ensure your configured IP address ${externalIp} is your public IP.
You can change it using {bold.cyanBright dashmate config set externalIp [IP]}.
Also, ensure that port ${port} on your public IP address is open
for incoming connections. You may need to configure your firewall to
ensure this port is accessible from the public internet. If you are using
Network Address Translation (NAT), please enable port forwarding for port 80
and all Dash service ports listed above.`,
and all Dash service ports listed above.`;
}

const problem = new Problem(
'Gateway HTTP port is unavailable for incoming connections.',
solution,
SEVERITY.HIGH,
);

Expand All @@ -196,13 +220,25 @@ and all Dash service ports listed above.`,
if (tenderdashP2pPort && tenderdashP2pPort !== 'OPEN') {
const port = config.get('platform.drive.tenderdash.p2p.port');
const externalIp = config.get('externalIp');
const problem = new Problem(
'Tenderdash P2P port is unavailable for incoming connections.',
chalk`Please ensure that port ${port} on your public IP address ${externalIp} is open

let solution = chalk`Please ensure that port ${port} on your public IP address ${externalIp} is open
for incoming connections. You may need to configure your firewall to
ensure this port is accessible from the public internet. If you are using
Network Address Translation (NAT), please enable port forwarding for port 80
and all Dash service ports listed above.`,
and all Dash service ports listed above.`;
if (externalIp) {
solution = chalk`Please ensure your configured IP address ${externalIp} is your public IP.
You can change it using {bold.cyanBright dashmate config set externalIp [IP]}.
Also, ensure that port ${port} on your public IP address is open
for incoming connections. You may need to configure your firewall to
ensure this port is accessible from the public internet. If you are using
Network Address Translation (NAT), please enable port forwarding for port 80
and all Dash service ports listed above.`;
}

const problem = new Problem(
'Tenderdash P2P port is unavailable for incoming connections.',
solution,
SEVERITY.HIGH,
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ export default function collectSamplesTaskFactory(
title: 'Core P2P port',
task: async () => {
const port = config.get('core.p2p.port');
const response = await providers.mnowatch.checkPortStatus(port);
const response = await providers.mnowatch.checkPortStatus(port, config.get('externalIp'));

ctx.samples.setServiceInfo('core', 'p2pPort', response);
},
Expand All @@ -176,7 +176,7 @@ export default function collectSamplesTaskFactory(
enabled: () => config.get('platform.enable'),
task: async () => {
const port = config.get('platform.gateway.listeners.dapiAndDrive.port');
const response = await providers.mnowatch.checkPortStatus(port);
const response = await providers.mnowatch.checkPortStatus(port, config.get('externalIp'));

ctx.samples.setServiceInfo('gateway', 'httpPort', response);
},
Expand All @@ -185,7 +185,7 @@ export default function collectSamplesTaskFactory(
title: 'Tenderdash P2P port',
task: async () => {
const port = config.get('platform.drive.tenderdash.p2p.port');
const response = await providers.mnowatch.checkPortStatus(port);
const response = await providers.mnowatch.checkPortStatus(port, config.get('externalIp'));

ctx.samples.setServiceInfo('drive_tenderdash', 'p2pPort', response);
},
Expand Down
11 changes: 9 additions & 2 deletions packages/dashmate/src/status/providers.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,14 @@ export default {
},
},
mnowatch: {
checkPortStatus: async (port) => {
/**
* Check the status of a port and optionally validate an IP address.
*
* @param {number} port - The port number to check.
* @param {string} [ip] - Optional. The IP address to validate.
* @returns {Promise<string>} A promise that resolves to the port status.
*/
checkPortStatus: async (port, ip = undefined) => {
// We use http request instead fetch function to force
// using IPv4 otherwise mnwatch could try to connect to IPv6 node address
// and fail (Core listens for IPv4 only)
Expand All @@ -72,7 +79,7 @@ export default {
const options = {
hostname: 'mnowatch.org',
port: 443,
path: `/${port}/`,
path: ip ? `/${port}/?validateIp=${ip}` : `/${port}/`,
method: 'GET',
family: 4, // Force IPv4
timeout: MAX_REQUEST_TIMEOUT,
Expand Down
2 changes: 1 addition & 1 deletion packages/dashmate/src/status/scopes/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ export default function getCoreScopeFactory(

const providersResult = await Promise.allSettled([
providers.github.release('dashpay/dash'),
providers.mnowatch.checkPortStatus(config.get('core.p2p.port')),
providers.mnowatch.checkPortStatus(config.get('core.p2p.port'), config.get('externalIp')),
providers.insight(config.get('network')).status(),
]);

Expand Down
4 changes: 2 additions & 2 deletions packages/dashmate/src/status/scopes/platform.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,8 @@ export default function getPlatformScopeFactory(
// Collecting platform data fails if Tenderdash is waiting for core to sync
if (info.serviceStatus === ServiceStatusEnum.up) {
const portStatusResult = await Promise.allSettled([
providers.mnowatch.checkPortStatus(config.get('platform.gateway.listeners.dapiAndDrive.port')),
providers.mnowatch.checkPortStatus(config.get('platform.drive.tenderdash.p2p.port')),
providers.mnowatch.checkPortStatus(config.get('platform.gateway.listeners.dapiAndDrive.port'), config.get('externalIp')),
providers.mnowatch.checkPortStatus(config.get('platform.drive.tenderdash.p2p.port'), config.get('externalIp')),
]);
const [httpPortState, p2pPortState] = portStatusResult.map((result) => (result.status === 'fulfilled' ? result.value : null));

Expand Down
Loading