Unattended Upgrades Debian

Unattended Upgrades in Debian

Feels like since forever have I been using unattended-upgrades package to automate the Security upgrades on my various Debian Stable based machines.

Default Settings

By default unattended-upgrades will install only Security updates. It also will not send any email reports. That is not surprising – well, you have to have email delivery configured and unattended-upgrades needs to know, what email address to send those reports to.

Tweaking the Config

If you need more than what the defaults give you, it’s easy to modify the config as described in the Debian Wiki. I think the most elegant way of customizing the configuration is described in the README.md of the Debian package source. You basically create /etc/apt/apt.conf.d/52unattended-upgrades-local and put any overrides to the default config you need.

Actually the file can be named anything you want, as long as alphabetically it falls after 50unattended-upgrades, because the config files are parsed alphabetically and every other file overrides any previously set config options.

Repeating Myself

Since every single time beside the Security upgrades I also wanted the Proposed Updates. I also always configure ssmtp to send emails via an SMTP account that I have set specifically for automated emails from my machines.

So after a couple of times of manually creating /etc/apt/apt.conf.d/52unattended-upgrades-local with something like this:

// The email address, unattended-upgrades will send the report to:
Unattended-Upgrade::Mail "patryk@debian.org";

// An email address, unattended-upgrades will use as "From" when sending the
// report email:
Unattended-Upgrade::Sender "my_email__for_automated@emails.com";

Unattended-Upgrade::Origins-Pattern {
        // Codename based matching:
        // This will follow the migration of a release through different
        // archives (e.g. from testing to stable and later oldstable).
        // Software will be the latest available for the named release,
        // but the Debian release itself will not be automatically upgraded.
        "origin=Debian,codename=${distro_codename}";
        "origin=Debian,codename=${distro_codename}-updates";
        "origin=Debian,codename=${distro_codename}-proposed-updates";
        "origin=Debian,codename=${distro_codename},label=Debian";
        "origin=Debian,codename=${distro_codename},label=Debian-Security";
        "origin=Debian,codename=${distro_codename}-security,label=Debian-Security";

};

One-offs

Say you’re self-hosting some services. Maybe you have your own Jellyfin installed from Jellyfin team’s repository. In that case:

$ apt-cache policy
...
 500 https://repo.jellyfin.org/debian bullseye/main amd64 Packages
     release o=Jellyfin,n=bullseye,l=Jellyfin,c=main,b=amd64
     origin repo.jellyfin.org
...

So if you want unattended-upgrades to update your Jellyfin from the repo above, you’d add:

"origin=repo.jellyfin.org,codename=bullseye";

to the Unattended-Upgrade::Origins-Pattern block.

Or maybe you’re self-hosting GitLab, but instead of using not using Debian’s official package, you prefer GitLab’s official Omnibus package. In that case:

...
 500 https://packages.gitlab.com/gitlab/gitlab-ee/debian bullseye/main amd64 Packages
     release v=1,o=packages.gitlab.com/gitlab/gitlab-ee,a=bullseye,n=bullseye,l=gitlab-ee,c=main,b=amd64
     origin packages.gitlab.com
...

For this you’d add:

"o=packages.gitlab.com/gitlab/gitlab-ee,codename=bullseye,label=gitlab-ee";

Automating with Ansible

I’ve automated the process by writing an Ansible Role for it. To use the role, you have to add the following to your playbook’s requirements.yml:

...
- src: git+https://gitlab.com/prezu-debian/unattended-upgrades-debian
  version: main
  name: unattended-upgrades-debian
...

Then make sure to install the role:

$ ansible-galaxy install -r requirements.yml

And then use it in your playbook:

...
  roles:
    - role: unattended-upgrades-debian
      vars:
        email_to: 'patryk@cisek.email'
        email_from: 'prezuu@zohomail.com'
        custom_matchers:
          - '"origin=repo.jellyfin.org,codename=bullseye";'
          - '"o=packages.gitlab.com/gitlab/gitlab-ee,codename=bullseye,label=gitlab-ee";'
...

Note: You probably shouldn’t be running Jellyfin on the same host as GitLab. This example here is just to ilustrate the idea.

No Emails at all

If you don’t want/have set up email sending on your system, you can omit email_to/email_from:

...
  roles:
    - role: unattended-upgrades-debian
      vars:
        custom_matchers:
          - '"origin=repo.jellyfin.org,codename=bullseye";'
          - '"o=packages.gitlab.com/gitlab/gitlab-ee,codename=bullseye,label=gitlab-ee";'
...

No Frills, just Security Upgrades

For the simple stuff – no emails and only the Security and Proposed Upgrades – just do this:

...
  roles:
    - unattended-upgrades-debian
...

If you have any comments, please, fell free to shoot me an email, or drop me a note.

Debian