Subscribe to the feed
Linux 

Configuration files, which include other files, are not new. Placing those included files in sub-directories has also been an option since the beginning. Let's review use cases and see how to get the most out of this organization method. 

Some people find a single configuration file to be the "simple" approach and a whole tree of files to be more complex. However, stop and think about how large some configuration files might grow, or how many different people or programs need to edit them. It really can be easier to allow each subproject to drop their configuration into their own file in a subdirectory. Recently, such as in systemd documentation, these files are sometimes called "drop-in" files. 

Over time, and especially in the past few years, the use of subdirectories in /etc has increased. Two significant situations are driving this movement:

  • Larger programs have split complex configuration files into multiple smaller files.
  • Many other programs have become dependent on a single utility. Each of those utilities needs to manage a portion of the configuration.
Output of ls -d /etc/*.d

 

Populate per package

Some of the first uses of *.d directories I encountered were for logging and scheduling. Let's look at the logrotate utility. The main configuration file is /etc/logrotate.conf. It is not very complicated, but each file to be rotated needs to be specified. Each file may also need different configuration options. Instead of editing this single file each time an application is added or updated on the system, we separate the configuration for each application to a specific file. 

$ grep ^include /etc/logrotate.conf 
include /etc/logrotate.d

The main configuration file includes all files in another directory. Files in the directory may originate from different RPM packages.

$ rpm -qf /etc/logrotate.d/aide
aide-0.16-12.fc31.x86_64
$rpm -qf /etc/logrotate.d/rsyslog
rsyslog-8.2002.0-1.fc31.x86_64
$ rpm -qf /etc/logrotate.d/chrony
chrony-3.5-4.fc31.x86_64

The owner of each package knows what needs to be rotated and how frequently. They provide a configuration file specific to their application and add it to logrotate.d directory during installation. It is also removed from logrotate.d directory when the package is uninstalled from the system. 

Other examples of this use case are scheduling with cron in the cron.d directory and authentication configuration with PAM in the pam.d directory. By using separate files, the system administrator does not need to manage conflicting writes to a single file.

Organize by function

The Apache web server is an extensive program with many configuration options. Apache utilizes a conf.d directory for organization. When I started with Apache, it was common to have a single server host multiple virtual sites. Each of those virtual hosts had its own configuration file. This approach allowed us to share the administration duties of the files as well as share the files on different systems during migration, recovery, and load balancing. Today, I see more cases where the configuration is separated by function.

Another factor is if the feature is installed as a separate module. 

$ rpm -qf /etc/httpd/conf.d/ssl.conf 
mod_ssl-2.4.43-1.fc31.x86_64

The ssl.conf configuration is made available only when the mod_ssl package is installed. Other modules may also drop files into the conf.d directory. Some applications, like the mod_auth_kerb package, provide a sample in a /usr/share/doc directory. It is up to the web administrator to create or manage the production files.

[ Need more help learning Linux? Free online course: Red Hat Enterprise Linux technical overview. ]

Centralized management

As I suggested with web configuration files, another use of separate configuration files is to make centralized management of these files easier, and only distribute relevant components to each managed node.

The modules.d directory holds the configuration for kernel module settings and the sysctl.d directory contains kernel tuning settings. These settings may only be needed on some systems, or may require hardware-specific settings. The settings can be organized by hardware, function, or a combination. 

Configuration management programs can push just the relevant files to specific managed hosts or generate the files on each host based on a template. If you are distributing these files with a configuration management solution such as Ansible, use something like the ansible_managed variable to include a comment indicating that the file is managed remotely.  

Determine a name and location

While dot-d directories have common use cases for assisting with organization and distribution, there are many different ways of handling the includes. For each application or utility, we need to determine how best to name our files. Some configurations only recognize files with a specific extension, such as .conf, while others reference all files in the directory. 

The man pages for the main configuration file, such as man logrotate.conf, will usually describe the options. Still, I start by looking for an include statement in the configuration file.

When I search for includes, I see a variety of methods (formatted for readability):

$ grep ^include /etc/*conf
krb5.conf :     includedir /etc/krb5.conf.d/
ld.so.conf :     include ld.so.conf.d/*.conf
logrotate.conf :  include /etc/logrotate.d
rsyslog.conf :    include(file="/etc/rsyslog.d/*.conf" mode="optional")

The ld.so and rsyslog configurations both expect included files to end in .conf. The others look like they include all files, but further investigation may show a method for excluding files. For example, man logrotate.conf shows that tabooext and taboopat can be used to filter out .orig, .bak, .rpmnew, or other files that might result from versioning or updates. For the krb5.conf file, there is both an include and includedir directive. The man page indicates that the includedir directive covers "all files within the directory whose names consist solely of alphanumeric characters, dashes, or underscores." It goes on to point out that files that start with a dot (.) are ignored.

Another consideration for included files is the read and merge order. I have seen a few that read in a random order, but most include files in the order they are found in the directory. If the sequence is particularly important, such as for modules or startup scripts, it is common to start the filenames with a number. Other naming standards such as "pre" or "post" are also common.

$ ls /etc/NetworkManager/dispatcher.d/
04-iscsi  20-chrony  no-wait.d  pre-down.d  pre-up.d

A few utilities may even have expansion symbols that help with managing and distributing centralized files. The sudoers configuration is an example where a %h represents the short form of the hostname.

include /etc/sudoers.d/sudoers.%h

The include line above specifies the configuration file for the current host, even if the directory contains other files. See man sudoers for more examples.

Verify files

Another hazard to using dot-d directories is that you may have to modify your syntax-checking commands. 

In some cases, all of the configuration files must be checked at once. For example, with Apache, the apachectl configtest command always checks the main configuration file, which can include other files. It uses default options. You can run the httpd -t command with additional options. For example, there is an option to list all the included files.

$ httpd -t -D DUMP_INCLUDES
Included configuration files:
  (*) /etc/httpd/conf/httpd.conf
    (59) /etc/httpd/conf.modules.d/00-base.conf
    (59) /etc/httpd/conf.modules.d/00-dav.conf

The httpd command also takes an -f option to specify a particular file. However, that file must pass all configuration checks, so checking an included file may not give the desired results. The following error occurs when checking the default ssl.conf configuration file provided by the mod_ssl package.

$ httpd -t -f /etc/httpd/conf.d/ssl.conf
AH00534: httpd: Configuration error: No MPM loaded.

Other applications do have methods of verifying the syntax for an included file. The sudo configuration is normally modified by using the visudo command so that a syntax validation can be done before saving and exiting. This utility edits the /etc/sudoers file by default but also supports an -f option to specify a different file.

$ sudo visudo -f /etc/sudoers.d/demo
>>> /etc/sudoers.d/demo: syntax error near line 1 <<<
What now? q
Options are:
  (e)dit sudoers file again
  e(x)it without saving changes to sudoers file
  (Q)uit and save changes to sudoers file (DANGER!)

What now? x

The same command also supports a --check option to only validate a file without an edit.

$ visudo -c demo.sudo
>>> demo.sudo: syntax error near line 1 <<<
parse error in demo.sudo near line 1

Combine this with a validate option in your configuration management program to ensure that template expansions do not break a configuration file. There are samples in the documentation for the Ansible copy and template modules. I have also provided the following example from ansible-doc template for sshd:

- name: Update sshd configuration safely, avoid locking yourself out
  template:
    src: etc/ssh/sshd_config.j2
    dest: /etc/ssh/sshd_config
    owner: root
    group: root
    mode: '0600'
    validate: /usr/sbin/sshd -t -f %s
    backup: yes

A little digging through commented lines and man pages will help you get the most out of this organizational method by displaying distribution options, naming conventions, and syntax validation information.

Wrap up

Organizing configuration files into directories can make administration easier to manage and to delegate. Files may be organized by package or function and configuration management solutions such as Ansible can even benefit from smaller template files. You may need to standardize on file names and locations, and you may need to update file verification tools, but using a dot d folder to house multiple configuration files can save you a lot of effort.

[ Want to try out Red Hat Enterprise Linux? Download it now for free. ]


About the author

Susan Lauber is a Consultant and Technical Trainer with her own company, Lauber System Solutions, Inc. She has over 25 years of experience working with Information Systems and specializes in Open Source technologies, specifically platform and data center installation, interoperability, automation, and security.

Susan is always an open source advocate and ambassador of projects she follows. She contributes to projects mostly by way of documentation and QA processes. She has contributed to Fedora Magazine and Opensource.com and is the author of "Linux Command Line Complete Video Course" (2016, Prentice Hall).

Susan is an independent instructor for several companies and holds an alphabet of certifications in those products. She is also a Certified Information Systems Security Professional (CISSP) and a Certified Technical Trainer (CTT). She has been a Red Hat Certified Instructor since 1999 and a co-author and contributor to several Red Hat Training student guides.

Follow her on twitter @laubersm to see what she is reading. Posts include a variety of technology topics as well as some travel, animals, sports, and other randomness.

 

Read full bio
UI_Icon-Red_Hat-Close-A-Black-RGB

Browse by channel

automation icon

Automation

The latest on IT automation for tech, teams, and environments

AI icon

Artificial intelligence

Updates on the platforms that free customers to run AI workloads anywhere

open hybrid cloud icon

Open hybrid cloud

Explore how we build a more flexible future with hybrid cloud

security icon

Security

The latest on how we reduce risks across environments and technologies

edge icon

Edge computing

Updates on the platforms that simplify operations at the edge

Infrastructure icon

Infrastructure

The latest on the world’s leading enterprise Linux platform

application development icon

Applications

Inside our solutions to the toughest application challenges

Original series icon

Original shows

Entertaining stories from the makers and leaders in enterprise tech