#6 Added /del endpoint
parent
62179c8833
commit
41dbde0a5a
|
@ -1,5 +1,5 @@
|
||||||
'use strict'
|
'use strict'
|
||||||
/* srv-add.js
|
/* admin/add.js
|
||||||
* routes for intra-server peer sharing
|
* routes for intra-server peer sharing
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
28
admin/del.js
28
admin/del.js
|
@ -1,12 +1,32 @@
|
||||||
'use strict'
|
'use strict'
|
||||||
/* srv-del.js
|
/* admin/del.js
|
||||||
* routes for intra-server peer sharing
|
* routes for intra-server peer sharing
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const env = require('../env/env.json')
|
const env = require(process.argv[2]||'../env/env.json')
|
||||||
const fs = require('fs').promises
|
const fs = require('fs').promises
|
||||||
|
|
||||||
module.exports = async (req, res) => {
|
module.exports = async (req, res) => {
|
||||||
console.log(`Received delete from ${req.requester}`)
|
console.log(`Received delete from ${req.requester} for ${req.body}`)
|
||||||
res.send(req.body)
|
let config
|
||||||
|
try {
|
||||||
|
const config_file = await fs.readFile(env.WG_CONFIG_FILE)
|
||||||
|
config = config_file.toString()
|
||||||
|
} catch (err) {
|
||||||
|
console.error(`Failed to load config from ${env.WG_CONFIG_FILE}:\n`,err)
|
||||||
|
res.sendStatus(500)
|
||||||
|
}
|
||||||
|
const peer = config.split('\n\n')
|
||||||
|
.filter( (paragraph) => {
|
||||||
|
return paragraph.includes('[Peer]')
|
||||||
|
}).filter( (peer) => {
|
||||||
|
return peer.includes(`PublicKey = ${req.body}`)
|
||||||
|
})
|
||||||
|
try {
|
||||||
|
await fs.writeFile(env.WG_CONFIG_FILE, config.replace(`\n\n${peer}`,''))
|
||||||
|
} catch (err) {
|
||||||
|
console.error(`Failed to delete peer config from ${env.WG_CONFIG_FILE}:\n`,err)
|
||||||
|
res.sendStatus(500)
|
||||||
|
}
|
||||||
|
res.sendStatus(200)
|
||||||
}
|
}
|
|
@ -22,7 +22,7 @@ module.exports = async (req, res) => {
|
||||||
const hostname = req.query['name']
|
const hostname = req.query['name']
|
||||||
if (!hostname) {
|
if (!hostname) {
|
||||||
console.log(`New peer request from ${req.requester} didn't provide a hostname`)
|
console.log(`New peer request from ${req.requester} didn't provide a hostname`)
|
||||||
res.sendStatus(500); return
|
res.sendStatus(400); return
|
||||||
}
|
}
|
||||||
console.log(`New peer request from ${req.requester} for ${hostname}`)
|
console.log(`New peer request from ${req.requester} for ${hostname}`)
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ module.exports = async (req, res) => {
|
||||||
// Check if host exists
|
// Check if host exists
|
||||||
if (line.includes(`# ${hostname}.`)) {
|
if (line.includes(`# ${hostname}.`)) {
|
||||||
console.log(`Host already exists for ${hostname}`)
|
console.log(`Host already exists for ${hostname}`)
|
||||||
res.sendStatus(500); return
|
res.sendStatus(409); return
|
||||||
}
|
}
|
||||||
found_usernames.push(line.split('.').slice(-2,-1)[0])
|
found_usernames.push(line.split('.').slice(-2,-1)[0])
|
||||||
}
|
}
|
||||||
|
@ -75,7 +75,7 @@ module.exports = async (req, res) => {
|
||||||
// Should never get here because this req.requester can't access this IP!
|
// Should never get here because this req.requester can't access this IP!
|
||||||
} else if (found_usernames.length ===0) {
|
} else if (found_usernames.length ===0) {
|
||||||
console.log(`Received request from ${req.requester} not in wg.conf!`)
|
console.log(`Received request from ${req.requester} not in wg.conf!`)
|
||||||
res.sendStatus(500); return
|
res.sendStatus(403); return
|
||||||
// Check that all usernames are correct or error out
|
// Check that all usernames are correct or error out
|
||||||
// https://stackoverflow.com/a/35568895
|
// https://stackoverflow.com/a/35568895
|
||||||
} else if (!found_usernames.every( (v,i,r) => v === r[0] )) {
|
} else if (!found_usernames.every( (v,i,r) => v === r[0] )) {
|
||||||
|
@ -131,7 +131,8 @@ PresharedKey = ${psk}
|
||||||
AllowedIPs = ${ipv4_addr}/32, ${ipv6_addr}/128`
|
AllowedIPs = ${ipv4_addr}/32, ${ipv6_addr}/128`
|
||||||
if (server.host===env.LOCAL_SERVER) {
|
if (server.host===env.LOCAL_SERVER) {
|
||||||
// Add server_config to wg0.conf
|
// Add server_config to wg0.conf
|
||||||
fs.appendFile(env.WG_CONFIG_FILE, server_config)
|
try { await fs.appendFile(env.WG_CONFIG_FILE, server_config) }
|
||||||
|
catch (err) { console.error(err); return}
|
||||||
} else {
|
} else {
|
||||||
// Send config to other server
|
// Send config to other server
|
||||||
console.log(`Sending config to ${server.host}.gf4`)
|
console.log(`Sending config to ${server.host}.gf4`)
|
||||||
|
|
98
app/del.js
98
app/del.js
|
@ -4,13 +4,101 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const fs = require('fs').promises
|
const fs = require('fs').promises
|
||||||
const env = require('../env/env.json')
|
const env = require(process.argv[2]||'../env/env.json')
|
||||||
|
const wg = require('../includes/wireguard')
|
||||||
|
const https = require('https')
|
||||||
|
// Construct axios in IIFE for async/await
|
||||||
|
let axios; (async()=>{
|
||||||
|
try {
|
||||||
|
axios = require('axios').create({
|
||||||
|
httpsAgent: new https.Agent({
|
||||||
|
ca: await fs.readFile(env.CA_CERT_FILE),
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
} catch (err) { console.log(err) }
|
||||||
|
})()
|
||||||
|
|
||||||
module.exports = async (req, res) => {
|
module.exports = async (req, res) => {
|
||||||
const privkey = req.query['del']
|
console.log(`Received request from ${req.requester} to delete ${JSON.stringify(req.query)}`)
|
||||||
|
|
||||||
|
// Load wg.conf and search for peers
|
||||||
|
let config_file
|
||||||
|
let peer_pubkey
|
||||||
|
try { config_file = await fs.readFile(env.WG_CONFIG_FILE) }
|
||||||
|
catch (err) { console.error(err); res.sendStatus(500); return }
|
||||||
|
const config = config_file.toString()
|
||||||
|
const peer = config.split('\n\n')
|
||||||
|
.filter( (paragraph) => {
|
||||||
|
return paragraph.includes('[Peer]')
|
||||||
|
}).filter( (peer) => {
|
||||||
|
// .filter() doesn't support async so use then/catch in this block
|
||||||
|
if (req.query['name']) {
|
||||||
|
return peer.includes(`[Peer] # ${req.query['name']}.`)
|
||||||
|
} else if (req.query['pubkey']) {
|
||||||
|
peer_pubkey = req.query['pubkey']
|
||||||
|
return peer.includes(`PublicKey = ${req.query['pubkey']}`)
|
||||||
|
} else if (req.query['psk']) {
|
||||||
|
return peer.includes(`PresharedKey = ${req.query['psk']}`)
|
||||||
|
} else if (req.query['ip']) {
|
||||||
|
return peer.split('\n').some( (line) => (
|
||||||
|
line.includes('AllowedIPs') &&
|
||||||
|
line.includes(` ${req.query['ip']}/`)
|
||||||
|
) )
|
||||||
|
} else if (req.query['privkey']) {
|
||||||
|
wg.getPubkeyFromPrivkey(req.query['privkey'])
|
||||||
|
.then((pubkey) => {
|
||||||
|
peer_pubkey = pubkey
|
||||||
|
return peer.includes(`PublicKey = ${pubkey}`)
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.error(`Failed to generate public key from private key during delete request\n`,err)
|
||||||
|
res.sendStatus(500); return
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
console.error(`${req.requester} sent delete request without specifying a peer`)
|
||||||
|
res.sendStatus(400); return
|
||||||
|
}
|
||||||
|
})[0]
|
||||||
|
if (peer===undefined) {
|
||||||
|
console.log(`No peer found for delete request from ${req.requester}`)
|
||||||
|
res.sendStatus(404); return
|
||||||
|
}
|
||||||
|
|
||||||
console.log(`Received request from ${req.requester} to delete ${privkey}`)
|
// Parse peer
|
||||||
res.setHeader('content-type', 'text/plain')
|
const peer_lines = peer.split('\n')
|
||||||
res.send(`Delete ${privkey}`)
|
const peer_name = peer_lines
|
||||||
|
.filter( (line) => line.includes('[Peer] # ') )[0]
|
||||||
|
.split(' # ')[1]
|
||||||
|
if (peer_pubkey===undefined) {
|
||||||
|
peer_pubkey = peer_lines
|
||||||
|
.filter( (line) => line.includes('PublicKey = ') )[0]
|
||||||
|
.split(' = ')[1]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete from config
|
||||||
|
console.log(`Deleting ${peer_name}`); try {
|
||||||
|
await fs.writeFile(env.WG_CONFIG_FILE, config.replace(`\n\n${peer}`,''))
|
||||||
|
} catch (err) {
|
||||||
|
console.error(`Failed to delete ${peer_name}:\n`,err)
|
||||||
|
res.sendStatus(500); return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inform other servers
|
||||||
|
for (const server of env.SERVERS) {
|
||||||
|
if (server.host!==env.LOCAL_SERVER) {
|
||||||
|
try {
|
||||||
|
console.log(`Informing ${server.host} to delete ${peer_name}`)
|
||||||
|
await axios.post(`${server.admin_endpoint}/del`, peer_pubkey, {
|
||||||
|
headers: {'Content-Type': 'text/plain'},
|
||||||
|
})
|
||||||
|
} catch (err) {
|
||||||
|
console.error(`Failed to inform ${server.host} to delete ${peer_name}:\n\n`,err)
|
||||||
|
res.sendStatus(500); return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inform user that delete was successful
|
||||||
|
res.sendStatus(200)
|
||||||
|
|
||||||
}
|
}
|
|
@ -162,23 +162,32 @@ const keyToBase64 = (key) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
|
||||||
generateKeypair: async () => {
|
generateKeypair: async () => {
|
||||||
let privateKey, publicKey
|
let privateKey, publicKey
|
||||||
try {
|
try {
|
||||||
privateKey = await generatePrivateKey()
|
privateKey = await generatePrivateKey()
|
||||||
} catch (err) { console.log(err) }
|
} catch (err) { console.error(err) }
|
||||||
try {
|
try {
|
||||||
publicKey = await generatePublicKey(privateKey)
|
publicKey = await generatePublicKey(privateKey)
|
||||||
} catch (err) { console.log(err) }
|
} catch (err) { console.error(err) }
|
||||||
return [
|
return [
|
||||||
keyToBase64(publicKey),
|
keyToBase64(publicKey),
|
||||||
keyToBase64(privateKey),
|
keyToBase64(privateKey),
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
||||||
generatePSK: async () => {
|
generatePSK: async () => {
|
||||||
try {
|
try {
|
||||||
return keyToBase64(await generatePresharedKey())
|
return keyToBase64(await generatePresharedKey())
|
||||||
} catch (err) { console.log(err) }
|
} catch (err) { console.error(err); return }
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getPubkeyFromPrivkey: async (privKey) => {
|
||||||
|
try {
|
||||||
|
return await generatePublicKey(privKey)
|
||||||
|
} catch (err) { console.error(err); return }
|
||||||
|
},
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue