build-sgmodule-always-realip.ts 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. import path from 'node:path';
  2. import { task } from './trace';
  3. import { compareAndWriteFile } from './lib/create-file';
  4. import { DIRECTS, LANS } from '../Source/non_ip/direct';
  5. import * as yaml from 'yaml';
  6. import { OUTPUT_INTERNAL_DIR, OUTPUT_MODULES_DIR } from './constants/dir';
  7. import { appendArrayInPlace } from './lib/append-array-in-place';
  8. const HOSTNAMES = [
  9. // Network Detection, Captive Portal
  10. 'dns.msftncsi.com',
  11. // '*.msftconnecttest.com',
  12. // 'network-test.debian.org',
  13. // 'detectportal.firefox.com',
  14. // Handle SNAT conversation properly
  15. '*.srv.nintendo.net',
  16. '*.stun.playstation.net',
  17. 'xbox.*.microsoft.com',
  18. '*.xboxlive.com',
  19. '*.turn.twilio.com',
  20. '*.stun.twilio.com',
  21. 'stun.syncthing.net',
  22. 'stun.*'
  23. // 'controlplane.tailscale.com',
  24. // NTP
  25. // 'time.*.com', 'time.*.gov', 'time.*.edu.cn', 'time.*.apple.com', 'time?.*.com', 'ntp.*.com', 'ntp?.*.com', '*.time.edu.cn', '*.ntp.org.cn', '*.pool.ntp.org'
  26. // 'time*.cloud.tencent.com', 'ntp?.aliyun.com',
  27. // QQ Login
  28. // 'localhost.*.qq.com'
  29. // 'localhost.ptlogin2.qq.com
  30. // 'localhost.sec.qq.com',
  31. // 'localhost.work.weixin.qq.com',
  32. ];
  33. export const buildAlwaysRealIPModule = task(require.main === module, __filename)(async (span) => {
  34. // Intranet, Router Setup, and mant more
  35. const dataset = [
  36. DIRECTS.HOTSPOT_CAPTIVE_PORTAL,
  37. DIRECTS.SYSTEM,
  38. ...Object.values(LANS)
  39. ];
  40. const surge = dataset.flatMap(({ domains }) => domains.flatMap((domain) => {
  41. switch (domain[0]) {
  42. case '+':
  43. return [`*.${domain.slice(1)}`];
  44. case '$':
  45. return [domain.slice(1)];
  46. default:
  47. return [domain, `*.${domain}`];
  48. }
  49. }));
  50. return Promise.all([
  51. compareAndWriteFile(
  52. span,
  53. [
  54. '#!name=[Sukka] Always Real IP Plus',
  55. `#!desc=Last Updated: ${new Date().toISOString()}`,
  56. '',
  57. '[General]',
  58. `always-real-ip = %APPEND% ${HOSTNAMES.concat(surge).join(', ')}`
  59. ],
  60. path.resolve(OUTPUT_MODULES_DIR, 'sukka_common_always_realip.sgmodule')
  61. ),
  62. compareAndWriteFile(
  63. span,
  64. yaml.stringify(
  65. {
  66. dns: {
  67. 'fake-ip-filter': appendArrayInPlace(
  68. /** clash */
  69. dataset.flatMap(({ domains }) => domains.map((domain) => `+.${domain}`)),
  70. HOSTNAMES
  71. )
  72. }
  73. },
  74. { version: '1.1' }
  75. ).split('\n'),
  76. path.join(OUTPUT_INTERNAL_DIR, 'clash_fake_ip_filter.yaml')
  77. )
  78. ]);
  79. });