1

In an ansible (ver. 2.10) playbook I would need to invoke the dpkg-reconfigure openssh-server command to recreate SSH server keys.

- name: Create new SSH host's keys
  shell: dpkg-reconfigure openssh-server
  notify: restart sshd

The problem is that dpkg-reconfigure openssh-server opens a dialog box, and the script get stucked...

Looking into ansible documentation, it seems that dpkg-reconfigure can be managed by debconf module:

Code example related to locales module:

- name: Set default locale to fr_FR.UTF-8
  debconf:
    name: locales
    question: locales/default_environment_locale
    value: fr_FR.UTF-8
    vtype: select

The question from openssh-server debconf module is: What do you want to do about modified configuration file sshd_config? and the answer would be: keep the local version currently installed.

How could I manage it using ansible debconf module?

Roberto Jobet
  • 153
  • 4
  • 15

4 Answers4

2

This is not a debconf issue. The file is marked as a config file by Debian packaging and dpkg is handling it at a generic level. dpkg --configure has --force-confold but dpkg-reconfigure does not.

https://wiki.debian.org/ConfigPackages may also be useful.

Carolus
  • 477
  • 4
  • 16
lbt
  • 766
  • 6
  • 10
2

TL;DR; Yes, use Ansible debconf but mv /var/lib/dpkg/info/<package>.config file aside whilst reconfiguring.

The rest of this is for others searching for insight into debconf and Ansible's debconf module.

I spent some time digging into this and have submitted some docs to the Ansible debconf module which I've edited a bit for this answer.

Reconfiguring packages in Debian using debconf is not straightforward!

The Ansible debconf module does not reconfigure packages, it just updates the debconf database. An additional playbook step is needed (typically via notify if debconf makes a change) to reconfigure the package and apply the changes.

Now debconf is primarily used for pre-seeding configuration prior to installation.

So, whilst dpkg-reconfigure does use debconf data, it is not always authoritative and you may need to check how your package is handled.

dpkg-reconfigure is a 3-phase process. It invokes the control scripts from the /var/lib/dpkg/info directory with the following arguments:

  <package>.prerm  reconfigure <version>
  <package>.config reconfigure <version>
  <package>.postinst control <version>

The main issue is that the <package>.config reconfigure step for many packages will first reset the debconf database (overriding changes made by the Ansible module) by checking the on-disk configuration. If this is the case for your package then dpkg-reconfigure will effectively ignore changes made by this debconf module.

However although dpkg-reconfigure finally invokes:

/var/lib/dpkg/info/<package>.postinst configure <version>

to actually configure the package; using this turns out not to be that simple. The script is expected to be run from a "debconf frontend" and uses IPC to respond to the _db_cmd statements in the script.

To see this in more detail

export DPKG_MAINTSCRIPT_PACKAGE=<package>
export DPKG_MAINTSCRIPT_NAME=<script path>
export DEBIAN_HAS_FRONTEND=1

and run the script. I was trying to setup unattended-upgrades so I ran:

sh -x /var/lib/dpkg/info/unattended-upgrades.postinst configure 1.11.2

This then halts waiting for a response from the frontend.

Running

/usr/share/debconf/frontend /var/lib/dpkg/info/unattended-upgrades.postinst configure 1.11.2

works... but has the exact same problem as dpkg-reconfigure - it resets the debconf database :(

This is because running

 /var/lib/dpkg/info/unattended-upgrades.postinst configure 1.11.2

sources /usr/share/debconf/confmodule which exec()s /usr/share/debconf/frontend which forces the <package>.config configure phase to take place.

This is done based on the existence (ie using shell [-e]) of the .config file and cannot be avoided.

The solution is to mv /var/lib/dpkg/info/<package>.config out of the way whilst dpkg-reconfigure (or other related debconf code) runs.

Note the Debian programmers manual says that the config script's sole purpose is to populate debconf and must not affect other files; so doing this in a playbook is (to my understanding) compliant with debian policy: http://www.fifi.org/doc/debconf-doc/tutorial.html#AEN113

HTH

lbt
  • 766
  • 6
  • 10
2

I also had this problem and I want to share my workaround. In my case, I want non-root users to be able to sniff network traffic with wireshark/tshark. The package in question is wireshark-common which I normally reconfigure to modify dumpcap as setuid.

In my playbook, I do the following. First, use debconf to modify the config and than run the dpkg-reconfigure command in non-interactive mode, but only if the config has changed.

- name: wireshark setuid
  ansible.builtin.debconf:
    name: wireshark-common
    question: wireshark-common/install-setuid
    value: yes
    vtype: boolean
  register: reconfigure_changed
- name: make debconf changes active
  ansible.builtin.command:
    cmd: "dpkg-reconfigure wireshark-common"
  environment:
    DEBIAN_FRONTEND: noninteractive
  when: reconfigure_changed.changed

Hope this is helpful.

0

I am looking myself for a solution but I haven't found one yet to achieve that with debconf and ansible. The Problem is, debconf has no "selection" in terms of sshd_config. When you look for debconf and preseed (Debian unattended installation) there is simply no Argument where you can specify to keep the current sshd_config.

for example active debconf settings:

  sudo debconf-show openssh-server  
  openssh-server/permit-root-login: false
  openssh-server/password-authentication: false

These are the questions for the ansible debconf module.

what we are looking for, but thats not possible:

- debconf:
    name: openssh-server
    question: openssh-server/keep-current-sshd-config
    value: true

Unfortunately, we have to find a workaround. For my case, I wanted to reconfigure openssh-server on my raspberry pi's Luckily, there is a systemd file on raspbian OS /lib/systemd/system/regenerate_ssh_host_keys.service that does what the name says. To make use of it, just delete the ssh_host_* files and reboot the machine.

If you need to get that for different hosts, you need to find another workaround. Maybe importing new ssh_host key files via ansible, or build a small script.