VPN Setup
This commit is contained in:
parent
2e7731e704
commit
03814c6c99
|
|
@ -40,7 +40,8 @@
|
||||||
"uglify-js": "^3.19.3",
|
"uglify-js": "^3.19.3",
|
||||||
"uuid": "^11.0.3",
|
"uuid": "^11.0.3",
|
||||||
"winston": "^3.17.0",
|
"winston": "^3.17.0",
|
||||||
"winston-daily-rotate-file": "^5.0.0"
|
"winston-daily-rotate-file": "^5.0.0",
|
||||||
|
"wireguard-tools": "^0.1.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/cli": "^7.26.4",
|
"@babel/cli": "^7.26.4",
|
||||||
|
|
@ -6198,6 +6199,12 @@
|
||||||
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
|
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/lodash.mergewith": {
|
||||||
|
"version": "4.6.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz",
|
||||||
|
"integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/lodash.once": {
|
"node_modules/lodash.once": {
|
||||||
"version": "4.1.1",
|
"version": "4.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
|
||||||
|
|
@ -9338,6 +9345,15 @@
|
||||||
"node": ">= 12.0.0"
|
"node": ">= 12.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/wireguard-tools": {
|
||||||
|
"version": "0.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/wireguard-tools/-/wireguard-tools-0.1.0.tgz",
|
||||||
|
"integrity": "sha512-oBnnSB6wXGEAB1ZVPfbfpX8WlHNw7wv45r13ILX73felVnrGpMxMjFcKGAsMeRfBOGzXcW0LgAWe+T53dRcI+g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"lodash.mergewith": "^4.6.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/wordwrap": {
|
"node_modules/wordwrap": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,8 @@
|
||||||
"uglify-js": "^3.19.3",
|
"uglify-js": "^3.19.3",
|
||||||
"uuid": "^11.0.3",
|
"uuid": "^11.0.3",
|
||||||
"winston": "^3.17.0",
|
"winston": "^3.17.0",
|
||||||
"winston-daily-rotate-file": "^5.0.0"
|
"winston-daily-rotate-file": "^5.0.0",
|
||||||
|
"wireguard-tools": "^0.1.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/cli": "^7.26.4",
|
"@babel/cli": "^7.26.4",
|
||||||
|
|
@ -58,4 +59,4 @@
|
||||||
"webpack-cli": "^6.0.1",
|
"webpack-cli": "^6.0.1",
|
||||||
"webpack-node-externals": "^3.0.0"
|
"webpack-node-externals": "^3.0.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ import { project_add_sf } from "../../controllers/project/projectAddSf.controlle
|
||||||
import { update_project_sf } from "../../controllers/project/projectUpdateSf.controller.js"
|
import { update_project_sf } from "../../controllers/project/projectUpdateSf.controller.js"
|
||||||
import { authValidator } from "../../middlewares/auth.middleware.js";
|
import { authValidator } from "../../middlewares/auth.middleware.js";
|
||||||
import { delete_project_sf } from "../../controllers/project/deleteProjectSf.controller.js"
|
import { delete_project_sf } from "../../controllers/project/deleteProjectSf.controller.js"
|
||||||
|
import { createWireGuardConnection } from '../../vpnHandler/vpn.js';
|
||||||
|
|
||||||
const v1Routes = express.Router()
|
const v1Routes = express.Router()
|
||||||
|
|
||||||
|
|
@ -38,5 +39,22 @@ v1Routes.get("/", function(req, res) {
|
||||||
res.json({"connected": true})
|
res.json({"connected": true})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
v1Routes.post("/vpn/connect", (req, res) => {
|
||||||
|
try {
|
||||||
|
const data = createWireGuardConnection();
|
||||||
|
res.json({
|
||||||
|
success: true,
|
||||||
|
message: "VPN connection created",
|
||||||
|
...data
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
res.status(500).json({
|
||||||
|
success: false,
|
||||||
|
error: err.message
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
// v1Routes.use("/form_submit", authValidator, formRoutes);
|
// v1Routes.use("/form_submit", authValidator, formRoutes);
|
||||||
export default v1Routes;
|
export default v1Routes;
|
||||||
|
|
@ -115,7 +115,7 @@ app.get('/clientregister/:sf_token?', (req, res) => {
|
||||||
app.get('/auth/password/reset-form', render_reset_form);
|
app.get('/auth/password/reset-form', render_reset_form);
|
||||||
|
|
||||||
app.get('/health', (req, res) => {
|
app.get('/health', (req, res) => {
|
||||||
res.status(201).send({ status: "Server is healthy" });
|
res.status(400).send({ status: "Server is not healthy" });
|
||||||
})
|
})
|
||||||
|
|
||||||
app.get("/client/login", (req, res) => {
|
app.get("/client/login", (req, res) => {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,97 @@
|
||||||
|
import fs from "fs";
|
||||||
|
import { execSync } from "child_process";
|
||||||
|
|
||||||
|
const WG_CONF = "/etc/wireguard/wg0.conf";
|
||||||
|
const PEER_DB = "/etc/wireguard/peers.json";
|
||||||
|
const CLIENT_DIR = "/etc/wireguard/clients";
|
||||||
|
|
||||||
|
const SERVER_PUBLIC_KEY = "<SERVER_PUBLIC_KEY>";
|
||||||
|
const SERVER_IP = "<SERVER_PUBLIC_IP>";
|
||||||
|
|
||||||
|
function loadDb() {
|
||||||
|
try {
|
||||||
|
return JSON.parse(fs.readFileSync(PEER_DB, "utf8"));
|
||||||
|
} catch {
|
||||||
|
const initial = { lastIp: 1, active: {}, free: [] };
|
||||||
|
fs.writeFileSync(PEER_DB, JSON.stringify(initial, null, 2));
|
||||||
|
return initial;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveDb(db) {
|
||||||
|
fs.writeFileSync(PEER_DB, JSON.stringify(db, null, 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
function allocateIp(db) {
|
||||||
|
if (db.free.length > 0) {
|
||||||
|
return db.free.shift(); // reuse old IP
|
||||||
|
}
|
||||||
|
|
||||||
|
db.lastIp++;
|
||||||
|
if (db.lastIp >= 255) db.lastIp = 2;
|
||||||
|
|
||||||
|
return `10.0.0.${db.lastIp}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function generateKeyPair() {
|
||||||
|
const privateKey = execSync("wg genkey").toString().trim();
|
||||||
|
const publicKey = execSync(`echo ${privateKey} | wg pubkey`).toString().trim();
|
||||||
|
return { privateKey, publicKey };
|
||||||
|
}
|
||||||
|
|
||||||
|
function addPeerToServer(publicKey, ip) {
|
||||||
|
const ipLast = ip.split(".")[3];
|
||||||
|
|
||||||
|
const peerEntry = `
|
||||||
|
[Peer]
|
||||||
|
PublicKey = ${publicKey}
|
||||||
|
AllowedIPs = 10.0.0.${ipLast}/32
|
||||||
|
`;
|
||||||
|
|
||||||
|
fs.appendFileSync(WG_CONF, peerEntry);
|
||||||
|
|
||||||
|
// apply config instantly
|
||||||
|
execSync(`wg syncconf wg0 <(wg-quick strip wg0)`, { shell: "/bin/bash" });
|
||||||
|
}
|
||||||
|
|
||||||
|
function generateClientConf(privateKey, ip) {
|
||||||
|
return `
|
||||||
|
[Interface]
|
||||||
|
PrivateKey = ${privateKey}
|
||||||
|
Address = ${ip}/32
|
||||||
|
DNS = 1.1.1.1
|
||||||
|
|
||||||
|
[Peer]
|
||||||
|
PublicKey = ${SERVER_PUBLIC_KEY}
|
||||||
|
Endpoint = ${SERVER_IP}:51820
|
||||||
|
AllowedIPs = 10.0.0.0/24
|
||||||
|
PersistentKeepalive = 25
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createWireGuardConnection() {
|
||||||
|
let db = loadDb();
|
||||||
|
|
||||||
|
// 1. allocate IP
|
||||||
|
const ip = allocateIp(db);
|
||||||
|
|
||||||
|
// 2. generate keys
|
||||||
|
const { privateKey, publicKey } = generateKeyPair();
|
||||||
|
|
||||||
|
// 3. update server config
|
||||||
|
addPeerToServer(publicKey, ip);
|
||||||
|
|
||||||
|
// 4. update DB
|
||||||
|
db.active[ip] = publicKey;
|
||||||
|
saveDb(db);
|
||||||
|
|
||||||
|
// 5. prepare client.conf
|
||||||
|
const clientConf = generateClientConf(privateKey, ip);
|
||||||
|
|
||||||
|
// (optional) save it
|
||||||
|
if (!fs.existsSync(CLIENT_DIR)) fs.mkdirSync(CLIENT_DIR);
|
||||||
|
fs.writeFileSync(`${CLIENT_DIR}/client-${ip}.conf`, clientConf);
|
||||||
|
|
||||||
|
// 6. return to Electron app
|
||||||
|
return { ip, publicKey, clientConf };
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue