hlandau / acmetool

:lock: acmetool, an automatic certificate acquisition tool for ACME (Let's Encrypt)
https://hlandau.github.io/acmetool/
2.06k stars 130 forks source link

Redirector: Use 301 redirect instead of 308 #209

Closed davidmehren closed 7 years ago

davidmehren commented 8 years ago

Hi everyone!

I think the redirector module should use the 301 Moved Permanently redirect instead of 308 Permanent Redirect as 308 confuses some HTTPS testing sites (e.g. hstspreload.appspot.com) and software (e.g. wget). Mozilla also recommends 301 in their Web Security Guidelines: https://wiki.mozilla.org/Security/Guidelines/Web_Security#HTTP_Redirections

hlandau commented 8 years ago

This is as intended. The difference between 308 and 301 is that 308 preserves the request method.

For example:

$ curl -L -X POST -d foo=bar http://foo/

If 301 were used the POST would be converted to a GET, which is not desired. This would be reasonable behaviour if the POST had been processed and the redirect was to e.g. a created resource (though 303 would be more appropriate). In this case though, it is an indication that the POST has not been processed and a method-preserving response code is appropriate.

(In this case, of course, any data transmitted has been transmitted in the clear, but the redirector is powerless to prevent this.)

davidmehren commented 8 years ago

I understand the idea behind 308. My point is: 308 seems to not be an official standard yet (its only "proposed" https://datatracker.ietf.org/doc/rfc7538/). Because of that many tools do not expect a 308, wget e.g. exits with an error.

Additionally the current implementation makes it impossible to use HSTS Preloading for my domains, because the official website for that does not support 308 (it says "no redirect from HTTP"). Instead of using the redirector I could stop nginx and let acmetool listen to port 80 while updating certs, but that impacts all users.

Of course using 301 has the downsides you mentioned, but Mozilla and Google (https://support.google.com/webmasters/answer/6073543?hl=en) recommend it anyway. Probably most clients don't convert a POST to a GET after a 301.

What about a config option to choose between 301 and 308?

snoopdouglas commented 7 years ago

+1, we've just found out that some older versions of IE and Opera don't like the 308 and display an ugly redirect page that doesn't automatically send the user anywhere.

Might it be worth adding at least one of these to the HTML sent with the 308 (as much as it pains me to suggest this):

<meta http-equiv="refresh" content="0; url=http://redirects-to-here/">
snoopdouglas commented 7 years ago

For the moment, could we at least have the ability to change the HTML served with the 308? This is hard-coded currently:

const redirBody = `<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
<head><title>Permanently Moved</title></head>
<body><h1>Permanently Moved</h1>
<p>This resource has <strong>moved permanently</strong> to
 <a href="%s">%s</a>.</p>
</body></html>`

(redirector.go, line 216)

snoopdouglas commented 7 years ago

@davidmehren @hlandau Have gone ahead and submitted the above PR. Thoughts?

hlandau commented 7 years ago

Now implemented.