mirror of https://github.com/zulip/zulip.git
puppet: Default to installing smokescreen on application frontends.
This is an additional security hardening step, to make Zulip default to preventing SSRF attacks. The overhead of running Smokescreen is minimal, and there is no reason to force deployments to take additional steps in order to secure themselves against SSRF attacks. Deployments which already have a different external proxy configured will not gain a local Smokescreen installation, and running without Smokescreen is supported by explicitly unsetting the `host` or `port` values in `/etc/zulip/zulip.conf`.
This commit is contained in:
parent
44f1ea6bae
commit
c33562f0a8
|
@ -307,7 +307,7 @@ log][commit-log] for an up-to-date list of raw changes.
|
|||
major release.
|
||||
|
||||
[docker-zulip-manual]: https://github.com/zulip/docker-zulip#manual-configuration
|
||||
[smokescreen]: ../production/deployment.html#using-an-outgoing-http-proxy
|
||||
[smokescreen]: ../production/deployment.html#customizing-the-outgoing-http-proxy
|
||||
[update-settings-docs]: ../production/upgrade-or-modify.html#updating-settings-py-inline-documentation
|
||||
|
||||
#### Full feature changelog
|
||||
|
|
|
@ -223,28 +223,14 @@ behind reverse proxies.
|
|||
|
||||
[using-http]: ../production/deployment.html#configuring-zulip-to-allow-http
|
||||
|
||||
## Using an outgoing HTTP proxy
|
||||
## Customizing the outgoing HTTP proxy
|
||||
|
||||
Zulip supports routing all of its outgoing HTTP and HTTPS traffic
|
||||
through an HTTP `CONNECT` proxy, such as [Smokescreen][smokescreen];
|
||||
this includes outgoing webhooks, image and website previews, and
|
||||
mobile push notifications. You may wish to enable this feature to
|
||||
provide a consistent egress point, or enforce access control on URLs
|
||||
to prevent [SSRF][ssrf] against internal resources.
|
||||
To protect against [SSRF][ssrf], Zulip 4.8 and above default to
|
||||
routing all outgoing HTTP and HTTPS traffic through
|
||||
[Smokescreen][smokescreen], an HTTP `CONNECT` proxy; this includes
|
||||
outgoing webhooks, website previews, and mobile push notifications.
|
||||
|
||||
To use Smokescreen:
|
||||
|
||||
1. Add `, zulip::profile::smokescreen` to the list of `puppet_classes`
|
||||
in `/etc/zulip/zulip.conf`. A typical value after this change is:
|
||||
|
||||
```ini
|
||||
puppet_classes = zulip::profile::standalone, zulip::profile::smokescreen
|
||||
```
|
||||
|
||||
1. Optionally, configure the [smokescreen ACLs][smokescreen-acls]. By
|
||||
default, Smokescreen denies access to all [non-public IP
|
||||
addresses](https://en.wikipedia.org/wiki/Private_network), including
|
||||
127.0.0.1.
|
||||
To use a custom outgoing proxy:
|
||||
|
||||
1. Add the following block to `/etc/zulip/zulip.conf`, substituting in
|
||||
your proxy's hostname/IP and port:
|
||||
|
@ -255,19 +241,28 @@ To use Smokescreen:
|
|||
port = 4750
|
||||
```
|
||||
|
||||
1. If you intend to also make the Smokescreen install available to
|
||||
other hosts, set `listen_address` in the same block. Note that you
|
||||
must control access to the Smokescreen port if you do this, as
|
||||
failing to do so opens a public HTTP proxy!
|
||||
|
||||
1. As root, run
|
||||
`/home/zulip/deployments/current/scripts/zulip-puppet-apply`. This
|
||||
will compile and install Smokescreen, reconfigure services to use
|
||||
it, and restart Zulip.
|
||||
will reconfigure and restart Zulip.
|
||||
|
||||
If you would like to use an already-installed HTTP proxy, omit the
|
||||
first step, and adjust the IP address and port in the second step
|
||||
accordingly.
|
||||
If you have a deployment with multiple frontend servers, or wish to
|
||||
install Smokescreen on a separate host, you can apply the
|
||||
`zulip::profile::smokescreen` Puppet class on that host, and follow
|
||||
the above steps, setting the `[http_proxy]` block to point to that
|
||||
host.
|
||||
|
||||
If you wish to disable the outgoing proxy entirely, follow the above
|
||||
steps, configuring an empty `host` value.
|
||||
|
||||
Optionally, you can also configure the [Smokescreen ACL
|
||||
list][smokescreen-acls]. By default, Smokescreen denies access to all
|
||||
[non-public IP
|
||||
addresses](https://en.wikipedia.org/wiki/Private_network), including
|
||||
127.0.0.1, but allows traffic to all public Internet hosts.
|
||||
|
||||
In Zulip 4.7 and older, to enable SSRF protection via Smokescreen, you
|
||||
will need to explicitly add the `zulip::profile::smokescreen` Puppet
|
||||
class, and configure the `[http_proxy]` block as above.
|
||||
|
||||
[smokescreen]: https://github.com/stripe/smokescreen
|
||||
[smokescreen-acls]: https://github.com/stripe/smokescreen#acls
|
||||
|
@ -651,11 +646,13 @@ load balancers whose `X-Forwarded-For` should be respected.
|
|||
#### `host`
|
||||
|
||||
The hostname or IP address of an [outgoing HTTP `CONNECT`
|
||||
proxy](#using-an-outgoing-http-proxy).
|
||||
proxy](#customizing-the-outgoing-http-proxy). Defaults to `localhost`
|
||||
if unspecified.
|
||||
|
||||
#### `port`
|
||||
|
||||
The TCP port of the HTTP `CONNECT` proxy on the host specified above.
|
||||
Defaults to `4750` if unspecified.
|
||||
|
||||
#### `listen_address`
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ support forwarding push notifications to a central push notification
|
|||
forwarding service. Accessing this service requires outgoing HTTPS
|
||||
access to the public Internet; if that is restricted by a proxy, you
|
||||
will need to [configure Zulip to use your outgoing HTTP
|
||||
proxy](../production/deployment.html#using-an-outgoing-http-proxy)
|
||||
proxy](../production/deployment.html#customizing-the-outgoing-http-proxy)
|
||||
first.
|
||||
|
||||
You can enable this for your Zulip server as follows:
|
||||
|
|
|
@ -96,13 +96,14 @@ on hardware requirements for larger organizations.
|
|||
address as its external hostname (though we don't recommend that
|
||||
configuration).
|
||||
- Zulip supports [running behind a reverse proxy][reverse-proxy].
|
||||
- Zulip servers running inside a private network should configure the
|
||||
[Smokescreen integration][smokescreen-proxy] to protect against
|
||||
[SSRF attacks][ssrf], where users could make the Zulip server make
|
||||
requests to private resources.
|
||||
- Zulip configures [Smokescreen, and outgoing HTTP
|
||||
proxy][smokescreen-proxy], to protect against [SSRF attacks][ssrf],
|
||||
which prevents user from making the Zulip server make requests to
|
||||
private resources. If your network has its own outgoing HTTP proxy,
|
||||
Zulip supports using that instead.
|
||||
|
||||
[ssrf]: https://owasp.org/www-community/attacks/Server_Side_Request_Forgery
|
||||
[smokescreen-proxy]: ../production/deployment.html#using-an-outgoing-http-proxy
|
||||
[smokescreen-proxy]: ../production/deployment.html#customizing-the-outgoing-http-proxy
|
||||
[reverse-proxy]: ../production/deployment.html#putting-the-zulip-application-behind-a-reverse-proxy
|
||||
[email-mirror-code]: https://github.com/zulip/zulip/blob/main/zerver/management/commands/email_mirror.py
|
||||
|
||||
|
|
|
@ -259,15 +259,15 @@ strength allowed is controlled by two settings in
|
|||
- Mobile push notifications (must be configured to be enabled)
|
||||
|
||||
- Notably, these first 3 features give end users (limited) control to cause
|
||||
the Zulip server to make HTTP requests on their behalf. As a result,
|
||||
Zulip supports routing all outgoing outgoing HTTP requests [through
|
||||
the Zulip server to make HTTP requests on their behalf. Because of this,
|
||||
Zulip routes all outgoing outgoing HTTP requests [through
|
||||
Smokescreen][smokescreen-setup] to ensure that Zulip cannot be
|
||||
used to execute [SSRF attacks][ssrf] against other systems on an
|
||||
internal corporate network. The default Smokescreen configuration
|
||||
denies access to all non-public IP addresses, including 127.0.0.1.
|
||||
|
||||
[ssrf]: https://owasp.org/www-community/attacks/Server_Side_Request_Forgery
|
||||
[smokescreen-setup]: ../production/deployment.html#using-an-outgoing-http-proxy
|
||||
[smokescreen-setup]: ../production/deployment.html#customizing-the-outgoing-http-proxy
|
||||
|
||||
## Final notes and security response
|
||||
|
||||
|
|
|
@ -96,8 +96,14 @@ class zulip::app_frontend_base {
|
|||
$uwsgi_default_processes = 4
|
||||
}
|
||||
$tornado_ports = $zulip::tornado_sharding::tornado_ports
|
||||
$proxy_host = zulipconf('http_proxy', 'host', '')
|
||||
$proxy_port = zulipconf('http_proxy', 'port', '')
|
||||
|
||||
$proxy_host = zulipconf('http_proxy', 'host', 'localhost')
|
||||
$proxy_port = zulipconf('http_proxy', 'port', '4750')
|
||||
|
||||
if ($proxy_host in ['localhost', '127.0.0.1', '::1']) and ($proxy_port == '4750') {
|
||||
include zulip::smokescreen
|
||||
}
|
||||
|
||||
if $proxy_host != '' and $proxy_port != '' {
|
||||
$proxy = "http://${proxy_host}:${proxy_port}"
|
||||
} else {
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
# in a cluster.
|
||||
|
||||
class zulip::app_frontend_once {
|
||||
$proxy_host = zulipconf('http_proxy', 'host', '')
|
||||
$proxy_port = zulipconf('http_proxy', 'port', '')
|
||||
$proxy_host = zulipconf('http_proxy', 'host', 'localhost')
|
||||
$proxy_port = zulipconf('http_proxy', 'port', '4750')
|
||||
if $proxy_host != '' and $proxy_port != '' {
|
||||
$proxy = "http://${proxy_host}:${proxy_port}"
|
||||
} else {
|
||||
|
|
Loading…
Reference in New Issue