#7415 CA installer need to check availability of port 8080
Closed: fixed Opened by rcritten.

Issue

User on freeipa-users reported failed installation in the CA step due to timeout:

https://lists.fedoraproject.org/archives/list/freeipa-users@lists.fedorahosted.org/thread/NJGOCCDSEOM3TOZXI6BHX6XH66EW77Q4/#TSY3TY5YOJDTQQC46Z3TB57366A3Q646

The user diagnosed this to be due to another process listening on port 8080.

port 8443 is checked in ipaserver/install/cainstance.py::check_port() but AFAICT port 8080 is not checked anywhere.


Metadata Update from @cheimes:
- Issue priority set to: important
- Issue set to the milestone: FreeIPA 4.6.4
- Issue tagged with: easyfix

Metadata Update from @rcritten:
- Issue priority set to: low (was: important)
- Issue set to the milestone: FreeIPA 4.7 (was: FreeIPA 4.6.4)

I was looking into this issue and there seems to be some misuse of ipautil.host_port_open():

not ipautil.host_port_open(None, 8443)

host_port_open() only returns true if a process is listening on all resolved addresses i.e ipv4 and ipv6.

Negating the result is not the same as checking whether a port is free. If a process is listening only on ipv4 then host_port_open() will return False, which when negated will incorrectly tell us that the port is free.

I think we need another function written to check whether a port is free... thoughts?

I've created a PR for review... https://github.com/freeipa/freeipa/pull/1721

Some of my testing output:

server listening on port 8080

[admin@idm ~]$ ./conn_test_srv -p 8080
[] listening on port 8080
[
] connection from 127.0.0.1 <-- port check connection
[] waiting for response
[
] received:

perform server install

[admin@idm freeipa]$ sudo ipa-server-install

The log file for this installation can be found in /var/log/ipaserver-install.log

This program will set up the FreeIPA Server.

This includes:
* Configure a stand-alone CA (dogtag) for certificate management
* Configure the Network Time Daemon (ntpd)
* Create and configure an instance of Directory Server
* Create and configure a Kerberos Key Distribution Center (KDC)
* Configure Apache (httpd)
* Configure the KDC to enable PKINIT

To accept the default shown in brackets, press the Enter key.

WARNING: conflicting time&date synchronization service 'chronyd' will be disabled
in favor of ntpd

Do you want to configure integrated DNS (BIND)? [no]: yes

Enter the fully qualified domain name of the computer
on which you're setting up server software. Using the form
.
Example: master.example.com.

Server host name [idm.lab.internal]:

Warning: skipping DNS resolution of host idm.lab.internal
The domain name has been determined based on the host name.

Please confirm the domain name [lab.internal]:

The kerberos protocol requires a Realm name to be defined.
This is typically the domain name converted to uppercase.

Please provide a realm name [LAB.INTERNAL]:
Certain directory server operations require an administrative user.
This user is referred to as the Directory Manager and has full access
to the Directory for system management tasks and will be added to the
instance of directory server created for IPA.
The password must be at least 8 characters long.

Directory Manager password:
Password (confirm):

The IPA server requires an administrative user, named 'admin'.
This user is a regular system account used for IPA server administration.

IPA admin password:
Password (confirm):

IPA requires ports 8443 and 8080 for PKI but one or more are currently in use.
ipapython.admintool: ERROR Aborting installation
ipapython.admintool: ERROR The ipa-server-install command failed. See /var/log/ipaserver-install.log for more information

log msgs with log_conns=True

...
2018-03-22T01:25:06Z DEBUG Failed to connect to port 8443 tcp on ::1
2018-03-22T01:25:06Z DEBUG Failed to connect to port 8443 tcp on 127.0.0.1
2018-03-22T01:25:06Z DEBUG Failed to connect to port 8080 tcp on ::1
2018-03-22T01:25:06Z DEBUG Connected to port 8080 tcp on 127.0.0.1
2018-03-22T01:25:06Z DEBUG File "/usr/lib/python3.6/site-packages/ipapython/admintool.py", line 174, in execute
return_value = self.run()
File "/usr/lib/python3.6/site-packages/ipapython/install/cli.py", line 319, in run
return cfgr.run()
...

thanks

Sorry.. PR was broken.. new PR: https://github.com/freeipa/freeipa/pull/1722

Good catch! :)

You are correct. The current code is wrong. I looked into other use of the host_port_open function and opened #7460.

Your approach in PR https://github.com/freeipa/freeipa/pull/1722 has another issue. You are using None as a hostname. That translates into whatever the IP address for localhost is (127.0.0.1 for AF_INET and ::1 for AF_INET6). The new code isn't checking public interfaces. Dogtag and 389-DS bind to all interfaces on all protocols.

AFAIK the only correct approach is to attempt to bind a socket and see if it succeeds. We need a new function that checks if a port is bindable:

  • bind('', 8080) will fail if any application has opened port 8080 on either all interfaces or just on ip.
  • bind with AF_INET6 also binds to IPv4 by default. You can check both IPv4 and IPv6 in one go.
  • Use s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True) before you bind.
  • Fall back to IPv4 if IPv6 protocol is not available.

:p .. the new function was a direct copy... I didn't look into host_port_open() enough to see that it was THAT broken... I'll attack it again tomorrow.. thanks!

master:

  • 6aca027ecc5c1bbcd1a69deea10d2ff991c53f5e Fix installer CA port check for port 8080

Metadata Update from @cheimes:
- Issue close_status updated to: fixed
- Issue status updated to: Closed (was: Open)

Metadata