mirror of
https://github.com/zulip/zulip.git
synced 2025-10-23 04:52:12 +00:00
nginx: Add an option which defaults loadbalancer requests to https.
In some cases, it is not possible to configure the load-balancer to add an X-Forwarded-Proto header. If Zulip is serving its traffic over HTTP, it will rightly error out, since it cannot guarantee that its response will be served over an encrypted connection. Add a new `loadbalancer.rejects_http_requests` settings which serves as a way for the operator to swear that the load-balancer will *never* serve responses from Zulip over an unencrypted connection. In most cases, this is because the load-balancer is configured to have port 80 always serve an HTTP 301 redirect to the same URL over HTTPS. Properly configuring the proxy to send `X-Forwarded-Proto` is always a better solution than using this configuration parameter, so use of this should be viewed as a last resort.
This commit is contained in:
committed by
Tim Abbott
parent
b047c4d322
commit
3ec896ebda
@@ -244,6 +244,11 @@ things you need to be careful about when configuring it:
|
||||
connection mechanism from your proxy to Zulip. Note that the proxies _must_
|
||||
set the header, overriding any existing values, not add a new header.
|
||||
|
||||
If your proxy _cannot_ set the `X-Forwarded-Proto` header, you can opt to do
|
||||
all HTTP-to-HTTPS redirection at the load-balancer level, and set
|
||||
[`loadbalancer.rejects_http_requests` in `zulip.conf`][no-proto-header]; but
|
||||
note the important security caveats for that in its documentation.
|
||||
|
||||
1. Configure your proxy to pass along the `Host:` header as was sent
|
||||
from the client, not the internal hostname as seen by the proxy.
|
||||
If this is not possible, you can set `USE_X_FORWARDED_HOST = True`
|
||||
@@ -272,4 +277,5 @@ things you need to be careful about when configuring it:
|
||||
with multiple IPs for your Zulip machine; sometimes this happens with
|
||||
IPv6 configuration).
|
||||
|
||||
[no-proto-header]: system-configuration.md#rejects_http_requests
|
||||
[nginx-proxy-longpolling-config]: https://github.com/zulip/zulip/blob/main/puppet/zulip/files/nginx/zulip-include-common/proxy_longpolling
|
||||
|
@@ -370,6 +370,16 @@ Comma-separated list of IP addresses or netmasks of external load balancers
|
||||
whose `X-Forwarded-For` and `X-Forwarded-Proto` should be respected. These can
|
||||
be individual IP addresses, or CIDR IP address ranges.
|
||||
|
||||
#### `rejects_http_requests`
|
||||
|
||||
Set to a true value if incoming requests from load loadbalancer's IP addresses
|
||||
which do not contain an `X-Forwarded-Proto` should be assumed to have come into
|
||||
them over HTTPS. This setting _is a security vulnerability_ unless the load
|
||||
balancer unilaterally rejects unencrypted HTTP connections, or responds to them
|
||||
with 301 status codes. Note that Zulip's HSTS headers are not sufficient
|
||||
protection here, since API clients do not respect them; the load balancer _must
|
||||
not_ send any requests to Zulip which came in unencrypted.
|
||||
|
||||
### `[http_proxy]`
|
||||
|
||||
#### `host`
|
||||
|
@@ -56,6 +56,7 @@ class zulip::nginx {
|
||||
}
|
||||
|
||||
$loadbalancers = split(zulipconf('loadbalancer', 'ips', ''), ',')
|
||||
$lb_rejects_http_requests = zulipconf('loadbalancer', 'rejects_http_requests', false)
|
||||
file { '/etc/nginx/zulip-include/trusted-proto':
|
||||
ensure => file,
|
||||
require => Package[$zulip::common::nginx],
|
||||
|
@@ -31,14 +31,19 @@ geo $remote_addr $is_from_proxy {
|
||||
# We set $trusted_x_forwarded_proto in two steps because `geo` does
|
||||
# not support variable interpolation in the value, but does support
|
||||
# CIDR notation, which the loadbalancer list may use.
|
||||
map $is_x_forwarded_proto_trusted $trusted_x_forwarded_proto {
|
||||
0 $scheme;
|
||||
1 $http_x_forwarded_proto;
|
||||
map "$is_x_forwarded_proto_trusted:$http_x_forwarded_proto" $trusted_x_forwarded_proto {
|
||||
"~^0:" $scheme;
|
||||
<%- if @lb_rejects_http_requests -%>
|
||||
"~^1:$" "https";
|
||||
<% end -%>
|
||||
"~^1:" $http_x_forwarded_proto;
|
||||
}
|
||||
|
||||
map "$is_from_proxy:$is_x_forwarded_proto_trusted:$http_x_forwarded_proto" $x_proxy_misconfiguration {
|
||||
"~^0:0:" "Incorrect reverse proxy IPs set in Zulip (try $remote_addr?); see https://zulip.readthedocs.io/en/latest/production/reverse-proxies.html";
|
||||
<%- if not @lb_rejects_http_requests -%>
|
||||
"~^0:1:$" "No X-Forwarded-Proto header sent from trusted proxy $realip_remote_addr; see example configurations in https://zulip.readthedocs.io/en/latest/production/reverse-proxies.html";
|
||||
<% end -%>
|
||||
default "";
|
||||
}
|
||||
<% end %>
|
||||
|
Reference in New Issue
Block a user