Bug 1255507

Summary: NetworkManager no longer provides complete FQDN (DHCP_HOSTNAME) to dhclient
Product: Red Hat Enterprise Linux 7 Reporter: Patrick Talbert <ptalbert>
Component: NetworkManagerAssignee: Beniamino Galvani <bgalvani>
Status: CLOSED ERRATA QA Contact: Desktop QE <desktop-qa-list>
Severity: high Docs Contact: Mirek Jahoda <mjahoda>
Priority: urgent    
Version: 7.1CC: atragler, bgalvani, dcbw, ffotorel, jkurik, kfiresmith, kperrier, lrintel, mjahoda, mknutson, mkolaja, mmatsuya, mmezynsk, ppostler, ptalbert, rkhan, rmetrich, snagar, sukulkar, thaller, tpelka, vbenes
Target Milestone: rcKeywords: ZStream
Target Release: 7.3   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
NetworkManager no longer provides complete FQDN (DHCP_HOSTNAME) to dhclient. Previously, NetworkManager always sent only the host part of a machine host name in a DHCP request. As a consequence, it was not possible to force sending a Fully Qualified Domain Name (FQDN). After this update, the user can configure the FQDN to be sent in a DHCP request by using nmcli and setting ipv4.dhcp-fqdn to the desired FQDN and ensuring that ipv4.dhcp-send-hostname is enabled. In configuration files, the FQDN can be specified with the DHCP_FQDN variable.
Story Points: ---
Clone Of:
: 1353270 (view as bug list) Environment:
Last Closed: 2016-11-03 19:15:05 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On:    
Bug Blocks: 1203710, 1301628, 1313485, 1353270    
Attachments:
Description Flags
[PATCH] dhcp: let users override FQDN dhclient options
none
[PATCH v2] dhcp: let users override FQDN dhclient options none

Description Patrick Talbert 2015-08-20 19:11:02 UTC
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?

Comment 2 Dan Williams 2015-08-20 22:06:01 UTC
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.

Comment 3 Dan Williams 2015-08-20 22:10:24 UTC
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.

Comment 4 Patrick Talbert 2015-08-21 13:46:29 UTC
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

Comment 5 Beniamino Galvani 2015-08-24 08:37:10 UTC
(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.

Comment 6 Patrick Talbert 2015-08-25 21:42:38 UTC
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

Comment 9 Beniamino Galvani 2015-09-03 08:39:08 UTC
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.

Comment 10 Dan Williams 2015-09-05 16:34:48 UTC
(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.

Comment 11 Beniamino Galvani 2015-09-09 11:47:07 UTC
(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.

Comment 12 Beniamino Galvani 2015-10-19 11:19:09 UTC
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.

Comment 13 Lubomir Rintel 2015-10-19 13:46:02 UTC
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?

Comment 14 Jirka Klimes 2015-10-19 15:32:55 UTC
> 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.

Comment 15 Thomas Haller 2015-10-20 08:29:28 UTC
>> 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.

Comment 16 Beniamino Galvani 2015-11-02 13:10:57 UTC
(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.

Comment 17 Beniamino Galvani 2015-11-02 13:13:46 UTC
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).

Comment 20 Dan Williams 2015-11-15 18:07:02 UTC
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.

Comment 29 Beniamino Galvani 2016-05-27 12:54:59 UTC
Created attachment 1162459 [details]
[PATCH] dhcp: let users override FQDN dhclient options

Comment 31 Dan Williams 2016-05-27 18:46:01 UTC
Patch LGTM, but could you add a testcase for it too?

Comment 32 Beniamino Galvani 2016-05-28 08:29:53 UTC
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.

Comment 34 Thomas Haller 2016-05-31 09:00:27 UTC
(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

Comment 42 Thomas Haller 2016-06-14 10:30:44 UTC
+    /**
+     * 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".

Comment 45 Monte Knutson 2016-06-22 14:33:16 UTC
which 7.2.z batch will this be included in?

Comment 55 Kodiak Firesmith 2016-08-10 21:02:01 UTC
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

Comment 57 errata-xmlrpc 2016-11-03 19:15:05 UTC
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

Comment 58 Red Hat Bugzilla 2023-09-14 03:04:03 UTC
The needinfo request[s] on this closed bug have been removed as they have been unresolved for 1000 days