Fix fedpkg double uploads by abusing the krb5 replay cache being local

Signed-off-by: Patrick Uiterwijk <puiterwijk@redhat.com>
This commit is contained in:
Patrick Uiterwijk 2017-07-22 11:32:04 +00:00
parent 0a0268b89e
commit dc7d020e21
3 changed files with 60 additions and 0 deletions

View file

@ -49,6 +49,8 @@
website: codecs.fedoraproject.org
- role: fedora-web/alt
website: alt.fedoraproject.org
- role: fedora-web/src
website: src.fedoraproject.org
# Some other static content, not strictly part of "fedora-web" goes below here
- role: fedora-docs/proxy

View file

@ -0,0 +1,12 @@
# For info, check roles/httpd/reverseproxy/templates/reversepassproxy.src.conf
- name: Install the pkgs keytab
file: src="{{ private }}/files/keytabs/{{env}}/pkgs"
dest=/etc/pkgs.keytab
owner=apache
group=apache
mode=0600
notify:
- reloadhttpd
tags:
- fedora-web
- fedora-web/src

View file

@ -0,0 +1,46 @@
{% if rewrite %}
RewriteEngine On
RewriteRule ^{{remotepath}}$ %{REQUEST_URI}/ [R=301]
{% endif %}
{% if header_scheme %}
RequestHeader set X-Forwarded-Scheme https early
RequestHeader set X-Scheme https early
RequestHeader set X-Forwarded-Proto https early
{% endif %}
{% if header_expect %}
RequestHeader unset Expect early
{% endif %}
{% if keephost %}
ProxyPreserveHost On
{% endif %}
# If you are a krb5 purist, please skip this.
# This is (ab)using the fact that krb5 replay cache is local to a server to protect against local attacks
# while having an auth check on the proxies.
# This is done because when fedpkg uploads a tarball, PycURL first sends an Expect: 100-Continue, but
# unless the proxy is aware of the auth requirement, it will send the 100-Continue immediately, after
# which the request will still fail (because pkgs will require auth).
# What we do here is make the proxies require GSSAPI auth with the same keytab that pkgs uses.
# As a consequence, the auth request is made by the proxies, avoiding the 100-Continue that causes
# files to be uploaded twice.
# However, I did not want to make the proxies send a plain HTTP header, since this means that whenever
# someone gets into the local network, they could send their own request to the pkgs server, which will
# then trust any username header (terrible idea, see CVE-2016-1000038).
# So, instead, I just depend on mod_proxy forwarding the Authorization: Negotiate header that the client
# sends on to pkgs, which will then *again* start a new GSSAPI security context and that way
# authenticate the user on its own accord.
# This depends on the fact that the krb5 replace cache is local, since both the terminating proxy *and*
# pkgs will accept the GSSAPI security context.
<Location /repo/pkgs/upload.cgi>
AuthType GSSAPI
AuthName "GSSAPI Single Sign On Login"
GssapiCredStore keytab:/etc/pkgs.keytab
Require valid-user
</Location>
ProxyPass {{ localpath }} {{ proxyurl }}{{remotepath}}
ProxyPassReverse {{ localpath }} {{ proxyurl }}{{remotepath}}