Skip to content

Commit

Permalink
fixes/dep updates/oqs
Browse files Browse the repository at this point in the history
Signed-off-by: Zoey <[email protected]>
  • Loading branch information
renovate[bot] authored and Zoey2936 committed Sep 30, 2024
1 parent a1f44c5 commit 8c882b8
Show file tree
Hide file tree
Showing 35 changed files with 379 additions and 322 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/dependency-updates.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
sed -i "s|ARG CSNB_VER=.*|ARG CSNB_VER=$CSNB_VER|" Dockerfile
echo "version=$CSNB_VER" >> $GITHUB_OUTPUT
- name: Create Pull Request
uses: peter-evans/create-pull-request@v6
uses: peter-evans/create-pull-request@v7
with:
signoff: true
delete-branch: true
Expand All @@ -51,7 +51,7 @@ jobs:
sed -i "s|ARG CRS_VER=.*|ARG CRS_VER=$CRS_VER|" Dockerfile
echo "version=$CRS_VER" >> $GITHUB_OUTPUT
- name: Create Pull Request
uses: peter-evans/create-pull-request@v6
uses: peter-evans/create-pull-request@v7
with:
signoff: true
delete-branch: true
Expand Down
2 changes: 0 additions & 2 deletions .github/workflows/update-and-lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,7 @@ jobs:
- name: nginxbeautifier
run: |
yarn global add nginxbeautifier
mv -v rootfs/usr/local/nginx/conf/exploits.conf exploits.conf
nginxbeautifier -s 4 -r rootfs/usr/local/nginx/conf
mv -v exploits.conf rootfs/usr/local/nginx/conf/exploits.conf
- name: push changes
run: |
git add -A
Expand Down
2 changes: 1 addition & 1 deletion Caddy.Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM alpine:3.20.2
FROM alpine:3.20.3
RUN apk add --no-cache ca-certificates tzdata
COPY --from=caddy:2.8.4 /usr/bin/caddy /usr/bin/caddy
COPY Caddyfile /etc/caddy/Caddyfile
Expand Down
20 changes: 11 additions & 9 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# syntax=docker/dockerfile:labs
FROM --platform="$BUILDPLATFORM" alpine:3.20.2 AS frontend
FROM --platform="$BUILDPLATFORM" alpine:3.20.3 AS frontend
COPY frontend /app
COPY global/certbot-dns-plugins.json /app/certbot-dns-plugins.json
ARG NODE_ENV=production \
Expand All @@ -18,7 +18,7 @@ COPY darkmode.css /app/dist/css/darkmode.css
COPY security.txt /app/dist/.well-known/security.txt


FROM --platform="$BUILDPLATFORM" alpine:3.20.2 AS build-backend
FROM --platform="$BUILDPLATFORM" alpine:3.20.3 AS build-backend
SHELL ["/bin/ash", "-eo", "pipefail", "-c"]
COPY backend /app
COPY global/certbot-dns-plugins.json /app/certbot-dns-plugins.json
Expand All @@ -37,15 +37,15 @@ RUN apk upgrade --no-cache -a && \
fi && \
yarn cache clean --all && \
clean-modules --yes
FROM alpine:3.20.2 AS strip-backend
FROM alpine:3.20.3 AS strip-backend
COPY --from=build-backend /app /app
RUN apk upgrade --no-cache -a && \
apk add --no-cache ca-certificates binutils file && \
find /app/node_modules -name "*.node" -type f -exec strip -s {} \; && \
find /app/node_modules -name "*.node" -type f -exec file {} \;


FROM --platform="$BUILDPLATFORM" alpine:3.20.2 AS crowdsec
FROM --platform="$BUILDPLATFORM" alpine:3.20.3 AS crowdsec
SHELL ["/bin/ash", "-eo", "pipefail", "-c"]
ARG CSNB_VER=v1.0.8
WORKDIR /src
Expand All @@ -67,22 +67,24 @@ RUN apk upgrade --no-cache -a && \
sed -i "s|BOUNCING_ON_TYPE=all|BOUNCING_ON_TYPE=ban|g" /src/crowdsec-nginx-bouncer/lua-mod/config_example.conf


