Security
- Check advanced_config permissions before creating a certificate on
host update (proxy, redirection and 404 hosts). A refused request
previously requested a Let's Encrypt certificate first, leaving an
orphan certificate and using up rate limit.
- Only trust X-NPM-Peer-Addr when it comes with a secret generated at
container start. The admin nginx sends both headers. Any proxy host or
stream forwarding to 127.0.0.1:3000 was also a loopback peer, so it
could forge the header and get a fresh rate-limit bucket on every
request. Without the secret (dev, or a mounted production.conf), the
header is ignored.
- Add a login limit per IP across all accounts (30 failed attempts a
minute) alongside the per-account one. Before this, one address could
spray passwords over any number of accounts. Behind a shared proxy,
everyone using that proxy shares this limit.
- Stop trusting X-Real-IP from loopback. It was only there for an older
version of the rate limiter, and it let a stream host forwarding to a
local proxy host forge the client IP and get past IP access lists.
Loopback now behaves as it does on master.
Correctness
- Refuse to delete a certificate that hosts still use (400, with counts
per host type). Their configs include its files, and a successful
revoke deleted them anyway, which broke nginx -t. Otherwise the
certificate is revoked and its files are removed even if the revoke
fails.
- Let non-admins clear a location's advanced config. Deleting the
location was already allowed and has the same effect, and a location
deleted and re-added at the same path arrives with an empty config,
which was refused.
- Clear proxy host grants (meta.proxy_host_ids) when visibility isn't
"user" or proxy hosts are hidden, and drop ids of deleted hosts.
Before, hidden grants came back when proxy hosts were shown again.
The backend enforces this; the permissions modal also stops sending
them.
- 404 host and redirection host modals now wait for the current user
to load, so an admin's advanced config change isn't dropped if they
submit before it loads.
Tests
- NonAdminHosts.cy.js: refused change doesn't create a certificate,
location rename and clear rules, grant clearing.
- Certificates.cy.js: deleting a certificate that is in use.
Security
- Redact certbot output before it reaches the API: strip the
certificate's DNS credential values, URL query strings and userinfo,
secret-looking key=value pairs and Bearer/Basic tokens. DNS plugins
can echo request URLs carrying API keys. The raw CommandError is no
longer attached as `previous`, since the error handler returns
`previous` to the client on certificate routes.
- Rate limit login/2FA on the admin nginx's real TCP peer, passed as
X-NPM-Peer-Addr ($realip_remote_addr), instead of X-Forwarded-For.
nginx trusts X-Real-IP from private ranges, so a client on the LAN or
Docker network could get a fresh bucket on every request. Behind
another proxy, limits now apply per account through that proxy.
- Bound rate limiter memory: hash keys over 128 chars and cap each store
at 50k entries, removing expired entries first and then the oldest.
Correctness
- Proxy host modal: send location advanced configs unchanged for
non-admins instead of looking them up by path, which dropped the
config from a renamed location.
- Location advanced config: locations that omit advanced_config now get
a config only after explicit ones are matched, so a new location at
an old path can't take the config from the renamed location.
- Certificate upload: check that the certificate matches the private
key (uploaded or stored) before writing, so a mismatched pair can't
break nginx -t.
- Certificate delete: keep the Let's Encrypt files when revoke fails and
hosts still use the certificate, so their configs still load.
Cleanup
- Make the rate-limit certbot hint first in the list, as its comment
says.
- Proxy host getCount uses the permissions access has already loaded
instead of querying user_permission again.
- Rate limiter: register the success refund listener in one place and
call it a fixed window, not a sliding one.
- Add in-memory sliding window rate limiter for auth token endpoints with CI/test bypass and successful request exclusion
- Add user_permission meta column migration and Objection model configuration
- Support scoping allowed proxy hosts per user when in 'Created Items Only' visibility mode
- Restrict advanced nginx configuration editing on hosts to admin users only
- Fix user permissions route ID parsing and omit id from permission update payloads
- Add allowed proxy hosts selector in permissions modal and display permissions summary badges in users table
Some paths rendered host configs without fully loading the relations
the templates depend on, silently dropping access rules (and SSL):
- Enabling a proxy host loaded the access list without its clients or
auth items, so the host came back with no access restrictions.
- Requesting a Let's Encrypt certificate re-rendered every host sharing
its domains from bare rows, dropping access rules and SSL.
generateConfig now loads any referenced certificate or access list that
isn't fully loaded, so no caller can render a partial config. The two
callers above also fetch the relations themselves, and a warning is
logged when a host's access list is missing or has no rules.
Adds integration tests covering access lists across disable/enable.
Fixes#5919, #4286, #5710
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Use optional chaining for nullable checks
- Replace template literals with string literals for plain SQL
- Add node: protocol to fs/promises import in setup.js
- /schema now returns full openapi/swagger schema
- That schema is used to validate incoming requests
- And used as a contract in future integration tests
- Moved route files up one level
- Fixed incorrect 404 reponses when getting objects
- Fixed saving new objects and passing jsonschemavalidation
This fixes an Objection warning: 'Duplicate relation "proxy_hosts" in a relation expression. You should use "a.[b, c]" instead of "[a.b, a.c]". This will cause an error in objection 2.0'.
It also fixes the access list clients not being properly eager-loaded when building the proxy host nginx configuration files. Closes#434
* Fix wrapping when too many hosts are shown (#207)
* Update npm packages, fixes CVE-2019-10757
* Revert some breaking packages
* Major overhaul
- Docker buildx support in CI
- Cypress API Testing in CI
- Restructured folder layout (insert clean face meme)
- Added Swagger documentation and validate API against that (to be completed)
- Use common base image for all supported archs, which includes updated nginx with ipv6 support
- Updated certbot and changes required for it
- Large amount of Hosts names will wrap in UI
- Updated packages for frontend
- Version bump 2.1.0
* Updated documentation
* Fix JWT expire time going crazy. Now set to 1day
* Backend JS formatting rules
* Remove v1 importer, I doubt anyone is using v1 anymore
* Added backend formatting rules and enforce them
in Jenkins builds
* Fix CI, doesn't need a tty
* Thanks bcrypt. Why can't you just be normal.
* Cleanup after syntax check
Co-authored-by: Marcelo Castagna <margaale@users.noreply.github.com>