mirror of
https://github.com/NginxProxyManager/nginx-proxy-manager.git
synced 2025-08-02 15:33:32 +00:00
4
.github/workflows/docker.yml
vendored
4
.github/workflows/docker.yml
vendored
@@ -30,9 +30,9 @@ jobs:
|
||||
run: |
|
||||
sudo npm install --global cross-env
|
||||
sudo pip install certbot
|
||||
sudo mkdir -p /usr/local/nginx/conf/conf.d/include /tmp/letsencrypt-acme-challenge
|
||||
sudo mkdir -p /usr/local/nginx/conf/conf.d/include /data/ssl/certbot /tmp/acme-challenge
|
||||
sudo touch /usr/local/nginx/conf/conf.d/include/ip_ranges.conf
|
||||
sudo cp rootfs/usr/local/nginx/conf/letsencrypt.ini /usr/local/nginx/conf/letsencrypt.ini
|
||||
sudo cp rootfs/etc/ssl/certbot.ini /data/ssl/certbot/config.ini
|
||||
mv global backend
|
||||
cd backend
|
||||
npm install --force
|
||||
|
2
.github/workflows/frontend.yml
vendored
2
.github/workflows/frontend.yml
vendored
@@ -30,6 +30,8 @@ jobs:
|
||||
sed -i "s/0.0.0/$(cat ../global/.version)/g" package.json
|
||||
yarn --no-lockfile install
|
||||
yarn --no-lockfile build
|
||||
mkdir dist/.well-known
|
||||
cp ../security.txt dist/.well-known
|
||||
|
||||
- name: Cache frontend
|
||||
uses: actions/cache/save@v3
|
||||
|
6
.github/workflows/pull-request.yaml
vendored
6
.github/workflows/pull-request.yaml
vendored
@@ -25,9 +25,9 @@ jobs:
|
||||
run: |
|
||||
sudo npm install --global cross-env
|
||||
sudo pip install certbot
|
||||
sudo mkdir -p /usr/local/nginx/conf/conf.d/include /tmp/letsencrypt-acme-challenge
|
||||
sudo mkdir -p /usr/local/nginx/conf/conf.d/include /data/ssl/certbot /tmp/acme-challenge
|
||||
sudo touch /usr/local/nginx/conf/conf.d/include/ip_ranges.conf
|
||||
sudo cp rootfs/usr/local/nginx/conf/letsencrypt.ini /usr/local/nginx/conf/letsencrypt.ini
|
||||
sudo cp rootfs/etc/ssl/certbot.ini /data/ssl/certbot/config.ini
|
||||
mv global backend
|
||||
cd backend
|
||||
npm install --force
|
||||
@@ -57,6 +57,8 @@ jobs:
|
||||
sed -i "s/0.0.0/$(cat ../global/.version)/g" package.json
|
||||
yarn --no-lockfile install
|
||||
yarn --no-lockfile build
|
||||
mkdir dist/.well-known
|
||||
cp ../security.txt dist/.well-known
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
|
10
Dockerfile
10
Dockerfile
@@ -1,4 +1,4 @@
|
||||
FROM zoeyvid/nginx-quic:29
|
||||
FROM zoeyvid/nginx-quic:30
|
||||
COPY rootfs /
|
||||
COPY backend /app
|
||||
COPY global /app/global
|
||||
@@ -21,8 +21,8 @@ RUN echo https://dl-cdn.alpinelinux.org/alpine/edge/testing | tee -a /etc/apk/re
|
||||
wget https://bootstrap.pypa.io/get-pip.py -O - | python3 && \
|
||||
|
||||
# Change permission
|
||||
chmod +x /usr/local/bin/start && \
|
||||
chmod +x /usr/local/bin/check-health && \
|
||||
chmod +x /bin/start.sh && \
|
||||
chmod +x /bin/check-health.sh && \
|
||||
|
||||
# Build Backend
|
||||
sed -i "s/0.0.0/$(cat global/.version)/g" package.json && \
|
||||
@@ -33,5 +33,5 @@ RUN echo https://dl-cdn.alpinelinux.org/alpine/edge/testing | tee -a /etc/apk/re
|
||||
ENV NODE_ENV=production \
|
||||
DB_SQLITE_FILE=/data/database.sqlite
|
||||
|
||||
ENTRYPOINT ["bash", "start"]
|
||||
HEALTHCHECK CMD check-health
|
||||
ENTRYPOINT ["start.sh"]
|
||||
HEALTHCHECK CMD check-health.sh
|
||||
|
22
README.md
22
README.md
@@ -44,7 +44,7 @@ so that the barrier for entry here is low.
|
||||
- Fix Proxy Hosts, if origin only accepts TLSv1.3
|
||||
- Only use TLSv1.2 and TLSv1.3
|
||||
- Uses OCSP Stapling
|
||||
- Needs manual migration if you use custom certificates, just upload the CA/Intermediate Certificate (file name: `chain.pem`) in the `/opt/npm/custom_ssl/npm-[certificate-id]` folder
|
||||
- Needs manual migration if you use custom certificates, just upload the CA/Intermediate Certificate (file name: `chain.pem`) in the `/opt/npm/ssl/custom/npm-[certificate-id]` folder
|
||||
- Smaller then the original
|
||||
- Runs the admin interface on port 81 with ssl (https)
|
||||
- Default page runs also with ssl (https)
|
||||
@@ -53,7 +53,9 @@ so that the barrier for entry here is low.
|
||||
- Easy security headers, see [here](https://github.com/GetPageSpeed/ngx_security_headers), enabled by default if you enable hsts
|
||||
- Access Log disabled
|
||||
- Error Log written to console
|
||||
- PHP included, you can add php extensions, see aviable packages here: https://pkgs.alpinelinux.org/packages?name=php*
|
||||
- PHP included, you can add php extensions, see aviable packages here: https://pkgs.alpinelinux.org/packages?branch=edge&name=php*&arch=x86_64
|
||||
- allows different acme servers
|
||||
- up to 64 domains per cert allowed
|
||||
|
||||
## Soon
|
||||
- more
|
||||
@@ -66,13 +68,17 @@ so that the barrier for entry here is low.
|
||||
3. Maybe set an Access List
|
||||
4. Make your SSL Settings
|
||||
5.
|
||||
a) Custom Nginx Configuration (advanced tab), which looks the following for plain html, the slash at the end of the file path is important:
|
||||
a) Custom Nginx Configuration (advanced tab), which looks the following for file server:
|
||||
- Note: the slash at the end of the file path is important
|
||||
```
|
||||
location / {
|
||||
alias /var/www/<your-html-site-folder-name>/;
|
||||
}
|
||||
```
|
||||
b) Custom Nginx Configuration (advanced tab), which looks the following for plain html & php, the slash at the end of the file path is important:
|
||||
b) Custom Nginx Configuration (advanced tab), which looks the following for file server and **php**:
|
||||
- Note: the slash at the end of the file path is important
|
||||
- Note: you can replace `fastcgi_pass php82;` with `fastcgi_pass` `php7`/`php8`/`php81`/`php82` `;`
|
||||
- Note: to add more php extension use the packes from [here](https://pkgs.alpinelinux.org/packages?branch=edge&name=php\*&arch=x86_64) and add them using the `PHP_APKS` env (see compose file)
|
||||
```
|
||||
location / {
|
||||
alias /var/www/<your-php-site-folder-name>/;
|
||||
@@ -84,6 +90,12 @@ if (!-f $document_root$fastcgi_script_name) {return 404;}
|
||||
}}
|
||||
```
|
||||
|
||||
# custom acme server
|
||||
1. Open this file: `nano` `/opt/npm/ssl/certbot/config.ini`
|
||||
2. uncomment the server line and change it to your acme server
|
||||
3. maybe set eab keys
|
||||
4. create your cert
|
||||
|
||||
# Quick Setup
|
||||
|
||||
1. Install Docker and Docker Compose (or portainer)
|
||||
@@ -109,7 +121,7 @@ services:
|
||||
- "TZ=Europe/Berlin"
|
||||
# - "NGINX_LOG_NOT_FOUND=true" # Allow logging of 404 errors
|
||||
# - "NPM_LISTEN_LOCALHOST=true" # Bind the NPM Dashboard on Port 81 only to localhost
|
||||
# - "PHP_APKS=php7-curl php8-curl php81-curl php-82-curl" # Add php extensions, see aviable packages here: https://pkgs.alpinelinux.org/packages?name=php*
|
||||
# - "PHP_APKS=php7-curl php8-curl php81-curl php-82-curl" # Add php extensions, see aviable packages here: https://pkgs.alpinelinux.org/packages?branch=edge&name=php\*&arch=x86_64
|
||||
```
|
||||
|
||||
3. Bring up your stack by running (or deploy your portainer stack)
|
||||
|
2
backend/config/.gitignore
vendored
2
backend/config/.gitignore
vendored
@@ -1,2 +0,0 @@
|
||||
*
|
||||
!.gitignore
|
1
backend/config/.gitkeep
Normal file
1
backend/config/.gitkeep
Normal file
@@ -0,0 +1 @@
|
||||
|
@@ -467,7 +467,7 @@ const internalAccessList = {
|
||||
* @returns {String}
|
||||
*/
|
||||
getFilename: (list) => {
|
||||
return '/data/access/' + list.id;
|
||||
return '/data/nginx/access/' + list.id;
|
||||
},
|
||||
|
||||
/**
|
||||
|
@@ -11,12 +11,11 @@ const dnsPlugins = require('../global/certbot-dns-plugins');
|
||||
const internalAuditLog = require('./audit-log');
|
||||
const internalNginx = require('./nginx');
|
||||
const internalHost = require('./host');
|
||||
const letsencryptStaging = process.env.NODE_ENV !== 'production';
|
||||
const letsencryptConfig = '/usr/local/nginx/conf/letsencrypt.ini';
|
||||
const certbotCommand = 'certbot --config-dir /data/letsencrypt';
|
||||
const archiver = require('archiver');
|
||||
const path = require('path');
|
||||
const { isArray } = require('lodash');
|
||||
const certbotConfig = '/data/ssl/certbot/config.ini';
|
||||
const certbotCommand = 'certbot --config-dir /data/ssl/certbot';
|
||||
|
||||
function omissions() {
|
||||
return ['is_deleted'];
|
||||
@@ -45,10 +44,9 @@ const internalCertificate = {
|
||||
logger.info('Renewing SSL certs close to expiry...');
|
||||
|
||||
const cmd = certbotCommand + ' renew --non-interactive --quiet ' +
|
||||
'--config "' + letsencryptConfig + '" ' +
|
||||
'--config "' + certbotConfig + '" ' +
|
||||
'--preferred-challenges "dns,http" ' +
|
||||
'--disable-hook-validation ' +
|
||||
(letsencryptStaging ? '--staging' : '');
|
||||
'--disable-hook-validation';
|
||||
|
||||
return utils.exec(cmd)
|
||||
.then((result) => {
|
||||
@@ -63,7 +61,7 @@ const internalCertificate = {
|
||||
});
|
||||
})
|
||||
.then(() => {
|
||||
// Now go and fetch all the letsencrypt certs from the db and query the files and update expiry times
|
||||
// Now go and fetch all the certbot certs from the db and query the files and update expiry times
|
||||
return certificateModel
|
||||
.query()
|
||||
.where('is_deleted', 0)
|
||||
@@ -74,7 +72,7 @@ const internalCertificate = {
|
||||
|
||||
certificates.map(function (certificate) {
|
||||
promises.push(
|
||||
internalCertificate.getCertificateInfoFromFile('/data/letsencrypt/live/npm-' + certificate.id + '/fullchain.pem')
|
||||
internalCertificate.getCertificateInfoFromFile('/data/ssl/certbot/live/npm-' + certificate.id + '/fullchain.pem')
|
||||
.then((cert_info) => {
|
||||
return certificateModel
|
||||
.query()
|
||||
@@ -202,9 +200,9 @@ const internalCertificate = {
|
||||
}
|
||||
})
|
||||
.then(() => {
|
||||
// At this point, the letsencrypt cert should exist on disk.
|
||||
// At this point, the certbot cert should exist on disk.
|
||||
// Lets get the expiry date from the file and update the row silently
|
||||
return internalCertificate.getCertificateInfoFromFile('/data/letsencrypt/live/npm-' + certificate.id + '/fullchain.pem')
|
||||
return internalCertificate.getCertificateInfoFromFile('/data/ssl/certbot/live/npm-' + certificate.id + '/fullchain.pem')
|
||||
.then((cert_info) => {
|
||||
return certificateModel
|
||||
.query()
|
||||
@@ -354,7 +352,7 @@ const internalCertificate = {
|
||||
})
|
||||
.then((certificate) => {
|
||||
if (certificate.provider === 'letsencrypt') {
|
||||
const zipDirectory = '/data/letsencrypt/live/npm-' + data.id;
|
||||
const zipDirectory = '/data/ssl/certbot/live/npm-' + data.id;
|
||||
|
||||
if (!fs.existsSync(zipDirectory)) {
|
||||
throw new error.ItemNotFoundError('Certificate ' + certificate.nice_name + ' does not exists');
|
||||
@@ -523,7 +521,7 @@ const internalCertificate = {
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
if (certificate.provider === 'letsencrypt') {
|
||||
reject(new Error('Refusing to write letsencrypt certs here'));
|
||||
reject(new Error('Refusing to write certbot certs here'));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -844,14 +842,12 @@ const internalCertificate = {
|
||||
logger.info('Requesting Let\'sEncrypt certificates for Cert #' + certificate.id + ': ' + certificate.domain_names.join(', '));
|
||||
|
||||
const cmd = certbotCommand + ' certonly ' +
|
||||
'--config "' + letsencryptConfig + '" ' +
|
||||
'--config "' + certbotConfig + '" ' +
|
||||
'--cert-name "npm-' + certificate.id + '" ' +
|
||||
'--agree-tos ' +
|
||||
'--authenticator webroot ' +
|
||||
'--email "' + certificate.meta.letsencrypt_email + '" ' +
|
||||
'--preferred-challenges "dns,http" ' +
|
||||
'--domains "' + certificate.domain_names.join(',') + '" ' +
|
||||
(letsencryptStaging ? '--staging' : '');
|
||||
'--domains "' + certificate.domain_names.join(',') + '"';
|
||||
|
||||
logger.info('Command:', cmd);
|
||||
|
||||
@@ -878,24 +874,18 @@ const internalCertificate = {
|
||||
|
||||
logger.info(`Requesting Let's Encrypt certificates via ${dns_plugin.display_name} for Cert #${certificate.id}: ${certificate.domain_names.join(', ')}`);
|
||||
|
||||
const credentialsLocation = '/data/letsencrypt/credentials/credentials-' + certificate.id;
|
||||
const credentialsLocation = '/data/ssl/certbot/credentials/credentials-' + certificate.id;
|
||||
// Escape single quotes and backslashes
|
||||
const escapedCredentials = certificate.meta.dns_provider_credentials.replaceAll('\'', '\\\'').replaceAll('\\', '\\\\');
|
||||
const credentialsCmd = 'mkdir -p /data/letsencrypt/credentials 2> /dev/null; echo \'' + escapedCredentials + '\' > \'' + credentialsLocation + '\' && chmod 600 \'' + credentialsLocation + '\'';
|
||||
const credentialsCmd = 'mkdir -p /data/ssl/certbot/credentials 2> /dev/null; echo \'' + escapedCredentials + '\' > \'' + credentialsLocation + '\' && chmod 600 \'' + credentialsLocation + '\'';
|
||||
let prepareCmd = 'pip install ' + dns_plugin.package_name + (dns_plugin.version_requirement || '') + ' ' + dns_plugin.dependencies;
|
||||
|
||||
// Special case for cloudflare
|
||||
if (dns_plugin.package_name === 'certbot-dns-cloudflare') {
|
||||
prepareCmd = 'pip install certbot-dns-cloudflare --index-url https://www.piwheels.org/simple --prefer-binary';
|
||||
}
|
||||
|
||||
// Whether the plugin has a --<name>-credentials argument
|
||||
const hasConfigArg = certificate.meta.dns_provider !== 'route53';
|
||||
|
||||
let mainCmd = certbotCommand + ' certonly ' +
|
||||
'--config "' + letsencryptConfig + '" ' +
|
||||
'--config "' + certbotConfig + '" ' +
|
||||
'--cert-name "npm-' + certificate.id + '" ' +
|
||||
'--agree-tos ' +
|
||||
'--email "' + certificate.meta.letsencrypt_email + '" ' +
|
||||
'--domains "' + certificate.domain_names.join(',') + '" ' +
|
||||
'--authenticator ' + dns_plugin.full_plugin_name + ' ' +
|
||||
@@ -908,8 +898,7 @@ const internalCertificate = {
|
||||
certificate.meta.propagation_seconds !== undefined
|
||||
? ' --' + dns_plugin.full_plugin_name + '-propagation-seconds ' + certificate.meta.propagation_seconds
|
||||
: ''
|
||||
) +
|
||||
(letsencryptStaging ? ' --staging' : '');
|
||||
);
|
||||
|
||||
// Prepend the path to the credentials file as an environment variable
|
||||
if (certificate.meta.dns_provider === 'route53') {
|
||||
@@ -954,7 +943,7 @@ const internalCertificate = {
|
||||
|
||||
return renewMethod(certificate)
|
||||
.then(() => {
|
||||
return internalCertificate.getCertificateInfoFromFile('/data/letsencrypt/live/npm-' + certificate.id + '/fullchain.pem');
|
||||
return internalCertificate.getCertificateInfoFromFile('/data/ssl/certbot/live/npm-' + certificate.id + '/fullchain.pem');
|
||||
})
|
||||
.then((cert_info) => {
|
||||
return certificateModel
|
||||
@@ -989,12 +978,11 @@ const internalCertificate = {
|
||||
logger.info('Renewing Let\'sEncrypt certificates for Cert #' + certificate.id + ': ' + certificate.domain_names.join(', '));
|
||||
|
||||
const cmd = certbotCommand + ' renew --force-renewal ' +
|
||||
'--config "' + letsencryptConfig + '" ' +
|
||||
'--config "' + certbotConfig + '" ' +
|
||||
'--cert-name "npm-' + certificate.id + '" ' +
|
||||
'--preferred-challenges "dns,http" ' +
|
||||
'--no-random-sleep-on-renew ' +
|
||||
'--disable-hook-validation ' +
|
||||
(letsencryptStaging ? '--staging' : '');
|
||||
'--disable-hook-validation ';
|
||||
|
||||
logger.info('Command:', cmd);
|
||||
|
||||
@@ -1019,15 +1007,14 @@ const internalCertificate = {
|
||||
logger.info(`Renewing Let's Encrypt certificates via ${dns_plugin.display_name} for Cert #${certificate.id}: ${certificate.domain_names.join(', ')}`);
|
||||
|
||||
let mainCmd = certbotCommand + ' renew ' +
|
||||
'--config "' + letsencryptConfig + '" ' +
|
||||
'--config "' + certbotConfig + '" ' +
|
||||
'--cert-name "npm-' + certificate.id + '" ' +
|
||||
'--disable-hook-validation ' +
|
||||
'--no-random-sleep-on-renew ' +
|
||||
(letsencryptStaging ? ' --staging' : '');
|
||||
'--no-random-sleep-on-renew';
|
||||
|
||||
// Prepend the path to the credentials file as an environment variable
|
||||
if (certificate.meta.dns_provider === 'route53') {
|
||||
const credentialsLocation = '/data/letsencrypt/credentials/credentials-' + certificate.id;
|
||||
const credentialsLocation = '/data/ssl/certbot/credentials/credentials-' + certificate.id;
|
||||
mainCmd = 'AWS_CONFIG_FILE=\'' + credentialsLocation + '\' ' + mainCmd;
|
||||
}
|
||||
|
||||
@@ -1049,13 +1036,12 @@ const internalCertificate = {
|
||||
logger.info('Revoking Let\'sEncrypt certificates for Cert #' + certificate.id + ': ' + certificate.domain_names.join(', '));
|
||||
|
||||
const mainCmd = certbotCommand + ' revoke ' +
|
||||
'--config "' + letsencryptConfig + '" ' +
|
||||
'--cert-path "/data/letsencrypt/live/npm-' + certificate.id + '/fullchain.pem" ' +
|
||||
'--delete-after-revoke ' +
|
||||
(letsencryptStaging ? '--staging' : '');
|
||||
'--config "' + certbotConfig + '" ' +
|
||||
'--cert-path "/data/ssl/certbot/live/npm-' + certificate.id + '/fullchain.pem" ' +
|
||||
'--delete-after-revoke';
|
||||
|
||||
// Don't fail command if file does not exist
|
||||
const delete_credentialsCmd = `rm -f '/data/letsencrypt/credentials/credentials-${certificate.id}' || true`;
|
||||
const delete_credentialsCmd = `rm -f '/data/ssl/certbot/credentials/credentials-${certificate.id}' || true`;
|
||||
|
||||
logger.info('Command:', mainCmd + '; ' + delete_credentialsCmd);
|
||||
|
||||
@@ -1079,7 +1065,7 @@ const internalCertificate = {
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
hasLetsEncryptSslCerts: (certificate) => {
|
||||
const letsencryptPath = '/data/letsencrypt/live/npm-' + certificate.id;
|
||||
const letsencryptPath = '/data/ssl/certbot/live/npm-' + certificate.id;
|
||||
|
||||
return fs.existsSync(letsencryptPath + '/fullchain.pem') && fs.existsSync(letsencryptPath + '/privkey.pem');
|
||||
},
|
||||
@@ -1155,7 +1141,7 @@ const internalCertificate = {
|
||||
}
|
||||
|
||||
// Create a test challenge file
|
||||
const testChallengeDir = '/tmp/letsencrypt-acme-challenge/.well-known/acme-challenge';
|
||||
const testChallengeDir = '/tmp/acme-challenge/.well-known/acme-challenge';
|
||||
const testChallengeFile = testChallengeDir + '/test-challenge';
|
||||
fs.mkdirSync(testChallengeDir, {recursive: true});
|
||||
fs.writeFileSync(testChallengeFile, 'Success', {encoding: 'utf8'});
|
||||
|
@@ -270,7 +270,7 @@ const internalNginx = {
|
||||
|
||||
/**
|
||||
* This generates a temporary nginx config listening on port 80 for the domain names listed
|
||||
* in the certificate setup. It allows the letsencrypt acme challenge to be requested by letsencrypt
|
||||
* in the certificate setup. It allows the certbot acme challenge to be requested by certbot
|
||||
* when requesting a certificate without having a hostname set up already.
|
||||
*
|
||||
* @param {Object} certificate
|
||||
@@ -278,7 +278,7 @@ const internalNginx = {
|
||||
*/
|
||||
generateLetsEncryptRequestConfig: (certificate) => {
|
||||
if (debug_mode) {
|
||||
logger.info('Generating LetsEncrypt Request Config:', certificate);
|
||||
logger.info('Generating certbot Request Config:', certificate);
|
||||
}
|
||||
|
||||
let renderEngine = new Liquid({
|
||||
@@ -287,10 +287,10 @@ const internalNginx = {
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
let template = null;
|
||||
let filename = '/usr/local/nginx/conf/conf.d/letsencrypt_' + certificate.id + '.conf';
|
||||
let filename = '/usr/local/nginx/conf/conf.d/certbot_' + certificate.id + '.conf';
|
||||
|
||||
try {
|
||||
template = fs.readFileSync(__dirname + '/../templates/letsencrypt-request.conf', {encoding: 'utf8'});
|
||||
template = fs.readFileSync(__dirname + '/../templates/certbot-request.conf', {encoding: 'utf8'});
|
||||
} catch (err) {
|
||||
reject(new error.ConfigurationError(err.message));
|
||||
return;
|
||||
|
@@ -172,7 +172,7 @@
|
||||
"description": "Domain Names separated by a comma",
|
||||
"example": "*.jc21.com,blog.jc21.com",
|
||||
"type": "array",
|
||||
"maxItems": 15,
|
||||
"maxItems": 64,
|
||||
"uniqueItems": true,
|
||||
"items": {
|
||||
"type": "string",
|
||||
|
@@ -169,26 +169,21 @@ const setupCertbotPlugins = () => {
|
||||
.andWhere('provider', 'letsencrypt')
|
||||
.then((certificates) => {
|
||||
if (certificates && certificates.length) {
|
||||
let plugins = [];
|
||||
let promises = [];
|
||||
let install_cloudflare_plugin = false;
|
||||
let plugins = [];
|
||||
let promises = [];
|
||||
|
||||
certificates.map(function (certificate) {
|
||||
if (certificate.meta && certificate.meta.dns_challenge === true) {
|
||||
const dns_plugin = dns_plugins[certificate.meta.dns_provider];
|
||||
const dns_plugin = dns_plugins[certificate.meta.dns_provider];
|
||||
const packages_to_install = `${dns_plugin.package_name}${dns_plugin.version_requirement || ''} ${dns_plugin.dependencies}`;
|
||||
|
||||
if (dns_plugin.package_name === 'certbot-dns-cloudflare') {
|
||||
install_cloudflare_plugin = true;
|
||||
} else {
|
||||
const packages_to_install = `${dns_plugin.package_name}${dns_plugin.version_requirement || ''} ${dns_plugin.dependencies}`;
|
||||
if (plugins.indexOf(packages_to_install) === -1) plugins.push(packages_to_install);
|
||||
}
|
||||
if (plugins.indexOf(packages_to_install) === -1) plugins.push(packages_to_install);
|
||||
|
||||
// Make sure credentials file exists
|
||||
const credentials_loc = '/data/letsencrypt/credentials/credentials-' + certificate.id;
|
||||
const credentials_loc = '/data/ssl/certbot/credentials/credentials-' + certificate.id;
|
||||
// Escape single quotes and backslashes
|
||||
const escapedCredentials = certificate.meta.dns_provider_credentials.replaceAll('\'', '\\\'').replaceAll('\\', '\\\\');
|
||||
const credentials_cmd = '[ -f \'' + credentials_loc + '\' ] || { mkdir -p /data/letsencrypt/credentials 2> /dev/null; echo \'' + escapedCredentials + '\' > \'' + credentials_loc + '\' && chmod 600 \'' + credentials_loc + '\'; }';
|
||||
const credentials_cmd = '[ -f \'' + credentials_loc + '\' ] || { mkdir -p /data/ssl/certbot/credentials 2> /dev/null; echo \'' + escapedCredentials + '\' > \'' + credentials_loc + '\' && chmod 600 \'' + credentials_loc + '\'; }';
|
||||
promises.push(utils.exec(credentials_cmd));
|
||||
}
|
||||
});
|
||||
@@ -198,10 +193,6 @@ const setupCertbotPlugins = () => {
|
||||
promises.push(utils.exec(install_cmd));
|
||||
}
|
||||
|
||||
if (install_cloudflare_plugin) {
|
||||
promises.push(utils.exec('pip install certbot-dns-cloudflare --index-url https://www.piwheels.org/simple --prefer-binary'));
|
||||
}
|
||||
|
||||
if (promises.length) {
|
||||
return Promise.all(promises)
|
||||
.then(() => {
|
||||
|
@@ -2,17 +2,17 @@
|
||||
{% if certificate.provider == "letsencrypt" %}
|
||||
# Let's Encrypt SSL
|
||||
include conf.d/include/ssl-ciphers.conf;
|
||||
ssl_certificate /data/letsencrypt/live/npm-{{ certificate_id }}/fullchain.pem;
|
||||
ssl_certificate_key /data/letsencrypt/live/npm-{{ certificate_id }}/privkey.pem;
|
||||
ssl_trusted_certificate /data/letsencrypt/live/npm-{{ certificate_id }}/chain.pem;
|
||||
ssl_certificate /data/ssl/certbot/live/npm-{{ certificate_id }}/fullchain.pem;
|
||||
ssl_certificate_key /data/ssl/certbot/live/npm-{{ certificate_id }}/privkey.pem;
|
||||
ssl_trusted_certificate /data/ssl/certbot/live/npm-{{ certificate_id }}/chain.pem;
|
||||
ssl_stapling on;
|
||||
ssl_stapling_verify on;
|
||||
{% else %}
|
||||
# Custom SSL
|
||||
include conf.d/include/ssl-ciphers.conf;
|
||||
ssl_certificate /data/custom_ssl/npm-{{ certificate_id }}/fullchain.pem;
|
||||
ssl_certificate_key /data/custom_ssl/npm-{{ certificate_id }}/privkey.pem;
|
||||
ssl_trusted_certificate /data/custom_ssl/npm-{{ certificate_id }}/chain.pem;
|
||||
ssl_certificate /data/ssl/custom/npm-{{ certificate_id }}/fullchain.pem;
|
||||
ssl_certificate_key /data/ssl/custom/npm-{{ certificate_id }}/privkey.pem;
|
||||
ssl_trusted_certificate /data/ssl/custom/npm-{{ certificate_id }}/chain.pem;
|
||||
ssl_stapling on;
|
||||
ssl_stapling_verify on;
|
||||
{% endif %}
|
||||
|
@@ -6,11 +6,11 @@ server {
|
||||
|
||||
server_name {{ domain_names | join: " " }};
|
||||
|
||||
include conf.d/include/letsencrypt-acme-challenge.conf;
|
||||
include conf.d/include/acme-challenge.conf;
|
||||
include conf.d/include/block-exploits.conf;
|
||||
|
||||
location / {
|
||||
include conf.d/include/letsencrypt-acme-challenge.conf;
|
||||
include conf.d/include/acme-challenge.conf;
|
||||
return 404;
|
||||
}
|
||||
}
|
@@ -8,13 +8,17 @@ server {
|
||||
{% include "_forced_ssl.conf" %}
|
||||
|
||||
{{ advanced_config }}
|
||||
include conf.d/include/letsencrypt-acme-challenge.conf;
|
||||
include conf.d/include/acme-challenge.conf;
|
||||
include conf.d/include/block-exploits.conf;
|
||||
{% if use_default_location %}
|
||||
location / {
|
||||
alias /html/404/;
|
||||
include conf.d/include/acme-challenge.conf;
|
||||
}
|
||||
{% endif %}
|
||||
|
||||
# Custom
|
||||
include /data/nginx/custom/server_dead.conf;
|
||||
|
||||
}
|
||||
{% endif %}
|
||||
|
@@ -15,7 +15,7 @@ server {
|
||||
|
||||
include conf.d/include/force-ssl.conf;
|
||||
include conf.d/include/ssl-ciphers.conf;
|
||||
include conf.d/include/letsencrypt-acme-challenge.conf;
|
||||
include conf.d/include/acme-challenge.conf;
|
||||
include conf.d/include/block-exploits.conf;
|
||||
add_header alt-svc 'h3=":443"; ma=86400, h3-29=":443"; ma=86400';
|
||||
|
||||
@@ -30,21 +30,21 @@ server {
|
||||
|
||||
{%- if value == "redirect" %}
|
||||
location / {
|
||||
include conf.d/include/letsencrypt-acme-challenge.conf;
|
||||
include conf.d/include/acme-challenge.conf;
|
||||
return 307 {{ meta.redirect }};
|
||||
}
|
||||
{%- endif %}
|
||||
|
||||
{%- if value == "congratulations" %}
|
||||
location / {
|
||||
include conf.d/include/letsencrypt-acme-challenge.conf;
|
||||
include conf.d/include/acme-challenge.conf;
|
||||
alias /html/default/;
|
||||
}
|
||||
{%- endif %}
|
||||
|
||||
{%- if value == "html" %}
|
||||
location / {
|
||||
include conf.d/include/letsencrypt-acme-challenge.conf;
|
||||
include conf.d/include/acme-challenge.conf;
|
||||
alias /data/nginx/html/;
|
||||
}
|
||||
{%- endif %}
|
||||
|
@@ -11,14 +11,14 @@ server {
|
||||
{% include "_hsts.conf" %}
|
||||
{% include "_forced_ssl.conf" %}
|
||||
|
||||
include conf.d/include/letsencrypt-acme-challenge.conf;
|
||||
include conf.d/include/acme-challenge.conf;
|
||||
include conf.d/include/block-exploits.conf;
|
||||
|
||||
{{ advanced_config }}
|
||||
|
||||
{% if use_default_location %}
|
||||
location / {
|
||||
include conf.d/include/letsencrypt-acme-challenge.conf;
|
||||
include conf.d/include/acme-challenge.conf;
|
||||
|
||||
{% if access_list_id > 0 %}
|
||||
{% if access_list.items.length > 0 %}
|
||||
@@ -40,7 +40,7 @@ server {
|
||||
{% if access_list.items.length > 0 %}
|
||||
# Authorization
|
||||
auth_basic "Authorization required";
|
||||
auth_basic_user_file /data/access/{{ access_list_id }};
|
||||
auth_basic_user_file /data/nginx/access/{{ access_list_id }};
|
||||
|
||||
{{ access_list.passauth }}
|
||||
{% endif %}
|
||||
|
@@ -8,11 +8,11 @@ server {
|
||||
{% include "_forced_ssl.conf" %}
|
||||
|
||||
{{ advanced_config }}
|
||||
include conf.d/include/letsencrypt-acme-challenge.conf;
|
||||
include conf.d/include/acme-challenge.conf;
|
||||
include conf.d/include/block-exploits.conf;
|
||||
{% if use_default_location %}
|
||||
location / {
|
||||
include conf.d/include/letsencrypt-acme-challenge.conf;
|
||||
include conf.d/include/acme-challenge.conf;
|
||||
{% if preserve_path == 1 or preserve_path == true %}
|
||||
return {{ forward_http_code }} {{ forward_scheme }}://{{ forward_domain_name }}$request_uri;
|
||||
{% else %}
|
||||
|
@@ -13,4 +13,4 @@ services:
|
||||
- "TZ=Europe/Berlin"
|
||||
# - "NGINX_LOG_NOT_FOUND=true" # Allow logging of 404 errors
|
||||
# - "NPM_LISTEN_LOCALHOST=true" # Bind the NPM Dashboard on Port 81 only to localhost
|
||||
# - "PHP_APKS=php7-curl php8-curl php81-curl php-82-curl" # Add php extensions, see aviable packages here: https://pkgs.alpinelinux.org/packages?name=php*
|
||||
# - "PHP_APKS=php7-curl php8-curl php81-curl php-82-curl" # Add php extensions, see aviable packages here: https://pkgs.alpinelinux.org/packages?branch=edge&name=php\*&arch=x86_64
|
||||
|
@@ -268,7 +268,7 @@ module.exports = Mn.View.extend({
|
||||
this.ui.domain_names.selectize({
|
||||
delimiter: ',',
|
||||
persist: false,
|
||||
maxOptions: 15,
|
||||
maxOptions: 64,
|
||||
create: function (input) {
|
||||
return {
|
||||
value: input,
|
||||
|
@@ -233,7 +233,7 @@ module.exports = Mn.View.extend({
|
||||
this.ui.domain_names.selectize({
|
||||
delimiter: ',',
|
||||
persist: false,
|
||||
maxOptions: 15,
|
||||
maxOptions: 64,
|
||||
create: function (input) {
|
||||
return {
|
||||
value: input,
|
||||
|
@@ -271,7 +271,7 @@ module.exports = Mn.View.extend({
|
||||
this.ui.domain_names.selectize({
|
||||
delimiter: ',',
|
||||
persist: false,
|
||||
maxOptions: 15,
|
||||
maxOptions: 64,
|
||||
create: function (input) {
|
||||
return {
|
||||
value: input,
|
||||
|
@@ -235,7 +235,7 @@ module.exports = Mn.View.extend({
|
||||
this.ui.domain_names.selectize({
|
||||
delimiter: ',',
|
||||
persist: false,
|
||||
maxOptions: 15,
|
||||
maxOptions: 64,
|
||||
create: function (input) {
|
||||
return {
|
||||
value: input,
|
||||
|
@@ -79,7 +79,7 @@
|
||||
"ssl-certificate": "SSL Certificate",
|
||||
"none": "None",
|
||||
"new-cert": "Request a new SSL Certificate",
|
||||
"with-le": "with Let's Encrypt",
|
||||
"with-le": "with Certbot",
|
||||
"no-ssl": "This host will not use HTTPS",
|
||||
"advanced": "Advanced",
|
||||
"advanced-warning": "Enter your custom Nginx configuration here at your own risk!",
|
||||
@@ -97,14 +97,14 @@
|
||||
"delete": "Delete"
|
||||
},
|
||||
"ssl": {
|
||||
"letsencrypt": "Let's Encrypt",
|
||||
"letsencrypt": "Certbot",
|
||||
"other": "Custom",
|
||||
"none": "HTTP only",
|
||||
"letsencrypt-email": "Email Address for Let's Encrypt",
|
||||
"letsencrypt-agree": "I Agree to the <a href=\"{url}\" target=\"_blank\">Let's Encrypt Terms of Service</a>",
|
||||
"letsencrypt-email": "Email Address for Certbot",
|
||||
"letsencrypt-agree": "I Agree to the <a href=\"{url}\" target=\"_blank\">Let's Encrypt Terms of Service</a> / ToS of custom set CA",
|
||||
"delete-ssl": "The SSL certificates attached will NOT be removed, they will need to be removed manually.",
|
||||
"hosts-warning": "These domains must be already configured to point to this installation",
|
||||
"no-wildcard-without-dns": "Cannot request Let's Encrypt Certificate for wildcard domains when not using DNS challenge",
|
||||
"no-wildcard-without-dns": "Cannot request Certificate for wildcard domains when not using DNS challenge",
|
||||
"dns-challenge": "Use a DNS Challenge",
|
||||
"certbot-warning": "This section requires some knowledge about Certbot and its DNS plugins. Please consult the respective plugins documentation.",
|
||||
"dns-provider": "DNS Provider",
|
||||
@@ -185,11 +185,11 @@
|
||||
"title": "SSL Certificates",
|
||||
"empty": "There are no SSL Certificates",
|
||||
"add": "Add SSL Certificate",
|
||||
"form-title": "Add {provider, select, letsencrypt{Let's Encrypt} other{Custom}} Certificate",
|
||||
"form-title": "Add {provider, select, letsencrypt{Certbot} other{Custom}} Certificate",
|
||||
"delete": "Delete SSL Certificate",
|
||||
"delete-confirm": "Are you sure you want to delete this SSL Certificate? Any hosts using it will need to be updated later.",
|
||||
"help-title": "SSL Certificates",
|
||||
"help-content": "SSL certificates (correctly known as TLS Certificates) are a form of encryption key which allows your site to be encrypted for the end user.\nNPM uses a service called Let's Encrypt to issue SSL certificates for free.\nIf you have any sort of personal information, passwords, or sensitive data behind NPM, it's probably a good idea to use a certificate.\nNPM also supports DNS authentication for if you're not running your site facing the internet, or if you just want a wildcard certificate.",
|
||||
"help-content": "SSL certificates (correctly known as TLS Certificates) are a form of encryption key which allows your site to be encrypted for the end user.\nNPM uses by default a service called Let's Encrypt to issue SSL certificates for free.\nIf you have any sort of personal information, passwords, or sensitive data behind NPM, it's probably a good idea to use a certificate.\nNPM also supports DNS authentication for if you're not running your site facing the internet, or if you just want a wildcard certificate.",
|
||||
"other-certificate": "Certificate",
|
||||
"other-certificate-key": "Certificate Key",
|
||||
"other-intermediate-certificate": "Intermediate Certificate",
|
||||
@@ -205,7 +205,7 @@
|
||||
"reachability-wrong-data": "There is a server found at this domain but it returned an unexpected data. Is it the NPM server? Please make sure your domain points to the IP where your NPM instance is running.",
|
||||
"reachability-other": "There is a server found at this domain but it returned an unexpected status code {code}. Is it the NPM server? Please make sure your domain points to the IP where your NPM instance is running.",
|
||||
"download": "Download",
|
||||
"renew-title": "Renew Let's Encrypt Certificate",
|
||||
"renew-title": "Renew Certificate",
|
||||
"search": "Search Certificate…"
|
||||
},
|
||||
"access-lists": {
|
||||
|
@@ -511,7 +511,7 @@ aws_secret_access_key=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY`,
|
||||
version_requirement: '~=0.4.3',
|
||||
dependencies: '',
|
||||
credentials: `dns_transip_username = my_username
|
||||
dns_transip_key_file = /data/letsencrypt/transip-rsa.key`,
|
||||
dns_transip_key_file = /data/ssl/certbot/transip-rsa.key`,
|
||||
full_plugin_name: 'dns-transip',
|
||||
},
|
||||
//####################################################//
|
||||
|
9
rootfs/bin/check-health.sh
Normal file
9
rootfs/bin/check-health.sh
Normal file
@@ -0,0 +1,9 @@
|
||||
#!/bin/bash
|
||||
|
||||
if (cgi-fcgi -bind -connect /dev/php7.sock &> /dev/null && cgi-fcgi -bind -connect /dev/php8.sock &> /dev/null && cgi-fcgi -bind -connect /dev/php81.sock &> /dev/null && cgi-fcgi -bind -connect /dev/php82.sock &> /dev/null && [ "$(wget -q --no-check-certificate https://127.0.0.1:81/api -O - | jq --raw-output '.status')" == "OK" ]); then
|
||||
echo "OK"
|
||||
exit 0
|
||||
else
|
||||
echo "NOT OK"
|
||||
exit 1
|
||||
fi
|
@@ -1,4 +1,4 @@
|
||||
#!/bin/sh
|
||||
#!/bin/bash
|
||||
|
||||
# From https://github.com/nextcloud/all-in-one/pull/1377/files
|
||||
if [ -n "$PHP_APKS" ]; then
|
||||
@@ -21,23 +21,23 @@ if [ -n "$PHP_APKS" ]; then
|
||||
fi
|
||||
|
||||
echo "Installing $apk via apk..."
|
||||
if ! apk add --no-cache "$apk" >/dev/null; then
|
||||
if ! apk add --no-cache "$apk" &> /dev/null; then
|
||||
echo "The packet $apk was not installed!"
|
||||
fi
|
||||
|
||||
done
|
||||
fi
|
||||
|
||||
mkdir -p /tmp/letsencrypt-acme-challenge \
|
||||
/data/letsencrypt \
|
||||
/data/custom_ssl \
|
||||
/data/access \
|
||||
mkdir -p /tmp/acme-challenge \
|
||||
/data/ssl/certbot \
|
||||
/data/ssl/custom \
|
||||
/data/php \
|
||||
/data/nginx/redirection_host \
|
||||
/data/nginx/proxy_host \
|
||||
/data/nginx/dead_host \
|
||||
/data/nginx/stream \
|
||||
/data/nginx/custom \
|
||||
/data/nginx/access \
|
||||
/data/nginx/html || exit 1
|
||||
|
||||
if [ -f /data/nginx/default_host/site.conf ]; then
|
||||
@@ -48,21 +48,46 @@ if [ -f /data/nginx/default_www/index.html ]; then
|
||||
mv /data/nginx/default_www/index.html /data/nginx/html/index.html || exit 1
|
||||
fi
|
||||
|
||||
if [ -e /data/access ]; then
|
||||
mv /data/access/* /data/nginx/access || exit 1
|
||||
fi
|
||||
|
||||
if [ -e /etc/letsencrypt/live ]; then
|
||||
mv /etc/letsencrypt/* /data/ssl/certbot || exit 1
|
||||
fi
|
||||
|
||||
if [ -e /data/letsencrypt/live ]; then
|
||||
mv /data/letsencrypt/* /data/ssl/certbot || exit 1
|
||||
fi
|
||||
|
||||
if [ -e /data/custom_ssl/npm-* ]; then
|
||||
mv /data/custom_ssl/* /data/ssl/custom || exit 1
|
||||
fi
|
||||
|
||||
rm -rf /data/letsencrypt-acme-challenge \
|
||||
/data/nginx/default_host \
|
||||
/data/nginx/default_www \
|
||||
/data/nginx/streams \
|
||||
/data/nginx/temp \
|
||||
/data/index.html \
|
||||
/data/letsencrypt \
|
||||
/data/custom_ssl \
|
||||
/data/certbot \
|
||||
/data/access \
|
||||
/data/logs \
|
||||
/data/error.log \
|
||||
/data/nginx/error.log || exit 1
|
||||
|
||||
if [ -e /etc/letsencrypt/live ]; then
|
||||
mv /etc/letsencrypt/* /data/letsencrypt || exit 1
|
||||
fi
|
||||
find /data/nginx -type f -name '*.conf' -exec sed -i "s|/data/access|/data/nginx/access|g" {} \; || exit 1
|
||||
|
||||
find /data/nginx -type f -name '*.conf' -exec sed -i "s|/etc/letsencrypt|/data/letsencrypt|g" {} \; || exit 1
|
||||
find /data/letsencrypt -type f -name '*.conf' -exec sed -i "s|/etc/letsencrypt|/data/letsencrypt|g" {} \; || exit 1
|
||||
find /data/nginx -type f -name '*.conf' -exec sed -i "s|/data/custom_ssl|/data/ssl/custom|g" {} \; || exit 1
|
||||
find /data/nginx -type f -name '*.conf' -exec sed -i "s|/etc/letsencrypt|/data/ssl/certbot|g" {} \; || exit 1
|
||||
find /data/nginx -type f -name '*.conf' -exec sed -i "s|/data/letsencrypt|/data/ssl/certbot|g" {} \; || exit 1
|
||||
|
||||
find /data/ssl/certbot/renewal -type f -name '*.conf' -exec sed -i "s|/etc/letsencrypt|/data/ssl/certbot|g" {} \; || exit 1
|
||||
find /data/ssl/certbot/renewal -type f -name '*.conf' -exec sed -i "s|/data/letsencrypt|/data/ssl/certbot|g" {} \; || exit 1
|
||||
|
||||
find /data/nginx -type f -name '*.conf' -exec sed -i "s|include conf.d/include/letsencrypt-acme-challenge.conf;|include conf.d/include/acme-challenge.conf;|g" {} \; || exit 1
|
||||
|
||||
find /data/nginx -type f -name '*.conf' -exec sed -i "s|include conf.d/include/assets.conf;||g" {} \; || exit 1
|
||||
find /data/nginx -type f -name '*.conf' -exec sed -i "s/# Asset Caching//g" {} \; || exit 1
|
||||
@@ -78,12 +103,17 @@ if [ ! -f /data/nginx/default.conf ]; then
|
||||
cp /usr/local/nginx/conf/conf.d/include/default.conf /data/nginx/default.conf || exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f /data/ssl/certbot/config.ini ]; then
|
||||
cp /etc/ssl/certbot.ini /data/ssl/certbot/config.ini || exit 1
|
||||
fi
|
||||
|
||||
touch /data/nginx/default.conf \
|
||||
/data/nginx/html/index.html \
|
||||
/data/nginx/custom/root.conf \
|
||||
/data/nginx/custom/events.conf \
|
||||
/data/nginx/custom/http.conf \
|
||||
/data/nginx/custom/http_top.conf \
|
||||
/data/nginx/custom/server_dead.conf \
|
||||
/data/nginx/custom/server_proxy.conf \
|
||||
/data/nginx/custom/server_redirect.conf \
|
||||
/data/nginx/custom/stream.conf \
|
||||
@@ -107,32 +137,32 @@ if [ "$NGINX_LOG_NOT_FOUND" == "true" ]; then
|
||||
sed -i "s/log_not_found off;/log_not_found on;/g" /usr/local/nginx/conf/nginx.conf || exit 1
|
||||
fi
|
||||
|
||||
if ! nginx -t 2> /dev/null; then
|
||||
if ! nginx -t &> /dev/null; then
|
||||
nginx -T || exit 1
|
||||
sleep inf || exit 1
|
||||
fi
|
||||
|
||||
if ! cross-env PHP_INI_SCAN_DIR=/data/php/7/conf.d php-fpm7 -c /data/php/7 -y /data/php/7/php-fpm.conf -FORt 2> /dev/null; then
|
||||
if ! cross-env PHP_INI_SCAN_DIR=/data/php/7/conf.d php-fpm7 -c /data/php/7 -y /data/php/7/php-fpm.conf -FORt &> /dev/null; then
|
||||
cross-env PHP_INI_SCAN_DIR=/data/php/7/conf.d php-fpm7 -c /data/php/7 -y /data/php/7/php-fpm.conf -FORt || exit 1
|
||||
sleep inf || exit 1
|
||||
fi
|
||||
|
||||
if ! cross-env PHP_INI_SCAN_DIR=/data/php/8/conf.d php-fpm8 -c /data/php/8 -y /data/php/8/php-fpm.conf -FORt 2> /dev/null; then
|
||||
if ! cross-env PHP_INI_SCAN_DIR=/data/php/8/conf.d php-fpm8 -c /data/php/8 -y /data/php/8/php-fpm.conf -FORt &> /dev/null; then
|
||||
cross-env PHP_INI_SCAN_DIR=/data/php/8/conf.d php-fpm8 -c /data/php/8 -y /data/php/8/php-fpm.conf -FORt || exit 1
|
||||
sleep inf || exit 1
|
||||
fi
|
||||
|
||||
if ! cross-env PHP_INI_SCAN_DIR=/data/php/81/conf.d php-fpm81 -c /data/php/81 -y /data/php/81/php-fpm.conf -FORt 2> /dev/null; then
|
||||
if ! cross-env PHP_INI_SCAN_DIR=/data/php/81/conf.d php-fpm81 -c /data/php/81 -y /data/php/81/php-fpm.conf -FORt &> /dev/null; then
|
||||
cross-env PHP_INI_SCAN_DIR=/data/php/81/conf.d php-fpm81 -c /data/php/81 -y /data/php/81/php-fpm.conf -FORt || exit 1
|
||||
sleep inf || exit 1
|
||||
fi
|
||||
|
||||
if ! cross-env PHP_INI_SCAN_DIR=/data/php/82/conf.d php-fpm82 -c /data/php/82 -y /data/php/82/php-fpm.conf -FORt 2> /dev/null; then
|
||||
if ! cross-env PHP_INI_SCAN_DIR=/data/php/82/conf.d php-fpm82 -c /data/php/82 -y /data/php/82/php-fpm.conf -FORt &> /dev/null; then
|
||||
cross-env PHP_INI_SCAN_DIR=/data/php/82/conf.d php-fpm82 -c /data/php/82 -y /data/php/82/php-fpm.conf -FORt || exit 1
|
||||
sleep inf || exit 1
|
||||
fi
|
||||
|
||||
while (nginx -t 2> /dev/null && cross-env PHP_INI_SCAN_DIR=/data/php/7/conf.d php-fpm7 -c /data/php/7 -y /data/php/7/php-fpm.conf -FORt 2> /dev/null && cross-env PHP_INI_SCAN_DIR=/data/php/8/conf.d php-fpm8 -c /data/php/8 -y /data/php/8/php-fpm.conf -FORt 2> /dev/null && cross-env PHP_INI_SCAN_DIR=/data/php/81/conf.d php-fpm81 -c /data/php/81 -y /data/php/81/php-fpm.conf -FORt 2> /dev/null && cross-env PHP_INI_SCAN_DIR=/data/php/82/conf.d php-fpm82 -c /data/php/82 -y /data/php/82/php-fpm.conf -FORt 2> /dev/null); do
|
||||
while (nginx -t &> /dev/null && cross-env PHP_INI_SCAN_DIR=/data/php/7/conf.d php-fpm7 -c /data/php/7 -y /data/php/7/php-fpm.conf -FORt &> /dev/null && cross-env PHP_INI_SCAN_DIR=/data/php/8/conf.d php-fpm8 -c /data/php/8 -y /data/php/8/php-fpm.conf -FORt &> /dev/null && cross-env PHP_INI_SCAN_DIR=/data/php/81/conf.d php-fpm81 -c /data/php/81 -y /data/php/81/php-fpm.conf -FORt &> /dev/null && cross-env PHP_INI_SCAN_DIR=/data/php/82/conf.d php-fpm82 -c /data/php/82 -y /data/php/82/php-fpm.conf -FORt &> /dev/null); do
|
||||
nginx || exit 1 &
|
||||
cross-env PHP_INI_SCAN_DIR=/data/php/7/conf.d php-fpm7 -c /data/php/7 -y /data/php/7/php-fpm.conf -FOR || exit 1 &
|
||||
cross-env PHP_INI_SCAN_DIR=/data/php/8/conf.d php-fpm8 -c /data/php/8 -y /data/php/8/php-fpm.conf -FOR || exit 1 &
|
||||
@@ -142,27 +172,27 @@ node --abort_on_uncaught_exception --max_old_space_size=250 index.js || exit 1 &
|
||||
wait
|
||||
done
|
||||
|
||||
if ! nginx -t 2> /dev/null; then
|
||||
if ! nginx -t &> /dev/null; then
|
||||
nginx -T || exit 1
|
||||
sleep inf || exit 1
|
||||
fi
|
||||
|
||||
if ! cross-env PHP_INI_SCAN_DIR=/data/php/7/conf.d php-fpm7 -c /data/php/7 -y /data/php/7/php-fpm.conf -FORt 2> /dev/null; then
|
||||
if ! cross-env PHP_INI_SCAN_DIR=/data/php/7/conf.d php-fpm7 -c /data/php/7 -y /data/php/7/php-fpm.conf -FORt &> /dev/null; then
|
||||
cross-env PHP_INI_SCAN_DIR=/data/php/7/conf.d php-fpm7 -c /data/php/7 -y /data/php/7/php-fpm.conf -FORt || exit 1
|
||||
sleep inf || exit 1
|
||||
fi
|
||||
|
||||
if ! cross-env PHP_INI_SCAN_DIR=/data/php/8/conf.d php-fpm8 -c /data/php/8 -y /data/php/8/php-fpm.conf -FORt 2> /dev/null; then
|
||||
if ! cross-env PHP_INI_SCAN_DIR=/data/php/8/conf.d php-fpm8 -c /data/php/8 -y /data/php/8/php-fpm.conf -FORt &> /dev/null; then
|
||||
cross-env PHP_INI_SCAN_DIR=/data/php/8/conf.d php-fpm8 -c /data/php/8 -y /data/php/8/php-fpm.conf -FORt || exit 1
|
||||
sleep inf || exit 1
|
||||
fi
|
||||
|
||||
if ! cross-env PHP_INI_SCAN_DIR=/data/php/81/conf.d php-fpm81 -c /data/php/81 -y /data/php/81/php-fpm.conf -FORt 2> /dev/null; then
|
||||
if ! cross-env PHP_INI_SCAN_DIR=/data/php/81/conf.d php-fpm81 -c /data/php/81 -y /data/php/81/php-fpm.conf -FORt &> /dev/null; then
|
||||
cross-env PHP_INI_SCAN_DIR=/data/php/81/conf.d php-fpm81 -c /data/php/81 -y /data/php/81/php-fpm.conf -FORt || exit 1
|
||||
sleep inf || exit 1
|
||||
fi
|
||||
|
||||
if ! cross-env PHP_INI_SCAN_DIR=/data/php/82/conf.d php-fpm82 -c /data/php/82 -y /data/php/82/php-fpm.conf -FORt 2> /dev/null; then
|
||||
if ! cross-env PHP_INI_SCAN_DIR=/data/php/82/conf.d php-fpm82 -c /data/php/82 -y /data/php/82/php-fpm.conf -FORt &> /dev/null; then
|
||||
cross-env PHP_INI_SCAN_DIR=/data/php/82/conf.d php-fpm82 -c /data/php/82 -y /data/php/82/php-fpm.conf -FORt || exit 1
|
||||
sleep inf || exit 1
|
||||
fi
|
13
rootfs/etc/ssl/certbot.ini
Normal file
13
rootfs/etc/ssl/certbot.ini
Normal file
@@ -0,0 +1,13 @@
|
||||
text = true
|
||||
agree-tos = true
|
||||
non-interactive = true
|
||||
key-type = ecdsa
|
||||
must-staple = true
|
||||
rsa-key-size = 4096
|
||||
elliptic-curve = secp384r1
|
||||
webroot-path = /tmp/acme-challenge
|
||||
|
||||
# An example of using an alternate ACME server that uses EAB credentials
|
||||
# server = https://dv.acme-v02.api.pki.goog/directory
|
||||
# eab-kid = somestringofstuffwithoutquotes
|
||||
# eab-hmac-key = yaddayaddahexhexnotquoted
|
@@ -1,96 +0,0 @@
|
||||
DH Parameters: (8192 bit)
|
||||
prime:
|
||||
00:ea:c9:82:7f:46:79:c5:05:5f:8e:70:c6:a7:2b:
|
||||
b2:66:57:1b:99:cd:9a:50:f2:96:57:c2:fb:fd:c7:
|
||||
40:e4:7c:43:52:bc:ec:4c:88:0f:1a:80:d9:b6:be:
|
||||
9c:30:e0:f2:15:f0:37:66:b8:29:70:fa:58:b4:06:
|
||||
2b:eb:c5:a5:04:b4:a3:55:de:da:74:68:68:29:fe:
|
||||
a0:69:c0:f6:c3:61:79:f5:64:59:c3:5a:77:7c:b8:
|
||||
83:c1:db:96:d7:fb:59:20:84:0e:49:ad:40:f0:bd:
|
||||
b7:21:1f:a9:bf:6e:38:88:24:27:83:cb:42:f2:1f:
|
||||
2e:37:d3:15:a9:b4:01:ab:19:1d:fe:a0:0b:36:80:
|
||||
40:49:c2:7b:06:de:fb:5e:48:c0:92:74:8b:cf:a1:
|
||||
0a:ff:f5:d9:f5:c6:57:2e:37:cc:8f:e2:45:f7:ec:
|
||||
f2:e1:52:ef:c6:fb:75:33:ae:3b:b8:aa:20:84:80:
|
||||
b5:10:ff:ae:db:ca:31:85:e4:ab:60:da:53:50:0b:
|
||||
7e:5d:66:83:b8:e8:e2:98:3c:b2:4a:bf:05:52:e9:
|
||||
d3:9b:a0:4b:b7:da:52:70:2e:92:38:97:65:0d:78:
|
||||
58:77:93:e3:c2:f6:ea:da:86:cc:df:4a:19:14:db:
|
||||
8f:8d:48:cf:5b:29:fa:b8:51:66:9d:6f:83:65:8f:
|
||||
59:70:fb:aa:c8:8d:98:6b:d8:9f:5b:ee:48:b5:f1:
|
||||
ef:c3:a4:85:cc:c8:15:fe:ed:4c:aa:bf:49:66:70:
|
||||
5a:21:6a:b8:af:cb:ad:6c:3d:59:33:10:18:a8:04:
|
||||
6b:f0:6b:39:1d:ec:46:34:1b:eb:24:2a:84:2b:06:
|
||||
7d:73:90:22:ef:06:1a:c2:10:bd:99:11:4b:67:a3:
|
||||
7b:86:6a:05:3a:cc:64:00:e6:6a:f5:b1:24:b6:79:
|
||||
0f:d4:ba:36:1b:80:eb:f4:23:a8:1d:8e:93:87:eb:
|
||||
d5:f4:43:e2:aa:ce:ad:7c:53:c6:e7:8e:92:9d:11:
|
||||
fe:18:53:c3:dc:24:77:77:8d:04:01:d8:14:5b:1c:
|
||||
aa:de:46:cb:5e:cd:b5:bd:41:6d:59:fa:9e:5a:8a:
|
||||
b8:25:76:63:ac:97:21:75:e8:ed:3c:d5:e2:bf:d1:
|
||||
79:b9:52:b5:fd:56:bd:91:8a:ea:61:69:f9:e2:80:
|
||||
ca:cd:4a:04:c0:e0:5d:26:96:49:73:67:90:5d:14:
|
||||
b2:c3:c8:80:68:7f:95:38:f8:da:fe:50:cc:ea:ef:
|
||||
c8:eb:a6:ae:51:92:50:73:c3:c2:44:09:f7:d5:a1:
|
||||
6a:da:03:33:ef:b5:ed:ac:89:a7:02:a1:f8:a4:37:
|
||||
eb:db:e9:6a:2a:39:5e:48:23:23:12:3c:80:60:f9:
|
||||
36:1a:c3:20:ff:e3:e5:67:ca:54:16:d7:44:c4:f3:
|
||||
75:f3:9b:37:19:4e:a5:07:a5:49:53:d3:17:6d:4a:
|
||||
b2:e5:34:88:e2:f4:b0:36:5a:4b:05:70:ef:de:c5:
|
||||
a0:a0:83:3d:72:a4:e0:13:27:0b:fe:29:95:5b:42:
|
||||
56:84:c1:3c:d7:09:80:ea:f8:33:2d:f1:42:20:b6:
|
||||
ca:8b:68:71:af:2c:24:e9:c6:b9:e0:f4:ca:8f:78:
|
||||
c1:ff:7c:d4:62:d1:e3:b3:65:aa:41:68:7f:18:9f:
|
||||
c1:90:a8:e4:8c:82:07:a8:72:81:f6:98:12:ea:bd:
|
||||
29:9e:54:94:fa:9e:f0:2f:e2:d5:47:88:4d:47:ee:
|
||||
ec:b9:16:ba:29:47:11:d9:c5:3c:0f:4c:87:93:2c:
|
||||
e4:93:df:70:71:17:df:01:7b:e2:84:d0:26:56:47:
|
||||
7e:03:a3:18:89:66:d6:a5:65:2c:ea:64:ff:6a:b9:
|
||||
8f:c4:18:2d:b3:68:2a:0e:74:b5:f5:9a:0b:cc:4e:
|
||||
20:ee:46:69:06:2e:a9:58:a0:48:b9:0c:71:2e:b7:
|
||||
3a:84:11:d0:6e:e0:1d:a7:56:4e:35:7c:da:88:72:
|
||||
4a:8e:7f:af:fd:4b:68:0b:08:dd:90:b0:a1:9c:e1:
|
||||
0a:7a:b9:38:1a:08:46:07:f7:83:70:ad:95:58:77:
|
||||
fa:bb:83:37:c3:81:90:2f:59:2a:9c:eb:f4:bf:dd:
|
||||
15:1b:b2:f0:b7:03:c8:aa:d9:6f:ee:e4:0b:42:c1:
|
||||
e5:bc:01:af:e5:c7:6c:07:a1:e0:47:ca:ad:b7:f6:
|
||||
2b:7c:4f:09:08:7c:d9:34:21:64:93:f6:a4:c3:6d:
|
||||
c4:de:11:5b:a5:85:af:f9:f7:13:1a:ab:1e:93:6a:
|
||||
99:20:23:63:d3:b4:52:1d:4a:a8:bc:cd:4c:27:42:
|
||||
e3:84:fb:42:69:00:65:ae:a1:ee:16:6e:e4:39:b2:
|
||||
c8:3f:34:de:ec:dc:46:56:8e:b2:e8:40:97:b5:56:
|
||||
f0:d7:d9:ae:1f:3b:ec:ca:56:80:c4:d1:18:21:19:
|
||||
8b:a6:13:08:8e:48:56:ad:63:42:89:43:41:f0:63:
|
||||
c8:cf:f2:6e:d1:6b:f6:1b:a5:bc:23:00:2e:2d:37:
|
||||
71:51:99:3b:1c:fe:1b:bb:2e:d2:c7:e3:2b:70:cc:
|
||||
aa:8b:8f:98:51:23:dc:3c:3f:32:47:99:41:c0:98:
|
||||
0a:3b:b5:44:23:f6:b7:ec:2d:b5:81:20:f2:e5:4a:
|
||||
3c:6e:f5:5d:da:dd:d2:7d:47:18:1d:43:d9:50:c5:
|
||||
6e:da:4e:73:5d:ba:17:c2:33:92:0d:8f:1a:8d:0a:
|
||||
3c:4b:9b:0f:0f:82:a6:d8:c7:fa:38:2b:89:95:df:
|
||||
05:16:d1:9e:e7
|
||||
generator: 5 (0x5)
|
||||
-----BEGIN DH PARAMETERS-----
|
||||
MIIECAKCBAEA6smCf0Z5xQVfjnDGpyuyZlcbmc2aUPKWV8L7/cdA5HxDUrzsTIgP
|
||||
GoDZtr6cMODyFfA3ZrgpcPpYtAYr68WlBLSjVd7adGhoKf6gacD2w2F59WRZw1p3
|
||||
fLiDwduW1/tZIIQOSa1A8L23IR+pv244iCQng8tC8h8uN9MVqbQBqxkd/qALNoBA
|
||||
ScJ7Bt77XkjAknSLz6EK//XZ9cZXLjfMj+JF9+zy4VLvxvt1M647uKoghIC1EP+u
|
||||
28oxheSrYNpTUAt+XWaDuOjimDyySr8FUunTm6BLt9pScC6SOJdlDXhYd5Pjwvbq
|
||||
2obM30oZFNuPjUjPWyn6uFFmnW+DZY9ZcPuqyI2Ya9ifW+5ItfHvw6SFzMgV/u1M
|
||||
qr9JZnBaIWq4r8utbD1ZMxAYqARr8Gs5HexGNBvrJCqEKwZ9c5Ai7wYawhC9mRFL
|
||||
Z6N7hmoFOsxkAOZq9bEktnkP1Lo2G4Dr9COoHY6Th+vV9EPiqs6tfFPG546SnRH+
|
||||
GFPD3CR3d40EAdgUWxyq3kbLXs21vUFtWfqeWoq4JXZjrJchdejtPNXiv9F5uVK1
|
||||
/Va9kYrqYWn54oDKzUoEwOBdJpZJc2eQXRSyw8iAaH+VOPja/lDM6u/I66auUZJQ
|
||||
c8PCRAn31aFq2gMz77XtrImnAqH4pDfr2+lqKjleSCMjEjyAYPk2GsMg/+PlZ8pU
|
||||
FtdExPN185s3GU6lB6VJU9MXbUqy5TSI4vSwNlpLBXDv3sWgoIM9cqTgEycL/imV
|
||||
W0JWhME81wmA6vgzLfFCILbKi2hxrywk6ca54PTKj3jB/3zUYtHjs2WqQWh/GJ/B
|
||||
kKjkjIIHqHKB9pgS6r0pnlSU+p7wL+LVR4hNR+7suRa6KUcR2cU8D0yHkyzkk99w
|
||||
cRffAXvihNAmVkd+A6MYiWbWpWUs6mT/armPxBgts2gqDnS19ZoLzE4g7kZpBi6p
|
||||
WKBIuQxxLrc6hBHQbuAdp1ZONXzaiHJKjn+v/UtoCwjdkLChnOEKerk4GghGB/eD
|
||||
cK2VWHf6u4M3w4GQL1kqnOv0v90VG7LwtwPIqtlv7uQLQsHlvAGv5cdsB6HgR8qt
|
||||
t/YrfE8JCHzZNCFkk/akw23E3hFbpYWv+fcTGqsek2qZICNj07RSHUqovM1MJ0Lj
|
||||
hPtCaQBlrqHuFm7kObLIPzTe7NxGVo6y6ECXtVbw19muHzvsylaAxNEYIRmLphMI
|
||||
jkhWrWNCiUNB8GPIz/Ju0Wv2G6W8IwAuLTdxUZk7HP4buy7Sx+MrcMyqi4+YUSPc
|
||||
PD8yR5lBwJgKO7VEI/a37C21gSDy5Uo8bvVd2t3SfUcYHUPZUMVu2k5zXboXwjOS
|
||||
DY8ajQo8S5sPD4Km2Mf6OCuJld8FFtGe5wIBBQ==
|
||||
-----END DH PARAMETERS-----
|
@@ -1,9 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
if (cgi-fcgi -bind -connect /dev/php7.sock > /dev/null && cgi-fcgi -bind -connect /dev/php8.sock > /dev/null && cgi-fcgi -bind -connect /dev/php81.sock > /dev/null && cgi-fcgi -bind -connect /dev/php82.sock > /dev/null && [ "$(wget -q --no-check-certificate https://127.0.0.1:81/api -O - | jq --raw-output '.status')" == "OK" ]); then
|
||||
echo "OK"
|
||||
exit 0
|
||||
else
|
||||
echo "NOT OK"
|
||||
exit 1
|
||||
fi
|
@@ -2,7 +2,7 @@ location ^~ /.well-known/acme-challenge/ {
|
||||
auth_basic off;
|
||||
auth_request off;
|
||||
allow all;
|
||||
root /tmp/letsencrypt-acme-challenge;
|
||||
root /tmp/acme-challenge;
|
||||
}
|
||||
|
||||
location = /.well-known/acme-challenge/ {
|
@@ -15,7 +15,7 @@ server {
|
||||
|
||||
include conf.d/include/force-ssl.conf;
|
||||
include conf.d/include/ssl-ciphers.conf;
|
||||
include conf.d/include/letsencrypt-acme-challenge.conf;
|
||||
include conf.d/include/acme-challenge.conf;
|
||||
include conf.d/include/block-exploits.conf;
|
||||
add_header alt-svc 'h3=":443"; ma=86400, h3-29=":443"; ma=86400';
|
||||
|
||||
@@ -23,7 +23,7 @@ server {
|
||||
ssl_certificate_key /data/nginx/dummykey.pem;
|
||||
|
||||
location / {
|
||||
include conf.d/include/letsencrypt-acme-challenge.conf;
|
||||
include conf.d/include/acme-challenge.conf;
|
||||
alias /html/default/;
|
||||
}
|
||||
}
|
||||
|
@@ -19,7 +19,6 @@ server {
|
||||
|
||||
include conf.d/include/force-ssl.conf;
|
||||
include conf.d/include/ssl-ciphers.conf;
|
||||
include conf.d/include/letsencrypt-acme-challenge.conf;
|
||||
include conf.d/include/block-exploits.conf;
|
||||
add_header alt-svc 'h3=":443"; ma=86400, h3-29=":443"; ma=86400';
|
||||
|
||||
|
@@ -10,7 +10,6 @@ server {
|
||||
ssl_certificate_key /data/nginx/dummykey.pem;
|
||||
include conf.d/include/ssl-ciphers.conf;
|
||||
include conf.d/include/block-exploits.conf;
|
||||
include conf.d/include/letsencrypt-acme-challenge.conf;
|
||||
add_header alt-svc 'h3=":443"; ma=86400, h3-29=":443"; ma=86400';
|
||||
|
||||
location /api {
|
||||
|
@@ -1,7 +0,0 @@
|
||||
text = True
|
||||
non-interactive = True
|
||||
webroot-path = /tmp/letsencrypt-acme-challenge
|
||||
rsa-key-size = 4096
|
||||
key-type = ecdsa
|
||||
elliptic-curve = secp384r1
|
||||
preferred-chain = ISRG Root X1
|
16
security.txt
Normal file
16
security.txt
Normal file
@@ -0,0 +1,16 @@
|
||||
-----BEGIN PGP SIGNED MESSAGE-----
|
||||
Hash: SHA512
|
||||
|
||||
Contact: mailto:zoeyvid@zvcdn.de
|
||||
Expires: 2023-12-31T22:59:00.000Z
|
||||
Encryption: https://zvcdn.de/publickey.asc
|
||||
Preferred-Languages: de, en
|
||||
Canonical: https://npm.zvcdn.de/.well-known/security.txt
|
||||
Canonical: https://raw.githubusercontent.com/ZoeyVid/nginx-proxy-manager/develop/rootfs/app/frontend/.well-known/security.txt
|
||||
-----BEGIN PGP SIGNATURE-----
|
||||
|
||||
iHUEARYKAB0WIQQZsl0LheH0mUz2hsVuOQn3bP/+fAUCY7CHHAAKCRBuOQn3bP/+
|
||||
fHysAP9ZfBWAtWp+dE1Oow886oGvRGuhikWy31JhFuGa9OjWZgD/UDNXnaTe3m06
|
||||
D56Zc3GiQIW1QEboXMVmVwX4IEQN7Qk=
|
||||
=uSIG
|
||||
-----END PGP SIGNATURE-----
|
Reference in New Issue
Block a user