diff --git a/src/client/components/monitor/provider/dns.tsx b/src/client/components/monitor/provider/dns.tsx
new file mode 100644
index 0000000..490863b
--- /dev/null
+++ b/src/client/components/monitor/provider/dns.tsx
@@ -0,0 +1,97 @@
+import { Form, Input, InputNumber, Select } from 'antd';
+import React from 'react';
+import { MonitorProvider } from './types';
+import { hostnameValidator, portValidator } from '../../../utils/validator';
+import { useTranslation } from '@i18next-toolkit/react';
+
+const rrtypeList = [
+ 'A',
+ 'AAAA',
+ 'CAA',
+ 'CNAME',
+ 'MX',
+ 'NS',
+ 'RTP',
+ 'SOA',
+ 'SRV',
+ 'TXT',
+];
+
+export const MonitorDNS: React.FC = React.memo(() => {
+ const { t } = useTranslation();
+
+ return (
+ <>
+
+
+
+
+
+
+
+
+
+
+
+
+ >
+ );
+});
+MonitorDNS.displayName = 'MonitorDNS';
+
+export const dnsProvider: MonitorProvider = {
+ label: 'DNS',
+ name: 'dns',
+ link: (info) => (
+
+ [{info.payload.rrtype}]
+ {info.payload.hostname}
+
+ ),
+ form: MonitorDNS,
+};
diff --git a/src/client/components/monitor/provider/index.ts b/src/client/components/monitor/provider/index.ts
index c728ab1..43cb93d 100644
--- a/src/client/components/monitor/provider/index.ts
+++ b/src/client/components/monitor/provider/index.ts
@@ -6,10 +6,12 @@ import { MonitorProvider } from './types';
import { openaiProvider } from './openai';
import { customProvider } from './custom';
import { tcpProvider } from './tcp';
+import { dnsProvider } from './dns';
export const monitorProviders: MonitorProvider[] = [
pingProvider, // ping
tcpProvider, // tcp
+ dnsProvider, // tcp
httpProvider, // http
openaiProvider, // openai
customProvider, // custom node script
diff --git a/src/server/model/monitor/provider/__tests__/dns.spec.ts b/src/server/model/monitor/provider/__tests__/dns.spec.ts
new file mode 100644
index 0000000..26243e3
--- /dev/null
+++ b/src/server/model/monitor/provider/__tests__/dns.spec.ts
@@ -0,0 +1,27 @@
+import { describe, expect, test } from 'vitest';
+import { dns } from '../dns';
+
+describe('dns', () => {
+ test('run', async () => {
+ const res = await dns.run({
+ id: '',
+ workspaceId: '',
+ name: '',
+ type: '',
+ active: true,
+ interval: 0,
+ maxRetries: 0,
+ createdAt: new Date(),
+ updatedAt: new Date(),
+ payload: {
+ hostname: 'tianji.msgbyte.com',
+ resolverServer: '1.1.1.1',
+ resolverPort: 53,
+ rrtype: 'CNAME',
+ },
+ });
+
+ expect(typeof res).toBe('number');
+ expect(res).not.toBe(-1);
+ });
+});
diff --git a/src/server/model/monitor/provider/dns.ts b/src/server/model/monitor/provider/dns.ts
new file mode 100644
index 0000000..6169cff
--- /dev/null
+++ b/src/server/model/monitor/provider/dns.ts
@@ -0,0 +1,60 @@
+import { MonitorProvider } from './type';
+import { Resolver } from 'dns';
+
+export const dns: MonitorProvider<{
+ hostname: string;
+ resolverServer: string;
+ resolverPort: number;
+ rrtype: string;
+}> = {
+ run: async (monitor) => {
+ if (typeof monitor.payload !== 'object') {
+ throw new Error('monitor.payload should be object');
+ }
+
+ const { hostname, resolverServer, resolverPort, rrtype } = monitor.payload;
+
+ const res = await dnsResolve(
+ hostname,
+ resolverServer,
+ resolverPort,
+ rrtype
+ );
+
+ return res;
+ },
+};
+
+function dnsResolve(
+ hostname: string,
+ resolverServer: string,
+ resolverPort: number,
+ rrtype: string
+) {
+ const start = Date.now();
+ return new Promise((resolve, reject) => {
+ const resolver = new Resolver();
+ // Remove brackets from IPv6 addresses so we can re-add them to
+ // prevent issues with ::1:5300 (::1 port 5300)
+ resolverServer = resolverServer.replace('[', '').replace(']', '');
+ resolver.setServers([`[${resolverServer}]:${resolverPort}`]);
+
+ if (rrtype === 'PTR') {
+ resolver.reverse(hostname, (err, records) => {
+ if (err) {
+ reject(err);
+ } else {
+ resolve(Date.now() - start);
+ }
+ });
+ } else {
+ resolver.resolve(hostname, rrtype, (err, records) => {
+ if (err) {
+ reject(err);
+ } else {
+ resolve(Date.now() - start);
+ }
+ });
+ }
+ });
+}
diff --git a/src/server/model/monitor/provider/index.ts b/src/server/model/monitor/provider/index.ts
index f740942..468fa7f 100644
--- a/src/server/model/monitor/provider/index.ts
+++ b/src/server/model/monitor/provider/index.ts
@@ -4,11 +4,13 @@ import { openai } from './openai';
import type { MonitorProvider } from './type';
import { custom } from './custom';
import { tcp } from './tcp';
+import { dns } from './dns';
export const monitorProviders: Record> = {
ping,
http,
tcp,
+ dns,
openai,
custom,
};