-
Notifications
You must be signed in to change notification settings - Fork 3
nginx: Support query params & fix OPCS-4 port conflict #35
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
+11
−3
Merged
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
proxy_passtarget host is built from the unvalidated$servicepath segment (captured in thelocationregex and then used to construct$upstream), which allows clients to control the upstream host for/cms/<service>/...requests. An attacker can send requests like/cms/attacker-controlled-host/some/path?x=yto force nginx to proxy arbitrary HTTP traffic to internal or external hosts on the configured ports, effectively creating an SSRF/open-proxy primitive. To mitigate this, restrict$serviceto a strict allowlist of known backends (e.g. via dedicatedlocationblocks or amap) instead of passing arbitrary user-controlled values intoproxy_pass.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment is interesting but not directly relevant to this PR, but what's described has in fact been the case since I introduced dynamic routing through the proxy, the whole point of which was to move away from strictly defined targets so that we can proxy to models deployed dynamically through the CMG.
Rationale behind dynamic routing through proxy
When running in airgapped environments, a proxy server is usually configured to handle all traffic deemed to be targeting resources outside of the local network. This also affects containerised applications using Docker service names for communication. For these to work, we explicitly add the names of the expected targets to the containers'
no_proxylist. However, this can only work when we know the names of all potential targets in advance (e.g. a backend server that only talks to a database and an object store). In the case of the CogStack Model Gateway, which allows the dynamic deployment of user-defined model servers, the list of targets can change dynamically. For that reason, instead of keeping track of all servers and attempting to maintain an up-to-dateno_proxylist, we choose to proxy all requests through a single service, the name of which we can safely add to the CMG containers'no_proxylist.Risk
In airgapped setups like our production environments, the risk posed by the unrestricted proxy pass is minimal. Any traffic exiting the cluster (outbound) is restricted by the configured Squid proxy, meaning that only local services can be targeted through the proxy. With that in mind, if an attacker is able to create arbitrary containers inside the Docker network, they hardly need the proxy to compromise our servers.
On the other hand, in environments with unrestricted outbound traffic, this can indeed be an actual security concern. For this reason, we can look into moving the dynamic routing logic to a separate internal proxy managed by the CMG project and revert to solely using the strictly configured upstreams here. In any case, that should be part of a different PR.