mirror of
https://github.com/jc21/nginx-proxy-manager.git
synced 2024-08-30 18:22:48 +00:00
Finished importer, advanced nginx config for hosts, custom certs used in nginx templates
This commit is contained in:
parent
d092d4bbe7
commit
c543a1dc34
8
TODO.md
8
TODO.md
@ -2,14 +2,12 @@
|
||||
|
||||
In order of importance, somewhat..
|
||||
|
||||
- v1 Importer
|
||||
- ssl certificates
|
||||
- nginx advanced config
|
||||
- Redirection host preserve path nginx configuration
|
||||
- Custom ssl certificate saving to disk and usage in nginx configs
|
||||
- Nginx config output:
|
||||
- Redirection host preserve path nginx configuration
|
||||
- Dashboard stats are caching instead of querying
|
||||
- UI Log tail
|
||||
- Custom Nginx Config Editor
|
||||
- Enable/Disable a config
|
||||
|
||||
Testing:
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
mkdir -p /tmp/nginx/body \
|
||||
/var/log/nginx \
|
||||
/data/nginx \
|
||||
/data/custom_ssl \
|
||||
/data/logs \
|
||||
/data/access \
|
||||
/data/nginx/proxy_host \
|
||||
|
@ -186,8 +186,6 @@ module.exports = function () {
|
||||
|
||||
// 2. rename archive folder name
|
||||
new_archive_path = new_archive_path + 'npm-' + certificate.id;
|
||||
//logger.debug('Renaming archive folder:', full_archive_path, '->', new_archive_path);
|
||||
|
||||
fs.renameSync(full_archive_path, new_archive_path);
|
||||
|
||||
return certificate;
|
||||
@ -195,9 +193,6 @@ module.exports = function () {
|
||||
.then(certificate => {
|
||||
// 3. rename live folder name
|
||||
new_live_path = new_live_path + 'npm-' + certificate.id;
|
||||
|
||||
//logger.debug('Renaming live folder:', full_live_path, '->', new_live_path);
|
||||
|
||||
fs.renameSync(full_live_path, new_live_path);
|
||||
|
||||
// and also update the symlinks in this folder:
|
||||
@ -211,8 +206,6 @@ module.exports = function () {
|
||||
];
|
||||
|
||||
names.map(function (name) {
|
||||
//logger.debug('Live Link:', name);
|
||||
|
||||
// remove symlink
|
||||
try {
|
||||
fs.unlinkSync(new_live_path + '/' + name[0]);
|
||||
@ -221,7 +214,6 @@ module.exports = function () {
|
||||
logger.error(err);
|
||||
}
|
||||
|
||||
//logger.debug('Creating Link:', '../../archive/npm-' + certificate.id + '/' + name[1]);
|
||||
// create new symlink
|
||||
fs.symlinkSync('../../archive/npm-' + certificate.id + '/' + name[1], name[0]);
|
||||
});
|
||||
@ -356,8 +348,6 @@ module.exports = function () {
|
||||
certificate_id = certificate_map[host.hostname];
|
||||
}
|
||||
|
||||
// TODO: Advanced nginx config
|
||||
|
||||
return proxyHostModel
|
||||
.query()
|
||||
.insertAndFetch({
|
||||
@ -370,6 +360,7 @@ module.exports = function () {
|
||||
ssl_forced: host.force_ssl || false,
|
||||
caching_enabled: host.asset_caching || false,
|
||||
block_exploits: host.block_exploits || false,
|
||||
advanced_config: host.advanced || '',
|
||||
meta: meta
|
||||
})
|
||||
.then(row => {
|
||||
@ -405,16 +396,15 @@ module.exports = function () {
|
||||
certificate_id = certificate_map[host.hostname];
|
||||
}
|
||||
|
||||
// TODO: Advanced nginx config
|
||||
|
||||
return deadHostModel
|
||||
.query()
|
||||
.insertAndFetch({
|
||||
owner_user_id: 1,
|
||||
domain_names: [host.hostname],
|
||||
certificate_id: certificate_id,
|
||||
ssl_forced: host.force_ssl || false,
|
||||
meta: meta
|
||||
owner_user_id: 1,
|
||||
domain_names: [host.hostname],
|
||||
certificate_id: certificate_id,
|
||||
ssl_forced: host.force_ssl || false,
|
||||
advanced_config: host.advanced || '',
|
||||
meta: meta
|
||||
})
|
||||
.then(row => {
|
||||
// re-fetch with cert
|
||||
@ -449,8 +439,6 @@ module.exports = function () {
|
||||
certificate_id = certificate_map[host.hostname];
|
||||
}
|
||||
|
||||
// TODO: Advanced nginx config
|
||||
|
||||
return redirectionHostModel
|
||||
.query()
|
||||
.insertAndFetch({
|
||||
@ -460,6 +448,7 @@ module.exports = function () {
|
||||
block_exploits: host.block_exploits || false,
|
||||
certificate_id: certificate_id,
|
||||
ssl_forced: host.force_ssl || false,
|
||||
advanced_config: host.advanced || '',
|
||||
meta: meta
|
||||
})
|
||||
.then(row => {
|
||||
@ -483,8 +472,6 @@ module.exports = function () {
|
||||
const importStream = function (access, host) {
|
||||
logger.info('Creating Stream: ' + host.incoming_port);
|
||||
|
||||
// TODO: Advanced nginx config
|
||||
|
||||
return streamModel
|
||||
.query()
|
||||
.insertAndFetch({
|
||||
@ -537,7 +524,7 @@ module.exports = function () {
|
||||
})
|
||||
.then(() => {
|
||||
// Write the /config/v2-imported file so we don't import again
|
||||
fs.writeFile('/config/v2-imported', 'true', function(err) {
|
||||
fs.writeFile('/config/v2-imported', 'true', function (err) {
|
||||
if (err) {
|
||||
logger.err(err);
|
||||
}
|
||||
|
@ -183,7 +183,10 @@ const internalCertificate = {
|
||||
});
|
||||
});
|
||||
} else {
|
||||
return certificate;
|
||||
return internalCertificate.writeCustomCert(certificate)
|
||||
.then(() => {
|
||||
return certificate;
|
||||
});
|
||||
}
|
||||
}).then(certificate => {
|
||||
|
||||
@ -401,6 +404,54 @@ const internalCertificate = {
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {Object} certificate
|
||||
* @returns {Promise}
|
||||
*/
|
||||
writeCustomCert: certificate => {
|
||||
return new Promise((resolve, reject) => {
|
||||
let dir = '/data/custom_ssl/npm-' + certificate.id;
|
||||
|
||||
if (certificate.provider === 'letsencrypt') {
|
||||
reject(new Error('Refusing to write letsencrypt certs here'));
|
||||
return;
|
||||
}
|
||||
|
||||
let cert_data = certificate.meta.certificate;
|
||||
if (typeof certificate.meta.intermediate_certificate !== 'undefined') {
|
||||
cert_data = cert_data + "\n" + certificate.meta.intermediate_certificate;
|
||||
}
|
||||
|
||||
try {
|
||||
if (!fs.existsSync(dir)) {
|
||||
fs.mkdirSync(dir);
|
||||
}
|
||||
} catch (err) {
|
||||
reject(err);
|
||||
return;
|
||||
}
|
||||
|
||||
fs.writeFile(dir + '/fullchain.pem', cert_data, function (err) {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
})
|
||||
.then(() => {
|
||||
return new Promise((resolve, reject) => {
|
||||
fs.writeFile(dir + '/privkey.pem', certificate.meta.certificate_key, function (err) {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {Access} access
|
||||
* @param {Object} data
|
||||
|
@ -76,6 +76,7 @@ exports.up = function (knex/*, Promise*/) {
|
||||
table.integer('ssl_forced').notNull().unsigned().defaultTo(0);
|
||||
table.integer('caching_enabled').notNull().unsigned().defaultTo(0);
|
||||
table.integer('block_exploits').notNull().unsigned().defaultTo(0);
|
||||
table.text('advanced_config').notNull().defaultTo('');
|
||||
table.json('meta').notNull().defaultTo('{}');
|
||||
});
|
||||
})
|
||||
@ -94,6 +95,7 @@ exports.up = function (knex/*, Promise*/) {
|
||||
table.integer('certificate_id').notNull().unsigned().defaultTo(0);
|
||||
table.integer('ssl_forced').notNull().unsigned().defaultTo(0);
|
||||
table.integer('block_exploits').notNull().unsigned().defaultTo(0);
|
||||
table.text('advanced_config').notNull().defaultTo('');
|
||||
table.json('meta').notNull().defaultTo('{}');
|
||||
});
|
||||
})
|
||||
@ -109,6 +111,7 @@ exports.up = function (knex/*, Promise*/) {
|
||||
table.json('domain_names').notNull();
|
||||
table.integer('certificate_id').notNull().unsigned().defaultTo(0);
|
||||
table.integer('ssl_forced').notNull().unsigned().defaultTo(0);
|
||||
table.text('advanced_config').notNull().defaultTo('');
|
||||
table.json('meta').notNull().defaultTo('{}');
|
||||
});
|
||||
})
|
||||
|
@ -24,18 +24,11 @@
|
||||
"ssl_forced": {
|
||||
"$ref": "../definitions.json#/definitions/ssl_forced"
|
||||
},
|
||||
"advanced_config": {
|
||||
"type": "string"
|
||||
},
|
||||
"meta": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"letsencrypt_email": {
|
||||
"type": "string",
|
||||
"format": "email"
|
||||
},
|
||||
"letsencrypt_agree": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
@ -57,6 +50,9 @@
|
||||
"ssl_forced": {
|
||||
"$ref": "#/definitions/ssl_forced"
|
||||
},
|
||||
"advanced_config": {
|
||||
"$ref": "#/definitions/advanced_config"
|
||||
},
|
||||
"meta": {
|
||||
"$ref": "#/definitions/meta"
|
||||
}
|
||||
@ -105,6 +101,9 @@
|
||||
"ssl_forced": {
|
||||
"$ref": "#/definitions/ssl_forced"
|
||||
},
|
||||
"advanced_config": {
|
||||
"$ref": "#/definitions/advanced_config"
|
||||
},
|
||||
"meta": {
|
||||
"$ref": "#/definitions/meta"
|
||||
}
|
||||
@ -139,6 +138,9 @@
|
||||
"ssl_forced": {
|
||||
"$ref": "#/definitions/ssl_forced"
|
||||
},
|
||||
"advanced_config": {
|
||||
"$ref": "#/definitions/advanced_config"
|
||||
},
|
||||
"meta": {
|
||||
"$ref": "#/definitions/meta"
|
||||
}
|
||||
|
@ -42,6 +42,9 @@
|
||||
"access_list_id": {
|
||||
"$ref": "../definitions.json#/definitions/access_list_id"
|
||||
},
|
||||
"advanced_config": {
|
||||
"type": "string"
|
||||
},
|
||||
"meta": {
|
||||
"type": "object"
|
||||
}
|
||||
@ -80,6 +83,9 @@
|
||||
"access_list_id": {
|
||||
"$ref": "#/definitions/access_list_id"
|
||||
},
|
||||
"advanced_config": {
|
||||
"$ref": "#/definitions/advanced_config"
|
||||
},
|
||||
"meta": {
|
||||
"$ref": "#/definitions/meta"
|
||||
}
|
||||
@ -145,6 +151,9 @@
|
||||
"access_list_id": {
|
||||
"$ref": "#/definitions/access_list_id"
|
||||
},
|
||||
"advanced_config": {
|
||||
"$ref": "#/definitions/advanced_config"
|
||||
},
|
||||
"meta": {
|
||||
"$ref": "#/definitions/meta"
|
||||
}
|
||||
@ -194,6 +203,9 @@
|
||||
"access_list_id": {
|
||||
"$ref": "#/definitions/access_list_id"
|
||||
},
|
||||
"advanced_config": {
|
||||
"$ref": "#/definitions/advanced_config"
|
||||
},
|
||||
"meta": {
|
||||
"$ref": "#/definitions/meta"
|
||||
}
|
||||
|
@ -35,18 +35,11 @@
|
||||
"block_exploits": {
|
||||
"$ref": "../definitions.json#/definitions/block_exploits"
|
||||
},
|
||||
"advanced_config": {
|
||||
"type": "string"
|
||||
},
|
||||
"meta": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"letsencrypt_email": {
|
||||
"type": "string",
|
||||
"format": "email"
|
||||
},
|
||||
"letsencrypt_agree": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
@ -77,6 +70,9 @@
|
||||
"block_exploits": {
|
||||
"$ref": "#/definitions/block_exploits"
|
||||
},
|
||||
"advanced_config": {
|
||||
"$ref": "#/definitions/advanced_config"
|
||||
},
|
||||
"meta": {
|
||||
"$ref": "#/definitions/meta"
|
||||
}
|
||||
@ -135,6 +131,9 @@
|
||||
"block_exploits": {
|
||||
"$ref": "#/definitions/block_exploits"
|
||||
},
|
||||
"advanced_config": {
|
||||
"$ref": "#/definitions/advanced_config"
|
||||
},
|
||||
"meta": {
|
||||
"$ref": "#/definitions/meta"
|
||||
}
|
||||
@ -178,6 +177,9 @@
|
||||
"block_exploits": {
|
||||
"$ref": "#/definitions/block_exploits"
|
||||
},
|
||||
"advanced_config": {
|
||||
"$ref": "#/definitions/advanced_config"
|
||||
},
|
||||
"meta": {
|
||||
"$ref": "#/definitions/meta"
|
||||
}
|
||||
|
@ -6,5 +6,6 @@
|
||||
ssl_certificate /etc/letsencrypt/live/npm-{{ certificate_id }}/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/npm-{{ certificate_id }}/privkey.pem;
|
||||
{% endif %}
|
||||
# TODO: Custom SSL paths
|
||||
{% endif %}
|
||||
ssl_certificate /data/custom_ssl/npm-{{ certificate_id }}/fullchain.pem;
|
||||
ssl_certificate_key /data/custom_ssl/npm-{{ certificate_id }}/privkey.pem;
|
||||
{% endif %}
|
||||
|
@ -6,7 +6,7 @@ server {
|
||||
|
||||
access_log /data/logs/dead_host-{{ id }}.log proxy;
|
||||
|
||||
# TODO: Advanced config options
|
||||
{{ advanced_config }}
|
||||
|
||||
return 404;
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ server {
|
||||
|
||||
access_log /data/logs/proxy_host-{{ id }}.log proxy;
|
||||
|
||||
# TODO: Advanced config options
|
||||
{{ advanced_config }}
|
||||
|
||||
location / {
|
||||
{%- if access_list_id > 0 -%}
|
||||
|
@ -8,7 +8,7 @@ server {
|
||||
|
||||
access_log /data/logs/redirection_host-{{ id }}.log proxy;
|
||||
|
||||
# TODO: Advanced config options
|
||||
{{ advanced_config }}
|
||||
|
||||
# TODO: Preserve Path Option
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
<ul class="nav nav-tabs" role="tablist">
|
||||
<li role="presentation" class="nav-item"><a href="#details" aria-controls="tab1" role="tab" data-toggle="tab" class="nav-link active"><i class="fe fe-zap"></i> <%- i18n('all-hosts', 'details') %></a></li>
|
||||
<li role="presentation" class="nav-item"><a href="#ssl-options" aria-controls="tab2" role="tab" data-toggle="tab" class="nav-link"><i class="fe fe-shield"></i> <%- i18n('str', 'ssl') %></a></li>
|
||||
<li role="presentation" class="nav-item"><a href="#advanced" aria-controls="tab3" role="tab" data-toggle="tab" class="nav-link"><i class="fe fe-settings"></i> <%- i18n('all-hosts', 'advanced') %></a></li>
|
||||
</ul>
|
||||
<div class="tab-content">
|
||||
<!-- Details -->
|
||||
@ -63,9 +64,19 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Advanced -->
|
||||
<div role="tabpanel" class="tab-pane" id="advanced">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="form-group mb-0">
|
||||
<label class="form-label"><%- i18n('all-hosts', 'advanced-config') %></label>
|
||||
<textarea name="advanced_config" rows="8" class="form-control text-monospace" placeholder="# <%- i18n('all-hosts', 'advanced-warning') %>"><%- advanced_config %></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
|
@ -8,12 +8,12 @@
|
||||
<ul class="nav nav-tabs" role="tablist">
|
||||
<li role="presentation" class="nav-item"><a href="#details" aria-controls="tab1" role="tab" data-toggle="tab" class="nav-link active"><i class="fe fe-zap"></i> <%- i18n('all-hosts', 'details') %></a></li>
|
||||
<li role="presentation" class="nav-item"><a href="#ssl-options" aria-controls="tab2" role="tab" data-toggle="tab" class="nav-link"><i class="fe fe-shield"></i> <%- i18n('str', 'ssl') %></a></li>
|
||||
<li role="presentation" class="nav-item"><a href="#advanced" aria-controls="tab3" role="tab" data-toggle="tab" class="nav-link"><i class="fe fe-settings"></i> <%- i18n('all-hosts', 'advanced') %></a></li>
|
||||
</ul>
|
||||
<div class="tab-content">
|
||||
<!-- Details -->
|
||||
<div role="tabpanel" class="tab-pane active" id="details">
|
||||
<div class="row">
|
||||
|
||||
<div class="col-sm-12 col-md-12">
|
||||
<div class="form-group">
|
||||
<label class="form-label"><%- i18n('all-hosts', 'domain-names') %> <span class="form-required">*</span></label>
|
||||
@ -101,9 +101,19 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Advanced -->
|
||||
<div role="tabpanel" class="tab-pane" id="advanced">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="form-group mb-0">
|
||||
<label class="form-label"><%- i18n('all-hosts', 'advanced-config') %></label>
|
||||
<textarea name="advanced_config" rows="8" class="form-control text-monospace" placeholder="# <%- i18n('all-hosts', 'advanced-warning') %>"><%- advanced_config %></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
|
@ -8,6 +8,7 @@
|
||||
<ul class="nav nav-tabs" role="tablist">
|
||||
<li role="presentation" class="nav-item"><a href="#details" aria-controls="tab1" role="tab" data-toggle="tab" class="nav-link active"><i class="fe fe-zap"></i> <%- i18n('all-hosts', 'details') %></a></li>
|
||||
<li role="presentation" class="nav-item"><a href="#ssl-options" aria-controls="tab2" role="tab" data-toggle="tab" class="nav-link"><i class="fe fe-shield"></i> <%- i18n('str', 'ssl') %></a></li>
|
||||
<li role="presentation" class="nav-item"><a href="#advanced" aria-controls="tab3" role="tab" data-toggle="tab" class="nav-link"><i class="fe fe-settings"></i> <%- i18n('all-hosts', 'advanced') %></a></li>
|
||||
</ul>
|
||||
<div class="tab-content">
|
||||
<!-- Details -->
|
||||
@ -87,9 +88,19 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Advanced -->
|
||||
<div role="tabpanel" class="tab-pane" id="advanced">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="form-group mb-0">
|
||||
<label class="form-label"><%- i18n('all-hosts', 'advanced-config') %></label>
|
||||
<textarea name="advanced_config" rows="8" class="form-control text-monospace" placeholder="# <%- i18n('all-hosts', 'advanced-warning') %>"><%- advanced_config %></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
|
@ -73,7 +73,10 @@
|
||||
"none": "None",
|
||||
"new-cert": "Request a new SSL Certificate",
|
||||
"with-le": "with Let's Encrypt",
|
||||
"no-ssl": "This host will not use HTTPS"
|
||||
"no-ssl": "This host will not use HTTPS",
|
||||
"advanced": "Advanced",
|
||||
"advanced-warning": "Enter your custom Nginx configuration here at your own risk!",
|
||||
"advanced-config": "Custom Nginx Configuration"
|
||||
},
|
||||
"ssl": {
|
||||
"letsencrypt": "Let's Encrypt",
|
||||
|
@ -7,16 +7,17 @@ const model = Backbone.Model.extend({
|
||||
|
||||
defaults: function () {
|
||||
return {
|
||||
id: undefined,
|
||||
created_on: null,
|
||||
modified_on: null,
|
||||
domain_names: [],
|
||||
certificate_id: 0,
|
||||
ssl_forced: false,
|
||||
meta: {},
|
||||
id: undefined,
|
||||
created_on: null,
|
||||
modified_on: null,
|
||||
domain_names: [],
|
||||
certificate_id: 0,
|
||||
ssl_forced: false,
|
||||
meta: {},
|
||||
advanced_config: '',
|
||||
// The following are expansions:
|
||||
owner: null,
|
||||
certificate: null
|
||||
owner: null,
|
||||
certificate: null
|
||||
};
|
||||
}
|
||||
});
|
||||
|
@ -18,6 +18,7 @@ const model = Backbone.Model.extend({
|
||||
ssl_forced: false,
|
||||
caching_enabled: false,
|
||||
block_exploits: false,
|
||||
advanced_config: '',
|
||||
meta: {},
|
||||
// The following are expansions:
|
||||
owner: null,
|
||||
|
@ -16,6 +16,7 @@ const model = Backbone.Model.extend({
|
||||
certificate_id: 0,
|
||||
ssl_forced: false,
|
||||
block_exploits: false,
|
||||
advanced_config: '',
|
||||
meta: {},
|
||||
// The following are expansions:
|
||||
owner: null,
|
||||
|
@ -116,3 +116,10 @@ $pink: #f66d9b;
|
||||
margin: 1.75rem auto;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Form mod */
|
||||
|
||||
textarea.form-control.text-monospace {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user