auditd records port "1" for outbound HTTPS connections

I'm trying to tune auditd(8) to record the destination address and port of network connections initiated by a web server, i.e. where the server is acting as a client. After configuring auditd to record all flags in /etc/security/audit_control, I fetched a web page with curl, and found the information I want is recorded in the socket-inet token during the audit of the connect(2) syscall. I'm aware that setting flags to "all" is usually foolish, but this web server is so sparsely visited that I haven't noticed any performance issues, and this is still an experiment.

Reviewing audit records for the connect(2) syscall, I found auditd(8) reports the expected destination IP address for all outbound connections, but in the case of outbound HTTPS connections, it reports a destination port of "1" instead of "443".

Does anyone know why auditd does this? If not, can you direct me to resources that might help me explain this? The auditd mailing list looks to be essentially dead, and the FreeBSD Handbook's discussion of auditing seems limited to theory and set up.

Below is an account of everything I've tried to understand this.

Details
=======

First, I confirmed that auditd was reliably producing audit trails on the web server. Then, I made web requests from the host to test my audit configuration. I su'd to root, then su'd to the test account "atest" and ran:

Code:
atest@myhost:~ $ curl https://www.freebsd.org

Seeing that the web request succeeded, I checked the audit trail, and found the connect(2) calls for the DNS requests and web requests that curl had made. The connections for the DNS requests look like this:

Code:
<record version="11" event="connect(2)" modifier="0" time="Thu Sep 19 12:33:45 2024" msec=" + 7 msec" >
<argument arg-num="1" value="0x7" desc="fd" />
<socket-inet type="2" port="53" addr="10.0.0.2" />
<subject audit-uid="my acutal username" uid="atest" gid="atest" ruid="atest" rgid="atest" pid="42732" sid="42683" tid="40826 myclientIP" />
<return errval="success" retval="0" />
</record>

The web request, however, looked like this:

Code:
<record version="11" event="connect(2)" modifier="0" time="Thu Sep 19 12:33:45 2024" msec=" + 71 msec" >
<argument arg-num="1" value="0x7" desc="fd" />
<socket-inet type="2" port="1" addr="173.228.147.99" />
<subject audit-uid="my actual username" uid="atest" gid="atest" ruid="atest" rgid="atest" pid="42732" sid="42683" tid="40826 myclientIP" />
<return errval="success" retval="0" />
</record>

Here, you see the web server connected to www.freebsd.org at 173.228.147.99, which looks like a regional mirror of the site that my web server would resolve from inside AWS. Instead of connecting its port 443, though, auditd reports a destination port of "1".

Wanting to see what this looked like from my laptop, I configured auditd to record "all" flags there, created the "atest" user, du'd to it from root, and made the same curl request. The audit trail recorded the same connect(2) events for the DNS queries made by curl, but records the following connect invocations unrelated to DNS:

Code:
<record version="11" event="connect(2)" modifier="0" time="Thu Sep 19 11:52:31 2024" msec=" + 927 msec" >
<argument arg-num="1" value="0xa" desc="fd" />
<subject audit-uid="root" uid="atest" gid="atest" ruid="atest" rgid="atest" pid="14532" sid="8295" tid="0 0.0.0.0" />
<return errval="failure : No route to host" retval="4294967295" />
</record>

<record version="11" event="connect(2)" modifier="0" time="Thu Sep 19 11:52:31 2024" msec=" + 927 msec" >
<argument arg-num="1" value="0xa" desc="fd" />
<socket-inet type="2" port="1" addr="96.47.72.77" />
<subject audit-uid="root" uid="atest" gid="atest" ruid="atest" rgid="atest" pid="14532" sid="8295" tid="0 0.0.0.0" />
<return errval="success" retval="0" />
</record>

<record version="11" event="connect(2)" modifier="0" time="Thu Sep 19 11:52:31 2024" msec=" + 928 msec" >
<argument arg-num="1" value="0x8" desc="fd" />
<subject audit-uid="root" uid="atest" gid="atest" ruid="atest" rgid="atest" pid="14532" sid="8295" tid="0 0.0.0.0" />
<return errval="failure : No route to host" retval="4294967295" />
</record>

<record version="11" event="connect(2)" modifier="0" time="Thu Sep 19 11:52:31 2024" msec=" + 928 msec" >
<argument arg-num="1" value="0x8" desc="fd" />
<socket-inet type="2" port="443" addr="96.47.72.77" />
<subject audit-uid="root" uid="atest" gid="atest" ruid="atest" rgid="atest" pid="14532" sid="8295" tid="0 0.0.0.0" />
<return errval="failure : Operation now in progress" retval="4294967295" />
</record>

I'm speculating that the events with errval "failure : No route to host" are due to curl maybe attempting to connect via IPv6 first. I need to look into that further.

Note the second event is much like the events for the HTTPS connection on the web server: exactly what I want, except for this port "1" value.

The last event is my desired output: time, destination IP address and the correct destination port (443). Curiously, the connect(2) syscall there is shown returning an error. In other tests, I've managed to see audit records for connect() calls that don't have a failure in "errval", but again, only on my laptop.

Anyone have a guess as to:

(1) Why auditd records destination port 1 for each web request, but not DNS requests? When I look at a few hours' worth of audit logs on my laptop (a nosier client system), I see the port 1 events preceding other connections outbound for hosts listening on 22 and 123, but none for port 80.

(2) Why would auditd record the correct destination port on my laptop, but not on the web server? They're both running 14.1-RELEASE-p4, using generic kernels, on AMD 64. The web server's using a UFS file while the laptop's using ZFS, but I can't think how that'd make a difference.

Thanks!
 
Back
Top