Hide Forgot
Description of problem: In RHEL 7 NetworkManager, if a FQDN is passed in a connection's DHCP_HOSTNAME, only the first part of the hostname is passed in the host-name DHCP option to dhclient. This is different than the behaviour of the network service scripts as well as NM in RHEL 6. Is this a deliberate change? Version-Release number of selected component (if applicable): NetworkManager-1.0.0-16.git20150121.b4ea599c.el7_1.x86_64 How reproducible: Always Steps to Reproduce: 1. Set DHCP_HOSTNAME in a connection profile which uses DHCP: # nmcli connection modify eth0 ipv4.dhcp-hostname "test.example.com" $ grep DHCP_HOSTNAME /etc/sysconfig/network-scripts/ifcfg-eth0 DHCP_HOSTNAME="test.example.com" 2. Bring up the interface: # nmcli connection up eth0 3. Confirm host-name option in /var/lib/NetworkManager/dhclient-eth0.conf Actual results: The shortname is being sent: # grep host-name /var/lib/NetworkManager/dhclient-eth0.conf send host-name "test"; # added by NetworkManager Expected results: The full name should be sent? send host-name "test.example.com"; Additional info: This is a change in behaviour which was unexpected in a customer's environment. Their DHCP responds differently depending on whether the FQDN is seen in host-name or not. From my read of the RFC is seems like it is valid to use host-name for the base name or the FQDN so while I do not believe the behaviour is wrong, I worry it will be non-obvious to customer's this is occurring: https://tools.ietf.org/html/rfc2132 3.14. Host Name Option This option specifies the name of the client. The name may or may not be qualified with the local domain name (see section 3.17 for the preferred way to retrieve the domain name). See RFC 1035 for character set restrictions. 3.17. Domain Name This option specifies the domain name that client should use when resolving hostnames via the Domain Name System. Would it be better for NetworkManager to behave the same way as the network service scripts and NM in RHEL 6? Or should NM set the domain field as well? Or is there a good reason for the new behaviour?
The behavior that strips off the FQDN for send-hostname was added for https://bugzilla.redhat.com/show_bug.cgi?id=694758#c25. The decision to only use the short name is fairly old too, as a result of https://bugzilla.redhat.com/show_bug.cgi?id=697877. It also looks like our internal DHCP client allows the full FQDN, but we should strive to be consistent between internal & dhclient. But there's some additional confusion here. The "-H" dhclient option maps directly to the send-hostname config item, and here the dhclient manpage says: "Specify the host-name option to send to the DHCP server. The host-name string only contains the client's hostname prefix, to which the server will append the ddns-domainname or domain-name options, if any, to derive the fully qualified domain name of the client." Which of course implies that send-hostname should only take a short name, not an FQDN. Which was probably the reason we started stripping the domain off the hostname in the first place. Other parts say that it's permissible (but not preferred) to send the FQDN with send-hostname.
Our RHEL7 old 'network' service initscripts also chop DHCP_HOSTNAME down to a short name, per: https://git.fedorahosted.org/cgit/initscripts.git/commit/?id=60ddb21fcdfb0594a35978aa0b04af4527c46d6e So at least in this respect, NM and 'network' service initscripts agree. I'm not 100% sure that this behavior is correct, but we need to at least agree on the right behavior between the two, and make them consistent.
Hey Dan, I apologize, I'm not sure how I missed those older bugs when I filed this. Thank you for pointing them out. I'll have to double check what is actually happening but I found that the FQDN in DHCP_HOSTNAME was passed by the RHEL 7 network service scripts, not the cut down hostname.... # nmcli con down eth0 # systemctl stop NetworkManager # rpm -q initscripts initscripts-9.49.24-1.el7.x86_64 # grep DHCP_HOSTNAME /etc/sysconfig/network-scripts/ifcfg-eth0 DHCP_HOSTNAME=text.example.com # ifup eth0 # ps aux | grep dhclient root 11161 0.0 1.2 103736 12700 ? Ss 09:38 0:00 /sbin/dhclient -H test.example.com -1 -q -lf /var/lib/dhclient/dhclient-b307d861-4fe2-4185-bfef-7211d9d47516-eth0.lease -pf /var/run/dhclient-eth0.pid eth0 So, the network service scripts pass the FQDN to the -H option of dhclient. As was pointed out in bz694758, it looks like this behaviour is incorrect per the dhclient man page: -H <host-name> Specify the host-name option to send to the DHCP server. The host-name string only contains the client's hostname prefix, to which the server will append the ddns-domainname or domain-name options, if any, to derive the fully qualified domain name of the client. The -H option cannot be used with the -F option. If we're going to pass the entire thing, it should be using -F? -F <fqdn.fqdn> Specify the fqdn.fqdn option to send to the DHCP server. This option cannot be used with the -H option. The fqdn.fqdn option must specify the com‐ plete domain name of the client host, which the server may use for dynamic DNS updates. I sorta lean towards making NM do the same thing that the network service scripts do now, as it has seemingly been done that way for so long... but at the end of the day it *appears* it has been wrong all along. Though, what NM in RHEL 7 does appears to be a more correct behaviour. How about having both NM and network service scripts send host-name if the DHCP_HOSTNAME is a bare hostname and send fqdn.fqdn (-F) if DHCP_HOSTNAME is a FQDN? Thank you again, Patrick
(In reply to Patrick Talbert from comment #4) > How about having both NM and network service scripts send host-name if the > DHCP_HOSTNAME is a bare hostname and send fqdn.fqdn (-F) if DHCP_HOSTNAME is > a FQDN? This seems the right thing to do, but I wonder if this new change in behavior could break some existing setups. Probably no, because sending '-F host.domain' should be equivalent to sending '-H host', maybe except in the cases in which the client domain is different from server domain. But the new behavior would be more correct anyway. And also, while the change to support this in NM is trivial for dhclient, the internal (systemd-networkd based) DHCP client doesn't support the fqdn option at the moment; if we decide to go this way we need to introduce this feature and merge it upstream.
Dan, Can you think of a workaround for this in RHEL 7 which still allows the use of NetworkManager? I don't think a dispatcher script can affect the dhclient config file NM generates before it is used, no? It would be awesome if it could.... The customer here is anxious for a fix but obviously it still needs to be determined what that would even be so I can't really provide any type of time line. I suggested: 1. Disabling NetworkManager 2. Setting the FQDN in the /etc/hostname file (hostnamectl) as NM will defer to that (right??) 3. Change the DHCP server settings (ha!) Shoot, I guess a dispatcher script could set the hostname to the value of DHCP_HOSTNAME after the interface comes up? ugh.... Thank you, Patrick
Looking at RHEL7 scripts, it may seem that DHCP_HOSTNAME gets stripped in network-functions:expand_config(), but actually the function is not called when the address is dynamic and so the final result is that the dhclient invocation: DHCLIENTARGS="${DHCLIENTARGS} -H ${DHCP_HOSTNAME:-${HOSTNAME%%.*}} ... only strips the system hostname. Probably this is a bug, as it seems that the purpose of commit: https://git.fedorahosted.org/cgit/initscripts.git/commit/?id=60ddb21fcdfb0594a35978aa0b04af4527c46d6e&context=30&ignorews=0&ss=0 was to strip also DHCP_HOSTNAME. So I think we have two options: 1. change NM to behave like init scripts and avoid stripping DHCP_HOSTNAME; HOSTNAME would be still stripped 2. change both NM and init scripts to send the fqdn option when HOSTNAME (or DHCP_HOSTNAME) is a FQDN. I would prefer 2. as 1. looks inconsistent and also not compliant with RFCs. Dan, what do you think? (In reply to Patrick Talbert from comment #6) > > Can you think of a workaround for this in RHEL 7 which still allows the use > of NetworkManager? I don't think a dispatcher script can affect the dhclient > config file NM generates before it is used, no? It would be awesome if it > could.... > > 2. Setting the FQDN in the /etc/hostname file (hostnamectl) as NM will defer > to that (right??) I don't think this will work as NM will remove the domain part before passing it to dhclient. As a workaround you can try to set dhcp=internal in the [main] section of /etc/NetworkManager/NetworkManager.conf since the internal DHCP client doesn't strip the hostname.
(In reply to Beniamino Galvani from comment #9) > Looking at RHEL7 scripts, it may seem that DHCP_HOSTNAME gets stripped > in network-functions:expand_config(), but actually the function is not > called when the address is dynamic and so the final result is that the > dhclient invocation: > > DHCLIENTARGS="${DHCLIENTARGS} -H ${DHCP_HOSTNAME:-${HOSTNAME%%.*}} ... > > only strips the system hostname. Probably this is a bug, as it seems > that the purpose of commit: > > > https://git.fedorahosted.org/cgit/initscripts.git/commit/ > ?id=60ddb21fcdfb0594a35978aa0b04af4527c46d6e&context=30&ignorews=0&ss=0 > > was to strip also DHCP_HOSTNAME. > > > So I think we have two options: > > 1. change NM to behave like init scripts and avoid stripping > DHCP_HOSTNAME; HOSTNAME would be still stripped > > 2. change both NM and init scripts to send the fqdn option when > HOSTNAME (or DHCP_HOSTNAME) is a FQDN. > > I would prefer 2. as 1. looks inconsistent and also not compliant with > RFCs. Dan, what do you think? I originally thought #1, because DHCP_HOSTNAME is explicitly set by the user and is only used for DHCP, and thus you could think of it as an admin override and the admin knows what they are doing. But I think you're right with #2 and that's the best path forward. So lets see if the initscripts people are OK with this? It seems clear that the intention back in 2010 was to strip the hostname anyway. Obviously we cannot strip the hostname for IPv6 though, since that's not allowed by the relevant DHCPv6 RFCs (#4704, https://tools.ietf.org/html/rfc4704). So this could present a problem in the ifcfg files, where DHCP_HOSTNAME is used for DHCPv4 and DHCPv6. If the admin wants to use a short hostname for DHCPv4, then we could not also send that with DHCPv6. But I think that's OK.
(In reply to Dan Williams from comment #10) > But I think you're right with #2 and that's the best path forward. So lets > see if the initscripts people are OK with this? It seems clear that the > intention back in 2010 was to strip the hostname anyway. Okay, I opened bug 1260552 against initscripts, let's see which is their opinion. > Obviously we cannot strip the hostname for IPv6 though, since that's not > allowed by the relevant DHCPv6 RFCs (#4704, > https://tools.ietf.org/html/rfc4704). So this could present a problem in > the ifcfg files, where DHCP_HOSTNAME is used for DHCPv4 and DHCPv6. If the > admin wants to use a short hostname for DHCPv4, then we could not also send > that with DHCPv6. But I think that's OK. Yes, I guess there's nothing we can do to solve this.
As suggested in bug 1260552, solution #2 would change behavior and possibly break working setups. A more conservative approach is to add a new 'ipv4.dhcp-fqdn' property, mutually exclusive with 'ipv4.dhcp-hostname', so that system administrator can choose which of the two options to send. When 'ipv4.dhcp-fqdn' is not set the old behavior is retained. Pushed branch bg/dhcp-send-fqdn-rh1255507 for review. While at this, I also made the different DHCP clients behave the same way WRT stripping of hostname (first 2 commits). The changes to libsystemd-network will need to be submitted upstream.
Adding a new option for this looks like a good idea to me. The patchset seems all good to me too apart from one tiny nitpick: systemd: add support for "Client FQDN" DHCP option + host_len = strlen(hostname); + if (host_len + 2 > len) + return -1; ^^^^^^^^ whitespace error?
> ifcfg-rh: support DHCP_FQDN variable + if (value && strlen (value)) { Let's use "if (value && *value) {" instead Other than that the branch look good to me.
>> systemd: add support for "Client FQDN" DHCP option whitespace error: + host_len = strlen(hostname); + if (host_len + 2 > len) + return -1; >> ifcfg-rh: support DHCP_FQDN variable This commit should come before the nmcli commit. + value = nm_setting_ip4_config_get_dhcp_fqdn (NM_SETTING_IP4_CONFIG (s_ip4)); + if (value) + svSetValue (ifcfg, "DHCP_FQDN", value, FALSE); IMO the "if (value)" is harmful. svSetValue() would remove the key if value is unset, which is exactly what we want. Similar for hostname above.
(In reply to Thomas Haller from comment #15) > + value = nm_setting_ip4_config_get_dhcp_fqdn (NM_SETTING_IP4_CONFIG > (s_ip4)); > + if (value) > + svSetValue (ifcfg, "DHCP_FQDN", value, FALSE); > > > IMO the "if (value)" is harmful. svSetValue() would remove the key if value > is unset, which is exactly what we want. > Similar for hostname above. Right; I fixed this by clearing DHCP_FQDN before calling write_ip4_setting(). Also, fixed the other comments above and repushed the branch.
Patrick, just to check before proceeding, would a new ipv4.dhcp-fqdn connection property solve the customer issue? When that property is set NM will send the property value in the FQDN option; instead if the property is empty the stripped hostname (from ipv4.dhcp-hostname or the system-configured one) will be sent in the hostname property (as it is now).
The approach of adding the new option sounds OK to me; there isn't any way to autodetect this so it's the best we can do.
Merged to master: http://cgit.freedesktop.org/NetworkManager/NetworkManager/commit/?id=9b1d195600721bac1ce6df6e5b284847a11b071c
Created attachment 1162459 [details] [PATCH] dhcp: let users override FQDN dhclient options
Patch LGTM, but could you add a testcase for it too?
Created attachment 1162587 [details] [PATCH v2] dhcp: let users override FQDN dhclient options (In reply to Dan Williams from comment #31) > Patch LGTM, but could you add a testcase for it too? Fixed in v2.
(In reply to Beniamino Galvani from comment #32) > Created attachment 1162587 [details] > [PATCH v2] dhcp: let users override FQDN dhclient options > > (In reply to Dan Williams from comment #31) > > Patch LGTM, but could you add a testcase for it too? > > Fixed in v2. fqdn_opts leaks the strings. otherwise, lgtm
(In reply to Thomas Haller from comment #34) > fqdn_opts leaks the strings. Fixed and applied to master: https://cgit.freedesktop.org/NetworkManager/NetworkManager/commit/?id=f940428c659eb9bd797da4545dd000bfa18ca99c and nm-1-2: https://cgit.freedesktop.org/NetworkManager/NetworkManager/commit/?h=nm-1-2&id=30f53e7e22628fb04d80dec978123b9b3653b89d
+ /** + * NMSettingIP4Config:dhcp-fqdn: + * + * Since: 1.0.6 this is not correct, because dhcp-fqdn is not (upstream) 1.0.6 API. If the Since tag allows arbitrary names, I would say something like "Since: 1.0.6-rhel7.2".
which 7.2.z batch will this be included in?
Woot! I can confirm for MS DHCP servers, using the RHEL 7.3 Z-stream packages (Thanks Red Hat support for the backport-sauce), that this works with the following settings, some of which my be redundant: /etc/sysconfig/network-scripts/ifcfg-$iface DHCP_HOSTNAME="host.ad.college.edu" DHCP_FQDN="host.ad.college.edu" ^^ this alone does not fix^^ nmcli con modify enp0s31f6 ipv4.dhcp-fqdn host.ad.college.edu ^^this is probably the only needed thing to fix w/ z-stream 7.3 packages^^ Results: # nmcli con show enp0s31f6 | grep host.ad.college.edu ipv4.dhcp-fqdn: host.ad.college.edu # cat /var/lib/NetworkManager/dhclient-enp0s31f6.conf # Created by NetworkManager send fqdn.fqdn "host.ad.college.edu"; # added by NetworkManager send fqdn.encoded on; send fqdn.server-update on; # dig +short host.ad.college.edu 10.123.456.789 RPMs that fixed the problem for me: Aug 10 16:37:43 Updated: 1:NetworkManager-libnm-1.0.6-31.el7_2.x86_64 Aug 10 16:37:45 Updated: 1:NetworkManager-1.0.6-31.el7_2.x86_64 Aug 10 16:37:45 Updated: 1:NetworkManager-tui-1.0.6-31.el7_2.x86_64 Aug 10 16:37:46 Updated: 1:NetworkManager-wifi-1.0.6-31.el7_2.x86_64 Aug 10 16:37:47 Updated: 1:NetworkManager-team-1.0.6-31.el7_2.x86_64 Aug 10 16:37:48 Updated: 1:NetworkManager-adsl-1.0.6-31.el7_2.x86_64 Aug 10 16:37:49 Updated: 1:NetworkManager-glib-1.0.6-31.el7_2.x86_64 Aug 10 16:37:50 Updated: 1:NetworkManager-config-server-1.0.6-31.el7_2.x86_64
Since the problem described in this bug report should be resolved in a recent advisory, it has been closed with a resolution of ERRATA. For information on the advisory, and where to find the updated files, follow the link below. If the solution does not work for you, open a new bug report. https://rhn.redhat.com/errata/RHSA-2016-2581.html