sks-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Sks-devel] peering broken for keyservers using reverse-proxies?


From: Daniel Kahn Gillmor
Subject: Re: [Sks-devel] peering broken for keyservers using reverse-proxies?
Date: Thu, 05 Apr 2012 17:32:32 -0400
User-agent: Notmuch/0.12 (http://notmuchmail.org) Emacs/23.4.1 (i486-pc-linux-gnu)

On Wed, 4 Apr 2012 18:02:49 -0600, Ryan <address@hidden> wrote:
> I had problems reverse proxying 11371 behind a load balancer; would
> break other sks servers fetching keys.

Yep, this seems to be the case.

I used strace to capture such a negotiation to see what was happening,
and this is what i see on a failed connection:

write(6, "2012-04-05 12:50:07 Requesting 2 missing keys from <ADDR_INET 
[94.142.241.93]:11371>, starting with 5855E8BFE87C212A57828BE1667C746B\n", 133) 
= 133
socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 9
bind(9, {sa_family=AF_INET, sin_port=htons(0), sin_addr=inet_addr("0.0.0.0")}, 
16) = 0
connect(9, {sa_family=AF_INET, sin_port=htons(11371), 
sin_addr=inet_addr("94.142.241.93")}, 16) = 0
lseek(9, 0, SEEK_CUR)                   = -1 ESPIPE (Illegal seek)
lseek(9, 0, SEEK_CUR)                   = -1 ESPIPE (Illegal seek)
write(9, "POST /pks/hashquery\r\ncontent-length: 
44\r\n\r\n\0\0\0\2\0\0\0\20XU\350\277\350|!*W\202\213\341f|tk\0\0\0\20\232\341d\34\217\330\343\342\311\303\223l\320\357b#",
 87) = 87
read(9, "<html>\r\n<head><title>400 Bad Request</title></head>\r\n<body 
bgcolor=\"white\">\r\n<center><h1>400 Bad 
Request</h1></center>\r\n<hr><center>nginx</center>\r\n</body>\r\n</html>\r\n", 
4096) = 166
close(9)                                = 0
stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=3519, ...}) = 0
write(6, "2012-04-05 12:50:07 Error getting missing keys: 
Failure(\"<html>\\r\")\n", 68) = 68


Turning up logging in the nginx frontend on keys.mayfirst.org, and
trying the same request against that keyserver yields a message in the
nginx logs:


2012/04/05 13:21:07 [info] 9608#0: *6325478 client sent invalid method in 
HTTP/0.9 request while reading client request line, client: 108.58.6.98, 
server: keys.mayfirst.org, request: "POST /pks/hashquery"

Digging through the nginx sources, src/http/ngx_http_parse.c contains:

...
    if (r->http_version == 9 && r->method != NGX_HTTP_GET) {
        return NGX_HTTP_PARSE_INVALID_09_METHOD;
    }
...

And indeed that POST violates HTTP/1.0 by not including an HTTP version
spec, so it must be 0.9, and 0.9 doesn't include POST methods.  So the
recon process in 1.1.1 is emitting invalid HTTP requests to its peers :(

> What I ended up doing was configure SKS to use 21371 on external
> interface and the proxy on 11371; other SKS servers started fetching
> keys off 21371 and bypassing the proxy yet clients always hit the
> proxy.

This is an interesting approach -- it sounds like you're saying that sks
will tell its peers what port it is listening on?  However, that means
that the 21371 public port is now subject to the same DoS attack that
the reverse proxy is intended to fix.

> I think the issue was fixed in latest SKS but alot of servers are not
> running it yet so this is my work-arround.

Indeed, that request is fixed to use HTTP 1.0 in sks 1.1.2:

0 address@hidden:~/src/sks$ diff -u sks-1.1.{1,2}/reconComm.ml
--- sks-1.1.1/reconComm.ml      2009-03-25 22:14:44.000000000 -0400
+++ sks-1.1.2/reconComm.ml      2011-10-01 08:23:23.000000000 -0400
@@ -81,7 +81,7 @@
                let sout = Channel.new_buffer_outc 0 in
                CMarshal.marshal_list ~f:CMarshal.marshal_string sout hashes;
                let msg = sout#contents in
-               cout#write_string "POST /pks/hashquery\r\n";
+               cout#write_string "POST /pks/hashquery HTTP/1.0\r\n";
                cout#write_string (sprintf "content-length: %d\r\n\r\n" 
                                     (String.length msg));
                cout#write_string msg;
1 address@hidden:~/src/sks$ 


The following patch probably also needs to be applied to the development
tree:

--- sks-1.1.2.orig/script.ml    2009-03-25 22:14:44.000000000 -0400
+++ sks-1.1.2/script.ml 2012-04-05 17:29:43.000000000 -0400
@@ -69,7 +69,7 @@
   let sout = Channel.new_buffer_outc 0 in
   CMarshal.marshal_list ~f:CMarshal.marshal_string sout hashes;
   let msg = sout#contents in
-  cout#write_string "POST /pks/hashquery\r\n";
+  cout#write_string "POST /pks/hashquery HTTP/1.0\r\n";
   cout#write_string (sprintf "content-length: %d\r\n\r\n" 
                       (String.length msg));
   cout#write_string msg;
@@ -97,7 +97,7 @@
   let sout = Channel.new_buffer_outc 0 in
   CMarshal.marshal_list ~f:CMarshal.marshal_string sout hashes;
   let msg = sout#contents in
-  cout#write_string "POST /pks/hashquery\r\n";
+  cout#write_string "POST /pks/hashquery HTTP/1.0\r\n";
   cout#write_string (sprintf "content-length: %d\r\n\r\n" 
                       (String.length msg));
   cout#write_string msg;


I'd be happy to try to commit it myself, but i don't think i have access
to the repo.

I'm going to try to get the former fix into debian so that at least
debian-maintained 1.1.1 servers won't send this kind of non-compliant
traffic.

   --dkg

Attachment: pgpCjwwzcj6tC.pgp
Description: PGP signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]