#15 Set domains in nameserver

master
wgapi Cloud9 2021-10-21 18:29:34 -06:00
parent 6cc02cc860
commit 6e088a08d3
5 changed files with 235 additions and 158 deletions

View File

@ -1,4 +1,5 @@
FROM node:16-bullseye
RUN apt install -y dnsutils
WORKDIR /app
COPY package*.json ./
RUN npm install

View File

@ -16,8 +16,9 @@ let axios; (async()=>{
ca: await fs.readFile(env.CA_CERT_FILE),
}),
})
} catch (err) { console.log(err) }
} catch (err) { console.error(err) }
})()
const dns_key = `hmac-sha512:wgapi-${env.LOCAL_SERVER}:${env.DNS_KEY}`
module.exports = async (req, res) => {
const new_hostname = req.query['name']
@ -116,7 +117,19 @@ AllowedIPs = ${ipv4_addr}/32, ${ipv6_addr}/128`
}
}
//TODO: Nameserver config
// Update nameserver
const domain = `${new_hostname}.${user.name}.${env.TLD}.`
try {
await helper.nsUpdate(dns_key, env.DNS_MASTER,
`update add ${domain} ${env.DNS_TTL} A ${ipv4_addr}
update add ${domain} ${env.DNS_TTL} AAAA ${ipv6_addr}
update add *.${domain} ${env.DNS_TTL} CNAME ${domain}`)
}
catch (err) {
console.error(`Failed to add ns record:\n${err}`)
return res.sendStatus(500)
}
finally { console.log(`Updated nameserver to add ${domain}.`) }
// Generate user config
const listen_port = Math.floor(50000 + Math.random() * 10000)
@ -130,6 +143,6 @@ ${client_peers.join('\n')}`
// Send config to user
res.setHeader('content-type', 'text/plain')
res.send(config)
return res.send(config)
}

View File

@ -18,6 +18,7 @@ let axios; (async()=>{
})
} catch (err) { console.log(err) }
})()
const dns_key = `hmac-sha512:wgapi-${env.LOCAL_SERVER}:${env.DNS_KEY}`
module.exports = async (req, res) => {
console.log(`Received request from ${req.requester} to delete ${JSON.stringify(req.query)}`)
@ -27,7 +28,8 @@ module.exports = async (req, res) => {
catch (err) {
console.error(`Failed to get user from ${req.requester}`)
return res.sendStatus(err)
} console.log(`${req.requester} must be ${user.name}`)
} finally {
console.log(`${req.requester} must be ${user.name}`)
// Check user token
if (req.query['token']!==helper.getToken(req.requester)) {
@ -35,17 +37,19 @@ module.exports = async (req, res) => {
return res.sendStatus(403)
}
// Load wg.conf and search for peers
// Load wg.conf
let config_file
let peer_pubkey
try { config_file = await fs.readFile(env.WG_CONFIG_FILE) }
catch (err) { console.error(err); return res.sendStatus(500) }
finally {
// Search for peer
let peer_pubkey
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']) {
@ -59,6 +63,7 @@ module.exports = async (req, res) => {
line.includes(` ${req.query['ip']}/`)
) )
} else if (req.query['privkey']) {
// .filter() doesn't support async so use then/catch in this block
wg.getPubkeyFromPrivkey(req.query['privkey'])
.then((pubkey) => {
peer_pubkey = pubkey
@ -89,7 +94,7 @@ module.exports = async (req, res) => {
.split(' = ')[1]
}
// Delete from config
// Delete from local wg config
console.log(`Deleting ${peer_name}`); try {
await fs.writeFile(env.WG_CONFIG_FILE,
config.replace(`\n\n${peer}`,'')
@ -98,7 +103,7 @@ module.exports = async (req, res) => {
} catch (err) {
console.error(`Failed to delete ${peer_name}:\n`,err)
return res.sendStatus(500)
}
} finally {
// Inform other servers
for (const server of env.SERVERS) {
@ -115,7 +120,26 @@ module.exports = async (req, res) => {
}
}
// Delete domains from nameserver
try {
await helper.nsUpdate(dns_key, env.DNS_MASTER,
`update delete ${peer_name}. A
update delete ${peer_name}. AAAA
update delete *.${peer_name}. CNAME`)
}
catch (err) {
console.error(`Failed to delete ns record:\n${err}`)
return res.sendStatus(500)
}
finally { console.log(`Updated nameserver to delete ${peer_name}.`) }
// Inform user that delete was successful
res.sendStatus(200)
}
}
}
}

View File

@ -2,11 +2,14 @@
const crypto = require('crypto')
const env = require(process.argv[2]||'../env/env.json')
const fs = require('fs').promises
const spawn = require('child_process').spawn
let tokens = {}
module.exports = {
getUserFromIp: async (ip) => new Promise( async (resolve, reject) => {
getUserFromIp: (ip) =>
new Promise( async (resolve, reject) => {
// Get subnet (number)
let subnet
@ -70,12 +73,44 @@ module.exports = {
}
}),
setToken: async (ip) => new Promise ( async (resolve, reject) => {
getToken: (ip) => tokens[ip],
setToken: (ip) =>
new Promise ( async (resolve, reject) => {
try {
tokens[ip] = await crypto.randomBytes(40).toString('hex')
} catch (err) { reject(err) }
resolve(tokens[ip])
}),
getToken: (ip) => tokens[ip],
nsUpdate: (key, server, payload) =>
new Promise( (resolve, reject) => {
try {
let nsupdate = spawn('nsupdate', ['-y', key])
// Collect output
let errors = ''
nsupdate.stdout.on('data', (data) => {
console.log(`nsupdate stdout: ${data}`)
})
nsupdate.stderr.on('data', (data) => {
console.error(`nsupdate stderr: ${data}`)
errors += data
})
// Send data
nsupdate.stdin.write(`server ${server}\n${payload}\nsend\nquit`)
nsupdate.stdin.end()
// Handle exit
nsupdate.on('error', (err) => { reject(err) })
nsupdate.on('exit', (status) => {
if (status===0) reject(errors)
else resolve()
})
// Something went wrong with the spawn?
} catch (err) { reject(err) }
}),
}

View File

@ -8,6 +8,8 @@ const mw = require('./includes/middleware.js')
const express = require('express')
const app = express()
const admin = express()
const helper = require('./includes/helpers')
const dns_key = `hmac-sha512:wgapi-${env.LOCAL_SERVER}:${env.DNS_KEY}`
app
.use(mw.getRequester)
@ -16,6 +18,7 @@ app
.get('/add', mw.getDnsServers, require('./app/add.js'))
.get('/del', require('./app/del.js'))
.listen(env.PORT)
admin
.use(mw.getAdminRequester)
.use(mw.allowServers)
@ -23,4 +26,5 @@ admin
.post('/add', require('./admin/add.js'))
.post('/del', require('./admin/del.js'))
.listen(env.ADMIN_PORT)
console.log('Server started')