robur-coop / albatross

Albatross: orchestrate and manage MirageOS unikernels with Solo5
ISC License
142 stars 17 forks source link

Albatross-tls-endpoint #143

Closed palainp closed 1 year ago

palainp commented 1 year ago

Hi, thanks for your work on albatross, it's very helpful! I've not updated albatross for a while until last week. I have now an issue starting albatross-tls-endpoint 1.5.3 (the daemon is started with systemd):

# albatross-tls-endpoint --version
version v1.5.3 protocol version 5
# albatross-tls-endpoint --port 1025 -v -v -v --verbosity=debug cacert.pem server.pem server.key
albatross-tls-endpoint: internal error, uncaught exception:
                        Unix.Unix_error(Unix.EINVAL, "bind", "")

This was the commands I used to have but something may have changed recently. With strace I have the following additional information:

...
stat("cacert.pem", {st_mode=S_IFREG|0644, st_size=396, ...}) = 0
stat("server.pem", {st_mode=S_IFREG|0644, st_size=518, ...}) = 0
stat("server.key", {st_mode=S_IFREG|0400, st_size=119, ...}) = 0
rt_sigaction(SIGPIPE, {sa_handler=SIG_IGN, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7ff7a2edb420}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
socket(AF_INET6, SOCK_STREAM, IPPROTO_IP) = 5
fcntl(5, F_GETFD)                       = 0
fcntl(5, F_SETFD, FD_CLOEXEC)           = 0
setsockopt(5, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
setsockopt(5, SOL_IPV6, IPV6_V6ONLY, [0], 4) = 0
bind(5, {sa_family=AF_INET, sin_port=htons(1025), sin_addr=inet_addr("0.0.0.0")}, 16) = -1 EINVAL (Invalid argument)
write(2, "albatross-tls-endpoint: internal"..., 150albatross-tls-endpoint: internal error, uncaught exception:
                        Unix.Unix_error(Unix.EINVAL, "bind", "")

) = 150
rt_sigaction(SIGCHLD, {sa_handler=0x5652b8785300, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7ff7a2edb420}, NULL, 8) = 0
rt_sigaction(SIGSEGV, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7ff7a2edb420}, NULL, 8) = 0
sigaltstack({ss_sp=0x28, ss_flags=SS_DISABLE, ss_size=140735027670208}, {ss_sp=0x5652b945eb50, ss_flags=0, ss_size=8192}) = 0
exit_group(125)                         = ?
+++ exited with 125 +++

The manual page for bind states that EINVAL is returned when the port is already binded (I checked that with netstat -talp and it's not), or addrlen is wrong, or addr is not a valid address for this ocket's domain.. The addrlen is 16 which suggest that bind try to use an IPv6 whereas sin_addr is an IPv4. Is there a way to specify which IP type address I want to use?

reynir commented 1 year ago

Thank you for your report.

I found the relevant code: https://github.com/roburio/albatross/blob/9fee7f7c082c766fd7505dee522d026d76987e1c/src/vmm_lwt.ml#L15-L23

The documentation for Unix.inet_addr_any says

A special IPv4 address, for use only with [bind], representing              
all the Internet addresses that the host machine possesses. 

So it seems we should maybe use Unix.inet6_addr_any instead. In the meantime I think you should be able to use systemd socket activation (if you use systemd). You should have a sample .service and .socket file installed in /usr/share/doc/albatross/ I believe.

It's a good point that it is currently not possible to specify what address to listen on.

hannesm commented 1 year ago

@reynir thanks for the fix, indeed a command line option to specify the listen address for the tls endpoint would be nice.

palainp commented 1 year ago

Thanks for your quick fix!

hannesm commented 1 year ago

Fixed by #144 #147