Arch Linux

Please read this before reporting a bug:
https://wiki.archlinux.org/index.php/Reporting_Bug_Guidelines

Do NOT report bugs when a package is just outdated, or it is in the AUR. Use the 'flag out of date' link on the package page, or the Mailing List.

REPEAT: Do NOT report bugs for outdated packages!
Tasklist

FS#71336 - ntpd -u ntp:ntp makes requests as root

Attached to Project: Arch Linux
Opened by Vasile M. (mvasi90) - Tuesday, 22 June 2021, 19:09 GMT
Last edited by Andreas Radke (AndyRTR) - Wednesday, 23 June 2021, 18:03 GMT
Task Type Bug Report
Category Security
Status Assigned
Assigned To Lukas Fleischer (lfleischer)
Architecture All
Severity High
Priority Normal
Reported Version
Due in Version Undecided
Due Date Undecided
Percent Complete 0%
Votes 0
Private No

Details

Description:

ntpd -u ntp:ntp from systemd service makes requests as root.

Additional info:
* package version(s)
4.2.8.p15-1
* journalctl log
kernel: IN= OUT=wlp3s1 SRC=192.168.1.5 DST=82.223.128.121 LEN=76 TOS=0x18 PREC=0xA0 TTL=64 ID=31789 DF PROTO=UDP SPT=123 DPT=123 LEN=56 UID=0 GID=0


Steps to reproduce:

My default iptables policy is drop for all chains. Whitelist mode.
You should use it too on all your systems if you want security and privacy. (vim plugins, gradle, Android Studio, IntelliJ, etc. are sending personal information to the servers...)

-P INPUT DROP
-P FORWARD DROP
-P OUTPUT DROP

Log all dropped packets:
# iptables -A OUTPUT -j LOG --uid-log

Start ntpd
# systemctl start ntpd.service

See the log:
# journalctl -e

Note: This should work, but doesn't work because the gid is 0 (root):
# iptables -A OUTPUT --match udp --protocol udp --dport 123 --match owner --gid-owner ntp -j ACCEPT
This task depends upon

Comment by Thomas Lübking (luebking) - Monday, 05 July 2021, 20:37 GMT
kernel: IN= OUT=wlp3s1 SRC=192.168.1.5 DST=82.223.128.121 LEN=76 TOS=0x18 PREC=0xA0 TTL=64 ID=31789 DF PROTO=UDP ***** SPT=123 ***** DPT=123 LEN=56 UID=0 GID=0

https://datatracker.ietf.org/doc/html/rfc5905
https://docs.oracle.com/cd/E36784_01/html/E37476/gnkmn.html
Fwwi, https://social.technet.microsoft.com/Forums/en-US/e16117c3-0341-4cb8-bb12-f2c084a68dc8/why-do-windows-ntp-queries-use-port-123-for-both-source-and-destination?forum=windowsinternals

Also this would be an upstream but at best.

More decidedly cilent-only implementations might use unprivileged ports in asymmetric mode, eg. ntpclient does.
https://wiki.archlinux.org/title/System_time#Time_synchronization
Comment by Vasile M. (mvasi90) - Tuesday, 06 July 2021, 13:30 GMT
I just realized that the ntpd daemon is listening on port 123:

ss -lupn
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
UNCONN 0 0 <IP>:123 0.0.0.0:* users:(("ntpd",pid=829,fd=23))

I misinterpreted the ArchLinux wiki:
> "Install the ntp package. By default, ntpd works in client mode without further configuration"

I thought it only uses port 123 as a client to connect remotely.
OUT=wlp3s1 *** DPT=123

> More decidedly client-only implementations might use unprivileged ports in asymmetric mode, eg. ntpclient does.
Of course, this would be the best decision. But I will try OpenNTPD instead of ntpclient, to avoid using unofficial repositories and not having to manually maintain and compile every time.

I don't have time to research the ntpd source code. I have two questions:
1. What is the ntp user and group for, if it makes the requests as root?
2. Why are "User=ntp", "Group=ntp", and "CapabilityBoundingSet=cap_net_bind_service" directives not used.

I consider a user process that can open privileged ports (if it is behind a firewall in whitelist mode) more secure than a root process.
A buffer overflow could cause major damage to your system.
Comment by Thomas Lübking (luebking) - Tuesday, 06 July 2021, 14:09 GMT
> I just *realized* that the ntpd daemon is listening on port 123:
That's certainly one way to put it…

ntpd.c:1300
-----

/*
* We may be running under non-root uid now, but we still hold full root privileges!
* We drop all of them, except for the crucial one or two: cap_sys_time and
* cap_net_bind_service if doing dynamic interface tracking.
*/
cap_t caps;
char *captext;

captext = (0 != interface_interval)
? "cap_sys_time,cap_net_bind_service=pe"
: "cap_sys_time=pe";
caps = cap_from_text(captext);
if (!caps) {
msyslog(LOG_ERR,
"cap_from_text(%s) failed: %m",
captext);
exit(-1);
}
if (-1 == cap_set_proc(caps)) {
msyslog(LOG_ERR,
"cap_set_proc() failed to drop root privs: %m");
exit(-1);
}
cap_free(caps);

-----

The process is supposed to run as that user, did you check ps?
You don't need systemd because ntpd has the feature baked in and you'll have to ask upstream for their motives.

Also I'm at hand not sure that a cap-elevated process wouldn't show up as UID in the netfilter stack. Feel free to actually test that.
Comment by Vasile M. (mvasi90) - Tuesday, 06 July 2021, 14:47 GMT
> The process is supposed to run as that user, did you check ps?

Yes, you're right. The process is executed with the user and group "ntp".

> Also I'm at hand not sure that a cap-elevated process wouldn't show up as UID in the netfilter stack.

Yes, the UID and GID are kept.
-----
# systemd-run -t -p User=developer -p Group=developer -p CapabilityBoundingSet=CAP_NET_BIND_SERVICE -p AmbientCapabilities=CAP_NET_BIND_SERVICE curl https://8.8.8.8

kernel: IN= OUT=enp0s20f0u8u2 SRC=<IP> DST=8.8.8.8 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=63555 DF PROTO=TCP SPT=38824 DPT=443 WINDOW=64240 RES=0x00 SYN URGP=0 *UID=1002 GID=1002*
-----

Then, it could make requests with the source port 123 without being root, using capabilities.

Knowing that ntpd requires root privileges because it uses this source port (SRC=123), could we close this bug or mark it as resolved?

I couldn't spend more time asking upstream. There are already alternative client only packages, like OpenNTPD, that solve this "problem".

Thank for your help.

Comment by Thomas Lübking (luebking) - Tuesday, 06 July 2021, 18:47 GMT
> could we close this bug or mark it as resolved?
It's your report and your or Lukas' call.

Loading...