group.of.nepali.translators team mailing list archive
-
group.of.nepali.translators team
-
Mailing list archive
-
Message #07290
[Bug 1619687] Re: nginx incorrectly handles slow connection in deferred mode
** Also affects: nginx (Ubuntu Xenial)
Importance: Undecided
Status: New
** Also affects: nginx (Ubuntu Trusty)
Importance: Undecided
Status: New
--
You received this bug notification because you are a member of नेपाली
भाषा समायोजकहरुको समूह, which is subscribed to Xenial.
Matching subscriptions: Ubuntu 16.04 Bugs
https://bugs.launchpad.net/bugs/1619687
Title:
nginx incorrectly handles slow connection in deferred mode
Status in nginx package in Ubuntu:
New
Status in nginx source package in Trusty:
New
Status in nginx source package in Xenial:
New
Bug description:
Summary:
When nginx has a server that is configured in the 'deferred' listen
mode and it takes the client more than approx. 1 second to send data,
nginx will hang and eventually time the connection out.
Tested Versions:
lsb_release -rd:
Description: Ubuntu 14.04.5 LTS
Release: 14.04
apt-cache policy nginx
nginx:
Installed: 1.4.6-1ubuntu3.5
Candidate: 1.4.6-1ubuntu3.5
Version table:
*** 1.4.6-1ubuntu3.5 0
500 http://mirrors.digitalocean.com/ubuntu/ trusty-updates/main amd64 Packages
500 http://security.ubuntu.com/ubuntu/ trusty-security/main amd64 Packages
100 /var/lib/dpkg/status
1.4.6-1ubuntu3 0
500 http://mirrors.digitalocean.com/ubuntu/ trusty/main amd64 Packages
Reproduction Guidelines:
1. Install nginx on a vanilla system: apt-get update && apt-get upgrade -y && apt-get install -y nginx
2. Configure nginx with a basic SSL setup. A self-signed certificate is fine. The only divergence from the regular nginx SSL setup should be that the 'listen' line must contain the "deferred" directive.
3. Confirm nginx functions correctly using curl (`curl -k https://localhost`). This should print the HTML of the default welcome page.
4. Open a file called test.py. Copy the following script into it:
import socket
import ssl
import sys
import time
TARGET = ('localhost', 443)
def connect_slowly():
print "connecting...",
sys.stdout.flush()
s = socket.create_connection(TARGET)
print "connected"
print "sleeping...",
sys.stdout.flush()
time.sleep(2)
print "slept"
print "beginning ssl handshake...",
sys.stdout.flush()
s = ssl.wrap_socket(s)
print "complete"
s.sendall(
b'GET / HTTP/1.1\r\n'
b'Host: localhost\r\n'
b'\r\n'
)
print s.recv(8192)
connect_slowly()
5. Execute `python test.py`
Expected behaviour:
Expect the script to run fairly promptly, and to print:
connecting... connected
sleeping... slept
beginning ssl handshake...complete
followed by some portion (possibly all) of the default landing page.
Actual behaviour:
The script produces the following output:
connecting... connected
sleeping... slept
beginning ssl handshake...
and then hangs for approximately a minute, after which it prints the
following traceback:
Traceback (most recent call last):
File "test.py", line 33, in <module>
connect_slowly()
File "test.py", line 23, in connect_slowly
s = ssl.wrap_socket(s)
File "/usr/lib/python2.7/ssl.py", line 487, in wrap_socket
ciphers=ciphers)
File "/usr/lib/python2.7/ssl.py", line 243, in __init__
self.do_handshake()
File "/usr/lib/python2.7/ssl.py", line 405, in do_handshake
self._sslobj.do_handshake()
socket.error: [Errno 104] Connection reset by peer
Explanation:
Some misbehaviour appears to be occurring in nginx around the
TCP_DEFER_ACCEPT timeout and TLS handshakes. Specifically, nginx seems
to "lose" the connection once the deferred timeout fires. Observing a
packet capture demonstrates the problem more clearly (though note that
for obvious reasons you can't do this on localhost!)
13:59:06.546468 IP 51.6.64.223.65442 > 67.205.133.224.443: Flags [S], seq 4198376207, win 65535, options [mss 1452,nop,wscale 5,nop,nop,TS val 146528037 ecr 0,sackOK,eol], length 0
13:59:06.546543 IP 67.205.133.224.443 > 51.6.64.223.65442: Flags [S.], seq 3994111434, ack 4198376208, win 28960, options [mss 1460,sackOK,TS val 729780 ecr 146528037,nop,wscale 6], length 0
13:59:06.835143 IP 51.6.64.223.65442 > 67.205.133.224.443: Flags [.], ack 3994111435, win 4140, options [nop,nop,TS val 146528326 ecr 729780], length 0
13:59:07.542989 IP 67.205.133.224.443 > 51.6.64.223.65442: Flags [S.], seq 3994111434, ack 4198376208, win 28960, options [mss 1460,sackOK,TS val 730030 ecr 146528326,nop,wscale 6], length 0
13:59:07.657420 IP 51.6.64.223.65442 > 67.205.133.224.443: Flags [.], ack 3994111435, win 4140, options [nop,nop,TS val 146529110 ecr 729780], length 0
13:59:08.943065 IP 51.6.64.223.65442 > 67.205.133.224.443: Flags [P.], seq 4198376208:4198376725, ack 3994111435, win 4140, options [nop,nop,TS val 146530274 ecr 729780], length 517
13:59:08.943087 IP 67.205.133.224.443 > 51.6.64.223.65442: Flags [.], ack 4198376725, win 470, options [nop,nop,TS val 730380 ecr 146530274], length 0
14:00:07.693962 IP 67.205.133.224.443 > 51.6.64.223.65442: Flags [R.], seq 3994111435, ack 4198376725, win 470, options [nop,nop,TS val 745067 ecr 146530274], length 0
In this capture, you can see that the TCP 3-way handshake is completed
almost immediately: within 300ms. The client then pauses for 2
seconds. 1 second after the original SYN packet was received, the
SYN+ACK from the server is retransmitted: this is the characteristic
sign of the timeout from TCP_DEFER_ACCEPT firing. The client
retransmits the ACK from packet 3. Two seconds after the original
client ACK was sent in packet 3, the client sends the SSL Client Hello
in a PSH+ACK segment that's 517 bytes long. This is ACK'd by the
server (showing that it received it), but no Server Hello is ever sent
back: nginx has *lost* the TLS handshake.
61 seconds after the connection was initiated, 60 seconds after the
DEFER_ACCEPT timer fired, nginx tears the connection down as idle.
This causes our Python traceback.
It's not yet clear to me where in nginx this problem is occurring, and
I'm not enough of an expert to dive in. I also haven't checked whether
this is patched in a future release: I'll investigate in Xenial
shortly. Insight welcome!
To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/nginx/+bug/1619687/+subscriptions