Initial fork commit
This commit is contained in:
parent
f3fe584bfa
commit
34d9abec19
25 changed files with 36 additions and 3840 deletions
1
.github/FUNDING.yml
vendored
1
.github/FUNDING.yml
vendored
|
|
@ -1 +0,0 @@
|
||||||
github: willnode
|
|
||||||
15
.gitignore
vendored
15
.gitignore
vendored
|
|
@ -5,27 +5,12 @@ npm-debug.log*
|
||||||
yarn-debug.log*
|
yarn-debug.log*
|
||||||
yarn-error.log*
|
yarn-error.log*
|
||||||
|
|
||||||
# Runtime data
|
|
||||||
pids
|
|
||||||
*.pid
|
|
||||||
*.seed
|
|
||||||
*.pid.lock
|
|
||||||
|
|
||||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||||
lib-cov
|
lib-cov
|
||||||
|
|
||||||
# Coverage directory used by tools like istanbul
|
# Coverage directory used by tools like istanbul
|
||||||
coverage
|
coverage
|
||||||
|
|
||||||
# nyc test coverage
|
|
||||||
.nyc_output
|
|
||||||
|
|
||||||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
|
||||||
.grunt
|
|
||||||
|
|
||||||
# Bower dependency directory (https://bower.io/)
|
|
||||||
bower_components
|
|
||||||
|
|
||||||
# node-waf configuration
|
# node-waf configuration
|
||||||
.lock-wscript
|
.lock-wscript
|
||||||
|
|
||||||
|
|
|
||||||
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
|
|
@ -1,3 +0,0 @@
|
||||||
{
|
|
||||||
"js/ts.implicitProjectConfig.checkJs": true
|
|
||||||
}
|
|
||||||
8
CHANGELOG.md
Normal file
8
CHANGELOG.md
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
# Changelog
|
||||||
|
All notable changes to **Domain-Forward** are documented in this *changelog*.
|
||||||
|
|
||||||
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and **Domain-Forward** adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
## [1.0.0] - 2023-12-12
|
||||||
|
|
||||||
|
Initial commit from fork: https://github.com/willnode/forward-domain
|
||||||
36
CHANGES.md
36
CHANGES.md
|
|
@ -1,36 +0,0 @@
|
||||||
# CHANGES
|
|
||||||
|
|
||||||
## v2.5 (2023-04-24)
|
|
||||||
|
|
||||||
+ Add `http-status` TXT record option to set HTTP status code. Contributed by [@dzegarra](https://github.com/willnode/forward-domain/pull/4)
|
|
||||||
+ Improve lock mechanism when a website is verificating certs.
|
|
||||||
|
|
||||||
## v2.4 (2023-04-21)
|
|
||||||
|
|
||||||
+ Fix global service lock when a website is verificating certs.
|
|
||||||
+ Update code deps, refactor imports to ESM.
|
|
||||||
|
|
||||||
## v2.3 (2022-08-16)
|
|
||||||
|
|
||||||
+ Add stat API `s.forwarddomain.net`, separate node script.
|
|
||||||
|
|
||||||
## v2.2 (2022-06-16)
|
|
||||||
|
|
||||||
+ Moving all parameters to `.env` file
|
|
||||||
+ Add a domain blacklist mechanism (we received a report that this service is used for phising activity, for the first time)
|
|
||||||
|
|
||||||
## v2.1 (2022-01-03)
|
|
||||||
|
|
||||||
+ Added `AAAA` record in `r.forwarddomain.net` for IPv6 support. (see [#2](https://github.com/willnode/forward-domain/issues/2#issuecomment-1003831835) for apex domains setup)
|
|
||||||
|
|
||||||
## v2.0 (2021-09-21)
|
|
||||||
|
|
||||||
+ Dropped `forward-domain-cert-maintainer=` record (as of [LE explanation](https://letsencrypt.org/docs/integration-guide/#who-is-the-subscriber) the provider is the bearer).
|
|
||||||
+ The software is now keeping LE's account keypair instead of generating new one every restart.
|
|
||||||
+ Changed IPv4 from `206.189.61.89` to `167.172.5.31` (we use DO's floating IP address now)
|
|
||||||
+ Changed TXT location to subdomain `_` (because TXT can't be put together with CNAME)
|
|
||||||
+ Dropped IPv6 record.
|
|
||||||
|
|
||||||
## v1.0 (2021-08-23)
|
|
||||||
|
|
||||||
+ First release
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
This guide will walk you through the process of setting up your own instance of ForwardDomain. This is not a guide for setting up a development environment, but rather a guide for setting up a production instance.
|
This guide will walk you through the process of setting up your own instance of ForwardDomain. This is not a guide for setting up a development environment, but rather a guide for setting up a production instance.
|
||||||
|
|
||||||
|
|
||||||
## Prerequisites
|
## Prerequisites
|
||||||
|
|
||||||
- [Node.js](https://nodejs.org/en/) (version 16 or higher).
|
- [Node.js](https://nodejs.org/en/) (version 16 or higher).
|
||||||
|
|
|
||||||
1
LICENSE
1
LICENSE
|
|
@ -1,6 +1,7 @@
|
||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) 2021 Wildan M
|
Copyright (c) 2021 Wildan M
|
||||||
|
Copyright (c) 2024 Pierre Lannoy / All modifications done after 2023-12-11
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,5 @@
|
||||||
# Forward Domain
|
# Forward Domain
|
||||||
|
|
||||||
[](https://github.com/willnode/forward-domain/stargazers)
|
|
||||||
[](https://stats.uptimerobot.com/AA77Xt9Jx8)
|
|
||||||
|
|
||||||
<img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7lp67jpzvabtf8opyzaf.png" alt="Banner" width="600">
|
|
||||||
|
|
||||||
> We're back with improvements! See [CHANGES.md](CHANGES.md)
|
|
||||||
|
|
||||||
This service forwards domains using HTTP(s) redirects.
|
This service forwards domains using HTTP(s) redirects.
|
||||||
|
|
||||||
Example scenarios:
|
Example scenarios:
|
||||||
|
|
|
||||||
2
app.js
2
app.js
|
|
@ -3,11 +3,13 @@ import https from "https";
|
||||||
import app from "./index.js";
|
import app from "./index.js";
|
||||||
import listener from "./src/client.js";
|
import listener from "./src/client.js";
|
||||||
import { SniPrepare, SniListener } from "./src/sni.js";
|
import { SniPrepare, SniListener } from "./src/sni.js";
|
||||||
|
|
||||||
// production endpoint (use pm2/phusion/whatever)
|
// production endpoint (use pm2/phusion/whatever)
|
||||||
config();
|
config();
|
||||||
|
|
||||||
const port80 = parseInt(process.env.HTTP_PORT || "80");
|
const port80 = parseInt(process.env.HTTP_PORT || "80");
|
||||||
const port443 = parseInt(process.env.HTTPS_PORT || "443");
|
const port443 = parseInt(process.env.HTTPS_PORT || "443");
|
||||||
|
|
||||||
const main = async () => {
|
const main = async () => {
|
||||||
await SniPrepare();
|
await SniPrepare();
|
||||||
const httpsServer = https.createServer({
|
const httpsServer = https.createServer({
|
||||||
|
|
|
||||||
2
index.js
2
index.js
|
|
@ -3,7 +3,7 @@ import http from "http";
|
||||||
import listener from "./src/client.js";
|
import listener from "./src/client.js";
|
||||||
import { isMainProcess } from "./src/util.js";
|
import { isMainProcess } from "./src/util.js";
|
||||||
|
|
||||||
// development endpoint (use ngrok)
|
// development endpoint - use ngrok
|
||||||
const server = http.createServer(listener);
|
const server = http.createServer(listener);
|
||||||
if (isMainProcess(import.meta.url)) {
|
if (isMainProcess(import.meta.url)) {
|
||||||
config();
|
config();
|
||||||
|
|
|
||||||
3769
package-lock.json
generated
3769
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"name": "forward-domain",
|
"name": "domain-forrward",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "Public service to forward domain for free",
|
"description": "Public service to forward domain for free",
|
||||||
"main": "app.js",
|
"main": "app.js",
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
"count": "find .certs -type d | grep '.\\.' | wc -l"
|
"count": "find .certs -type d | grep '.\\.' | wc -l"
|
||||||
},
|
},
|
||||||
"keywords": [],
|
"keywords": [],
|
||||||
"author": "Wildan Mubarok",
|
"author": "Pierre Lannoy",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"async-lock": "^1.4.0",
|
"async-lock": "^1.4.0",
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ import pem from "pem";
|
||||||
import * as common from "./common.js";
|
import * as common from "./common.js";
|
||||||
import request from "./request.js";
|
import request from "./request.js";
|
||||||
const createCsr = promisify(pem.createCSR);
|
const createCsr = promisify(pem.createCSR);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a Let's Encrypt account and
|
* Represents a Let's Encrypt account and
|
||||||
* sends requests to get valid TLS certificates.
|
* sends requests to get valid TLS certificates.
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ export const PRIVATE_KEY_TYPE = 'pkcs8';
|
||||||
export const PUBLIC_KEY_FORMAT = 'pem';
|
export const PUBLIC_KEY_FORMAT = 'pem';
|
||||||
export const PUBLIC_KEY_PERMISSIONS = 0o666;
|
export const PUBLIC_KEY_PERMISSIONS = 0o666;
|
||||||
export const PUBLIC_KEY_TYPE = 'spki';
|
export const PUBLIC_KEY_TYPE = 'spki';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {crypto.KeyObject} privateKey
|
* @param {crypto.KeyObject} privateKey
|
||||||
* @param {String} [passphrase]
|
* @param {String} [passphrase]
|
||||||
|
|
@ -30,6 +31,7 @@ export const exportPrivateKey = (privateKey, passphrase) => {
|
||||||
}
|
}
|
||||||
return privateKey.export(privateKeyOpts);
|
return privateKey.export(privateKeyOpts);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {crypto.KeyObject} publicKey
|
* @param {crypto.KeyObject} publicKey
|
||||||
*/
|
*/
|
||||||
|
|
@ -40,6 +42,7 @@ export const exportPublicKey = publicKey => {
|
||||||
format: PUBLIC_KEY_FORMAT
|
format: PUBLIC_KEY_FORMAT
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {String} privateKeyData
|
* @param {String} privateKeyData
|
||||||
* @param {String} [passphrase]
|
* @param {String} [passphrase]
|
||||||
|
|
@ -63,6 +66,7 @@ export const importPrivateKey = (privateKeyData, passphrase) => {
|
||||||
throw new Error('Failed to import private key');
|
throw new Error('Failed to import private key');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {String} publicKeyData
|
* @param {String} publicKeyData
|
||||||
*
|
*
|
||||||
|
|
@ -80,6 +84,7 @@ export const importPublicKey = publicKeyData => {
|
||||||
throw new Error('Failed to import public key');
|
throw new Error('Failed to import public key');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {String} filename
|
* @param {String} filename
|
||||||
* @param {crypto.KeyObject|string} key
|
* @param {crypto.KeyObject|string} key
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import https from "https";
|
import https from "https";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string | URL} url
|
* @param {string | URL} url
|
||||||
* @param {import('https').RequestOptions & {data?: string}} [options]
|
* @param {import('https').RequestOptions & {data?: string}} [options]
|
||||||
|
|
|
||||||
|
|
@ -9,10 +9,12 @@ import { findTxtRecord, isHostBlacklisted, combineURLs } from "./util.js";
|
||||||
* @property {number} expire
|
* @property {number} expire
|
||||||
* @property {number} httpStatus
|
* @property {number} httpStatus
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {Object<string, Cache>}
|
* @type {Object<string, Cache>}
|
||||||
*/
|
*/
|
||||||
const resolveCache = {};
|
const resolveCache = {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} host
|
* @param {string} host
|
||||||
* @returns {Promise<Cache>}
|
* @returns {Promise<Cache>}
|
||||||
|
|
@ -42,7 +44,9 @@ async function buildCache(host) {
|
||||||
httpStatus: parseInt(httpStatus),
|
httpStatus: parseInt(httpStatus),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const acme_prefix = '/.well-known/acme-challenge/';
|
const acme_prefix = '/.well-known/acme-challenge/';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {import('http').RequestListener}
|
* @type {import('http').RequestListener}
|
||||||
*/
|
*/
|
||||||
|
|
@ -92,4 +96,5 @@ const listener = async function (req, res) {
|
||||||
res.end();
|
res.end();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default listener;
|
export default listener;
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ function getCertCachePath(host) {
|
||||||
const hash = md5(host);
|
const hash = md5(host);
|
||||||
return path.join(certsDir, hash.substring(0, 2), hash.substring(2), host);
|
return path.join(certsDir, hash.substring(0, 2), hash.substring(2), host);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} host
|
* @param {string} host
|
||||||
*/
|
*/
|
||||||
|
|
@ -71,6 +72,7 @@ async function buildCache(host) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} servername
|
* @param {string} servername
|
||||||
*/
|
*/
|
||||||
|
|
@ -89,6 +91,7 @@ async function getKeyCert(servername) {
|
||||||
cert: cache.cert,
|
cert: cache.cert,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} servername
|
* @param {string} servername
|
||||||
* @param {(err: any, cb: tls.SecureContext|undefined) => void} ctx
|
* @param {(err: any, cb: tls.SecureContext|undefined) => void} ctx
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ import request from "./certnode/lib/request.js";
|
||||||
import crypto from "crypto";
|
import crypto from "crypto";
|
||||||
import fs from "fs";
|
import fs from "fs";
|
||||||
import { fileURLToPath } from "url";
|
import { fileURLToPath } from "url";
|
||||||
|
|
||||||
const recordParamDestUrl = 'forward-domain';
|
const recordParamDestUrl = 'forward-domain';
|
||||||
const recordParamHttpStatus = 'http-status';
|
const recordParamHttpStatus = 'http-status';
|
||||||
let blacklistURL = null;
|
let blacklistURL = null;
|
||||||
|
|
|
||||||
1
stat.js
1
stat.js
|
|
@ -3,6 +3,7 @@ import { execSync } from "child_process";
|
||||||
import http from "http";
|
import http from "http";
|
||||||
import { isMainProcess } from "./src/util.js";
|
import { isMainProcess } from "./src/util.js";
|
||||||
|
|
||||||
|
|
||||||
const updateStat = function () {
|
const updateStat = function () {
|
||||||
// run npm stat
|
// run npm stat
|
||||||
var buffer = execSync('npm run count');
|
var buffer = execSync('npm run count');
|
||||||
|
|
|
||||||
Loading…
Add table
editor.link_modal.header
Reference in a new issue