How can I restore configuration files?

Solution 1:

  1. Find out what package installed the config file:

    $ dpkg -S unity-greeter.conf
    unity-greeter: /etc/lightdm/unity-greeter.conf
    

    As you can see, the name of the package is unity-greeter.

    If you deleted a directory, like /etc/pam.d, you can list every package that added to it by using the directory path:

    $ dpkg -S /etc/pam.d
     login, sudo, libpam-runtime, cups-daemon, openssh-server, cron, policykit-1, at, samba-common, ppp, accountsservice, dovecot-core, passwd: /etc/pam.d
    
  2. Run the following command, replacing <package-name> with the name of the package:

    sudo apt install --reinstall -o Dpkg::Options::="--force-confask,confnew,confmiss" <package-name>
    

    And for restoring the directory:

    sudo apt install --reinstall -o Dpkg::Options::="--force-confask,confnew,confmiss" $(dpkg -S /etc/some/directory | sed 's/,//g; s/:.*//')
    
  3. If everything worked as expected, you should get a message:

    Configuration file `/etc/lightdm/unity-greeter.conf', does not exist on system. 
    Installing new config file as you requested.
    
  4. A Practical example when needing to reinstall all of the PulseAudio configuration files:

    apt-cache pkgnames pulse |xargs -n 1 apt-get -o Dpkg::Options::="--force-confmiss" install --reinstall 
    

Solution 2:

For many cases, the default configuration file is provided by a package directly. In such cases, you can extract the specific file from the package, thus easily recovering the file.

To check if a package provides the file, run dpkg -S on the full path of the file. For example:

$ dpkg -S /etc/ssh/sshd_config /etc/ssh/ssh_config /etc/sudoers
dpkg-query: no path found matching pattern /etc/ssh/sshd_config
openssh-client: /etc/ssh/ssh_config
sudo: /etc/sudoers

Provided by a package

As we can see, /etc/ssh/sshd_config is not directly provided by any package, but the other two are provided by openssh-client and sudo respectively. So, if you wished to recover /etc/ssh/ssh_config, first get the package:

apt-get download openssh-client

Now, you can either extract the file directly to its intended location, or to its intended location relative to the current directory instead of /, if you wished to compare and contrast, or manually merge them or something. For the former:

dpkg-deb --fsys-tarfile openssh-client_*.deb | sudo tar x ./etc/ssh/ssh_config -C /

The -C / tells tar to extract after changing to /, which means the target file will get replaced. If you remove it, tar will extract to the current directory, meaning ./etc/ssh/ssh_config will exist in your current directory.

If for some reason sudo doesn't work, use pkexec instead. If pkexec doesn't work either, reboot to recovery mode, mount / as rw. If that doesn't work...


Created by a package

What about /etc/ssh/sshd_config? It doesn't seem to be provided by any package, so how did it appear?

In this case (and in many other such cases, another example being /etc/modules), the file was created using a package maintainer script while installation. This is often done when the configuration file needs to be changed due to user responses to queries. OpenSSH, for example, asks if PermitRootLogin should be changed to no, in newer versions, among other things.

To identify such cases, try greping through the maintainer scripts. Typically you would only need to look postinst, but if you don't have any luck with postinst, try preinst as well:

grep -l /etc/ssh/sshd_config /var/lib/dpkg/info/*.postinst

In this case, we're in luck:

$ grep /etc/ssh/sshd_config /var/lib/dpkg/info/*.postinst -l
/var/lib/dpkg/info/openssh-server.postinst

Only one file matched, and as luck would have it, it contains code to create a default configuration file:

    cat <<EOF > /etc/ssh/sshd_config
# Package generated configuration file
# See the sshd_config(5) manpage for details

# What ports, IPs and protocols we listen for
Port 22
# Use these options to restrict which interfaces/protocols sshd will bind to
#ListenAddress ::
#ListenAddress 0.0.0.0
Protocol 2
# HostKeys for protocol version 2
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_dsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
#Privilege Separation is turned on for security
UsePrivilegeSeparation yes

# Lifetime and size of ephemeral version 1 server key
KeyRegenerationInterval 3600
ServerKeyBits 768

# Logging
SyslogFacility AUTH
LogLevel INFO

# Authentication:
LoginGraceTime 120
PermitRootLogin yes
StrictModes yes

RSAAuthentication yes
PubkeyAuthentication yes
#AuthorizedKeysFile %h/.ssh/authorized_keys

# Don't read the user's ~/.rhosts and ~/.shosts files
IgnoreRhosts yes
# For this to work you will also need host keys in /etc/ssh_known_hosts
RhostsRSAAuthentication no
# similar for protocol version 2
HostbasedAuthentication no
# Uncomment if you don't trust ~/.ssh/known_hosts for RhostsRSAAuthentication
#IgnoreUserKnownHosts yes

# To enable empty passwords, change to yes (NOT RECOMMENDED)
PermitEmptyPasswords no

# Change to yes to enable challenge-response passwords (beware issues with
# some PAM modules and threads)
ChallengeResponseAuthentication no

# Change to no to disable tunnelled clear text passwords
#PasswordAuthentication yes

# Kerberos options
#KerberosAuthentication no
#KerberosGetAFSToken no
#KerberosOrLocalPasswd yes
#KerberosTicketCleanup yes

# GSSAPI options
#GSSAPIAuthentication no
#GSSAPICleanupCredentials yes

X11Forwarding yes
X11DisplayOffset 10
PrintMotd no
PrintLastLog yes
TCPKeepAlive yes
#UseLogin no

#MaxStartups 10:30:60
#Banner /etc/issue.net

# Allow client to pass locale environment variables
AcceptEnv LANG LC_*

Subsystem sftp /usr/lib/openssh/sftp-server

# Set this to 'yes' to enable PAM authentication, account processing,
# and session processing. If this is enabled, PAM authentication will
# be allowed through the ChallengeResponseAuthentication and
# PasswordAuthentication.  Depending on your PAM configuration,
# PAM authentication via ChallengeResponseAuthentication may bypass
# the setting of "PermitRootLogin without-password".
# If you just want the PAM account and session checks to run without
# PAM authentication, then enable this but set PasswordAuthentication
# and ChallengeResponseAuthentication to 'no'.
UsePAM yes
EOF

Typically, this is what you would see (another example, /etc/modules from kmod):

cat > /path/to/the/file <<EOF
# default contents
EOF

So, you can look for this code and get the contents from the script directly.


No such script? You can still try poking through the filelists of related packages to see if anything hits, but at this point, I see no easily generalizable method (short of reinstallation on transient environments, like a chroot or a VM or a live USB).


In the long run, keep your configuration under version control. Any VCS worth its salt can save the day here, and the etckeeper utility considerably simplifies the task of keeping /etc in a VCS.

Solution 3:

Find the package that owns the configuration file:

dpkg --search /etc/path/to/config

it will outputs something similar to:

unity-greeter: /etc/lightdm/unity-greeter.conf

so the package name is "unity-greeter", download the package:

apt-get download unity-greeter

then extract its file system tree data to a tar file:

dpkg-deb --fsys-tarfile unity-greeter_version-0ubuntu1_amd64.deb > pkg.tar

finally extract only that exact configuration anywhere you want it to be:

tar -Oxf pkg.tar ./etc/lightdm/unity-greeter.conf |
sudo tee /etc/lightdm/unity-greeter.conf 
  • ./etc/lightdm/unity-greeter.conf is the file name in our archive.
  • /etc/lightdm/unity-greeter.conf is where I'm sending it to be stored.

Or as @Muru suggested, we can do it in one liner:

dpkg-deb --fsys-tarfile unity-greeter_version-0ubuntu1_amd64.deb |
sudo tar -x -C / ./etc/lightdm/unity-greeter.conf

Solution 4:

According to this thread on the Ubuntu Forums, it's as simple as running the following in a terminal:

sudo dpkg-reconfigure lightdm

Solution 5:

I had the same Problem on Ubuntu 17.04. The postinstall uses a template from /usr/share/openssh/. It checks if rootlogin is enabled or not, sets this option and copies it to /etc/ssh. After that it does some ucf and ucfr calls (I don't know what that is for).

Just copy /usr/share/openssh/sshd_config to /etc/ssh/sshd_config:

sudo cp /usr/share/openssh/sshd_config /etc/ssh/sshd_config

Now adjust your sshd_config as you want.