#6 Added /del endpoint
parent
62179c8833
commit
41dbde0a5a
|
@ -1,5 +1,5 @@
|
|||
'use strict'
|
||||
/* srv-add.js
|
||||
/* admin/add.js
|
||||
* routes for intra-server peer sharing
|
||||
*/
|
||||
|
||||
|
|
28
admin/del.js
28
admin/del.js
|
@ -1,12 +1,32 @@
|
|||
'use strict'
|
||||
/* srv-del.js
|
||||
/* admin/del.js
|
||||
* 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
|
||||
|
||||
module.exports = async (req, res) => {
|
||||
console.log(`Received delete from ${req.requester}`)
|
||||
res.send(req.body)
|
||||
console.log(`Received delete from ${req.requester} for ${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']
|
||||
if (!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}`)
|
||||
|
||||
|
@ -50,7 +50,7 @@ module.exports = async (req, res) => {
|
|||
// Check if host exists
|
||||
if (line.includes(`# ${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])
|
||||
}
|
||||
|
@ -75,7 +75,7 @@ module.exports = async (req, res) => {
|
|||
// Should never get here because this req.requester can't access this IP!
|
||||
} else if (found_usernames.length ===0) {
|
||||
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
|
||||
// https://stackoverflow.com/a/35568895
|
||||
} else if (!found_usernames.every( (v,i,r) => v === r[0] )) {
|
||||
|
@ -131,7 +131,8 @@ PresharedKey = ${psk}
|
|||
AllowedIPs = ${ipv4_addr}/32, ${ipv6_addr}/128`
|
||||
if (server.host===env.LOCAL_SERVER) {
|
||||
// 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 {
|
||||
// Send config to other server
|
||||
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 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) => {
|
||||
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}`)
|
||||
res.setHeader('content-type', 'text/plain')
|
||||
res.send(`Delete ${privkey}`)
|
||||
// Parse peer
|
||||
const peer_lines = peer.split('\n')
|
||||
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 = {
|
||||
|
||||
generateKeypair: async () => {
|
||||
let privateKey, publicKey
|
||||
try {
|
||||
privateKey = await generatePrivateKey()
|
||||
} catch (err) { console.log(err) }
|
||||
} catch (err) { console.error(err) }
|
||||
try {
|
||||
publicKey = await generatePublicKey(privateKey)
|
||||
} catch (err) { console.log(err) }
|
||||
} catch (err) { console.error(err) }
|
||||
return [
|
||||
keyToBase64(publicKey),
|
||||
keyToBase64(privateKey),
|
||||
]
|
||||
},
|
||||
|
||||
generatePSK: async () => {
|
||||
try {
|
||||
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