Compare commits
5 Commits
Author | SHA1 | Date | |
---|---|---|---|
0b8a49469f | |||
b16a68052f | |||
83686c4535 | |||
efa1424cad | |||
4fe26ec4c0 |
@ -29,4 +29,11 @@ ADD knexfile.js /app/knexfile.js
|
||||
VOLUME [ "/data", "/etc/letsencrypt" ]
|
||||
CMD [ "/init" ]
|
||||
|
||||
# Ports
|
||||
EXPOSE 80
|
||||
EXPOSE 81
|
||||
EXPOSE 443
|
||||
EXPOSE 9876
|
||||
|
||||
HEALTHCHECK --interval=15s --timeout=3s CMD curl -f http://localhost:9876/health || exit 1
|
||||
|
||||
|
@ -29,4 +29,10 @@ ADD knexfile.js /app/knexfile.js
|
||||
VOLUME [ "/data", "/etc/letsencrypt" ]
|
||||
CMD [ "/init" ]
|
||||
|
||||
# Ports
|
||||
EXPOSE 80
|
||||
EXPOSE 81
|
||||
EXPOSE 443
|
||||
EXPOSE 9876
|
||||
|
||||
HEALTHCHECK --interval=15s --timeout=3s CMD curl -f http://localhost:9876/health || exit 1
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
# Nginx Proxy Manager
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
|
26
bin/migrate_create
Executable file
26
bin/migrate_create
Executable file
@ -0,0 +1,26 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [ "$1" == "" ]; then
|
||||
echo "Error: migrate name must be specified as first arg"
|
||||
exit 1
|
||||
else
|
||||
# Code path
|
||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
if hash realpath 2>/dev/null; then
|
||||
export CODEBASE=$(realpath $SCRIPT_DIR/..)
|
||||
elif hash grealpath 2>/dev/null; then
|
||||
export CODEBASE=$(grealpath $SCRIPT_DIR/..)
|
||||
else
|
||||
export CODEBASE=$(readlink -e $SCRIPT_DIR/..)
|
||||
fi
|
||||
|
||||
if [ -z "$CODEBASE" ]; then
|
||||
echo "Unable to determine absolute codebase directory"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd "$CODEBASE"
|
||||
|
||||
sudo /usr/local/bin/docker-compose run --rm --no-deps app node node_modules/knex/bin/cli.js migrate:make "$1"
|
||||
exit $?
|
||||
fi
|
@ -2,7 +2,7 @@
|
||||
|
||||
# Nginx Proxy Manager
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "nginx-proxy-manager",
|
||||
"version": "2.0.2",
|
||||
"version": "2.0.3",
|
||||
"description": "A beautiful interface for creating Nginx endpoints",
|
||||
"main": "src/backend/index.js",
|
||||
"devDependencies": {
|
||||
|
@ -3,4 +3,9 @@
|
||||
mkdir -p /data/letsencrypt-acme-challenge
|
||||
|
||||
cd /app
|
||||
node --abort_on_uncaught_exception --max_old_space_size=250 /app/src/backend/index.js
|
||||
|
||||
while :
|
||||
do
|
||||
node --abort_on_uncaught_exception --max_old_space_size=250 /app/src/backend/index.js
|
||||
sleep 1
|
||||
done
|
||||
|
@ -1,9 +1,10 @@
|
||||
'use strict';
|
||||
|
||||
const fs = require('fs');
|
||||
const logger = require('./logger').import;
|
||||
const utils = require('./lib/utils');
|
||||
const batchflow = require('batchflow');
|
||||
const fs = require('fs');
|
||||
const logger = require('./logger').import;
|
||||
const utils = require('./lib/utils');
|
||||
const batchflow = require('batchflow');
|
||||
const debug_mode = process.env.NODE_ENV !== 'production';
|
||||
|
||||
const internalProxyHost = require('./internal/proxy-host');
|
||||
const internalRedirectionHost = require('./internal/redirection-host');
|
||||
@ -534,6 +535,10 @@ module.exports = function () {
|
||||
);
|
||||
|
||||
} else {
|
||||
if (debug_mode) {
|
||||
logger.debug('Importer skipped');
|
||||
}
|
||||
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
|
@ -8,4 +8,5 @@ module.exports = {
|
||||
nginx: new Signale({scope: 'Nginx '}),
|
||||
ssl: new Signale({scope: 'SSL '}),
|
||||
import: new Signale({scope: 'Importer'}),
|
||||
setup: new Signale({scope: 'Setup '})
|
||||
};
|
||||
|
37
src/backend/migrations/20180929054513_websockets.js
Normal file
37
src/backend/migrations/20180929054513_websockets.js
Normal file
@ -0,0 +1,37 @@
|
||||
'use strict';
|
||||
|
||||
const migrate_name = 'websockets';
|
||||
const logger = require('../logger').migrate;
|
||||
|
||||
/**
|
||||
* Migrate
|
||||
*
|
||||
* @see http://knexjs.org/#Schema
|
||||
*
|
||||
* @param {Object} knex
|
||||
* @param {Promise} Promise
|
||||
* @returns {Promise}
|
||||
*/
|
||||
exports.up = function (knex/*, Promise*/) {
|
||||
logger.info('[' + migrate_name + '] Migrating Up...');
|
||||
|
||||
return knex.schema.table('proxy_host', function (proxy_host) {
|
||||
proxy_host.integer('allow_websocket_upgrade').notNull().unsigned().defaultTo(0);
|
||||
})
|
||||
.then(() => {
|
||||
logger.info('[' + migrate_name + '] proxy_host Table altered');
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Undo Migrate
|
||||
*
|
||||
* @param {Object} knex
|
||||
* @param {Promise} Promise
|
||||
* @returns {Promise}
|
||||
*/
|
||||
exports.down = function (knex, Promise) {
|
||||
logger.warn('[' + migrate_name + '] You can\'t migrate down this one.');
|
||||
return Promise.resolve(true);
|
||||
};
|
@ -39,6 +39,11 @@
|
||||
"caching_enabled": {
|
||||
"$ref": "../definitions.json#/definitions/caching_enabled"
|
||||
},
|
||||
"allow_websocket_upgrade": {
|
||||
"description": "Allow Websocket Upgrade for all paths",
|
||||
"example": true,
|
||||
"type": "boolean"
|
||||
},
|
||||
"access_list_id": {
|
||||
"$ref": "../definitions.json#/definitions/access_list_id"
|
||||
},
|
||||
@ -80,6 +85,9 @@
|
||||
"caching_enabled": {
|
||||
"$ref": "#/definitions/caching_enabled"
|
||||
},
|
||||
"allow_websocket_upgrade": {
|
||||
"$ref": "#/definitions/allow_websocket_upgrade"
|
||||
},
|
||||
"access_list_id": {
|
||||
"$ref": "#/definitions/access_list_id"
|
||||
},
|
||||
@ -148,6 +156,9 @@
|
||||
"caching_enabled": {
|
||||
"$ref": "#/definitions/caching_enabled"
|
||||
},
|
||||
"allow_websocket_upgrade": {
|
||||
"$ref": "#/definitions/allow_websocket_upgrade"
|
||||
},
|
||||
"access_list_id": {
|
||||
"$ref": "#/definitions/access_list_id"
|
||||
},
|
||||
@ -200,6 +211,9 @@
|
||||
"caching_enabled": {
|
||||
"$ref": "#/definitions/caching_enabled"
|
||||
},
|
||||
"allow_websocket_upgrade": {
|
||||
"$ref": "#/definitions/allow_websocket_upgrade"
|
||||
},
|
||||
"access_list_id": {
|
||||
"$ref": "#/definitions/access_list_id"
|
||||
},
|
||||
|
@ -3,10 +3,11 @@
|
||||
const fs = require('fs');
|
||||
const NodeRSA = require('node-rsa');
|
||||
const config = require('config');
|
||||
const logger = require('./logger').global;
|
||||
const logger = require('./logger').setup;
|
||||
const userModel = require('./models/user');
|
||||
const userPermissionModel = require('./models/user_permission');
|
||||
const authModel = require('./models/auth');
|
||||
const debug_mode = process.env.NODE_ENV !== 'production';
|
||||
|
||||
module.exports = function () {
|
||||
return new Promise((resolve, reject) => {
|
||||
@ -22,6 +23,9 @@ module.exports = function () {
|
||||
config_data = require(filename);
|
||||
} catch (err) {
|
||||
// do nothing
|
||||
if (debug_mode) {
|
||||
logger.debug(filename + ' config file could not be required');
|
||||
}
|
||||
}
|
||||
|
||||
// Now create the keys and save them in the config.
|
||||
@ -40,12 +44,18 @@ module.exports = function () {
|
||||
reject(err);
|
||||
} else {
|
||||
logger.info('Wrote JWT key pair to config file: ' + filename);
|
||||
config.util.loadFileConfigs();
|
||||
resolve();
|
||||
|
||||
logger.warn('Restarting interface to apply new configuration');
|
||||
process.exit(0);
|
||||
}
|
||||
});
|
||||
|
||||
} else {
|
||||
// JWT key pair exists
|
||||
if (debug_mode) {
|
||||
logger.debug('JWT Keypair already exists');
|
||||
}
|
||||
|
||||
resolve();
|
||||
}
|
||||
})
|
||||
@ -54,49 +64,54 @@ module.exports = function () {
|
||||
.query()
|
||||
.select(userModel.raw('COUNT(`id`) as `count`'))
|
||||
.where('is_deleted', 0)
|
||||
.first('count')
|
||||
.then(row => {
|
||||
if (!row.count) {
|
||||
// Create a new user and set password
|
||||
logger.info('Creating a new user: admin@example.com with password: changeme');
|
||||
.first();
|
||||
})
|
||||
.then(row => {
|
||||
if (!row.count) {
|
||||
// Create a new user and set password
|
||||
logger.info('Creating a new user: admin@example.com with password: changeme');
|
||||
|
||||
let data = {
|
||||
is_deleted: 0,
|
||||
email: 'admin@example.com',
|
||||
name: 'Administrator',
|
||||
nickname: 'Admin',
|
||||
avatar: '',
|
||||
roles: ['admin']
|
||||
};
|
||||
let data = {
|
||||
is_deleted: 0,
|
||||
email: 'admin@example.com',
|
||||
name: 'Administrator',
|
||||
nickname: 'Admin',
|
||||
avatar: '',
|
||||
roles: ['admin']
|
||||
};
|
||||
|
||||
return userModel
|
||||
return userModel
|
||||
.query()
|
||||
.insertAndFetch(data)
|
||||
.then(user => {
|
||||
return authModel
|
||||
.query()
|
||||
.insertAndFetch(data)
|
||||
.then(user => {
|
||||
return authModel
|
||||
.insert({
|
||||
user_id: user.id,
|
||||
type: 'password',
|
||||
secret: 'changeme',
|
||||
meta: {}
|
||||
})
|
||||
.then(() => {
|
||||
return userPermissionModel
|
||||
.query()
|
||||
.insert({
|
||||
user_id: user.id,
|
||||
type: 'password',
|
||||
secret: 'changeme',
|
||||
meta: {}
|
||||
})
|
||||
.then(() => {
|
||||
return userPermissionModel
|
||||
.query()
|
||||
.insert({
|
||||
user_id: user.id,
|
||||
visibility: 'all',
|
||||
proxy_hosts: 'manage',
|
||||
redirection_hosts: 'manage',
|
||||
dead_hosts: 'manage',
|
||||
streams: 'manage',
|
||||
access_lists: 'manage',
|
||||
certificates: 'manage'
|
||||
});
|
||||
user_id: user.id,
|
||||
visibility: 'all',
|
||||
proxy_hosts: 'manage',
|
||||
redirection_hosts: 'manage',
|
||||
dead_hosts: 'manage',
|
||||
streams: 'manage',
|
||||
access_lists: 'manage',
|
||||
certificates: 'manage'
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
})
|
||||
.then(() => {
|
||||
logger.info('Initial setup completed');
|
||||
});
|
||||
} else if (debug_mode) {
|
||||
logger.debug('Admin user setup not required');
|
||||
}
|
||||
});
|
||||
};
|
||||
|
@ -22,6 +22,12 @@ server {
|
||||
|
||||
{% include "_forced_ssl.conf" %}
|
||||
|
||||
{% if allow_websocket_upgrade == 1 or allow_websocket_upgrade == true %}
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
proxy_http_version 1.1;
|
||||
{% endif %}
|
||||
|
||||
# Proxy!
|
||||
include conf.d/include/proxy.conf;
|
||||
}
|
||||
|
@ -50,6 +50,15 @@
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-12 col-md-12">
|
||||
<div class="form-group">
|
||||
<label class="custom-switch">
|
||||
<input type="checkbox" class="custom-switch-input" name="allow_websocket_upgrade" value="1"<%- allow_websocket_upgrade ? ' checked' : '' %>>
|
||||
<span class="custom-switch-indicator"></span>
|
||||
<span class="custom-switch-description"><%- i18n('proxy-hosts', 'allow-websocket-upgrade') %></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-12 col-md-12">
|
||||
<div class="form-group">
|
||||
<label class="form-label"><%- i18n('proxy-hosts', 'access-list') %></label>
|
||||
|
@ -54,9 +54,10 @@ module.exports = Mn.View.extend({
|
||||
let data = this.ui.form.serializeJSON();
|
||||
|
||||
// Manipulate
|
||||
data.forward_port = parseInt(data.forward_port, 10);
|
||||
data.block_exploits = !!data.block_exploits;
|
||||
data.caching_enabled = !!data.caching_enabled;
|
||||
data.forward_port = parseInt(data.forward_port, 10);
|
||||
data.block_exploits = !!data.block_exploits;
|
||||
data.caching_enabled = !!data.caching_enabled;
|
||||
data.allow_websocket_upgrade = !!data.allow_websocket_upgrade;
|
||||
|
||||
if (typeof data.ssl_forced !== 'undefined' && data.ssl_forced === '1') {
|
||||
data.ssl_forced = true;
|
||||
|
@ -98,7 +98,8 @@
|
||||
"delete-confirm": "Are you sure you want to delete the Proxy host for: <strong>{domains}</strong>?",
|
||||
"help-title": "What is a Proxy Host?",
|
||||
"help-content": "A Proxy Host is the incoming endpoint for a web service that you want to forward.\nIt provides optional SSL termination for your service that might not have SSL support built in.\nProxy Hosts are the most common use for the Nginx Proxy Manager.",
|
||||
"access-list": "Access List"
|
||||
"access-list": "Access List",
|
||||
"allow-websocket-upgrade": "Allow Websocket HTTP Upgrades"
|
||||
},
|
||||
"redirection-hosts": {
|
||||
"title": "Redirection Hosts",
|
||||
|
@ -7,23 +7,24 @@ const model = Backbone.Model.extend({
|
||||
|
||||
defaults: function () {
|
||||
return {
|
||||
id: undefined,
|
||||
created_on: null,
|
||||
modified_on: null,
|
||||
domain_names: [],
|
||||
forward_ip: '',
|
||||
forward_port: null,
|
||||
access_list_id: 0,
|
||||
certificate_id: 0,
|
||||
ssl_forced: false,
|
||||
caching_enabled: false,
|
||||
block_exploits: false,
|
||||
advanced_config: '',
|
||||
meta: {},
|
||||
id: undefined,
|
||||
created_on: null,
|
||||
modified_on: null,
|
||||
domain_names: [],
|
||||
forward_ip: '',
|
||||
forward_port: null,
|
||||
access_list_id: 0,
|
||||
certificate_id: 0,
|
||||
ssl_forced: false,
|
||||
caching_enabled: false,
|
||||
allow_websocket_upgrade: false,
|
||||
block_exploits: false,
|
||||
advanced_config: '',
|
||||
meta: {},
|
||||
// The following are expansions:
|
||||
owner: null,
|
||||
access_list: null,
|
||||
certificate: null
|
||||
owner: null,
|
||||
access_list: null,
|
||||
certificate: null
|
||||
};
|
||||
}
|
||||
});
|
||||
|
Reference in New Issue
Block a user