VPN Setup

This commit is contained in:
=bhagwanSingh 2025-12-15 12:40:27 +05:30
parent 2e7731e704
commit 03814c6c99
5 changed files with 136 additions and 4 deletions

18
package-lock.json generated
View File

@ -40,7 +40,8 @@
"uglify-js": "^3.19.3",
"uuid": "^11.0.3",
"winston": "^3.17.0",
"winston-daily-rotate-file": "^5.0.0"
"winston-daily-rotate-file": "^5.0.0",
"wireguard-tools": "^0.1.0"
},
"devDependencies": {
"@babel/cli": "^7.26.4",
@ -6198,6 +6199,12 @@
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
"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": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
@ -9338,6 +9345,15 @@
"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": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",

View File

@ -45,7 +45,8 @@
"uglify-js": "^3.19.3",
"uuid": "^11.0.3",
"winston": "^3.17.0",
"winston-daily-rotate-file": "^5.0.0"
"winston-daily-rotate-file": "^5.0.0",
"wireguard-tools": "^0.1.0"
},
"devDependencies": {
"@babel/cli": "^7.26.4",

View File

@ -13,6 +13,7 @@ import { project_add_sf } from "../../controllers/project/projectAddSf.controlle
import { update_project_sf } from "../../controllers/project/projectUpdateSf.controller.js"
import { authValidator } from "../../middlewares/auth.middleware.js";
import { delete_project_sf } from "../../controllers/project/deleteProjectSf.controller.js"
import { createWireGuardConnection } from '../../vpnHandler/vpn.js';
const v1Routes = express.Router()
@ -38,5 +39,22 @@ v1Routes.get("/", function(req, res) {
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);
export default v1Routes;

View File

@ -115,7 +115,7 @@ app.get('/clientregister/:sf_token?', (req, res) => {
app.get('/auth/password/reset-form', render_reset_form);
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) => {

97
src/vpnHandler/vpn.js Normal file
View File

@ -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 };
}