diff --git a/CHANGES b/CHANGES index b5b08b176..951d6142f 100644 --- a/CHANGES +++ b/CHANGES @@ -2122,4 +2122,5 @@ * Reduce duration of self-signed certs to 800 days * Better backup config filename when downloading * branding: footer can have template variables like %YEAR% and %VERSION% +* sftp: secure the API with a token diff --git a/src/infra_version.js b/src/infra_version.js index 1ddec8d8e..657596d34 100644 --- a/src/infra_version.js +++ b/src/infra_version.js @@ -22,6 +22,6 @@ exports = module.exports = { 'redis': { repo: 'cloudron/redis', tag: 'cloudron/redis:2.3.0@sha256:0e31ec817e235b1814c04af97b1e7cf0053384aca2569570ce92bef0d95e94d2' }, 'mail': { repo: 'cloudron/mail', tag: 'cloudron/mail:2.10.0@sha256:3aff92bfc85d6ca3cc6fc381c8a89625d2af95cc55ed2db692ef4e483e600372' }, 'graphite': { repo: 'cloudron/graphite', tag: 'cloudron/graphite:2.3.0@sha256:b7bc1ca4f4d0603a01369a689129aa273a938ce195fe43d00d42f4f2d5212f50' }, - 'sftp': { repo: 'cloudron/sftp', tag: 'cloudron/sftp:2.0.2@sha256:cbd604eaa970c99ba5c4c2e7984929668e05de824172f880e8c576b2fb7c976d' } + 'sftp': { repo: 'cloudron/sftp', tag: 'cloudron/sftp:3.0.0@sha256:a89c2dbb4137d088ee9d8274a76b1059a506d4d841770c0d576cb53111fdc44c' } } }; diff --git a/src/routes/filemanager.js b/src/routes/filemanager.js index 992242b94..0bd8aae00 100644 --- a/src/routes/filemanager.js +++ b/src/routes/filemanager.js @@ -4,12 +4,11 @@ exports = module.exports = { proxy }; -var assert = require('assert'), +var addons = require('../addons.js'), + assert = require('assert'), BoxError = require('../boxerror.js'), - docker = require('../docker.js'), middleware = require('../middleware/index.js'), HttpError = require('connect-lastmile').HttpError, - safe = require('safetydance'), url = require('url'); function proxy(req, res, next) { @@ -19,15 +18,15 @@ function proxy(req, res, next) { req.clearTimeout(); - docker.inspect('sftp', function (error, result) { - if (error)return next(BoxError.toHttpError(error)); + addons.getContainerDetails('sftp', 'CLOUDRON_SFTP_TOKEN', function (error, result) { + if (error) return next(BoxError.toHttpError(error)); - const ip = safe.query(result, 'NetworkSettings.Networks.cloudron.IPAddress', null); - if (!ip) return next(new BoxError(BoxError.INACTIVE, 'Error getting IP of sftp service')); + let parsedUrl = url.parse(req.url, true /* parseQueryString */); + parsedUrl.query['access_token'] = result.token; - req.url = req.originalUrl.replace(`/api/v1/apps/${appId}/files`, `/files/${appId}`); + req.url = url.format({ pathname: `/files/${appId}/${req.params[0]}`, query: parsedUrl.query }); - const proxyOptions = url.parse(`https://${ip}:3000`); + const proxyOptions = url.parse(`https://${result.ip}:3000`); proxyOptions.rejectUnauthorized = false; const fileManagerProxy = middleware.proxy(proxyOptions); diff --git a/src/sftp.js b/src/sftp.js index f1ffb9128..87ac2ccbc 100644 --- a/src/sftp.js +++ b/src/sftp.js @@ -9,6 +9,7 @@ var apps = require('./apps.js'), assert = require('assert'), async = require('async'), debug = require('debug')('box:sftp'), + hat = require('./hat.js'), infra = require('./infra_version.js'), safe = require('safetydance'), shell = require('./shell.js'), @@ -43,6 +44,7 @@ function rebuild(callback) { const tag = infra.images.sftp.tag; const memoryLimit = 256; + const cloudronToken = hat(8 * 128); apps.getAll(function (error, result) { if (error) return done(error); @@ -94,6 +96,7 @@ function rebuild(callback) { --dns-search=. \ -p 222:22 \ ${appDataVolumes} \ + -e CLOUDRON_SFTP_TOKEN="${cloudronToken}" \ -v "/etc/ssh:/etc/ssh:ro" \ --label isCloudronManaged=true \ --read-only -v /tmp -v /run "${tag}"`;