How to prevent Gunicorn from returning a 'Server' http header?

后端 未结 6 1100
走了就别回头了
走了就别回头了 2021-02-05 06:51

I would like to mask the version or remove the header altogether.

相关标签:
6条回答
  • 2021-02-05 07:30

    It's better to change it to something unique than remove it. You don't want to risk, e.g., spiders thinking you're noncompliant. Changing it to the name of software you aren't using can cause similar problems. Making it unique will prevent the same kind of assumptions ever being made. I recommend something like this:

    import gunicorn
    gunicorn.SERVER_SOFTWARE = 'intentionally-undisclosed-gensym384763'
    
    0 讨论(0)
  • 2021-02-05 07:32

    To change the 'Server:' http header, in your conf.py file:

     import gunicorn
     gunicorn.SERVER_SOFTWARE = 'Microsoft-IIS/6.0'
    

    And use an invocation along the lines of gunicorn -c conf.py wsgi:app

    To remove the header altogether, you can monkey-patch gunicorn by replacing its http response class with a subclass that filters out the header. This might be harmless, but is probably not recommended. Put the following in conf.py:

    from gunicorn.http import wsgi
    
    class Response(wsgi.Response):
        def default_headers(self, *args, **kwargs):
            headers = super(Response, self).default_headers(*args, **kwargs)
            return [h for h in headers if not h.startswith('Server:')]
    
    wsgi.Response = Response
    

    Tested with gunicorn 18

    0 讨论(0)
  • 2021-02-05 07:34

    My mocky-patch free solution, involves wrapping the default_headers method:

    import gunicorn.http.wsgi
    from six import wraps
    
    
    def wrap_default_headers(func):
        @wraps(func)
        def default_headers(*args, **kwargs):
            return [header for header in func(*args, **kwargs) if not header.startswith('Server: ')]
        return default_headers
    
    
    gunicorn.http.wsgi.Response.default_headers = wrap_default_headers(gunicorn.http.wsgi.Response.default_headers)
    
    0 讨论(0)
  • 2021-02-05 07:38

    This doesn't directly answer to the question but could address the issue as well and without monkey patching gunicorn.

    If you are using gunicorn behind a reverse proxy, as it usually happens, you can set, add, remove or perform a replacement in a response header coming downstream from the backend. In our case the Server header.

    I guess every Webserver should have an equivalent feature.


    For example, in Caddy 2 (currently in beta) it would be something as simple as:

    https://localhost {
        reverse_proxy unix//tmp/foo.sock {
            header_down Server intentionally-undisclosed-12345678
        }
    }
    

    For completeness I still add a minimal (but fully working) Caddyfile to handle Server header modification even in manual http->https redirect process (Caddy 2 does it automatically, if you don't override it), which could a bit tricky to figure it out correctly.

    http://localhost {
        # Fact: the `header` directive has less priority than `redir` (which means
        # it's evaluated later), so the header wouldn't be changed (and Caddy would
        # shown instead of the faked value).
        #
        # To override the directive ordering only for this server, instead of
        # change the "order" option globally, put the configuration inside a
        # route directive.
        # ref.
        #   https://caddyserver.com/docs/caddyfile/options
        #   https://caddyserver.com/docs/caddyfile/directives/route
        #   https://caddyserver.com/docs/caddyfile/directives#directive-order
        route {
            header Server intentionally-undisclosed-12345678
            redir https://{host}{uri}
        }
    }
    
    https://localhost {
        reverse_proxy unix//tmp/foo.sock {
            header_down Server intentionally-undisclosed-12345678
        }
    }
    

    To check if it works just use curl as curl --insecure -I http://localhost and curl --insecure -I http://localhost (--insecure because localhost certs are automatically generated as self signed).

    It's so simple to setup that you could also think to use it in development (with gunicorn --reload), especially if it resembles your staging/production environment.

    0 讨论(0)
  • 2021-02-05 07:48

    Easiest way -

    For newer releases(20.0.4), create file gunicorn.conf.py with below contents in the directory from where you will run the gunicorn command -

    import gunicorn
    gunicorn.SERVER_SOFTWARE = 'My WebServer'
    
    0 讨论(0)
  • 2021-02-05 07:50

    You can edit __init__.py to set SERVER_SOFTWARE to whatever you want. But I'd really like the ability to disable this with a flag so I didn't need to reapply the patch when I upgrade.

    0 讨论(0)
提交回复
热议问题