Compare commits

..

7 Commits

Author SHA1 Message Date
Girish Ramakrishnan 5447aa7c80 missed this one 2020-09-15 14:46:47 -07:00
Girish Ramakrishnan 933918ea27 Fix docs url 2020-09-15 14:46:22 -07:00
Girish Ramakrishnan cbbcdc5df1 regenerate nginx configs
Users are seeing SSL_ERROR_RX_UNEXPECTED_NEW_SESSION_TICKET. Probably related
some of the app configs had ssl_session_tickets off and some didn't . It seems nginx
has some issue if they are inconsistent (see also https://github.com/nginx-proxy/nginx-proxy/issues/580#issuecomment-249587149).

https://forum.cloudron.io/topic/3157/ssl-error-after-upgrading-to-5-6-0-on-ubuntu-16
2020-09-15 08:26:41 -07:00
Girish Ramakrishnan 4dfa7b132d ignore duplicates 2020-09-14 13:53:58 -07:00
Girish Ramakrishnan fb5bfaa2bd read does not read last line without a newline 2020-09-14 13:52:10 -07:00
Girish Ramakrishnan 20e206fa43 migrate blocklist to a txt file
this allows easy copy/pasting of existing deny lists which contain
comments and blank lines
2020-09-14 12:10:29 -07:00
Girish Ramakrishnan 467fa59023 Fix timeout issue when adding lots of network ranges 2020-09-14 09:56:35 -07:00
24 changed files with 106 additions and 53 deletions
+4
View File
@@ -2087,3 +2087,7 @@
* ovh: add sydney region
* s3: makes multi-part copies in parallel
[5.6.1]
* Blocklists are now stored in a text file instead of json
* regenerate nginx configs
+4 -4
View File
@@ -29,9 +29,9 @@ anyone to effortlessly host web applications on their server on their own terms.
* Trivially migrate to another server keeping your apps and data (for example, switch your
infrastructure provider or move to a bigger server).
* Comprehensive [REST API](https://cloudron.io/documentation/developer/api/).
* Comprehensive [REST API](https://docs.cloudron.io/api/).
* [CLI](https://cloudron.io/documentation/cli/) to configure apps.
* [CLI](https://docs.cloudron.io/custom-apps/cli/) to configure apps.
* Alerts, audit logs, graphs, dns management ... and much more
@@ -41,7 +41,7 @@ Try our demo at https://my.demo.cloudron.io (username: cloudron password: cloudr
## Installing
[Install script](https://cloudron.io/documentation/installation/) - [Pricing](https://cloudron.io/pricing.html)
[Install script](https://docs.cloudron.io/installation/) - [Pricing](https://cloudron.io/pricing.html)
**Note:** This repo is a small part of what gets installed on your server - there is
the dashboard, database addons, graph container, base image etc. Cloudron also relies
@@ -50,6 +50,6 @@ clone this repo and npm install and expect something to work.
## Support
* [Documentation](https://cloudron.io/documentation/)
* [Documentation](https://docs.cloudron.io/)
* [Forum](https://forum.cloudron.io/)
+1 -1
View File
@@ -130,7 +130,7 @@ timedatectl set-ntp 1
timedatectl set-timezone UTC
echo "==> Adding sshd configuration warning"
sed -e '/Port 22/ i # NOTE: Cloudron only supports moving SSH to port 202. See https://cloudron.io/documentation/security/#securing-ssh-access' -i /etc/ssh/sshd_config
sed -e '/Port 22/ i # NOTE: Cloudron only supports moving SSH to port 202. See https://docs.cloudron.io/security/#securing-ssh-access' -i /etc/ssh/sshd_config
# https://bugs.launchpad.net/ubuntu/+source/base-files/+bug/1701068
echo "==> Disabling motd news"
@@ -0,0 +1,27 @@
'use strict';
const OLD_FIREWALL_CONFIG_JSON = '/home/yellowtent/boxdata/firewall-config.json';
const PORTS_FILE = '/home/yellowtent/boxdata/firewall/ports.json';
const BLOCKLIST_FILE = '/home/yellowtent/boxdata/firewall/blocklist.txt';
const fs = require('fs');
exports.up = function (db, callback) {
if (!fs.existsSync(OLD_FIREWALL_CONFIG_JSON)) return callback();
try {
const dataJson = fs.readFileSync(OLD_FIREWALL_CONFIG_JSON, 'utf8');
const data = JSON.parse(dataJson);
fs.writeFileSync(BLOCKLIST_FILE, data.blocklist.join('\n') + '\n', 'utf8');
fs.writeFileSync(PORTS_FILE, JSON.stringify({ allowed_tcp_ports: data.allowed_tcp_ports }, null, 4), 'utf8');
fs.unlinkSync(OLD_FIREWALL_CONFIG_JSON);
} catch (error) {
console.log('Error migrating old firewall config', error);
}
callback();
};
exports.down = function (db, callback) {
callback();
};
+12 -5
View File
@@ -2438,9 +2438,9 @@
"integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw=="
},
"ipaddr.js": {
"version": "1.9.0",
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz",
"integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA=="
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.0.0.tgz",
"integrity": "sha512-S54H9mIj0rbxRIyrDMEuuER86LdlgUg9FSeZ8duQb6CUG2iRrA36MYVQBSprTF/ZeAwvyQ5mDGuNvIPM0BIl3w=="
},
"is-arguments": {
"version": "1.0.4",
@@ -3779,6 +3779,13 @@
"requires": {
"forwarded": "~0.1.2",
"ipaddr.js": "1.9.0"
},
"dependencies": {
"ipaddr.js": {
"version": "1.9.0",
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz",
"integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA=="
}
}
},
"proxy-middleware": {
@@ -4635,8 +4642,8 @@
"resolved": "https://registry.npmjs.org/prettyjson/-/prettyjson-1.2.1.tgz",
"integrity": "sha1-/P+rQdGcq0365eV15kJGYZsS0ok=",
"requires": {
"colors": "1.2.1",
"minimist": "1.2.0"
"colors": "^1.1.2",
"minimist": "^1.2.0"
}
}
}
+1
View File
@@ -33,6 +33,7 @@
"ejs": "^2.6.1",
"ejs-cli": "^2.2.0",
"express": "^4.17.1",
"ipaddr.js": "^2.0.0",
"js-yaml": "^3.14.0",
"json": "^9.0.6",
"ldapjs": "^1.0.2",
+1 -1
View File
@@ -53,7 +53,7 @@ eval set -- "${args}"
while true; do
case "$1" in
--help) echo "See https://cloudron.io/documentation/installation/ on how to install Cloudron"; exit 0;;
--help) echo "See https://docs.cloudron.io/installation/ on how to install Cloudron"; exit 0;;
--provider) provider="$2"; shift 2;;
--version) requestedVersion="$2"; shift 2;;
--env)
+1 -1
View File
@@ -57,7 +57,7 @@ if [[ "`df --output="avail" / | sed -n 2p`" -lt "10240" ]]; then
echo ""
df -h
echo ""
echo "To recover from a full disk, follow the guide at https://cloudron.io/documentation/troubleshooting/#recovery-after-disk-full"
echo "To recover from a full disk, follow the guide at https://docs.cloudron.io/troubleshooting/#recovery-after-disk-full"
exit 1
fi
+1
View File
@@ -57,6 +57,7 @@ mkdir -p "${PLATFORM_DATA_DIR}/logs/backup" \
mkdir -p "${PLATFORM_DATA_DIR}/update"
mkdir -p "${BOX_DATA_DIR}/appicons"
mkdir -p "${BOX_DATA_DIR}/firewall"
mkdir -p "${BOX_DATA_DIR}/profileicons"
mkdir -p "${BOX_DATA_DIR}/certs"
mkdir -p "${BOX_DATA_DIR}/acme" # acme keys
+2 -2
View File
@@ -20,8 +20,8 @@ iptables -t filter -A CLOUDRON -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -t filter -A CLOUDRON -p tcp -m tcp -m multiport --dports 22,25,80,202,443 -j ACCEPT # 202 is the alternate ssh port
# whitelist any user ports
user_firewall_json="/home/yellowtent/boxdata/firewall-config.json"
if allowed_tcp_ports=$(node -e "console.log(JSON.parse(fs.readFileSync('${user_firewall_json}', 'utf8')).allowed_tcp_ports.join(','))" 2>/dev/null); then
ports_json="/home/yellowtent/boxdata/firewall/ports.json"
if allowed_tcp_ports=$(node -e "console.log(JSON.parse(fs.readFileSync('${ports_json}', 'utf8')).allowed_tcp_ports.join(','))" 2>/dev/null); then
[[ -n "${allowed_tcp_ports}" ]] && iptables -A CLOUDRON -p tcp -m tcp -m multiport --dports "${allowed_tcp_ports}" -j ACCEPT
fi
+3 -3
View File
@@ -14,8 +14,8 @@ if [[ -z "$(ls -A /home/yellowtent/boxdata/mail/dkim)" ]]; then
printf "\t\t\t-------------------\n"
printf '\n\e[1;32m%-6s\e[m\n\n' "Visit https://${ip} on your browser and accept the self-signed certificate to finish setup."
printf "Cloudron overview - https://cloudron.io/documentation/ \n"
printf "Cloudron setup - https://cloudron.io/documentation/installation/#setup \n"
printf "Cloudron overview - https://docs.cloudron.io/ \n"
printf "Cloudron setup - https://docs.cloudron.io/installation/#setup \n"
else
printf "\t\t\tNOTE TO CLOUDRON ADMINS\n"
printf "\t\t\t-----------------------\n"
@@ -23,7 +23,7 @@ else
printf "Cloudron relies on and may break your installation. Ubuntu security updates\n"
printf "are automatically installed on this server every night.\n"
printf "\n"
printf "Read more at https://cloudron.io/documentation/security/#os-updates\n"
printf "Read more at https://docs.cloudron.io/security/#os-updates\n"
fi
printf "\nFor help and more information, visit https://forum.cloudron.io\n\n"
+2 -2
View File
@@ -1523,9 +1523,9 @@ function checkConfiguration(callback) {
let message = '';
if (backupConfig.provider === 'noop') {
message = 'Cloudron backups are disabled. Please ensure this server is backed up using alternate means. See https://cloudron.io/documentation/backups/#storage-providers for more information.';
message = 'Cloudron backups are disabled. Please ensure this server is backed up using alternate means. See https://docs.cloudron.io/backups/#storage-providers for more information.';
} else if (backupConfig.provider === 'filesystem' && !backupConfig.externalDisk) {
message = 'Cloudron backups are currently on the same disk as the Cloudron server instance. This is dangerous and can lead to complete data loss if the disk fails. See https://cloudron.io/documentation/backups/#storage-providers for storing backups in an external location.';
message = 'Cloudron backups are currently on the same disk as the Cloudron server instance. This is dangerous and can lead to complete data loss if the disk fails. See https://docs.cloudron.io/backups/#storage-providers for storing backups in an external location.';
}
callback(null, message);
+1 -1
View File
@@ -6,7 +6,7 @@
exports = module.exports = {
// a version change recreates all containers with latest docker config
'version': '48.17.0',
'version': '48.17.1',
'baseImages': [
{ repo: 'cloudron/base', tag: 'cloudron/base:2.0.0@sha256:f9fea80513aa7c92fe2e7bf3978b54c8ac5222f47a9a32a7f8833edf0eb5a4f4' }
+1 -1
View File
@@ -550,7 +550,7 @@ function checkConfiguration(callback) {
markdownMessage += '\n\n';
});
if (markdownMessage) markdownMessage += 'Email Status is checked every 30 minutes.\n See the [troubleshooting docs](https://cloudron.io/documentation/troubleshooting/#mail-dns) for more information.\n';
if (markdownMessage) markdownMessage += 'Email Status is checked every 30 minutes.\n See the [troubleshooting docs](https://docs.cloudron.io/troubleshooting/#mail-dns) for more information.\n';
callback(null, markdownMessage); // empty message means all status checks succeeded
});
+2 -2
View File
@@ -7,8 +7,8 @@ The application '<%= title %>' installed at <%= appFqdn %> is not responding.
This is most likely a problem in the application.
To resolve this, you can try the following:
* Restart the app by opening the app's web terminal - https://cloudron.io/documentation/apps/#web-terminal
* Restore the app to the latest backup - https://cloudron.io/documentation/backups/#restoring-an-app
* Restart the app by opening the app's web terminal - https://docs.cloudron.io/apps/#web-terminal
* Restore the app to the latest backup - https://docs.cloudron.io/backups/#restoring-an-app
* Contact us via <%= supportEmail %> or https://forum.cloudron.io
+1 -1
View File
@@ -2,7 +2,7 @@
Dear <%= cloudronName %> Admin,
Cloudron failed to create a complete backup. Please see https://cloudron.io/documentation/troubleshooting/#backups
Cloudron failed to create a complete backup. Please see https://docs.cloudron.io/troubleshooting/#backups
for troubleshooting.
Logs for this failure are available at <%= logUrl %>
@@ -8,7 +8,7 @@ The Cloudron will attempt to renew the certificate every 12 hours
until the certificate expires (at which point it will switch to
using the fallback certificate).
See https://cloudron.io/documentation/troubleshooting/#certificates to
See https://docs.cloudron.io/troubleshooting/#certificates to
double check if your server is configured correctly to obtain certificates
via Let's Encrypt.
+2 -2
View File
@@ -6,8 +6,8 @@ Dear <%= cloudronName %> Admin,
If this message appears repeatedly, give the app more memory.
* To increase an app's memory limit - https://cloudron.io/documentation/apps/#memory-limit
* To increase a service's memory limit - https://cloudron.io/documentation/troubleshooting/#services
* To increase an app's memory limit - https://docs.cloudron.io/apps/#memory-limit
* To increase a service's memory limit - https://docs.cloudron.io/troubleshooting/#services
Out of memory event:
+21 -14
View File
@@ -7,6 +7,7 @@ exports = module.exports = {
const assert = require('assert'),
BoxError = require('./boxerror.js'),
ipaddr = require('ipaddr.js'),
path = require('path'),
paths = require('./paths.js'),
safe = require('safetydance'),
@@ -19,27 +20,33 @@ const SET_BLOCKLIST_CMD = path.join(__dirname, 'scripts/setblocklist.sh');
function getBlocklist(callback) {
assert.strictEqual(typeof callback, 'function');
const data = safe.fs.readFileSync(paths.FIREWALL_CONFIG_FILE, 'utf8');
const config = safe.JSON.parse(data);
const blocklist = config && config.blocklist ? config.blocklist : [];
callback(null, blocklist);
const data = safe.fs.readFileSync(paths.FIREWALL_BLOCKLIST_FILE, 'utf8');
callback(null, data);
}
function setBlocklist(blocklist, callback) {
assert(Array.isArray(blocklist));
function setBlocklist(blocklist, auditSource, callback) {
assert.strictEqual(typeof blocklist, 'string');
assert.strictEqual(typeof auditSource, 'object');
assert.strictEqual(typeof callback, 'function');
if (!blocklist.every(x => validator.isIP(x) || validator.isIPRange(x))) return callback(new BoxError(BoxError.BAD_FIELD, 'blocklist must contain IP or IP range'));
const parsedIp = ipaddr.process(auditSource.ip);
for (const line of blocklist.split('\n')) {
if (!line || line.startsWith('#')) continue;
const rangeOrIP = line.trim();
if (!validator.isIP(rangeOrIP) && !validator.isIPRange(rangeOrIP)) return callback(new BoxError(BoxError.BAD_FIELD, `${rangeOrIP} is not a valid IP or range`));
if (rangeOrIP.indexOf('/') === -1) {
if (auditSource.ip === rangeOrIP) return callback(new BoxError(BoxError.BAD_FIELD, `${rangeOrIP} includes client IP. Cannot block yourself`));
} else {
const parsedRange = ipaddr.parseCIDR(rangeOrIP);
if (parsedIp.match(parsedRange)) return callback(new BoxError(BoxError.BAD_FIELD, `${rangeOrIP} includes client IP. Cannot block yourself`));
}
}
if (settings.isDemo()) return callback(new BoxError(BoxError.CONFLICT, 'Not allowed in demo mode'));
const data = safe.fs.readFileSync(paths.FIREWALL_CONFIG_FILE, 'utf8');
const config = safe.JSON.parse(data) || {};
config.blocklist = blocklist;
if (!safe.fs.writeFileSync(paths.FIREWALL_CONFIG_FILE, JSON.stringify(config, null, 4), 'utf8')) return callback(new BoxError(BoxError.FS_ERROR, safe.error.message));
if (!safe.fs.writeFileSync(paths.FIREWALL_BLOCKLIST_FILE, blocklist + '\n', 'utf8')) return callback(new BoxError(BoxError.FS_ERROR, safe.error.message));
shell.sudo('setBlocklist', [ SET_BLOCKLIST_CMD ], {}, function (error) {
if (error) return callback(new BoxError(BoxError.IPTABLES_ERROR, `Error setting blocklist: ${error.message}`));
+2 -2
View File
@@ -156,11 +156,11 @@ function oomEvent(eventId, app, addon, containerId, event, callback) {
if (app) {
program = `App ${app.fqdn}`;
title = `The application at ${app.fqdn} ran out of memory.`;
message = 'The application has been restarted automatically. If you see this notification often, consider increasing the [memory limit](https://cloudron.io/documentation/apps/#memory-limit)';
message = 'The application has been restarted automatically. If you see this notification often, consider increasing the [memory limit](https://docs.cloudron.io/apps/#memory-limit)';
} else if (addon) {
program = `${addon.name} service`;
title = `The ${addon.name} service ran out of memory`;
message = 'The service has been restarted automatically. If you see this notification often, consider increasing the [memory limit](https://cloudron.io/documentation/troubleshooting/#services)';
message = 'The service has been restarted automatically. If you see this notification often, consider increasing the [memory limit](https://docs.cloudron.io/troubleshooting/#services)';
} else { // this never happens currently
program = `Container ${containerId}`;
title = `The container ${containerId} ran out of memory`;
+1
View File
@@ -46,6 +46,7 @@ exports = module.exports = {
CLOUDRON_AVATAR_FILE: path.join(baseDir(), 'boxdata/avatar.png'),
UPDATE_CHECKER_FILE: path.join(baseDir(), 'boxdata/updatechecker.json'),
ADDON_TURN_SECRET_FILE: path.join(baseDir(), 'boxdata/addon-turn-secret'),
FIREWALL_BLOCKLIST_FILE: path.join(baseDir(), 'boxdata/firewall/blocklist.txt'),
FIREWALL_CONFIG_FILE: path.join(baseDir(), 'boxdata/firewall-config.json'),
LOG_DIR: path.join(baseDir(), 'platformdata/logs'),
+5 -3
View File
@@ -6,6 +6,7 @@ exports = module.exports = {
};
var assert = require('assert'),
auditSource = require('../auditsource.js'),
BoxError = require('../boxerror.js'),
HttpError = require('connect-lastmile').HttpError,
HttpSuccess = require('connect-lastmile').HttpSuccess,
@@ -22,10 +23,11 @@ function getBlocklist(req, res, next) {
function setBlocklist(req, res, next) {
assert.strictEqual(typeof req.body, 'object');
if (!Array.isArray(req.body.blocklist)) return next(new HttpError(400, 'blocklist is required'));
if (!req.body.blocklist.every(x => typeof x === 'string')) return next(new HttpError(400, 'blocklist must be array of strings'));
if (typeof req.body.blocklist !== 'string') return next(new HttpError(400, 'blocklist must be a string'));
network.setBlocklist(req.body.blocklist, function (error) {
req.clearTimeout(); // can take a while if there is a lot of network ranges
network.setBlocklist(req.body.blocklist, auditSource.fromRequest(req), function (error) {
if (error) return next(BoxError.toHttpError(error));
next(new HttpSuccess(200, {}));
+8 -5
View File
@@ -14,10 +14,13 @@ fi
ipset flush cloudron_blocklist
user_firewall_json="/home/yellowtent/boxdata/firewall-config.json"
if blocklist=$(node -e "console.log(JSON.parse(fs.readFileSync('${user_firewall_json}', 'utf8')).blocklist.join(' '))" 2>/dev/null); then
user_firewall_json="/home/yellowtent/boxdata/firewall/blocklist.txt"
for ip in ${blocklist}; do
ipset add cloudron_blocklist "${ip}"
done
if [[ -f "${user_firewall_json}" ]]; then
# without the -n block, any last line without a new line won't be read it!
while read -r line || [[ -n "$line" ]]; do
[[ -z "${line}" ]] && continue # ignore empty lines
[[ "$line" =~ ^#.*$ ]] && continue # ignore lines starting with #
ipset add -! cloudron_blocklist "${line}" # the -! ignore duplicates
done < "${user_firewall_json}"
fi
+2 -2
View File
@@ -182,8 +182,8 @@ let gDefaults = (function () {
remoteSupport: true,
ticketFormBody:
'Use this form to open support tickets. You can also write directly to [support@cloudron.io](mailto:support@cloudron.io).\n\n'
+ '* [Knowledge Base & App Docs](https://cloudron.io/documentation/apps/?support_view)\n'
+ '* [Custom App Packaging & API](https://cloudron.io/developer/packaging/?support_view)\n'
+ '* [Knowledge Base & App Docs](https://docs.cloudron.io/apps/?support_view)\n'
+ '* [Custom App Packaging & API](https://docs.cloudron.io/custom-apps/tutorial/?support_view)\n'
+ '* [Forum](https://forum.cloudron.io/)\n\n',
submitTickets: true
};