fix: dns checker

This commit is contained in:
Andras Bacsai
2022-07-25 10:16:25 +00:00
parent fc9bbac372
commit dd2a876a67
6 changed files with 125 additions and 18 deletions

View File

@@ -317,12 +317,16 @@ export function getDomain(domain: string): string {
export async function isDomainConfigured({
id,
fqdn,
checkOwn = false
checkOwn = false,
dockerId = undefined
}: {
id: string;
fqdn: string;
checkOwn?: boolean;
dockerId: string;
}): Promise<boolean> {
console.log({checkOwn, dockerId})
const domain = getDomain(fqdn);
const nakedDomain = domain.replace('www.', '');
const foundApp = await prisma.application.findFirst({
@@ -331,7 +335,10 @@ export async function isDomainConfigured({
{ fqdn: { endsWith: `//${nakedDomain}` } },
{ fqdn: { endsWith: `//www.${nakedDomain}` } }
],
id: { not: id }
id: { not: id },
destinationDocker: {
id: dockerId
}
},
select: { fqdn: true }
});
@@ -343,7 +350,10 @@ export async function isDomainConfigured({
{ minio: { apiFqdn: { endsWith: `//${nakedDomain}` } } },
{ minio: { apiFqdn: { endsWith: `//www.${nakedDomain}` } } }
],
id: { not: checkOwn ? undefined : id }
id: { not: checkOwn ? undefined : id },
destinationDocker: {
id: dockerId
}
},
select: { fqdn: true }
});
@@ -416,16 +426,13 @@ export async function checkDomainsIsValidInDNS({ hostname, fqdn, dualCerts }): P
}
} else {
try {
console.log({domain})
const ipDomain = await dns.resolve4(domain);
console.log({ipDomain})
let ipDomainFound = false;
for (const ip of ipDomain) {
if (resolves.includes(ip)) {
ipDomainFound = true;
}
}
console.log({ipDomainFound})
if (ipDomainFound) return { status: 200 };
throw { status: 500, message: `DNS not set correctly or propogated.<br>Please check your DNS settings.` }
} catch (error) {

View File

@@ -368,7 +368,7 @@ export async function checkDNS(request: FastifyRequest<CheckDNS>) {
const { destinationDocker: { id: dockerId, remoteIpAddress, remoteEngine }, exposePort: configuredPort } = await prisma.application.findUnique({ where: { id }, include: { destinationDocker: true } })
const { isDNSCheckEnabled } = await prisma.setting.findFirst({});
const found = await isDomainConfigured({ id, fqdn });
const found = await isDomainConfigured({ id, fqdn, dockerId });
if (found) {
throw { status: 500, message: `Domain ${getDomain(fqdn).replace('www.', '')} is already in use!` }
}

View File

@@ -2,13 +2,13 @@ import type { FastifyReply, FastifyRequest } from 'fastify';
import fs from 'fs/promises';
import yaml from 'js-yaml';
import bcrypt from 'bcryptjs';
import { prisma, uniqueName, asyncExecShell, getServiceImage, configureServiceType, getServiceFromDB, getContainerUsage, removeService, isDomainConfigured, saveUpdateableFields, fixType, decrypt, encrypt, getServiceMainPort, createDirectories, ComposeFile, makeLabelForServices, getFreePublicPort, getDomain, errorHandler, generatePassword, isDev, stopTcpHttpProxy, supportedServiceTypesAndVersions, executeDockerCmd, listSettings, getFreeExposedPort } from '../../../../lib/common';
import { prisma, uniqueName, asyncExecShell, getServiceImage, configureServiceType, getServiceFromDB, getContainerUsage, removeService, isDomainConfigured, saveUpdateableFields, fixType, decrypt, encrypt, getServiceMainPort, createDirectories, ComposeFile, makeLabelForServices, getFreePublicPort, getDomain, errorHandler, generatePassword, isDev, stopTcpHttpProxy, supportedServiceTypesAndVersions, executeDockerCmd, listSettings, getFreeExposedPort, checkDomainsIsValidInDNS } from '../../../../lib/common';
import { day } from '../../../../lib/dayjs';
import { checkContainer, dockerInstance, isContainerExited, removeContainer } from '../../../../lib/docker';
import cuid from 'cuid';
import type { OnlyId } from '../../../../types';
import type { ActivateWordpressFtp, CheckService, DeleteServiceSecret, DeleteServiceStorage, GetServiceLogs, SaveService, SaveServiceDestination, SaveServiceSecret, SaveServiceSettings, SaveServiceStorage, SaveServiceType, SaveServiceVersion, ServiceStartStop, SetWordpressSettings } from './types';
import type { ActivateWordpressFtp, CheckService, CheckServiceDomain, DeleteServiceSecret, DeleteServiceStorage, GetServiceLogs, SaveService, SaveServiceDestination, SaveServiceSecret, SaveServiceSettings, SaveServiceStorage, SaveServiceType, SaveServiceVersion, ServiceStartStop, SetWordpressSettings } from './types';
// async function startServiceNew(request: FastifyRequest<OnlyId>) {
// try {
@@ -346,22 +346,35 @@ export async function saveServiceSettings(request: FastifyRequest<SaveServiceSet
return errorHandler({ status, message })
}
}
export async function checkServiceDomain(request: FastifyRequest<CheckServiceDomain>) {
try {
const { id } = request.params
const { domain } = request.query
const { fqdn, dualCerts } = await prisma.service.findUnique({ where: { id }})
return await checkDomainsIsValidInDNS({ hostname: domain, fqdn, dualCerts });
} catch ({ status, message }) {
return errorHandler({ status, message })
}
}
export async function checkService(request: FastifyRequest<CheckService>) {
try {
const { id } = request.params;
let { fqdn, exposePort, otherFqdns } = request.body;
let { fqdn, exposePort, forceSave, otherFqdns, dualCerts } = request.body;
if (fqdn) fqdn = fqdn.toLowerCase();
if (otherFqdns && otherFqdns.length > 0) otherFqdns = otherFqdns.map((f) => f.toLowerCase());
if (exposePort) exposePort = Number(exposePort);
let found = await isDomainConfigured({ id, fqdn });
const { destinationDocker: { id: dockerId, remoteIpAddress, remoteEngine }, exposePort: configuredPort } = await prisma.service.findUnique({ where: { id }, include: { destinationDocker: true } })
const { isDNSCheckEnabled } = await prisma.setting.findFirst({});
let found = await isDomainConfigured({ id, fqdn, dockerId });
if (found) {
throw { status: 500, message: `Domain ${getDomain(fqdn).replace('www.', '')} is already in use!` }
}
if (otherFqdns && otherFqdns.length > 0) {
for (const ofqdn of otherFqdns) {
found = await isDomainConfigured({ id, fqdn: ofqdn, checkOwn: true });
found = await isDomainConfigured({ id, fqdn: ofqdn, dockerId });
if (found) {
throw { status: 500, message: `Domain ${getDomain(ofqdn).replace('www.', '')} is already in use!` }
}
@@ -371,7 +384,7 @@ export async function checkService(request: FastifyRequest<CheckService>) {
if (exposePort < 1024 || exposePort > 65535) {
throw { status: 500, message: `Exposed Port needs to be between 1024 and 65535.` }
}
const { destinationDocker: { id: dockerId, remoteIpAddress }, exposePort: configuredPort } = await prisma.service.findUnique({ where: { id }, include: { destinationDocker: true } })
if (configuredPort !== exposePort) {
const availablePort = await getFreeExposedPort(id, exposePort, dockerId, remoteIpAddress);
if (availablePort.toString() !== exposePort.toString()) {
@@ -379,6 +392,11 @@ export async function checkService(request: FastifyRequest<CheckService>) {
}
}
}
if (isDNSCheckEnabled && !isDev && !forceSave) {
let hostname = request.hostname.split(':')[0];
if (remoteEngine) hostname = remoteIpAddress;
return await checkDomainsIsValidInDNS({ hostname, fqdn, dualCerts });
}
return {}
} catch ({ status, message }) {
return errorHandler({ status, message })

View File

@@ -3,6 +3,7 @@ import {
activatePlausibleUsers,
activateWordpressFtp,
checkService,
checkServiceDomain,
deleteService,
deleteServiceSecret,
deleteServiceStorage,
@@ -29,7 +30,7 @@ import {
} from './handlers';
import type { OnlyId } from '../../../../types';
import type { ActivateWordpressFtp, CheckService, DeleteServiceSecret, DeleteServiceStorage, GetServiceLogs, SaveService, SaveServiceDestination, SaveServiceSecret, SaveServiceSettings, SaveServiceStorage, SaveServiceType, SaveServiceVersion, ServiceStartStop, SetWordpressSettings } from './types';
import type { ActivateWordpressFtp, CheckService, CheckServiceDomain, DeleteServiceSecret, DeleteServiceStorage, GetServiceLogs, SaveService, SaveServiceDestination, SaveServiceSecret, SaveServiceSettings, SaveServiceStorage, SaveServiceType, SaveServiceVersion, ServiceStartStop, SetWordpressSettings } from './types';
const root: FastifyPluginAsync = async (fastify): Promise<void> => {
fastify.addHook('onRequest', async (request) => {
@@ -44,6 +45,7 @@ const root: FastifyPluginAsync = async (fastify): Promise<void> => {
fastify.get<OnlyId>('/:id/status', async (request) => await getServiceStatus(request));
fastify.get<CheckServiceDomain>('/:id/check', async (request) => await checkServiceDomain(request));
fastify.post<CheckService>('/:id/check', async (request) => await checkService(request));
fastify.post<SaveServiceSettings>('/:id/settings', async (request, reply) => await saveServiceSettings(request, reply));

View File

@@ -25,9 +25,16 @@ export interface SaveServiceSettings extends OnlyId {
dualCerts: boolean
}
}
export interface CheckServiceDomain extends OnlyId {
Querystring: {
domain: string
}
}
export interface CheckService extends OnlyId {
Body: {
fqdn: string,
forceSave: boolean,
dualCerts: boolean,
exposePort: number,
otherFqdns: Array<string>
}