Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ikos server doesn't listen on IPv6, resulting in hangs #158

Closed
valpackett opened this issue Feb 20, 2020 · 7 comments
Closed

ikos server doesn't listen on IPv6, resulting in hangs #158

valpackett opened this issue Feb 20, 2020 · 7 comments
Assignees
Labels
L-python Language: Python
Milestone

Comments

@valpackett
Copy link

valpackett commented Feb 20, 2020

In an environment created by ikos-scan, IKOS_SCAN_SERVER is set like http://localhost:8433.
On a dualstack system, localhost usually resolves to both V4 and V6 addresses. E.g. curl tries both:

% curl -v localhost:8433
*   Trying ::1:8433...
* TCP_NODELAY set
*   Trying 127.0.0.1:8433...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8433 (#0)
> GET / HTTP/1.1

The ikos server only listens on V4:

% doas sockstat | rg 8433
val     python3.7  37245 3  tcp4   *:8433                *:*

But the ikos-scan-cc client tries to access V6:

% doas sockstat | rg 8433
val     python3.7  7535  3  tcp6   ::1:49105             ::1:8433

and hangs. (This is on FreeBSD.)

@arthaud
Copy link
Member

arthaud commented Feb 25, 2020

Interestingly, there is no mention of IPv4 or IPv6 in the code.

The server is handled by http.server.HTTPServer:

self.httpd = http.HTTPServer(('', self.port),

The client is urllib.request.urlopen:

http.urlopen(os.environ['IKOS_SCAN_SERVER'], data)

As a quick fix, try using 127.0.0.1 instead of localhost there:

os.environ['IKOS_SCAN_SERVER'] = 'http://localhost:%d' % server.port

I won't be able to commit on this project until I get the approval from my new employer.

@ivanperez-keera
Copy link
Collaborator

There are two files we'd have to change: analyzer/python/ikos/view.py and analyzer/python/ikos/scan.py, since both initialize servers and both do it in the same way.

At least on linux, creating a subclass of HTTPServer that sets address_family = socket.AF_INET6 and using that with the first argument set to '::' should be enough.

@ivanperez-keera ivanperez-keera self-assigned this Oct 29, 2023
@ivanperez-keera ivanperez-keera added the L-python Language: Python label Oct 29, 2023
@ivanperez-keera ivanperez-keera added this to the ikos 3.2 milestone Oct 29, 2023
ivanperez-keera added a commit to ivanperez-keera/ikos that referenced this issue Oct 29, 2023
This commit adds a new class HTTPServerIPv6 that inherits from
HTTPServer, but selects IPv6. In systems with dual stack (e.g., default
on linux), opening a server in IPv6 also listens in IPv4.
ivanperez-keera added a commit to ivanperez-keera/ikos that referenced this issue Oct 29, 2023
This commit replaces uses of HTTPServer, which by default only listens
in IPv4 interfaces, with calls to a custom class HTTPServerIPv6, which
listens to IPv6, as well as IPv4 whenever dual-stack is supported.
ivanperez-keera added a commit to ivanperez-keera/ikos that referenced this issue Oct 29, 2023
This commit adds a new class HTTPServerIPv6 that inherits from
HTTPServer, but selects IPv6. In systems with dual stack (e.g., default
on linux), opening a server in IPv6 also listens in IPv4.
ivanperez-keera added a commit to ivanperez-keera/ikos that referenced this issue Oct 29, 2023
This commit replaces uses of HTTPServer, which by default only listens
in IPv4 interfaces, with calls to a custom class HTTPServerIPv6, which
listens to IPv6, as well as IPv4 whenever dual-stack is supported.
ivanperez-keera added a commit to ivanperez-keera/ikos that referenced this issue Oct 29, 2023
This commit adds a new class HTTPServerIPv6 that inherits from
HTTPServer, but selects IPv6. In systems with dual stack (e.g., default
on linux), opening a server in IPv6 also listens in IPv4.
ivanperez-keera added a commit to ivanperez-keera/ikos that referenced this issue Oct 29, 2023
This commit replaces uses of HTTPServer, which by default only listens
in IPv4 interfaces, with calls to a custom class HTTPServerIPv6, which
listens to IPv6, as well as IPv4 whenever dual-stack is supported.
ivanperez-keera added a commit to ivanperez-keera/ikos that referenced this issue Oct 29, 2023
This commit adds a new class HTTPServerIPv6 that inherits from
HTTPServer, but selects IPv6. In systems with dual stack (e.g., default
on linux), opening a server in IPv6 also listens in IPv4.
ivanperez-keera added a commit to ivanperez-keera/ikos that referenced this issue Oct 29, 2023
This commit replaces uses of HTTPServer, which by default only listens
in IPv4 interfaces, with calls to a custom class HTTPServerIPv6, which
listens to IPv6, as well as IPv4 whenever dual-stack is supported.
@ivanperez-keera
Copy link
Collaborator

ivanperez-keera commented Oct 29, 2023

@valpackett Could you please check if #229 solves your issue? The PR is marked as a draft but that's just so that it's not merged accidentally before you try it.

ivanperez-keera added a commit to ivanperez-keera/ikos that referenced this issue Oct 29, 2023
This commit adds a new class HTTPServerIPv6 that inherits from
HTTPServer, but selects IPv6. In systems with dual stack (e.g., default
on linux), opening a server in IPv6 also listens in IPv4.
ivanperez-keera added a commit to ivanperez-keera/ikos that referenced this issue Oct 29, 2023
This commit replaces uses of HTTPServer, which by default only listens
in IPv4 interfaces, with calls to a custom class HTTPServerIPv6, which
listens to IPv6, as well as IPv4 whenever dual-stack is supported.
@valpackett
Copy link
Author

valpackett commented Oct 31, 2023

Woah, it's been 3 years! I haven't really been using ikos lately…

Interestingly I cannot reproduce the hang, not sure what changed where, but v6 errors out on an ioctl instead of hanging and it goes to v4:

__sysctl("net.inet6.ip6.addrctlpolicy",4,0x0,0x82036ea10,0x0,0) = 0 (0x0)
__sysctl("net.inet6.ip6.addrctlpolicy",4,0x30eafd1c6500,0x82036ea10,0x0,0) = 0 (0x0)
socket(PF_INET6,SOCK_DGRAM|SOCK_CLOEXEC,IPPROTO_UDP) = 3 (0x3)
connect(3,{ AF_INET6 [::1]:1 },28)               = 0 (0x0)
getsockname(3,{ AF_INET6 [::1]:13335 },0x82036e8bc) = 0 (0x0)
ioctl(3,SIOCGIFAFLAG_IN6,0x82036e8f0)            ERR#6 'Device not configured'
close(3)                                         = 0 (0x0)
socket(PF_INET,SOCK_DGRAM|SOCK_CLOEXEC,IPPROTO_UDP) = 3 (0x3)
connect(3,{ AF_INET 127.0.0.1:1 },16)            = 0 (0x0)
getsockname(3,{ AF_INET 127.0.0.1:44879 },0x82036e8bc) = 0 (0x0)
close(3)                                         = 0 (0x0)
socket(PF_INET,SOCK_STREAM|SOCK_CLOEXEC,IPPROTO_TCP) = 3 (0x3)
connect(3,{ AF_INET 127.0.0.1:8794 },16)         = 0 (0x0)
setsockopt(3,IPPROTO_TCP,TCP_NODELAY,0x82036f29c,4) = 0 (0x0)
sendto(3,"POST / HTTP/1.1\r\nAccept-Encodi"...,188,0,NULL,0) = 188 (0xbc)

With #229 it does connect over v6 in the end:

connect(3,{ AF_INET 127.0.0.1:8491 },16)         ERR#61 'Connection refused'
close(3)                                         = 0 (0x0)
socket(PF_INET6,SOCK_STREAM|SOCK_CLOEXEC,IPPROTO_TCP) = 3 (0x3)
connect(3,{ AF_INET6 [::1]:8491 },28)            = 0 (0x0)
setsockopt(3,IPPROTO_TCP,TCP_NODELAY,0x820244c1c,4) = 0 (0x0)
sendto(3,"POST / HTTP/1.1\r\nAccept-Encodi"...,188,0,NULL,0) = 188 (0xbc)

I'm a bit concerned about how #229 would behave on a v4-only system though.

Maybe would be better to ask @yurivict who maintains the package in FreeBSD Ports right now for more testing :) I have found an unrelated issue though.. (#230)

@ivanperez-keera
Copy link
Collaborator

ivanperez-keera commented Nov 1, 2023

I'm a bit concerned about how #229 would behave on a v4-only system though.

On a system with no support for IPv6, it'll give you the following error:

$ ikos-view output.db
[ERROR] Could not start the HTTP server: [Errno 97] Address family not supported by protocol

It should be trivial to catch this exception and try IPv4 as a fallback, if that (IPv4-only OSs) is a scenario we care to support.

ivanperez-keera added a commit to ivanperez-keera/ikos that referenced this issue Nov 27, 2023
This commit re-defines the IPv6 HTTP server class to attempt to open a
server listing only on IPv4 if IPv6 is not available.
ivanperez-keera added a commit to ivanperez-keera/ikos that referenced this issue Nov 27, 2023
ivanperez-keera added a commit to ivanperez-keera/ikos that referenced this issue Nov 27, 2023
This commit adds a new class HTTPServerIPv6 that inherits from
HTTPServer, but selects IPv6. In systems with dual stack (e.g., default
on linux), opening a server in IPv6 also listens in IPv4.

[ci skip]
ivanperez-keera added a commit to ivanperez-keera/ikos that referenced this issue Nov 27, 2023
This commit replaces uses of HTTPServer, which by default only listens
in IPv4 interfaces, with calls to a custom class HTTPServerIPv6, which
listens to IPv6, as well as IPv4 whenever dual-stack is supported.

[ci skip]
ivanperez-keera added a commit to ivanperez-keera/ikos that referenced this issue Nov 27, 2023
This commit re-defines the IPv6 HTTP server class to attempt to open a
server listing only on IPv4 if IPv6 is not available.

[ci skip]
ivanperez-keera added a commit to ivanperez-keera/ikos that referenced this issue Nov 27, 2023
ivanperez-keera added a commit to ivanperez-keera/ikos that referenced this issue Nov 27, 2023
Cannot import OSError from os.

[ci skip]
ivanperez-keera added a commit to ivanperez-keera/ikos that referenced this issue Nov 27, 2023
Use self to refer to the object variable. Otherwise, it's just a new
variable.

[ci skip]
ivanperez-keera added a commit to ivanperez-keera/ikos that referenced this issue Nov 27, 2023
…name (NASA-SW-VnV#158).

Use super().__init__. Will keep working even if we inherit from
something else.

[ci skip]
@ivanperez-keera
Copy link
Collaborator

ivanperez-keera commented Nov 27, 2023

I have updated my PR to also handle the case where the machine only supports IPv4. I have tried it with a linux machine with IPv6 enabled and with no IPv6 (disabled at kernel level during book using ipv6.disable=1 as a kernel parameter) and both cases work correctly.

Please try it @valpackett .

I intend to merge that PR and close this issue in a few days if we can't identify any cases for which it doesn't work. (I'll squash/clean the changes before I merge.)

Thanks.

ivanperez-keera added a commit to ivanperez-keera/ikos that referenced this issue Nov 27, 2023
Cannot import OSError from os.

[ci skip]
ivanperez-keera added a commit to ivanperez-keera/ikos that referenced this issue Nov 27, 2023
Use self to refer to the object variable. Otherwise, it's just a new
variable.

[ci skip]
ivanperez-keera added a commit to ivanperez-keera/ikos that referenced this issue Nov 27, 2023
…name (NASA-SW-VnV#158).

Use super().__init__. Will keep working even if we inherit from
something else.

[ci skip]
ivanperez-keera added a commit to ivanperez-keera/ikos that referenced this issue Nov 27, 2023
).

This commit adds a new class HTTPServerIPv6 that listens on IPv6 by
default when available.

In systems where IPv6 is not available, the server attemps to use IPv4.

In systems with dual stack (e.g., default on linux), opening a server in
IPv6 will also listen in IPv4.

[ci skip]
ivanperez-keera added a commit to ivanperez-keera/ikos that referenced this issue Nov 27, 2023
This commit makes ikos-scan and ikos-view use IPv6 when available. More
specifically, it replaces uses of HTTPServer, which by default only
listens on IPv4 interfaces, with calls to a custom class HTTPServerIPv6.
The latter listens on IPv6 when available, as well as IPv4 whenever
dual-stack is supported. If IPv6 is not available, the server defaults
to the old behavior implemented by HTTPServer.

[ci skip]
ivanperez-keera added a commit to ivanperez-keera/ikos that referenced this issue Nov 27, 2023
).

This commit adds a new class HTTPServerIPv6 that listens on IPv6 by
default when available.

In systems where IPv6 is not available, the server attemps to use IPv4.

In systems with dual stack (e.g., default on linux), opening a server in
IPv6 will also listen in IPv4.
ivanperez-keera added a commit to ivanperez-keera/ikos that referenced this issue Nov 27, 2023
This commit makes ikos-scan and ikos-view use IPv6 when available. More
specifically, it replaces uses of HTTPServer, which by default only
listens on IPv4 interfaces, with calls to a custom class HTTPServerIPv6.
The latter listens on IPv6 when available, as well as IPv4 whenever
dual-stack is supported. If IPv6 is not available, the server defaults
to the old behavior implemented by HTTPServer.
ivanperez-keera added a commit to ivanperez-keera/ikos that referenced this issue Nov 27, 2023
).

This commit adds a new class HTTPServerIPv6 that listens on IPv6 by
default when available.

In systems where IPv6 is not available, the server attemps to use IPv4.

In systems with dual stack (e.g., default on linux), opening a server in
IPv6 will also listen in IPv4.
ivanperez-keera added a commit to ivanperez-keera/ikos that referenced this issue Nov 27, 2023
This commit makes ikos-scan and ikos-view use IPv6 when available. More
specifically, it replaces uses of HTTPServer, which by default only
listens on IPv4 interfaces, with calls to a custom class HTTPServerIPv6.
The latter listens on IPv6 when available, as well as IPv4 whenever
dual-stack is supported. If IPv6 is not available, the server defaults
to the old behavior implemented by HTTPServer.
ivanperez-keera added a commit to ivanperez-keera/ikos that referenced this issue Nov 27, 2023
).

This commit adds a new class HTTPServerIPv6 that listens on IPv6 by
default when available.

In systems where IPv6 is not available, the server attemps to use IPv4.

In systems with dual stack (e.g., default on linux), opening a server in
IPv6 will also listen in IPv4.
ivanperez-keera added a commit to ivanperez-keera/ikos that referenced this issue Nov 27, 2023
This commit makes ikos-scan and ikos-view use IPv6 when available. More
specifically, it replaces uses of HTTPServer, which by default only
listens on IPv4 interfaces, with calls to a custom class HTTPServerIPv6.
The latter listens on IPv6 when available, as well as IPv4 whenever
dual-stack is supported. If IPv6 is not available, the server defaults
to the old behavior implemented by HTTPServer.
@ivanperez-keera
Copy link
Collaborator

ivanperez-keera commented Nov 27, 2023

I have cleaned and prepared the PR for merging. If you try it, let me know how it goes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
L-python Language: Python
Projects
None yet
Development

No branches or pull requests

3 participants