balena-supervisor/src/lib/vpn.coffee
2015-10-13 13:28:00 -03:00

66 lines
1.9 KiB
CoffeeScript

Promise = require 'bluebird'
_ = require 'lodash'
csrgen = Promise.promisify require 'csr-gen'
fs = Promise.promisifyAll require 'fs'
request = Promise.promisifyAll require 'request'
url = require 'url'
{spawn} = require 'child_process'
exports.generate = (apiEndpoint, userConfig) ->
# Generate SSL certificate
keys = csrgen(userConfig.uuid,
company: 'Rulemotion Ltd'
csrName: 'client.csr'
keyName: 'client.key'
outputDir: '/data'
email: 'vpn@resin.io'
read: true
country: ''
city: ''
state: ''
division: ''
)
.then (keys) ->
console.log('UUID:', userConfig.uuid)
console.log('User ID:', userConfig.userId)
console.log('User:', userConfig.username)
console.log('API key:', userConfig.apiKey)
console.log('Application ID:', userConfig.applicationId)
console.log('CSR :', keys.csr)
console.log('Posting to the API..')
userConfig.csr = keys.csr
return request.postAsync(
url: url.resolve(apiEndpoint, 'sign_certificate?apikey=' + userConfig.apiKey)
gzip: true
json: userConfig
)
.spread (response, body) ->
if response.statusCode >= 400
throw body
console.log('Configuring VPN..', JSON.stringify(body))
for prop in ['ca', 'cert', 'vpnhost', 'vpnport'] when _.isEmpty(body[prop])
throw new Error("'#{prop}' is empty, cannot bootstrap")
vpnConf = fs.readFileAsync(__dirname + '/openvpn.conf.tmpl', 'utf8')
.then (tmpl) ->
fs.writeFileAsync('/data/client.conf', _.template(tmpl)(body))
Promise.all([
fs.writeFileAsync('/data/ca.crt', body.ca)
fs.writeFileAsync('/data/client.crt', body.cert)
vpnConf
])
prefixData = (data) ->
prefix = 'OPENVPN: '
console.log((prefix + data).trim().replace(/\n/gm, "\n#{prefix}"))
exports.connect = ->
openvpn = spawn('openvpn', [ 'client.conf' ], cwd: '/data')
# Prefix and log all OpenVPN output
openvpn.stdout.on('data', prefixData)
openvpn.stderr.on('data', prefixData)