mirror of
https://github.com/jc21/nginx-proxy-manager.git
synced 2024-08-30 18:22:48 +00:00
commit
a56d976947
48
README.md
48
README.md
@ -1,7 +1,7 @@
|
|||||||
<p align="center">
|
<p align="center">
|
||||||
<img src="https://nginxproxymanager.com/github.png">
|
<img src="https://nginxproxymanager.com/github.png">
|
||||||
<br><br>
|
<br><br>
|
||||||
<img src="https://img.shields.io/badge/version-2.9.4-green.svg?style=for-the-badge">
|
<img src="https://img.shields.io/badge/version-2.9.5-green.svg?style=for-the-badge">
|
||||||
<a href="https://hub.docker.com/repository/docker/jc21/nginx-proxy-manager">
|
<a href="https://hub.docker.com/repository/docker/jc21/nginx-proxy-manager">
|
||||||
<img src="https://img.shields.io/docker/stars/jc21/nginx-proxy-manager.svg?style=for-the-badge">
|
<img src="https://img.shields.io/docker/stars/jc21/nginx-proxy-manager.svg?style=for-the-badge">
|
||||||
</a>
|
</a>
|
||||||
@ -17,7 +17,7 @@
|
|||||||
<a href="https://reddit.com/r/nginxproxymanager">
|
<a href="https://reddit.com/r/nginxproxymanager">
|
||||||
<img alt="Reddit" src="https://img.shields.io/reddit/subreddit-subscribers/nginxproxymanager?label=Reddit%20Community&style=for-the-badge">
|
<img alt="Reddit" src="https://img.shields.io/reddit/subreddit-subscribers/nginxproxymanager?label=Reddit%20Community&style=for-the-badge">
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
This project comes as a pre-built docker image that enables you to easily forward to your websites
|
This project comes as a pre-built docker image that enables you to easily forward to your websites
|
||||||
@ -414,6 +414,50 @@ Special thanks to the following contributors:
|
|||||||
<br /><sub><b>RBXII3</b></sub>
|
<br /><sub><b>RBXII3</b></sub>
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
|
<td align="center">
|
||||||
|
<a href="https://github.com/demize">
|
||||||
|
<img src="https://avatars.githubusercontent.com/u/264914?v=4" width="80" alt=""/>
|
||||||
|
<br /><sub><b>demize</b></sub>
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td align="center">
|
||||||
|
<a href="https://github.com/PUP-Loki">
|
||||||
|
<img src="https://avatars.githubusercontent.com/u/75944209?v=4" width="80" alt=""/>
|
||||||
|
<br /><sub><b>PUP-Loki</b></sub>
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td align="center">
|
||||||
|
<a href="https://github.com/DSorlov">
|
||||||
|
<img src="https://avatars.githubusercontent.com/u/8133650?v=4" width="80" alt=""/>
|
||||||
|
<br /><sub><b>Daniel Sörlöv</b></sub>
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td align="center">
|
||||||
|
<a href="https://github.com/Theyooo">
|
||||||
|
<img src="https://avatars.githubusercontent.com/u/58510131?v=4" width="80" alt=""/>
|
||||||
|
<br /><sub><b>Theyooo</b></sub>
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td align="center">
|
||||||
|
<a href="https://github.com/mrdink">
|
||||||
|
<img src="https://avatars.githubusercontent.com/u/514751?v=4" width="80" alt=""/>
|
||||||
|
<br /><sub><b>Justin Peacock</b></sub>
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td align="center">
|
||||||
|
<a href="https://github.com/ChrisTracy">
|
||||||
|
<img src="https://avatars.githubusercontent.com/u/58871574?v=4" width="80" alt=""/>
|
||||||
|
<br /><sub><b>Chris Tracy</b></sub>
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td align="center">
|
||||||
|
<a href="https://github.com/Fuechslein">
|
||||||
|
<img src="https://avatars.githubusercontent.com/u/15112818?v=4" width="80" alt=""/>
|
||||||
|
<br /><sub><b>Fuechslein</b></sub>
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
<!-- markdownlint-enable -->
|
<!-- markdownlint-enable -->
|
||||||
|
@ -1,19 +1,18 @@
|
|||||||
const fs = require('fs');
|
const _ = require('lodash');
|
||||||
const _ = require('lodash');
|
const fs = require('fs');
|
||||||
const logger = require('../logger').ssl;
|
const tempWrite = require('temp-write');
|
||||||
const error = require('../lib/error');
|
const moment = require('moment');
|
||||||
const certificateModel = require('../models/certificate');
|
const logger = require('../logger').ssl;
|
||||||
const internalAuditLog = require('./audit-log');
|
const error = require('../lib/error');
|
||||||
const tempWrite = require('temp-write');
|
const utils = require('../lib/utils');
|
||||||
const utils = require('../lib/utils');
|
const certificateModel = require('../models/certificate');
|
||||||
const moment = require('moment');
|
const dnsPlugins = require('../global/certbot-dns-plugins');
|
||||||
const debug_mode = process.env.NODE_ENV !== 'production' || !!process.env.DEBUG;
|
const internalAuditLog = require('./audit-log');
|
||||||
const le_staging = process.env.NODE_ENV !== 'production';
|
const internalNginx = require('./nginx');
|
||||||
const internalNginx = require('./nginx');
|
const internalHost = require('./host');
|
||||||
const internalHost = require('./host');
|
const letsencryptStaging = process.env.NODE_ENV !== 'production';
|
||||||
const certbot_command = 'certbot';
|
const letsencryptConfig = '/etc/letsencrypt.ini';
|
||||||
const le_config = '/etc/letsencrypt.ini';
|
const certbotCommand = 'certbot';
|
||||||
const dns_plugins = require('../global/certbot-dns-plugins');
|
|
||||||
|
|
||||||
function omissions() {
|
function omissions() {
|
||||||
return ['is_deleted'];
|
return ['is_deleted'];
|
||||||
@ -21,14 +20,14 @@ function omissions() {
|
|||||||
|
|
||||||
const internalCertificate = {
|
const internalCertificate = {
|
||||||
|
|
||||||
allowed_ssl_files: ['certificate', 'certificate_key', 'intermediate_certificate'],
|
allowedSslFiles: ['certificate', 'certificate_key', 'intermediate_certificate'],
|
||||||
interval_timeout: 1000 * 60 * 60, // 1 hour
|
intervalTimeout: 1000 * 60 * 60, // 1 hour
|
||||||
interval: null,
|
interval: null,
|
||||||
interval_processing: false,
|
intervalProcessing: false,
|
||||||
|
|
||||||
initTimer: () => {
|
initTimer: () => {
|
||||||
logger.info('Let\'s Encrypt Renewal Timer initialized');
|
logger.info('Let\'s Encrypt Renewal Timer initialized');
|
||||||
internalCertificate.interval = setInterval(internalCertificate.processExpiringHosts, internalCertificate.interval_timeout);
|
internalCertificate.interval = setInterval(internalCertificate.processExpiringHosts, internalCertificate.intervalTimeout);
|
||||||
// And do this now as well
|
// And do this now as well
|
||||||
internalCertificate.processExpiringHosts();
|
internalCertificate.processExpiringHosts();
|
||||||
},
|
},
|
||||||
@ -37,15 +36,15 @@ const internalCertificate = {
|
|||||||
* Triggered by a timer, this will check for expiring hosts and renew their ssl certs if required
|
* Triggered by a timer, this will check for expiring hosts and renew their ssl certs if required
|
||||||
*/
|
*/
|
||||||
processExpiringHosts: () => {
|
processExpiringHosts: () => {
|
||||||
if (!internalCertificate.interval_processing) {
|
if (!internalCertificate.intervalProcessing) {
|
||||||
internalCertificate.interval_processing = true;
|
internalCertificate.intervalProcessing = true;
|
||||||
logger.info('Renewing SSL certs close to expiry...');
|
logger.info('Renewing SSL certs close to expiry...');
|
||||||
|
|
||||||
let cmd = certbot_command + ' renew --non-interactive --quiet ' +
|
const cmd = certbotCommand + ' renew --non-interactive --quiet ' +
|
||||||
'--config "' + le_config + '" ' +
|
'--config "' + letsencryptConfig + '" ' +
|
||||||
'--preferred-challenges "dns,http" ' +
|
'--preferred-challenges "dns,http" ' +
|
||||||
'--disable-hook-validation ' +
|
'--disable-hook-validation ' +
|
||||||
(le_staging ? '--staging' : '');
|
(letsencryptStaging ? '--staging' : '');
|
||||||
|
|
||||||
return utils.exec(cmd)
|
return utils.exec(cmd)
|
||||||
.then((result) => {
|
.then((result) => {
|
||||||
@ -93,11 +92,11 @@ const internalCertificate = {
|
|||||||
});
|
});
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
internalCertificate.interval_processing = false;
|
internalCertificate.intervalProcessing = false;
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
logger.error(err);
|
logger.error(err);
|
||||||
internalCertificate.interval_processing = false;
|
internalCertificate.intervalProcessing = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -221,7 +220,7 @@ const internalCertificate = {
|
|||||||
await certificateModel
|
await certificateModel
|
||||||
.query()
|
.query()
|
||||||
.deleteById(certificate.id);
|
.deleteById(certificate.id);
|
||||||
|
|
||||||
throw error;
|
throw error;
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@ -448,11 +447,9 @@ const internalCertificate = {
|
|||||||
* @returns {Promise}
|
* @returns {Promise}
|
||||||
*/
|
*/
|
||||||
writeCustomCert: (certificate) => {
|
writeCustomCert: (certificate) => {
|
||||||
if (debug_mode) {
|
logger.info('Writing Custom Certificate:', certificate);
|
||||||
logger.info('Writing Custom Certificate:', certificate);
|
|
||||||
}
|
|
||||||
|
|
||||||
let dir = '/data/custom_ssl/npm-' + certificate.id;
|
const dir = '/data/custom_ssl/npm-' + certificate.id;
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (certificate.provider === 'letsencrypt') {
|
if (certificate.provider === 'letsencrypt') {
|
||||||
@ -460,9 +457,9 @@ const internalCertificate = {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let cert_data = certificate.meta.certificate;
|
let certData = certificate.meta.certificate;
|
||||||
if (typeof certificate.meta.intermediate_certificate !== 'undefined') {
|
if (typeof certificate.meta.intermediate_certificate !== 'undefined') {
|
||||||
cert_data = cert_data + '\n' + certificate.meta.intermediate_certificate;
|
certData = certData + '\n' + certificate.meta.intermediate_certificate;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -474,7 +471,7 @@ const internalCertificate = {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fs.writeFile(dir + '/fullchain.pem', cert_data, function (err) {
|
fs.writeFile(dir + '/fullchain.pem', certData, function (err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
reject(err);
|
reject(err);
|
||||||
} else {
|
} else {
|
||||||
@ -524,7 +521,7 @@ const internalCertificate = {
|
|||||||
// Put file contents into an object
|
// Put file contents into an object
|
||||||
let files = {};
|
let files = {};
|
||||||
_.map(data.files, (file, name) => {
|
_.map(data.files, (file, name) => {
|
||||||
if (internalCertificate.allowed_ssl_files.indexOf(name) !== -1) {
|
if (internalCertificate.allowedSslFiles.indexOf(name) !== -1) {
|
||||||
files[name] = file.data.toString();
|
files[name] = file.data.toString();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -582,7 +579,7 @@ const internalCertificate = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_.map(data.files, (file, name) => {
|
_.map(data.files, (file, name) => {
|
||||||
if (internalCertificate.allowed_ssl_files.indexOf(name) !== -1) {
|
if (internalCertificate.allowedSslFiles.indexOf(name) !== -1) {
|
||||||
row.meta[name] = file.data.toString();
|
row.meta[name] = file.data.toString();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -601,7 +598,7 @@ const internalCertificate = {
|
|||||||
});
|
});
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
return _.pick(row.meta, internalCertificate.allowed_ssl_files);
|
return _.pick(row.meta, internalCertificate.allowedSslFiles);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -649,9 +646,9 @@ const internalCertificate = {
|
|||||||
return tempWrite(certificate, '/tmp')
|
return tempWrite(certificate, '/tmp')
|
||||||
.then((filepath) => {
|
.then((filepath) => {
|
||||||
return internalCertificate.getCertificateInfoFromFile(filepath, throw_expired)
|
return internalCertificate.getCertificateInfoFromFile(filepath, throw_expired)
|
||||||
.then((cert_data) => {
|
.then((certData) => {
|
||||||
fs.unlinkSync(filepath);
|
fs.unlinkSync(filepath);
|
||||||
return cert_data;
|
return certData;
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
fs.unlinkSync(filepath);
|
fs.unlinkSync(filepath);
|
||||||
throw err;
|
throw err;
|
||||||
@ -667,33 +664,33 @@ const internalCertificate = {
|
|||||||
* @param {Boolean} [throw_expired] Throw when the certificate is out of date
|
* @param {Boolean} [throw_expired] Throw when the certificate is out of date
|
||||||
*/
|
*/
|
||||||
getCertificateInfoFromFile: (certificate_file, throw_expired) => {
|
getCertificateInfoFromFile: (certificate_file, throw_expired) => {
|
||||||
let cert_data = {};
|
let certData = {};
|
||||||
|
|
||||||
return utils.exec('openssl x509 -in ' + certificate_file + ' -subject -noout')
|
return utils.exec('openssl x509 -in ' + certificate_file + ' -subject -noout')
|
||||||
.then((result) => {
|
.then((result) => {
|
||||||
// subject=CN = something.example.com
|
// subject=CN = something.example.com
|
||||||
let regex = /(?:subject=)?[^=]+=\s+(\S+)/gim;
|
const regex = /(?:subject=)?[^=]+=\s+(\S+)/gim;
|
||||||
let match = regex.exec(result);
|
const match = regex.exec(result);
|
||||||
|
|
||||||
if (typeof match[1] === 'undefined') {
|
if (typeof match[1] === 'undefined') {
|
||||||
throw new error.ValidationError('Could not determine subject from certificate: ' + result);
|
throw new error.ValidationError('Could not determine subject from certificate: ' + result);
|
||||||
}
|
}
|
||||||
|
|
||||||
cert_data['cn'] = match[1];
|
certData['cn'] = match[1];
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
return utils.exec('openssl x509 -in ' + certificate_file + ' -issuer -noout');
|
return utils.exec('openssl x509 -in ' + certificate_file + ' -issuer -noout');
|
||||||
})
|
})
|
||||||
.then((result) => {
|
.then((result) => {
|
||||||
// issuer=C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
|
// issuer=C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
|
||||||
let regex = /^(?:issuer=)?(.*)$/gim;
|
const regex = /^(?:issuer=)?(.*)$/gim;
|
||||||
let match = regex.exec(result);
|
const match = regex.exec(result);
|
||||||
|
|
||||||
if (typeof match[1] === 'undefined') {
|
if (typeof match[1] === 'undefined') {
|
||||||
throw new error.ValidationError('Could not determine issuer from certificate: ' + result);
|
throw new error.ValidationError('Could not determine issuer from certificate: ' + result);
|
||||||
}
|
}
|
||||||
|
|
||||||
cert_data['issuer'] = match[1];
|
certData['issuer'] = match[1];
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
return utils.exec('openssl x509 -in ' + certificate_file + ' -dates -noout');
|
return utils.exec('openssl x509 -in ' + certificate_file + ' -dates -noout');
|
||||||
@ -701,39 +698,39 @@ const internalCertificate = {
|
|||||||
.then((result) => {
|
.then((result) => {
|
||||||
// notBefore=Jul 14 04:04:29 2018 GMT
|
// notBefore=Jul 14 04:04:29 2018 GMT
|
||||||
// notAfter=Oct 12 04:04:29 2018 GMT
|
// notAfter=Oct 12 04:04:29 2018 GMT
|
||||||
let valid_from = null;
|
let validFrom = null;
|
||||||
let valid_to = null;
|
let validTo = null;
|
||||||
|
|
||||||
let lines = result.split('\n');
|
const lines = result.split('\n');
|
||||||
lines.map(function (str) {
|
lines.map(function (str) {
|
||||||
let regex = /^(\S+)=(.*)$/gim;
|
const regex = /^(\S+)=(.*)$/gim;
|
||||||
let match = regex.exec(str.trim());
|
const match = regex.exec(str.trim());
|
||||||
|
|
||||||
if (match && typeof match[2] !== 'undefined') {
|
if (match && typeof match[2] !== 'undefined') {
|
||||||
let date = parseInt(moment(match[2], 'MMM DD HH:mm:ss YYYY z').format('X'), 10);
|
const date = parseInt(moment(match[2], 'MMM DD HH:mm:ss YYYY z').format('X'), 10);
|
||||||
|
|
||||||
if (match[1].toLowerCase() === 'notbefore') {
|
if (match[1].toLowerCase() === 'notbefore') {
|
||||||
valid_from = date;
|
validFrom = date;
|
||||||
} else if (match[1].toLowerCase() === 'notafter') {
|
} else if (match[1].toLowerCase() === 'notafter') {
|
||||||
valid_to = date;
|
validTo = date;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!valid_from || !valid_to) {
|
if (!validFrom || !validTo) {
|
||||||
throw new error.ValidationError('Could not determine dates from certificate: ' + result);
|
throw new error.ValidationError('Could not determine dates from certificate: ' + result);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (throw_expired && valid_to < parseInt(moment().format('X'), 10)) {
|
if (throw_expired && validTo < parseInt(moment().format('X'), 10)) {
|
||||||
throw new error.ValidationError('Certificate has expired');
|
throw new error.ValidationError('Certificate has expired');
|
||||||
}
|
}
|
||||||
|
|
||||||
cert_data['dates'] = {
|
certData['dates'] = {
|
||||||
from: valid_from,
|
from: validFrom,
|
||||||
to: valid_to
|
to: validTo
|
||||||
};
|
};
|
||||||
|
|
||||||
return cert_data;
|
return certData;
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
throw new error.ValidationError('Certificate is not valid (' + err.message + ')', err);
|
throw new error.ValidationError('Certificate is not valid (' + err.message + ')', err);
|
||||||
});
|
});
|
||||||
@ -747,7 +744,7 @@ const internalCertificate = {
|
|||||||
* @returns {Object}
|
* @returns {Object}
|
||||||
*/
|
*/
|
||||||
cleanMeta: function (meta, remove) {
|
cleanMeta: function (meta, remove) {
|
||||||
internalCertificate.allowed_ssl_files.map((key) => {
|
internalCertificate.allowedSslFiles.map((key) => {
|
||||||
if (typeof meta[key] !== 'undefined' && meta[key]) {
|
if (typeof meta[key] !== 'undefined' && meta[key]) {
|
||||||
if (remove) {
|
if (remove) {
|
||||||
delete meta[key];
|
delete meta[key];
|
||||||
@ -767,18 +764,16 @@ const internalCertificate = {
|
|||||||
requestLetsEncryptSsl: (certificate) => {
|
requestLetsEncryptSsl: (certificate) => {
|
||||||
logger.info('Requesting Let\'sEncrypt certificates for Cert #' + certificate.id + ': ' + certificate.domain_names.join(', '));
|
logger.info('Requesting Let\'sEncrypt certificates for Cert #' + certificate.id + ': ' + certificate.domain_names.join(', '));
|
||||||
|
|
||||||
let cmd = certbot_command + ' certonly --non-interactive ' +
|
const cmd = certbotCommand + ' certonly --non-interactive ' +
|
||||||
'--config "' + le_config + '" ' +
|
'--config "' + letsencryptConfig + '" ' +
|
||||||
'--cert-name "npm-' + certificate.id + '" ' +
|
'--cert-name "npm-' + certificate.id + '" ' +
|
||||||
'--agree-tos ' +
|
'--agree-tos ' +
|
||||||
'--email "' + certificate.meta.letsencrypt_email + '" ' +
|
'--email "' + certificate.meta.letsencrypt_email + '" ' +
|
||||||
'--preferred-challenges "dns,http" ' +
|
'--preferred-challenges "dns,http" ' +
|
||||||
'--domains "' + certificate.domain_names.join(',') + '" ' +
|
'--domains "' + certificate.domain_names.join(',') + '" ' +
|
||||||
(le_staging ? '--staging' : '');
|
(letsencryptStaging ? '--staging' : '');
|
||||||
|
|
||||||
if (debug_mode) {
|
logger.info('Command:', cmd);
|
||||||
logger.info('Command:', cmd);
|
|
||||||
}
|
|
||||||
|
|
||||||
return utils.exec(cmd)
|
return utils.exec(cmd)
|
||||||
.then((result) => {
|
.then((result) => {
|
||||||
@ -788,14 +783,14 @@ const internalCertificate = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Object} certificate the certificate row
|
* @param {Object} certificate the certificate row
|
||||||
* @param {String} dns_provider the dns provider name (key used in `certbot-dns-plugins.js`)
|
* @param {String} dns_provider the dns provider name (key used in `certbot-dns-plugins.js`)
|
||||||
* @param {String | null} credentials the content of this providers credentials file
|
* @param {String | null} credentials the content of this providers credentials file
|
||||||
* @param {String} propagation_seconds the cloudflare api token
|
* @param {String} propagation_seconds the cloudflare api token
|
||||||
* @returns {Promise}
|
* @returns {Promise}
|
||||||
*/
|
*/
|
||||||
requestLetsEncryptSslWithDnsChallenge: (certificate) => {
|
requestLetsEncryptSslWithDnsChallenge: (certificate) => {
|
||||||
const dns_plugin = dns_plugins[certificate.meta.dns_provider];
|
const dns_plugin = dnsPlugins[certificate.meta.dns_provider];
|
||||||
|
|
||||||
if (!dns_plugin) {
|
if (!dns_plugin) {
|
||||||
throw Error(`Unknown DNS provider '${certificate.meta.dns_provider}'`);
|
throw Error(`Unknown DNS provider '${certificate.meta.dns_provider}'`);
|
||||||
@ -803,46 +798,43 @@ const internalCertificate = {
|
|||||||
|
|
||||||
logger.info(`Requesting Let'sEncrypt certificates via ${dns_plugin.display_name} for Cert #${certificate.id}: ${certificate.domain_names.join(', ')}`);
|
logger.info(`Requesting Let'sEncrypt certificates via ${dns_plugin.display_name} for Cert #${certificate.id}: ${certificate.domain_names.join(', ')}`);
|
||||||
|
|
||||||
const credentials_loc = '/etc/letsencrypt/credentials/credentials-' + certificate.id;
|
const credentialsLocation = '/etc/letsencrypt/credentials/credentials-' + certificate.id;
|
||||||
const credentials_cmd = 'mkdir -p /etc/letsencrypt/credentials 2> /dev/null; echo \'' + certificate.meta.dns_provider_credentials.replace('\'', '\\\'') + '\' > \'' + credentials_loc + '\' && chmod 600 \'' + credentials_loc + '\'';
|
const credentialsCmd = 'mkdir -p /etc/letsencrypt/credentials 2> /dev/null; echo \'' + certificate.meta.dns_provider_credentials.replace('\'', '\\\'') + '\' > \'' + credentialsLocation + '\' && chmod 600 \'' + credentialsLocation + '\'';
|
||||||
const prepare_cmd = 'pip install ' + dns_plugin.package_name + '==' + dns_plugin.package_version + ' ' + dns_plugin.dependencies;
|
const prepareCmd = 'pip install ' + dns_plugin.package_name + '==' + dns_plugin.package_version + ' ' + dns_plugin.dependencies;
|
||||||
|
|
||||||
// Whether the plugin has a --<name>-credentials argument
|
// Whether the plugin has a --<name>-credentials argument
|
||||||
const has_config_arg = certificate.meta.dns_provider !== 'route53';
|
const hasConfigArg = certificate.meta.dns_provider !== 'route53';
|
||||||
|
|
||||||
let main_cmd =
|
let mainCmd = certbotCommand + ' certonly --non-interactive ' +
|
||||||
certbot_command + ' certonly --non-interactive ' +
|
|
||||||
'--cert-name "npm-' + certificate.id + '" ' +
|
'--cert-name "npm-' + certificate.id + '" ' +
|
||||||
'--agree-tos ' +
|
'--agree-tos ' +
|
||||||
'--email "' + certificate.meta.letsencrypt_email + '" ' +
|
'--email "' + certificate.meta.letsencrypt_email + '" ' +
|
||||||
'--domains "' + certificate.domain_names.join(',') + '" ' +
|
'--domains "' + certificate.domain_names.join(',') + '" ' +
|
||||||
'--authenticator ' + dns_plugin.full_plugin_name + ' ' +
|
'--authenticator ' + dns_plugin.full_plugin_name + ' ' +
|
||||||
(
|
(
|
||||||
has_config_arg
|
hasConfigArg
|
||||||
? '--' + dns_plugin.full_plugin_name + '-credentials "' + credentials_loc + '"'
|
? '--' + dns_plugin.full_plugin_name + '-credentials "' + credentialsLocation + '"'
|
||||||
: ''
|
: ''
|
||||||
) +
|
) +
|
||||||
(
|
(
|
||||||
certificate.meta.propagation_seconds !== undefined
|
certificate.meta.propagation_seconds !== undefined
|
||||||
? ' --' + dns_plugin.full_plugin_name + '-propagation-seconds ' + certificate.meta.propagation_seconds
|
? ' --' + dns_plugin.full_plugin_name + '-propagation-seconds ' + certificate.meta.propagation_seconds
|
||||||
: ''
|
: ''
|
||||||
) +
|
) +
|
||||||
(le_staging ? ' --staging' : '');
|
(letsencryptStaging ? ' --staging' : '');
|
||||||
|
|
||||||
// Prepend the path to the credentials file as an environment variable
|
// Prepend the path to the credentials file as an environment variable
|
||||||
if (certificate.meta.dns_provider === 'route53') {
|
if (certificate.meta.dns_provider === 'route53') {
|
||||||
main_cmd = 'AWS_CONFIG_FILE=\'' + credentials_loc + '\' ' + main_cmd;
|
mainCmd = 'AWS_CONFIG_FILE=\'' + credentialsLocation + '\' ' + mainCmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (debug_mode) {
|
logger.info('Command:', `${credentialsCmd} && ${prepareCmd} && ${mainCmd}`);
|
||||||
logger.info('Command:', `${credentials_cmd} && ${prepare_cmd} && ${main_cmd}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
return utils.exec(credentials_cmd)
|
return utils.exec(credentialsCmd)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
return utils.exec(prepare_cmd)
|
return utils.exec(prepareCmd)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
return utils.exec(main_cmd)
|
return utils.exec(mainCmd)
|
||||||
.then(async (result) => {
|
.then(async (result) => {
|
||||||
logger.info(result);
|
logger.info(result);
|
||||||
return result;
|
return result;
|
||||||
@ -850,8 +842,8 @@ const internalCertificate = {
|
|||||||
});
|
});
|
||||||
}).catch(async (err) => {
|
}).catch(async (err) => {
|
||||||
// Don't fail if file does not exist
|
// Don't fail if file does not exist
|
||||||
const delete_credentials_cmd = `rm -f '${credentials_loc}' || true`;
|
const delete_credentialsCmd = `rm -f '${credentialsLocation}' || true`;
|
||||||
await utils.exec(delete_credentials_cmd);
|
await utils.exec(delete_credentialsCmd);
|
||||||
throw err;
|
throw err;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -870,7 +862,7 @@ const internalCertificate = {
|
|||||||
})
|
})
|
||||||
.then((certificate) => {
|
.then((certificate) => {
|
||||||
if (certificate.provider === 'letsencrypt') {
|
if (certificate.provider === 'letsencrypt') {
|
||||||
let renewMethod = certificate.meta.dns_challenge ? internalCertificate.renewLetsEncryptSslWithDnsChallenge : internalCertificate.renewLetsEncryptSsl;
|
const renewMethod = certificate.meta.dns_challenge ? internalCertificate.renewLetsEncryptSslWithDnsChallenge : internalCertificate.renewLetsEncryptSsl;
|
||||||
|
|
||||||
return renewMethod(certificate)
|
return renewMethod(certificate)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
@ -908,16 +900,14 @@ const internalCertificate = {
|
|||||||
renewLetsEncryptSsl: (certificate) => {
|
renewLetsEncryptSsl: (certificate) => {
|
||||||
logger.info('Renewing Let\'sEncrypt certificates for Cert #' + certificate.id + ': ' + certificate.domain_names.join(', '));
|
logger.info('Renewing Let\'sEncrypt certificates for Cert #' + certificate.id + ': ' + certificate.domain_names.join(', '));
|
||||||
|
|
||||||
let cmd = certbot_command + ' renew --non-interactive ' +
|
const cmd = certbotCommand + ' renew --force-renewal --non-interactive ' +
|
||||||
'--config "' + le_config + '" ' +
|
'--config "' + letsencryptConfig + '" ' +
|
||||||
'--cert-name "npm-' + certificate.id + '" ' +
|
'--cert-name "npm-' + certificate.id + '" ' +
|
||||||
'--preferred-challenges "dns,http" ' +
|
'--preferred-challenges "dns,http" ' +
|
||||||
'--disable-hook-validation ' +
|
'--disable-hook-validation ' +
|
||||||
(le_staging ? '--staging' : '');
|
(letsencryptStaging ? '--staging' : '');
|
||||||
|
|
||||||
if (debug_mode) {
|
logger.info('Command:', cmd);
|
||||||
logger.info('Command:', cmd);
|
|
||||||
}
|
|
||||||
|
|
||||||
return utils.exec(cmd)
|
return utils.exec(cmd)
|
||||||
.then((result) => {
|
.then((result) => {
|
||||||
@ -931,7 +921,7 @@ const internalCertificate = {
|
|||||||
* @returns {Promise}
|
* @returns {Promise}
|
||||||
*/
|
*/
|
||||||
renewLetsEncryptSslWithDnsChallenge: (certificate) => {
|
renewLetsEncryptSslWithDnsChallenge: (certificate) => {
|
||||||
const dns_plugin = dns_plugins[certificate.meta.dns_provider];
|
const dns_plugin = dnsPlugins[certificate.meta.dns_provider];
|
||||||
|
|
||||||
if (!dns_plugin) {
|
if (!dns_plugin) {
|
||||||
throw Error(`Unknown DNS provider '${certificate.meta.dns_provider}'`);
|
throw Error(`Unknown DNS provider '${certificate.meta.dns_provider}'`);
|
||||||
@ -939,23 +929,20 @@ const internalCertificate = {
|
|||||||
|
|
||||||
logger.info(`Renewing Let'sEncrypt certificates via ${dns_plugin.display_name} for Cert #${certificate.id}: ${certificate.domain_names.join(', ')}`);
|
logger.info(`Renewing Let'sEncrypt certificates via ${dns_plugin.display_name} for Cert #${certificate.id}: ${certificate.domain_names.join(', ')}`);
|
||||||
|
|
||||||
let main_cmd =
|
let mainCmd = certbotCommand + ' renew --non-interactive ' +
|
||||||
certbot_command + ' renew --non-interactive ' +
|
|
||||||
'--cert-name "npm-' + certificate.id + '" ' +
|
'--cert-name "npm-' + certificate.id + '" ' +
|
||||||
'--disable-hook-validation' +
|
'--disable-hook-validation' +
|
||||||
(le_staging ? ' --staging' : '');
|
(letsencryptStaging ? ' --staging' : '');
|
||||||
|
|
||||||
// Prepend the path to the credentials file as an environment variable
|
// Prepend the path to the credentials file as an environment variable
|
||||||
if (certificate.meta.dns_provider === 'route53') {
|
if (certificate.meta.dns_provider === 'route53') {
|
||||||
const credentials_loc = '/etc/letsencrypt/credentials/credentials-' + certificate.id;
|
const credentialsLocation = '/etc/letsencrypt/credentials/credentials-' + certificate.id;
|
||||||
main_cmd = 'AWS_CONFIG_FILE=\'' + credentials_loc + '\' ' + main_cmd;
|
mainCmd = 'AWS_CONFIG_FILE=\'' + credentialsLocation + '\' ' + mainCmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (debug_mode) {
|
logger.info('Command:', mainCmd);
|
||||||
logger.info('Command:', main_cmd);
|
|
||||||
}
|
|
||||||
|
|
||||||
return utils.exec(main_cmd)
|
return utils.exec(mainCmd)
|
||||||
.then(async (result) => {
|
.then(async (result) => {
|
||||||
logger.info(result);
|
logger.info(result);
|
||||||
return result;
|
return result;
|
||||||
@ -970,28 +957,24 @@ const internalCertificate = {
|
|||||||
revokeLetsEncryptSsl: (certificate, throw_errors) => {
|
revokeLetsEncryptSsl: (certificate, throw_errors) => {
|
||||||
logger.info('Revoking Let\'sEncrypt certificates for Cert #' + certificate.id + ': ' + certificate.domain_names.join(', '));
|
logger.info('Revoking Let\'sEncrypt certificates for Cert #' + certificate.id + ': ' + certificate.domain_names.join(', '));
|
||||||
|
|
||||||
const main_cmd = certbot_command + ' revoke --non-interactive ' +
|
const mainCmd = certbotCommand + ' revoke --non-interactive ' +
|
||||||
'--cert-path "/etc/letsencrypt/live/npm-' + certificate.id + '/fullchain.pem" ' +
|
'--cert-path "/etc/letsencrypt/live/npm-' + certificate.id + '/fullchain.pem" ' +
|
||||||
'--delete-after-revoke ' +
|
'--delete-after-revoke ' +
|
||||||
(le_staging ? '--staging' : '');
|
(letsencryptStaging ? '--staging' : '');
|
||||||
|
|
||||||
// Don't fail command if file does not exist
|
// Don't fail command if file does not exist
|
||||||
const delete_credentials_cmd = `rm -f '/etc/letsencrypt/credentials/credentials-${certificate.id}' || true`;
|
const delete_credentialsCmd = `rm -f '/etc/letsencrypt/credentials/credentials-${certificate.id}' || true`;
|
||||||
|
|
||||||
if (debug_mode) {
|
logger.info('Command:', mainCmd + '; ' + delete_credentialsCmd);
|
||||||
logger.info('Command:', main_cmd + '; ' + delete_credentials_cmd);
|
|
||||||
}
|
|
||||||
|
|
||||||
return utils.exec(main_cmd)
|
return utils.exec(mainCmd)
|
||||||
.then(async (result) => {
|
.then(async (result) => {
|
||||||
await utils.exec(delete_credentials_cmd);
|
await utils.exec(delete_credentialsCmd);
|
||||||
logger.info(result);
|
logger.info(result);
|
||||||
return result;
|
return result;
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
if (debug_mode) {
|
logger.error(err.message);
|
||||||
logger.error(err.message);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (throw_errors) {
|
if (throw_errors) {
|
||||||
throw err;
|
throw err;
|
||||||
@ -1004,9 +987,9 @@ const internalCertificate = {
|
|||||||
* @returns {Boolean}
|
* @returns {Boolean}
|
||||||
*/
|
*/
|
||||||
hasLetsEncryptSslCerts: (certificate) => {
|
hasLetsEncryptSslCerts: (certificate) => {
|
||||||
let le_path = '/etc/letsencrypt/live/npm-' + certificate.id;
|
const letsencryptPath = '/etc/letsencrypt/live/npm-' + certificate.id;
|
||||||
|
|
||||||
return fs.existsSync(le_path + '/fullchain.pem') && fs.existsSync(le_path + '/privkey.pem');
|
return fs.existsSync(letsencryptPath + '/fullchain.pem') && fs.existsSync(letsencryptPath + '/privkey.pem');
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -201,9 +201,29 @@ const setupCertbotPlugins = () => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts a timer to call run the logrotation binary every two days
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
|
const setupLogrotation = () => {
|
||||||
|
const intervalTimeout = 1000 * 60 * 60 * 24 * 2; // 2 days
|
||||||
|
|
||||||
|
const runLogrotate = async () => {
|
||||||
|
await utils.exec('logrotate /etc/logrotate.d/nginx-proxy-manager');
|
||||||
|
logger.info('Logrotate completed.');
|
||||||
|
};
|
||||||
|
|
||||||
|
logger.info('Logrotate Timer initialized');
|
||||||
|
setInterval(runLogrotate, intervalTimeout);
|
||||||
|
// And do this now as well
|
||||||
|
return runLogrotate();
|
||||||
|
};
|
||||||
|
|
||||||
module.exports = function () {
|
module.exports = function () {
|
||||||
return setupJwt()
|
return setupJwt()
|
||||||
.then(setupDefaultUser)
|
.then(setupDefaultUser)
|
||||||
.then(setupDefaultSettings)
|
.then(setupDefaultSettings)
|
||||||
.then(setupCertbotPlugins);
|
.then(setupCertbotPlugins)
|
||||||
|
.then(setupLogrotation);
|
||||||
};
|
};
|
||||||
|
@ -7,7 +7,8 @@ server {
|
|||||||
{% include "_hsts.conf" %}
|
{% include "_hsts.conf" %}
|
||||||
{% include "_forced_ssl.conf" %}
|
{% include "_forced_ssl.conf" %}
|
||||||
|
|
||||||
access_log /data/logs/dead_host-{{ id }}.log standard;
|
access_log /data/logs/dead-host-{{ id }}_access.log standard;
|
||||||
|
error_log /data/logs/dead-host-{{ id }}_error.log warn;
|
||||||
|
|
||||||
{{ advanced_config }}
|
{{ advanced_config }}
|
||||||
|
|
||||||
|
@ -12,7 +12,8 @@ server {
|
|||||||
#listen [::]:80;
|
#listen [::]:80;
|
||||||
{% endif %}
|
{% endif %}
|
||||||
server_name default-host.localhost;
|
server_name default-host.localhost;
|
||||||
access_log /data/logs/default_host.log combined;
|
access_log /data/logs/default-host_access.log combined;
|
||||||
|
error_log /data/logs/default-host_error.log warn;
|
||||||
{% include "_exploits.conf" %}
|
{% include "_exploits.conf" %}
|
||||||
|
|
||||||
{%- if value == "404" %}
|
{%- if value == "404" %}
|
||||||
|
@ -8,7 +8,8 @@ server {
|
|||||||
|
|
||||||
server_name {{ domain_names | join: " " }};
|
server_name {{ domain_names | join: " " }};
|
||||||
|
|
||||||
access_log /data/logs/letsencrypt-requests.log standard;
|
access_log /data/logs/letsencrypt-requests_access.log standard;
|
||||||
|
error_log /data/logs/letsencrypt-requests_error.log warn;
|
||||||
|
|
||||||
include conf.d/include/letsencrypt-acme-challenge.conf;
|
include conf.d/include/letsencrypt-acme-challenge.conf;
|
||||||
|
|
||||||
|
@ -19,8 +19,8 @@ proxy_set_header Connection $http_connection;
|
|||||||
proxy_http_version 1.1;
|
proxy_http_version 1.1;
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
access_log /data/logs/proxy-host-{{ id }}_access.log proxy;
|
||||||
access_log /data/logs/proxy_host-{{ id }}.log proxy;
|
error_log /data/logs/proxy-host-{{ id }}_error.log warn;
|
||||||
|
|
||||||
{{ advanced_config }}
|
{{ advanced_config }}
|
||||||
|
|
||||||
|
@ -9,7 +9,8 @@ server {
|
|||||||
{% include "_hsts.conf" %}
|
{% include "_hsts.conf" %}
|
||||||
{% include "_forced_ssl.conf" %}
|
{% include "_forced_ssl.conf" %}
|
||||||
|
|
||||||
access_log /data/logs/redirection_host-{{ id }}.log standard;
|
access_log /data/logs/redirection-host-{{ id }}_access.log standard;
|
||||||
|
error_log /data/logs/redirection-host-{{ id }}_error.log warn;
|
||||||
|
|
||||||
{{ advanced_config }}
|
{{ advanced_config }}
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ ENV SUPPRESS_NO_CONFIG_WARNING=1 \
|
|||||||
|
|
||||||
RUN echo "fs.file-max = 65535" > /etc/sysctl.conf \
|
RUN echo "fs.file-max = 65535" > /etc/sysctl.conf \
|
||||||
&& apt-get update \
|
&& apt-get update \
|
||||||
&& apt-get install -y --no-install-recommends jq \
|
&& apt-get install -y --no-install-recommends jq logrotate \
|
||||||
&& apt-get clean \
|
&& apt-get clean \
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
@ -43,6 +43,9 @@ COPY docker/rootfs /
|
|||||||
# Remove frontend service not required for prod, dev nginx config as well
|
# Remove frontend service not required for prod, dev nginx config as well
|
||||||
RUN rm -rf /etc/services.d/frontend /etc/nginx/conf.d/dev.conf
|
RUN rm -rf /etc/services.d/frontend /etc/nginx/conf.d/dev.conf
|
||||||
|
|
||||||
|
# Change permission of logrotate config file
|
||||||
|
RUN chmod 644 /etc/logrotate.d/nginx-proxy-manager
|
||||||
|
|
||||||
VOLUME [ "/data", "/etc/letsencrypt" ]
|
VOLUME [ "/data", "/etc/letsencrypt" ]
|
||||||
ENTRYPOINT [ "/init" ]
|
ENTRYPOINT [ "/init" ]
|
||||||
HEALTHCHECK --interval=5s --timeout=3s CMD /bin/check-health
|
HEALTHCHECK --interval=5s --timeout=3s CMD /bin/check-health
|
||||||
|
@ -7,7 +7,7 @@ ENV S6_LOGGING=0 \
|
|||||||
|
|
||||||
RUN echo "fs.file-max = 65535" > /etc/sysctl.conf \
|
RUN echo "fs.file-max = 65535" > /etc/sysctl.conf \
|
||||||
&& apt-get update \
|
&& apt-get update \
|
||||||
&& apt-get install -y certbot jq python3-pip \
|
&& apt-get install -y certbot jq python3-pip logrotate \
|
||||||
&& apt-get clean \
|
&& apt-get clean \
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
@ -18,6 +18,7 @@ RUN cd /usr \
|
|||||||
|
|
||||||
COPY rootfs /
|
COPY rootfs /
|
||||||
RUN rm -f /etc/nginx/conf.d/production.conf
|
RUN rm -f /etc/nginx/conf.d/production.conf
|
||||||
|
RUN chmod 644 /etc/logrotate.d/nginx-proxy-manager
|
||||||
|
|
||||||
# s6 overlay
|
# s6 overlay
|
||||||
RUN curl -L -o /tmp/s6-overlay-amd64.tar.gz "https://github.com/just-containers/s6-overlay/releases/download/v1.22.1.0/s6-overlay-amd64.tar.gz" \
|
RUN curl -L -o /tmp/s6-overlay-amd64.tar.gz "https://github.com/just-containers/s6-overlay/releases/download/v1.22.1.0/s6-overlay-amd64.tar.gz" \
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
# WARNING: This is a DEVELOPMENT docker-compose file, it should not be used for production.
|
# WARNING: This is a DEVELOPMENT docker-compose file, it should not be used for production.
|
||||||
version: "3"
|
version: "3.5"
|
||||||
services:
|
services:
|
||||||
|
|
||||||
npm:
|
npm:
|
||||||
image: nginxproxymanager:dev
|
image: nginxproxymanager:dev
|
||||||
|
container_name: npm_core
|
||||||
build:
|
build:
|
||||||
context: ./
|
context: ./
|
||||||
dockerfile: ./dev/Dockerfile
|
dockerfile: ./dev/Dockerfile
|
||||||
@ -36,6 +36,7 @@ services:
|
|||||||
|
|
||||||
db:
|
db:
|
||||||
image: jc21/mariadb-aria
|
image: jc21/mariadb-aria
|
||||||
|
container_name: npm_db
|
||||||
networks:
|
networks:
|
||||||
- nginx_proxy_manager
|
- nginx_proxy_manager
|
||||||
environment:
|
environment:
|
||||||
@ -47,21 +48,26 @@ services:
|
|||||||
- db_data:/var/lib/mysql
|
- db_data:/var/lib/mysql
|
||||||
|
|
||||||
swagger:
|
swagger:
|
||||||
image: 'swaggerapi/swagger-ui:latest'
|
image: "swaggerapi/swagger-ui:latest"
|
||||||
|
container_name: npm_swagger
|
||||||
ports:
|
ports:
|
||||||
- 3001:80
|
- 3001:80
|
||||||
networks:
|
networks:
|
||||||
- nginx_proxy_manager
|
- nginx_proxy_manager
|
||||||
environment:
|
environment:
|
||||||
URL: "http://127.0.0.1:3081/api/schema"
|
URL: "http://127.0.0.1:3081/api/schema"
|
||||||
PORT: '80'
|
PORT: "80"
|
||||||
depends_on:
|
depends_on:
|
||||||
- npm
|
- npm
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
npm_data:
|
npm_data:
|
||||||
|
name: npm_core_data
|
||||||
le_data:
|
le_data:
|
||||||
|
name: npm_le_data
|
||||||
db_data:
|
db_data:
|
||||||
|
name: npm_db_data
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
nginx_proxy_manager:
|
nginx_proxy_manager:
|
||||||
|
name: npm_network
|
||||||
|
25
docker/rootfs/etc/logrotate.d/nginx-proxy-manager
Normal file
25
docker/rootfs/etc/logrotate.d/nginx-proxy-manager
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
/data/logs/*_access.log /data/logs/*/access.log {
|
||||||
|
create 0644 root root
|
||||||
|
weekly
|
||||||
|
rotate 4
|
||||||
|
missingok
|
||||||
|
notifempty
|
||||||
|
compress
|
||||||
|
sharedscripts
|
||||||
|
postrotate
|
||||||
|
/bin/kill -USR1 `cat /run/nginx.pid 2>/dev/null` 2>/dev/null || true
|
||||||
|
endscript
|
||||||
|
}
|
||||||
|
|
||||||
|
/data/logs/*_error.log /data/logs/*/error.log {
|
||||||
|
create 0644 root root
|
||||||
|
weekly
|
||||||
|
rotate 10
|
||||||
|
missingok
|
||||||
|
notifempty
|
||||||
|
compress
|
||||||
|
sharedscripts
|
||||||
|
postrotate
|
||||||
|
/bin/kill -USR1 `cat /run/nginx.pid 2>/dev/null` 2>/dev/null || true
|
||||||
|
endscript
|
||||||
|
}
|
@ -8,7 +8,7 @@ server {
|
|||||||
set $port "80";
|
set $port "80";
|
||||||
|
|
||||||
server_name localhost-nginx-proxy-manager;
|
server_name localhost-nginx-proxy-manager;
|
||||||
access_log /data/logs/default.log standard;
|
access_log /data/logs/fallback_access.log standard;
|
||||||
error_log /dev/null crit;
|
error_log /dev/null crit;
|
||||||
include conf.d/include/assets.conf;
|
include conf.d/include/assets.conf;
|
||||||
include conf.d/include/block-exploits.conf;
|
include conf.d/include/block-exploits.conf;
|
||||||
@ -29,7 +29,7 @@ server {
|
|||||||
set $port "443";
|
set $port "443";
|
||||||
|
|
||||||
server_name localhost;
|
server_name localhost;
|
||||||
access_log /data/logs/default.log standard;
|
access_log /data/logs/fallback-access.log standard;
|
||||||
error_log /dev/null crit;
|
error_log /dev/null crit;
|
||||||
ssl_certificate /data/nginx/dummycert.pem;
|
ssl_certificate /data/nginx/dummycert.pem;
|
||||||
ssl_certificate_key /data/nginx/dummykey.pem;
|
ssl_certificate_key /data/nginx/dummykey.pem;
|
||||||
|
@ -5,6 +5,7 @@ location ^~ /.well-known/acme-challenge/ {
|
|||||||
# Since this is for letsencrypt authentication of a domain and they do not give IP ranges of their infrastructure
|
# Since this is for letsencrypt authentication of a domain and they do not give IP ranges of their infrastructure
|
||||||
# we need to open up access by turning off auth and IP ACL for this location.
|
# we need to open up access by turning off auth and IP ACL for this location.
|
||||||
auth_basic off;
|
auth_basic off;
|
||||||
|
auth_request off;
|
||||||
allow all;
|
allow all;
|
||||||
|
|
||||||
# Set correct content type. According to this:
|
# Set correct content type. According to this:
|
||||||
|
@ -9,7 +9,7 @@ worker_processes auto;
|
|||||||
# Enables the use of JIT for regular expressions to speed-up their processing.
|
# Enables the use of JIT for regular expressions to speed-up their processing.
|
||||||
pcre_jit on;
|
pcre_jit on;
|
||||||
|
|
||||||
error_log /data/logs/error.log warn;
|
error_log /data/logs/fallback_error.log warn;
|
||||||
|
|
||||||
# Includes files with directives to load dynamic modules.
|
# Includes files with directives to load dynamic modules.
|
||||||
include /etc/nginx/modules/*.conf;
|
include /etc/nginx/modules/*.conf;
|
||||||
@ -46,8 +46,7 @@ http {
|
|||||||
log_format proxy '[$time_local] $upstream_cache_status $upstream_status $status - $request_method $scheme $host "$request_uri" [Client $remote_addr] [Length $body_bytes_sent] [Gzip $gzip_ratio] [Sent-to $server] "$http_user_agent" "$http_referer"';
|
log_format proxy '[$time_local] $upstream_cache_status $upstream_status $status - $request_method $scheme $host "$request_uri" [Client $remote_addr] [Length $body_bytes_sent] [Gzip $gzip_ratio] [Sent-to $server] "$http_user_agent" "$http_referer"';
|
||||||
log_format standard '[$time_local] $status - $request_method $scheme $host "$request_uri" [Client $remote_addr] [Length $body_bytes_sent] [Gzip $gzip_ratio] "$http_user_agent" "$http_referer"';
|
log_format standard '[$time_local] $status - $request_method $scheme $host "$request_uri" [Client $remote_addr] [Length $body_bytes_sent] [Gzip $gzip_ratio] "$http_user_agent" "$http_referer"';
|
||||||
|
|
||||||
|
access_log /data/logs/fallback_access.log proxy;
|
||||||
access_log /data/logs/default.log proxy;
|
|
||||||
|
|
||||||
# Dynamically generated resolvers file
|
# Dynamically generated resolvers file
|
||||||
include /etc/nginx/conf.d/include/resolvers.conf;
|
include /etc/nginx/conf.d/include/resolvers.conf;
|
||||||
|
@ -2650,9 +2650,9 @@ color-name@^1.0.0, color-name@^1.1.4, color-name@~1.1.4:
|
|||||||
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
|
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
|
||||||
|
|
||||||
color-string@^1.5.2, color-string@^1.5.3:
|
color-string@^1.5.2, color-string@^1.5.3:
|
||||||
version "1.5.3"
|
version "1.5.5"
|
||||||
resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.5.3.tgz#c9bbc5f01b58b5492f3d6857459cb6590ce204cc"
|
resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.5.5.tgz#65474a8f0e7439625f3d27a6a19d89fc45223014"
|
||||||
integrity sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==
|
integrity sha512-jgIoum0OfQfq9Whcfc2z/VhCNcmQjWbey6qBX0vqt7YICflUmBCh9E9CiQD5GSJ+Uehixm3NUwHVhqUAWRivZg==
|
||||||
dependencies:
|
dependencies:
|
||||||
color-name "^1.0.0"
|
color-name "^1.0.0"
|
||||||
simple-swizzle "^0.2.2"
|
simple-swizzle "^0.2.2"
|
||||||
|
@ -251,7 +251,7 @@ module.exports = Mn.View.extend({
|
|||||||
text: input
|
text: input
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
createFilter: /^(?:[^.]+\.?)+[^.]$/
|
createFilter: /^(?:\*\.)?(?:[^.*]+\.?)+[^.]$/
|
||||||
});
|
});
|
||||||
this.ui.dns_challenge_content.hide();
|
this.ui.dns_challenge_content.hide();
|
||||||
this.ui.credentials_file_content.hide();
|
this.ui.credentials_file_content.hide();
|
||||||
|
@ -278,7 +278,7 @@ module.exports = Mn.View.extend({
|
|||||||
text: input
|
text: input
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
createFilter: /^(?:\.)?(?:[^.*]+\.?)+[^.]$/
|
createFilter: /^(?:\*\.)?(?:[^.*]+\.?)+[^.]$/
|
||||||
});
|
});
|
||||||
|
|
||||||
// Access Lists
|
// Access Lists
|
||||||
|
@ -60,7 +60,7 @@
|
|||||||
},
|
},
|
||||||
"footer": {
|
"footer": {
|
||||||
"fork-me": "Fork me on Github",
|
"fork-me": "Fork me on Github",
|
||||||
"copy": "© 2019 <a href=\"{url}\" target=\"_blank\">jc21.com</a>.",
|
"copy": "© 2021 <a href=\"{url}\" target=\"_blank\">jc21.com</a>.",
|
||||||
"theme": "Theme by <a href=\"{url}\" target=\"_blank\">Tabler</a>"
|
"theme": "Theme by <a href=\"{url}\" target=\"_blank\">Tabler</a>"
|
||||||
},
|
},
|
||||||
"dashboard": {
|
"dashboard": {
|
||||||
|
@ -293,6 +293,16 @@ certbot_dns_ispconfig:dns_ispconfig_endpoint = https://localhost:8080`,
|
|||||||
certbot_dns_isset:dns_isset_token="<token>"`,
|
certbot_dns_isset:dns_isset_token="<token>"`,
|
||||||
full_plugin_name: 'certbot-dns-isset:dns-isset',
|
full_plugin_name: 'certbot-dns-isset:dns-isset',
|
||||||
},
|
},
|
||||||
|
joker: {
|
||||||
|
display_name: 'Joker',
|
||||||
|
package_name: 'certbot-dns-joker',
|
||||||
|
package_version: '1.1.0',
|
||||||
|
dependencies: '',
|
||||||
|
credentials: `certbot_dns_joker:dns_joker_username = <Dynamic DNS Authentication Username>
|
||||||
|
certbot_dns_joker:dns_joker_password = <Dynamic DNS Authentication Password>
|
||||||
|
certbot_dns_joker:dns_joker_domain = <Dynamic DNS Domain>`,
|
||||||
|
full_plugin_name: 'certbot-dns-joker:dns-joker',
|
||||||
|
},
|
||||||
//####################################################//
|
//####################################################//
|
||||||
linode: {
|
linode: {
|
||||||
display_name: 'Linode',
|
display_name: 'Linode',
|
||||||
|
Loading…
Reference in New Issue
Block a user