FROM zoeyvid/nginx-quic:306-python
FROM zoeyvid/nginx-quic:337-python
SHELL ["/bin/ash", "-eo", "pipefail", "-c"]
COPY rootfs /
COPY --from=zoeyvid/certbot-docker:46 /usr/local /usr/local
COPY --from=zoeyvid/curl-quic:408 /usr/local/bin/curl /usr/local/bin/curl
COPY --from=zoeyvid/certbot-docker:49 /usr/local /usr/local
COPY --from=zoeyvid/curl-quic:416 /usr/local/bin/curl /usr/local/bin/curl

ARG CRS_VER=v4.5.0
ARG CRS_VER=v4.7.0
RUN apk upgrade --no-cache -a && \
apk add --no-cache ca-certificates tzdata tini \
nodejs \
bash nano \
openssl apache2-utils \
logrotate apache2-utils \
lua5.1-lzlib lua5.1-socket \
coreutils grep findutils jq shadow su-exec \
luarocks5.1 lua5.1-dev lua5.1-sec build-base git yarn && \
curl https://raw.githubusercontent.com/acmesh-official/acme.sh/master/acme.sh | sh -s -- --install-online --home /usr/local/acme.sh --nocron && \
curl https://raw.githubusercontent.com/tomwassenberg/certbot-ocsp-fetcher/refs/heads/main/certbot-ocsp-fetcher -o /usr/local/bin/certbot-ocsp-fetcher.sh && \
chmod +x /usr/local/bin/certbot-ocsp-fetcher.sh && \
git clone https://github.com/coreruleset/coreruleset --branch "$CRS_VER" /tmp/coreruleset && \
mkdir -v /usr/local/nginx/conf/conf.d/include/coreruleset && \
mv -v /tmp/coreruleset/crs-setup.conf.example /usr/local/nginx/conf/conf.d/include/coreruleset/crs-setup.conf.example && \
Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ running at home or otherwise, including free TLS, without having to know too muc
**Note: ModSecurity overblocking (403 Error)? Please see `/opt/npm/etc/modsecurity`, if you also use CRS please see [here](https://coreruleset.org/docs/concepts/false_positives_tuning).** <br>
**Note: Other Databases like MariaDB may work, but are unsupported.** <br>
**Note: access.log/stream.log, logrotate and goaccess are NOT enabled by default bceuase of GDPR, you can enable them in the compose.yaml.** <br>
**Note: if you remove a cert, which is still used by a host, NPM/NPMplus will crash.** <br>


## Project Goal
Expand Down Expand Up @@ -61,7 +62,6 @@ so that the barrier for entry here is low.
- Only enables TLSv1.2 and TLSv1.3 protocols
- Faster creation of TLS certificates can be achieved by eliminating unnecessary Nginx reloads and configuration creations.
- Uses OCSP Stapling for enhanced security
- If using custom certificates, upload the CA/Intermediate Certificate (file name: `chain.pem`) in the `/opt/npm/tls/custom/npm-[certificate-id]` folder (manual migration may be needed)
- Resolved dnspod plugin issue
- To migrate manually, delete all dnspod certs and recreate them OR change the credentials file as per the template given [here](https://github.com/ZoeyVid/NPMplus/blob/develop/global/certbot-dns-plugins.js)
- Smaller docker image with alpine-based distribution
Expand Down Expand Up @@ -91,11 +91,11 @@ so that the barrier for entry here is low.

## migration
- **NOTE: migrating back to the original is not possible**, so make first a **backup** before migration, so you can use the backup to switch back
- if you use custom certificates, you need to upload the CA/Intermediate Certificate (file name: `chain.pem`) in the `/opt/npm/tls/custom/npm-[certificate-id]` folder
- some buttons have changed, check if they are still correct
- since many buttons changed, please edit every host you have and click save. (Please also resave it, if all buttons/values are fine, to update the host config to fully fit the NPMplus template)
- please delete all dnspod certs and recreate them OR you manually change the credentialsfile (see [here](https://github.com/ZoeyVid/npmplus/blob/develop/global/certbot-dns-plugins.js) for the template)
- since this fork has dependency on `network_mode: host`, please don't forget to open port 80/tcp, 443/tcp and 443/udp (and maybe 81/tcp) in your firewall
- if you have a healthcheck defined in your compose yaml file, remove it - this fork defines its own healthcheck in the Dockerfile, so you don't need to have it in compose anymore
- please report all migration issues you have

# Crowdsec
1. Install crowdsec using this compose file: https://github.com/ZoeyVid/NPMplus/blob/develop/compose.crowdsec.yaml and enable LOGROTATE
Expand Down Expand Up @@ -198,7 +198,7 @@ You may need to use another IP-Address.
[https://127.0.0.1:81](https://127.0.0.1:81)
Default Admin User:
```
Email: admin@example.com
Email: admin@example.org
Password: iArhP1j7p1P6TA92FA2FMbbUGYqwcYzxC4AVEe12Wbi94FY9gNN62aKyF1shrvG4NycjjX9KfmDQiwkLZH1ZDR9xMjiG2QmoHXi
```
Immediately after logging in with this default user you will be asked to modify your details and change your password.
Expand Down
6 changes: 3 additions & 3 deletions backend/doc/api.swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@
"modified_on": "2023-03-30T01:11:50.000Z",
"is_deleted": 0,
"is_disabled": 0,
"email": "admin@example.com",
"email": "admin@example.org",
"name": "Administrator",
"nickname": "Admin",
"avatar": "",
Expand Down Expand Up @@ -144,7 +144,7 @@
"modified_on": "2023-03-30T01:11:50.000Z",
"is_deleted": 0,
"is_disabled": 0,
"email": "admin@example.com",
"email": "admin@example.org",
"name": "Administrator",
"nickname": "Admin",
"avatar": "",
Expand Down Expand Up @@ -223,7 +223,7 @@
"modified_on": "2023-03-30T01:11:50.000Z",
"is_deleted": 0,
"is_disabled": 0,
"email": "admin@example.com",
"email": "admin@example.org",
"name": "Administrator",
"nickname": "Admin",
"avatar": "",
Expand Down
35 changes: 19 additions & 16 deletions backend/internal/certificate.js
Original file line number Diff line number Diff line change
Expand Up @@ -480,14 +480,6 @@ const internalCertificate = {
resolve();
}
});

fs.writeFile(dir + '/chain.pem', certificate.meta.intermediate_certificate, function (err) {
if (err) {
reject(err);
} else {
resolve();
}
});
}).then(() => {
return new Promise((resolve, reject) => {
fs.writeFile(dir + '/privkey.pem', certificate.meta.certificate_key, function (err) {
Expand Down Expand Up @@ -777,7 +769,7 @@ const internalCertificate = {
requestLetsEncryptSsl: (certificate) => {
logger.info('Requesting Certbot certificates for Cert #' + certificate.id + ': ' + certificate.domain_names.join(', '));

let cmd = certbotCommand + ' certonly ' + '--config "' + certbotConfig + '" ' + '--cert-name "npm-' + certificate.id + '" ' + '--authenticator webroot ' + '--preferred-challenges "dns,http" ' + '--domains "' + certificate.domain_names.join(',') + '"';
let cmd = certbotCommand + ' certonly ' + '--config "' + certbotConfig + '" ' + '--cert-name "npm-' + certificate.id + '" ' + '--authenticator webroot ' + '--preferred-challenges "http,dns" ' + '--domains "' + certificate.domain_names.join(',') + '"';

if (certificate.meta.letsencrypt_email === '') {
cmd = cmd + ' --register-unsafely-without-email ';
Expand Down Expand Up @@ -881,7 +873,15 @@ const internalCertificate = {
renewLetsEncryptSsl: (certificate) => {
logger.info('Renewing Certbot certificates for Cert #' + certificate.id + ': ' + certificate.domain_names.join(', '));

const cmd = certbotCommand + ' renew --force-renewal ' + '--config "' + certbotConfig + '" ' + '--cert-name "npm-' + certificate.id + '" ' + '--preferred-challenges "dns,http" ' + '--no-random-sleep-on-renew';
const cmdr = certbotCommand + ' revoke ' + '--config "' + certbotConfig + '" ' + '--cert-path "/data/tls/certbot/live/npm-' + certificate.id + '/privkey.pem" ' + '--cert-path "/data/tls/certbot/live/npm-' + certificate.id + '/fullchain.pem"';

logger.info('Command:', cmdr);

utils.exec(cmdr).then((result) => {
logger.info(result);
});

const cmd = certbotCommand + ' renew --force-renewal ' + '--config "' + certbotConfig + '" ' + '--cert-name "npm-' + certificate.id + '" ' + '--preferred-challenges "http,dns" ' + '--no-random-sleep-on-renew';

logger.info('Command:', cmd);

Expand All @@ -904,6 +904,14 @@ const internalCertificate = {

logger.info(`Renewing Certbot certificates via ${dnsPlugin.name} for Cert #${certificate.id}: ${certificate.domain_names.join(', ')}`);

const mainCmdr = certbotCommand + ' revoke ' + '--config "' + certbotConfig + '" ' + '--cert-path "/data/tls/certbot/live/npm-' + certificate.id + '/privkey.pem" ' + '--cert-path "/data/tls/certbot/live/npm-' + certificate.id + '/fullchain.pem"';

logger.info('Command:', mainCmdr);

utils.exec(mainCmdr).then(async (result) => {
logger.info(result);
});

const mainCmd = certbotCommand + ' renew --force-renewal ' + '--config "' + certbotConfig + '" ' + '--cert-name "npm-' + certificate.id + '" ' + '--preferred-challenges "dns,http" ' + '--no-random-sleep-on-renew';

logger.info('Command:', mainCmd);
Expand All @@ -924,15 +932,10 @@ const internalCertificate = {

const mainCmd = certbotCommand + ' revoke ' + '--config "' + certbotConfig + '" ' + '--cert-path "/data/tls/certbot/live/npm-' + certificate.id + '/privkey.pem" ' + '--cert-path "/data/tls/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/tls/certbot/credentials/credentials-${certificate.id}' || true`;

logger.info('Command:', mainCmd + '; ' + delete_credentialsCmd);

return utils
.exec(mainCmd)
.then(async (result) => {
await utils.exec(delete_credentialsCmd);
await fs.rm('/data/tls/certbot/credentials/credentials-' + certificate.id, { force: true });
logger.info(result);
return result;
})
Expand Down
2 changes: 1 addition & 1 deletion backend/internal/ip_ranges.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ const internalIpRanges = {
const renderEngine = utils.getRenderEngine();
return new Promise((resolve, reject) => {
let template = null;
const filename = '/data/nginx/ip_ranges.conf';
const filename = '/tmp/ip_ranges.conf';
try {
template = fs.readFileSync(__dirname + '/../templates/ip_ranges.conf', { encoding: 'utf8' });
} catch (err) {
Expand Down
74 changes: 19 additions & 55 deletions backend/internal/nginx.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ const internalNginx = {
// We're deleting this config regardless.
// Don't throw errors, as the file may not exist at all
// Delete the .err file too
return internalNginx.deleteConfig(host_type, host, false, true);
return internalNginx.deleteConfig(host_type, host);
})
.then(() => {
return internalNginx.generateConfig(host_type, host);
Expand All @@ -52,27 +52,11 @@ const internalNginx = {
meta: combined_meta,
});
})
.catch((err) => {
// Remove the error_log line because it's a docker-ism false positive that doesn't need to be reported.
// It will always look like this:
// nginx: [alert] could not open error log file: open() "/dev/null" failed (6: No such device or address)

const valid_lines = [];
const err_lines = err.message.split('\n');
err_lines.map(function (line) {
if (line.indexOf('/dev/null') === -1) {
valid_lines.push(line);
}
});

if (config.debug()) {
logger.error('Nginx test failed:', valid_lines.join('\n'));
}

// config is bad, update meta and delete config
.catch(() => {
utils.exec('nginx -t');
combined_meta = _.assign({}, host.meta, {
nginx_online: false,
nginx_err: valid_lines.join('\n'),
nginx_err: 'see dockert logs',
});

return model
Expand All @@ -83,9 +67,6 @@ const internalNginx = {
})
.then(() => {
internalNginx.renameConfigAsError(host_type, host);
})
.then(() => {
return internalNginx.deleteConfig(host_type, host, true);
});
});
})
Expand Down Expand Up @@ -114,17 +95,23 @@ const internalNginx = {

reload: () => {
return internalNginx.test().then(() => {
try {
utils.exec('certbot-ocsp-fetcher.sh -c /data/tls/certbot -o /data/tls/certbot/live --quiet --no-reload-webserver');
} catch {
// do nothing
}
if (fs.existsSync(NgxPidFilePath)) {
const ngxPID = fs.readFileSync(NgxPidFilePath, 'utf8').trim();
if (ngxPID.length > 0) {
logger.info('Reloading Nginx');
utils.exec('nginx -s reload');
} else {
logger.info('Starting Nginx');
utils.execfg('nginx -e stderr');
utils.execfg('nginx -e stderr');
}
} else {
logger.info('Starting Nginx');
utils.exec('certbot-ocsp-fetcher.sh -c /data/tls/certbot -o /data/tls/certbot/live --quiet --no-reload-webserver');
utils.execfg('nginx -e stderr');
}
});
Expand Down Expand Up @@ -262,20 +249,6 @@ const internalNginx = {
});
},

/**
* A simple wrapper around unlinkSync that writes to the logger
*
* @param {String} filename
*/
deleteFile: (filename) => {
logger.debug('Deleting file: ' + filename);
try {
fs.unlinkSync(filename);
} catch (err) {
logger.debug('Could not delete file:', JSON.stringify(err, null, 2));
}
},

/**
*
* @param {String} host_type
Expand All @@ -291,15 +264,11 @@ const internalNginx = {
* @param {Boolean} [delete_err_file]
* @returns {Promise}
*/
deleteConfig: (host_type, host, delete_err_file) => {
deleteConfig: (host_type, host) => {
const config_file = internalNginx.getConfigName(internalNginx.getFileFriendlyHostType(host_type), typeof host === 'undefined' ? 0 : host.id);
const config_file_err = config_file + '.err';

return new Promise((resolve /*, reject */) => {
internalNginx.deleteFile(config_file);
if (delete_err_file) {
internalNginx.deleteFile(config_file_err);
}
fs.rm(config_file, { force: true });
resolve();
});
},
Expand All @@ -312,16 +281,11 @@ const internalNginx = {
renameConfigAsError: (host_type, host) => {
const config_file = internalNginx.getConfigName(internalNginx.getFileFriendlyHostType(host_type), typeof host === 'undefined' ? 0 : host.id);
const config_file_err = config_file + '.err';

return new Promise((resolve /*, reject */) => {
fs.unlink(config_file, () => {
// ignore result, continue
fs.rename(config_file, config_file_err, () => {
// also ignore result, as this is a debugging informative file anyway
resolve();
});
});
});
try {
fs.rename(config_file, config_file_err);
} catch {
// do nothing
}
},

/**
Expand All @@ -346,7 +310,7 @@ const internalNginx = {
bulkDeleteConfigs: (host_type, hosts) => {
const promises = [];
hosts.map(function (host) {
promises.push(internalNginx.deleteConfig(host_type, host, true));
promises.push(internalNginx.deleteConfig(host_type, host));
});

return Promise.all(promises);
Expand Down
Loading

0 comments on commit 8c882b8

Please sign in to comment.