]> sipb.mit.edu Git - ikiwiki.git/blob - doc/plugins/openid/troubleshooting.mdwn
c80d645eb6e52d0f443eba6e15fb984dd9795f77
[ikiwiki.git] / doc / plugins / openid / troubleshooting.mdwn
1 **TL;DR**
2
3 [[!toc levels=3]]
4
5 # An odyssey through lots of things that have to be right before OpenID works
6
7 Having just (at last) made an ikiwiki installation accept my
8 OpenID, I have learned many of the things that may have to be checked
9 when getting the [[plugins/openid]] plugin to work. (These are probably
10 the reasons why [ikiwiki.info](/) itself won't accept my OpenID!)
11
12 Just to describe my OpenID setup a bit (and why it makes a good stress-test
13 for the OpenID plugin :).
14
15 I'm using my personal home page URL as my OpenID. My page lives at
16 a shared-hosting service I have hired. It contains links that delegate
17 my OpenID processing to [indieauth.com](https://indieauth.com).
18
19 IndieAuth, in turn, uses
20 [rel-me authentication](http://microformats.org/wiki/RelMeAuth) to find
21 an [OAuth](http://microformats.org/wiki/OAuth) provider that can authenticate
22 me. (At present, I am using [github](http://github.com) for that, which
23 is an OAuth provider but not an OpenID provider, so the gatewaying provided
24 by IndieAuth solves that problem.) As far as ikiwiki is concerned,
25 IndieAuth is my OpenID provider; the details beyond that are transparent.
26
27 So, what were the various issues I had to sort out before my first successful
28 login with the [[plugins/openid]] plugin?
29
30 ## no_identity_server: Could not determine ID provider from URL.
31
32 This is the message [ikiwiki.info](/) shows as soon as I enter my home URL
33 as an OpenID. It is also the first one I got on my own ikiwiki installation.
34
35 ### various possible causes ...
36
37 There could be lots of causes. Maybe:
38
39 * the offered OpenID is an `https:` URL and there is an issue in checking
40     the certificate, so the page can't be retrieved?
41 * the page can be retrieved, but it isn't well-formed HTML and the library
42     can't parse it for the needed OpenID links?
43 * ...?
44
45 ### make a luckier setting of useragent ?!
46
47 In my case, it was none of the above. It turns out my shared-hosting provider
48 has a rule that refuses requests with `User-Agent: libwww-perl/6.03` (!!).
49 This is the sort of problem that's really hard to anticipate or plan around.
50 I could fix it (_for this case!_) by changing `useragent:` in `ikiwiki.setup`
51 to a different string that my goofy provider lets through.
52
53 __Recommendation:__ set `useragent:` in `ikiwiki.setup` to some
54 unlikely-to-be-blacklisted value. I can't guess what the best
55 unlikely-to-be-blacklisted value is; if there is one, it's probably the
56 next one all the rude bots will be using anyway, and some goofy provider
57 like mine will blacklist it.
58
59 > If your shared hosting provider is going to randomly break functionality,
60 > I would suggest "voting with your wallet" and taking your business to
61 > one that does not.
62 >
63 > In principle we could set the default UA (if `$config{useragent}` is
64 > unspecified) to `IkiWiki/3.20140915`, or `IkiWiki/3.20140915 libwww-perl/6.03`
65 > (which would be the "most correct" option AIUI), or some such.
66 > That might work, or might get randomly blacklisted too, depending on the
67 > whims of shared hosting providers. If you can't trust your provider to
68 > behave helpfully then there isn't much we can do about it.
69 >
70 > Blocking requests according to UA seems fundamentally flawed, since
71 > I'm fairly sure no hosting provider can afford to blacklist UAs that
72 > claim to be, for instance, Firefox or Chrome. I wouldn't want
73 > to patch IkiWiki to claim to be an interactive browser by default,
74 > but malicious script authors will have no such qualms, so I would
75 > argue that your provider's strategy is already doomed... --[[smcv]]
76
77 ## Error: OpenID failure: naive_verify_failed_network: Could not contact ID provider to verify response.
78
79 Again, this could have various causes. It was helpful to bump the debug level
80 and get some logging, to see:
81
82     500 Can't connect to indieauth.com:443 (Net::SSL from Crypt-SSLeay can't
83     verify hostnames; either install IO::Socket::SSL or turn off verification
84     by setting the PERL_LWP_SSL_VERIFY_HOSTNAME environment variable to 0)
85
86 I don't belong to the camp that solves every verification problem by turning
87 verification off, so this meant finding out how to get verification to be done.
88 It turns out there are two different Perl modules that can be used for SSL:
89
90 * `IO::Socket::SSL` (verifies hostnames)
91 * `Net::SSL` (_does not_ verify hostnames)
92
93 Both were installed on my hosted server. How was Perl deciding which one
94 to use?
95
96 ### set `PERL_NET_HTTPS_SSL_SOCKET_CLASS` appropriately
97
98 It turns out
99 [there's an environment variable](https://rt.cpan.org/Public/Bug/Display.html?id=71599).
100 So just set `PERL_NET_HTTPS_SSL_SOCKET_CLASS` to `IO::Socket::SSL` and the
101 right module gets used, right?
102
103 [Wrong](https://github.com/csirtgadgets/LWPx-ParanoidAgent/commit/fed6f7d7df8619df0754e8883cfad2ac15703a38#diff-2).
104 That change was made to `ParanoidAgent.pm` back in November 2013 because of an
105 unrelated [bug](https://github.com/csirtgadgets/LWPx-ParanoidAgent/issues/4)
106 in `IO::Socket::SSL`. Essentially, _hmm, something goes wrong in
107 `IO::Socket::SSL` when reading certain large documents, so we'll fix it by
108 forcing the use of `Net::SSL` instead (the one that never verifies hostnames!),
109 no matter what the admin has set `PERL_NET_HTTPS_SSL_SOCKET_CLASS` to!_
110
111 ### undo change that broke `PERL_NET_HTTPS_SSL_SOCKET_CLASS`
112
113 Plenty of [comments](https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=738493)
114 quickly appeared about how good an idea that wasn't, and it was corrected in
115 June 2014 with [one commit](https://github.com/csirtgadgets/LWPx-ParanoidAgent/commit/a92ed8f45834a6167ff62d3e7330bb066b307a35)
116 to fix the original reading-long-documents issue in `IO::Socket::SSL` and
117 [another commit](https://github.com/csirtgadgets/LWPx-ParanoidAgent/commit/815c691ad5554a219769a90ca5f4001ae22a4019)
118 that reverts the forcing of `Net::SSL` no matter how the environment is set.
119
120 Unfortunately, there isn't a release in CPAN yet that includes those two
121 commits, but they are only a few lines to edit into your own locally-installed
122 module.
123
124 > To be clear, these are patches to [[!cpan LWPx::ParanoidAgent]].
125 > Debian's `liblwpx-paranoidagent-perl (>= 1.10-3)` appears to
126 > have those two patches. --[[smcv]]
127
128 ## Still naive_verify_failed_network, new improved reason
129
130     500 Can't connect to indieauth.com:443 (SSL connect attempt failed
131     with unknown error error:14090086:SSL
132     routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed)
133
134 Yay, at least it's trying to verify! Now why can't it verify IndieAuth's
135 certificate?
136
137 [Here's why](https://tools.ietf.org/html/rfc6066#section-3). As it turns out,
138 [indieauth.com](https://indieauth.com/) is itself a virtual host on a shared
139 server. If you naively try
140
141     openssl s_client -connect indieauth.com:443
142
143 you get back a certificate for [indieweb.org](https://indieweb.org/)
144 instead, so the hostname won't verify. If you explicitly indicate what server
145 name you're connecting to:
146
147     openssl s_client -connect indieauth.com:443 -servername indieauth.com
148
149 then, magically, the correct certificate comes back.
150
151 ### ensure `OpenSSL`, `Net::SSLeay`, `IO::Socket::SSL` new enough for SNI
152
153 If your `openssl` doesn't recognize the `-servername` option, it is too old
154 to do SNI, and a newer version needs to be built and installed. In fact,
155 even though SNI support was reportedly backported into OpenSSL 0.9.8f, it will
156 not be used by `IO::Socket::SSL` unless it is
157 [1.0 or higher](http://search.cpan.org/~sullr/IO-Socket-SSL-1.998/lib/IO/Socket/SSL.pod#SNI_Support).
158
159 Then a recent `Net::SSLeay` perl module needs to be built and linked against it.
160
161 > I would tend to be somewhat concerned about the update status and security
162 > of a shared hosting platform that is still on an OpenSSL major version from
163 > pre-2010 - it might be fine, because it might be RHEL or some similarly
164 > change-averse distribution backporting security fixes to ye olde branch,
165 > but equally it might be as bad as it seems at first glance.
166 > "Let the buyer beware", I think... --[[smcv]]
167
168 ### Local OpenSSL installation will need certs to trust
169
170 Bear in mind that the OpenSSL distribution doesn't come with a collection
171 of trusted issuer certs. If a newer version is built and installed locally
172 (say, on a shared server where the system locations can't be written), it will
173 need to be given a directory of trusted issuer certs, say by linking to the
174 system-provided ones. However, a change to the certificate hash algorithm used
175 for the symlinks in that directory was [reportedly](http://www.cilogon.org/openssl1)
176 made with OpenSSL 1.0.0. So if the system-provided trusted certificate directory
177 was set up for an earlier OpenSSL version, all the certificates in it will be
178 fine but the hash symlinks will be wrong. That can be fixed by linking only the
179 named certificate files from the system directory into the newly-installed one,
180 and then running the new version of `c_rehash` there.
181
182 ## Still certificate verify failed
183
184 Using [SNI](https://tools.ietf.org/html/rfc6066#section-3)-supporting versions
185 of `IO::Socket::SSL`, `Net::SSLeay`, and `OpenSSL` doesn't do any good if an
186 upper layer hasn't passed down the name of the host being connected to so the
187 SSL layer can SNI for it.
188
189 ### ensure that `LWPx::ParanoidAgent` passes server name to SSL layer for SNI
190
191 That was fixed in `LWPx::ParanoidAgent` with
192 [this commit](https://github.com/csirtgadgets/LWPx-ParanoidAgent/commit/df6df19ccdeeb717c709cccb011af35d3713f546),
193 which needs to be backported by hand if it hasn't made it into a CPAN release
194 yet.
195
196 > Also in Debian's `liblwpx-paranoidagent-perl (>= 1.10-3)`, for the record.
197 > --[[smcv]]
198
199 Only that still doesn't end the story, because that hand didn't know what
200 [this hand](https://github.com/noxxi/p5-io-socket-ssl/commit/4f83a3cd85458bd2141f0a9f22f787174d51d587#diff-1)
201 was doing. What good is passing the name in
202 `PeerHost` if the SSL code looks in `PeerAddr` first ... and then, if that
203 doesn't match a regex for a hostname, decides you didn't supply one at all,
204 without even looking at `PeerHost`?
205
206 Happily, is is possible to assign a key that _explicitly_ supplies the
207 server name for SNI:
208
209     --- LWPx/Protocol/http_paranoid.pm    2014-09-08 03:33:00.000000000 -0400
210     +++ LWPx/Protocol/http_paranoid.pm    2014-09-08 03:33:27.000000000 -0400
211     @@ -73,6 +73,7 @@
212             close($el);
213              $sock = $self->socket_class->new(PeerAddr => $addr,
214                                               PeerHost => $host,
215     +                                         SSL_hostname => $host,
216                                               PeerPort => $port,
217                                               Proto    => 'tcp',
218                                               Timeout  => $conn_timeout,
219
220 ... not submitted upstream yet, so needs to be applied by hand.
221
222 > I've [reported this to Debian](https://bugs.debian.org/761635)
223 > (which is where ikiwiki.info's supporting packages come from).
224 > Please report it upstream too, if the Debian maintainer doesn't
225 > get there first. --[[smcv]]
226
227 # Success!!
228
229 And with that, ladies and gents, I got my first successful OpenID login!
230 I'm pretty sure that if the same fixes can be applied to
231 [ikiwiki.info](/) itself, a wider range of OpenID logins (like mine, for
232 example :) will work here too.
233
234 -- Chap