VPN Setup
This commit is contained in:
parent
2e7731e704
commit
03814c6c99
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -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) => {
|
||||
|
|
|
|||
|
|
@ -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