Merge ~ahasenack/ubuntu/+source/rsyslog:lunar-rsyslog-enable-apparmor-dep8-take4-dot-d into ubuntu/+source/rsyslog:ubuntu/devel

Proposed by Andreas Hasenack
Status: Merged
Approved by: git-ubuntu bot
Approved revision: not available
Merged at revision: 76271daab8cbf6a7bf649bd3e5a3c2e15139d8c1
Proposed branch: ~ahasenack/ubuntu/+source/rsyslog:lunar-rsyslog-enable-apparmor-dep8-take4-dot-d
Merge into: ubuntu/+source/rsyslog:ubuntu/devel
Diff against target: 774 lines (+556/-24)
26 files modified
debian/NEWS (+30/-0)
debian/README.apparmor (+132/-0)
debian/README.apparmor.rsyslog.d (+16/-0)
debian/apparmor/rsyslog-gnutls.apparmor (+3/-0)
debian/apparmor/rsyslog-mysql.apparmor (+20/-0)
debian/apparmor/rsyslog-openssl.apparmor (+3/-0)
debian/apparmor/rsyslog-pgsql.apparmor (+9/-0)
debian/changelog (+42/-0)
debian/reload-apparmor-profile (+14/-0)
debian/rsyslog-gnutls.install (+1/-0)
debian/rsyslog-mysql.install (+1/-0)
debian/rsyslog-openssl.install (+1/-0)
debian/rsyslog-pgsql.install (+1/-0)
debian/rsyslog.dirs (+1/-1)
debian/rsyslog.docs (+1/-0)
debian/rsyslog.install (+2/-0)
debian/rsyslog.postinst (+7/-0)
debian/rsyslog.preinst (+0/-15)
debian/rsyslog.service (+2/-0)
debian/tests/apparmor-include-mechanism (+92/-0)
debian/tests/control (+19/-0)
debian/tests/simple-logger (+36/-0)
debian/tests/simple-mysql (+42/-0)
debian/tests/simple-pgsql (+38/-0)
debian/tests/utils (+41/-0)
debian/usr.sbin.rsyslogd (+2/-8)
Reviewer Review Type Date Requested Status
git-ubuntu bot Approve
Athos Ribeiro (community) Approve
Simon Déziel (community) Approve
Canonical Server Core Reviewers Pending
Canonical Server Reporter Pending
Review via email: mp+436955@code.launchpad.net

Description of the change

Enable apparmor in enforce mode by default on fresh installs. UPDATE: upgrades from older versions (< $this-version) WILL change the confinement status.

PPA: https://launchpad.net/~ahasenack/+archive/ubuntu/rsyslog-apparmor-dep8-take4/

LP won't run the DEP8 tests because this package never had such tests before, so you will have to run them locally. Bileto also didn't work, they are queued up for days (and against an older version of this work, so don't bother): https://bileto.ubuntu.com/#/ticket/4980

This is take 4 of my experiments with enforcing apparmor on rsyslog. How it works is documented in the new d/README.apparmor file.

It's a lot of delta to add at first glance, but I think it's easy to maintain as it's mostly new files, and small touches in existing ones. More importantly, no dependency or packaging changes, and we have tests :)

I checked the whole archive (with apt-file find) for packages that install files in /etc/rsyslog.d, looking for the ones that would violate the current apparmor rules (I know this misses packages that generate those config files in postinst). I found two:

prometheus-postfix-exporter
This package adds a rsyslog config that tells it to log mail messages to /var/lib/prometheus/postfix-exporter/mail.log, which is not covered by the apparmor profile. I used this package as an example to show what maintainers can do in such a case, and pushed it to the same PPA, and this branch:

https://code.launchpad.net/~ahasenack/ubuntu/+source/prometheus-postfix-exporter/+git/prometheus-postfix-exporter/+ref/lunar-prometheus-postfix-exporter-rsyslog-apparmor

The change is simple (I think):

https://git.launchpad.net/~ahasenack/ubuntu/+source/prometheus-postfix-exporter/commit/?id=dac36355f663bdc1eaf8aac164865b9d19b028f2

UPDATE 2022-02-11: that is no longer needed, as debian's latest upload of this package gave up on the custom mail.log file and is now using the normal /var/log/mail.log one, which is covered by the normal rsyslog apparmor profile.

octopussy
This one I didn't bother updating, because a) it's removed from debian; b) it's broken even without these apparmor changes. But the change would be the same approach as prometheus-postfix-exporter. It is piping logs to a fifo, so we would need an extra apparmor rule for that.

I still have other bin:rsyslog-* packages (from src:rsyslog) to go over, but the approach is the same, and I think it's time to get this reviewed and hopefully uploaded.

# Sending to debian
Before sending any of this to debian, we need to see how it will work out in practice for us.

# Merge from debian
There is a new debian upload which needs merging, and I commit to that after this branch.

# Take4? What's in take1, 2, and 3?

Just as a summary of what I tried previously, in case you are wondering "why didn't you try X?". If you want more details about those attempts, ask.

## Triggers
Work beautifully, but run too late. I found out many packages (part of rsyslog, and third party ones) restart rsyslog in their postinst, even though there is a trigger for that (just place a file in /etc/rsyslog.d and the trigger will restart rsyslog at the end of the apt/dpkg transaction). This meant that for a while rsyslog would be running without the apparmor changes applied by the trigger, and that was enough to cause it to fail

## Config file analysis
This looked promising, and I can still use it in the future if I want, but as the sole method of adjusting the apparmor profile, it's complicated. I can easily enough get a full dump of the whole config file, with all the included files, but the problem is that rsyslog supports 3 config languages: very old syslog, old syslog, and current rainer script. The last two ones are hard to parse, as can be multi-line and have "if" statements and so on. "grep" only takes me so far. I can still use this for some cases, at least to warn the user that something might not work, like when the "omprog" plugin is used (or pipe), as this one can call out to any binary on the system, anywhere.

To post a comment you must log in.
Revision history for this message
Simon Déziel (sdeziel) wrote :

Thanks for working on this, I'll happily take it for a test drive!

You cannot include <rsyslog/include.d/*.apparmor> but you can include a whole directory:

  include if exists <rsyslog/include.d/>

What do you think?

Revision history for this message
Andreas Hasenack (ahasenack) wrote :

> include if exists <rsyslog/include.d/>

I briefly looked at the manpage and didn't see this option mentioned, of including whole directories. I'll search again, but if you have a direct link to it, I'd appreciate it :)

I'm curious to see what types of files does this include, if it's all files regardless of extension (bad), or something else.

Revision history for this message
Simon Déziel (sdeziel) wrote :

I didn't find any mention in the man page but figured it with trial/error.

IMHO, having it include everything isn't that big of a deal. Putting a notice in commented out text in /etc/apparmor.d/rsyslog/include.d/README should make it clear to everyone. Something like this:

# Every file under /etc/apparmor.d/rsyslog/include.d/
# is included by the rsyslog Apparmor profile

Revision history for this message
Andreas Hasenack (ahasenack) wrote :

> IMHO, having it include everything isn't that big of a deal.

We can't have it include everything. Think of *.dpkg-new, *.conf~, *~ backup files, editor temp files, even this README, etc.

Revision history for this message
Seth Arnold (seth-arnold) wrote :

I think the parser already skips the *.dpkg-new etc files:

https://sources.debian.org/src/apparmor/3.0.8-2/parser/parser_main.c/#L1329
https://sources.debian.org/src/apparmor/3.0.8-2/libraries/libapparmor/src/private.c/#L127
https://sources.debian.org/src/apparmor/3.0.8-2/libraries/libapparmor/src/private.c/#L65

static struct ignored_suffix_t ignored_suffixes[] = {
 /* Debian packging files, which are in flux during install
           should be silently ignored. */
 { ".dpkg-new", 9, 1 },
 { ".dpkg-old", 9, 1 },
 { ".dpkg-dist", 10, 1 },
 { ".dpkg-bak", 9, 1 },
 { ".dpkg-remove", 12, 1 },
 /* Archlinux packaging files */
 { ".pacsave", 8, 1 },
 { ".pacnew", 7, 1 },
 /* RPM packaging files have traditionally not been silently
           ignored */
 { ".rpmnew", 7, 0 },
 { ".rpmsave", 8, 0 },
 /* patch file backups/conflicts */
 { ".orig", 5, 0 },
 { ".rej", 4, 0 },
 /* Backup files should be mentioned */
 { "~", 1, 0 },
 { NULL, 0, 0 }
};

Revision history for this message
Andreas Hasenack (ahasenack) wrote :

Any idea why this isn't documented? It was just forgotten, or is this an experimental feature, or a happy side effect of something else? I just don't want to rely on something that could go away all of a sudden, or change behavior unexpectedly, and then hear "you were relying on undocumented behavior, sorry" ;)

Revision history for this message
Simon Déziel (sdeziel) wrote (last edit ):

If the `ignored_suffixes` thing is officially supported, including a README file containing a few lines starting with "# " shouldn't matter too much, wouldn't it?

Revision history for this message
Sergio Durigan Junior (sergiodj) wrote :

The code to ignore certain file extensions is also replicated in the Python code that sits under utils/apparmor/:

https://git.launchpad.net/ubuntu/+source/apparmor/tree/utils/apparmor/rule/include.py#n141
https://git.launchpad.net/ubuntu/+source/apparmor/tree/utils/apparmor/common.py#n174

The feature is undocumented, but seems to be something formally supported by the project.

Also, README files are ignored so you shouldn't need to prefix its lines with a comment.

Revision history for this message
Andreas Hasenack (ahasenack) wrote :

Thanks for these links, Sergio, and the discussion in our standup. I'll proceed with making the changes to use a single include directory.

Revision history for this message
Andreas Hasenack (ahasenack) wrote :

I force-pushed changes to use a include directory without the intermediate generated file. Opening up for review again.

Revision history for this message
Simon Déziel (sdeziel) wrote :

LGTM, my only small observation is that reload-apparmor-profile could well be using `/bin/sh` instead of `/bin/bash`.

review: Approve
Revision history for this message
Andreas Hasenack (ahasenack) wrote :

> LGTM, my only small observation is that reload-apparmor-profile could well be
> using `/bin/sh` instead of `/bin/bash`.

Indeed, it got even simpler now. Switched.

Revision history for this message
Andreas Hasenack (ahasenack) wrote :

After a brief exchange in ubuntu-devel, I added a commit that changes the upgrade behavior of the package.

If upgrading from a version older than this one, apparmor will be enabled. In this way, if someone decides to disable apparmor after this update, it will remain so.

Revision history for this message
Athos Ribeiro (athos-ribeiro) wrote :

Thanks, Andreas!

This LGTM. I do appreciate you took the time to write documentation in different places here.

I added a few inline comments, mostly regarding the DEP8 tests introduced here.

Revision history for this message
Andreas Hasenack (ahasenack) :
Revision history for this message
Andreas Hasenack (ahasenack) wrote :

Made the last changes, uploaded a new build to the ppa (ppa17).

Revision history for this message
Andreas Hasenack (ahasenack) wrote :

I ran the tests locally on amd64:
autopkgtest [15:19:42]: @@@@@@@@@@@@@@@@@@@@ summary
apparmor-include-mechanism PASS
simple-logger PASS
simple-mysql PASS
simple-pgsql PASS

real 2m27,433s

We will only be able to run them in the ppa, with all architectures, once the package with at least one DEP8 test is uploaded and migrates.

Revision history for this message
Athos Ribeiro (athos-ribeiro) wrote :

Thanks for the changes and verification, Andreas. LGTM.

review: Approve
Revision history for this message
git-ubuntu bot (git-ubuntu-bot) wrote :

Approvers: ahasenack, athos-ribeiro
Uploaders: ahasenack, athos-ribeiro
MP auto-approved

review: Approve
Revision history for this message
Andreas Hasenack (ahasenack) wrote :

Thanks, uploaded:
Uploading rsyslog_8.2210.0-3ubuntu2.dsc
Uploading rsyslog_8.2210.0-3ubuntu2.debian.tar.xz
Uploading rsyslog_8.2210.0-3ubuntu2_source.buildinfo
Uploading rsyslog_8.2210.0-3ubuntu2_source.changes

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/debian/NEWS b/debian/NEWS
2index 35058fa..1421f59 100644
3--- a/debian/NEWS
4+++ b/debian/NEWS
5@@ -1,3 +1,33 @@
6+rsyslog (8.2210.0-3ubuntu2) lunar; urgency=medium
7+
8+ The apparmor profile of rsyslog now defaults to be enforced on a fresh
9+ install and upgrades from an earlier version. Upgrades from this version
10+ forward won't change the enforcement status.
11+
12+ Packages that add an rsyslog configuration that might be blocked by the
13+ apparmor profile, can add an apparmor configuration snippet in
14+
15+ /etc/apparmor.d/rsyslog.d/
16+
17+ This file should preferably be named like <pkg>.apparmor, but only standard
18+ backup extensions are excluded. See
19+ https://sources.debian.org/src/apparmor/3.0.8-2/libraries/libapparmor/src/private.c/#L68
20+ for a list.
21+
22+ When the rsyslog service is started, its systemd unit file first executes
23+ the /usr/lib/rsyslog/reload-apparmor-profile script via ExecStartPre. That
24+ script will reload the rsyslogd apparmor profile including the configuration
25+ snippets in /etc/apparmor.d/rsyslogd.d/, if any.
26+
27+ The confinement status is not changed.
28+
29+ After this, the unit proceeds to start rsyslog as usual.
30+
31+ For more information, check the README.apparmor file in the documentation
32+ directory of this package.
33+
34+ -- Andreas Hasenack <andreas@canonical.com> Sun, 05 Feb 2023 15:42:31 -0300
35+
36 rsyslog (5.8.1-1) unstable; urgency=low
37
38 The way rsyslog processes SIGHUP has changed. It no longer does a reload
39diff --git a/debian/README.apparmor b/debian/README.apparmor
40new file mode 100644
41index 0000000..ab5e706
42--- /dev/null
43+++ b/debian/README.apparmor
44@@ -0,0 +1,132 @@
45+# rsyslog and AppArmor
46+
47+Starting with version 8.2210.0-3ubuntu2, on fresh installs and upgrades from
48+earlier versions, rsyslog will be confined by default with AppArmor in enforce
49+mode.
50+
51+The AppArmor profile for rsyslog has a static component, and a dynamic one. It
52+all starts with the main profile in `/etc/apparmor.d/usr.sbin.rsyslogd`. That
53+profile has an include directive for the dynamic component in
54+`/etc/apparmor.d/rsyslog.d`:
55+
56+ # apparmor snippets for rsyslog from other packages
57+ include if exists <rsyslog.d>
58+
59+All files placed in `/etc/apparmor.d/rsyslog.d` will be included, with the
60+exception of standard backup files like files ending in `~`, or with a suffix
61+generated by `dpkg` when there was a config file prompt. The full list of
62+exclusions is not really documented, but can be inspected in the source code at
63+https://sources.debian.org/src/apparmor/3.0.8-2/libraries/libapparmor/src/private.c/#L65.
64+A `README` file is also ignored.
65+
66+When `rsyslog` is started, it will reload the apparmor profile, including all
67+the snippets that may exist in the `rsyslog.d` include directory. This is done
68+via a `ExecStartPre` call in the systemd unit file:
69+
70+ [Service]
71+ Type=notify
72+ ExecStartPre=/usr/lib/rsyslog/reload-apparmor-profile
73+ ExecStart=/usr/sbin/rsyslogd -n -iNONE
74+ ...
75+
76+Packages (and users) can place apparmor profile config file snippets in
77+`/etc/apparmor.d/rsyslog.d/`. It is suggested that the filename be in the form
78+of `<pkg>.apparmor`.
79+
80+For example, the `rsyslog-pgsql` debian package installs this file
81+`/etc/apparmor.d/rsyslog.d/rsyslog-pgsql.apparmor`:
82+
83+ # PostgreSQL local access
84+ include <abstractions/openssl>
85+ include <abstractions/ssl_certs>
86+ /etc/gss/mech.d/ r,
87+ /etc/gss/mech.d/* r,
88+ /{,var/}run/postgresql/.s.PGSQL.*[0-9] rw,
89+
90+When `rsyslog` starts, the `reload-apparmor-profile` will run and
91+reload the `rsyslogd` apparmor profile just before rsyslogd itself is
92+started. Note that the enforcement status of the profile (enforce, complain) is
93+not changed.
94+
95+
96+# Troubleshooting
97+
98+When rsyslog gets something denied, particularly if it's in an output module,
99+it will retry a few times and eventually give up. It usually won´t crash, so
100+the only way to notice something is wrong is by inspecting the logs, or, well,
101+by noticing something isn't working, like logging to a database.
102+
103+Here are the most useful troubleshooting tips.
104+
105+
106+## Watch the logs
107+
108+Look for rsyslog errors in the logs, particularly `/var/log/syslog`, or via
109+`journalctl -u rsyslog.service -f`. For example, when it can't connect to a
110+local MySQL server, messages like these will appear:
111+
112+ Jan 31 17:27:15 sender rsyslogd[82257]: ommysql: db error (2002): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (13) [v8.2210.0]
113+ Jan 31 17:27:15 sender rsyslogd[82257]: action 'action-8-ommysql' suspended (module 'ommysql'), retry 0. There should be messages before this one giving the reason for suspe>
114+
115+
116+## Inspect dmesg/apparmor
117+
118+If the rsyslog apparmor profile is interfering with rsyslog, there will be
119+messages about it in the `dmesg` output (or in the audit log, if `auditd` is
120+installed). For example, for the mysql case:
121+
122+ [Tue Feb 7 12:35:28 2023] audit: type=1400 audit(1675773329.453:84): apparmor="DENIED" operation="connect" class="file" profile="rsyslogd" name="/run/mysqld/mysqld.sock" pid=15495 comm=72733A6D61696E20513A526567 requested_mask="wr" denied_mask="wr" fsuid=101 ouid=107
123+
124+Since the rsyslog apparmor profile now may include multiple files from
125+`/etc/apparmor.d/rsyslog.d`, it helps to visualize the whole profile as one
126+file. The `apparmor_parser` command can be used for that with the `-p` option:
127+
128+ # apparmor_parser -p /etc/apparmor.d/usr.sbin.rsyslogd
129+ ...
130+ ##included <rsyslog.d/rsyslog-mysql.apparmor>
131+ # MySQL local server access
132+ ...
133+
134+This will show all included files, including abstractions.
135+
136+
137+# Example
138+
139+Here is an example of what it would look like to adapt a package that ships a
140+rsyslog configuration that needs the rsyslog apparmor profile to be adjusted.
141+
142+The `prometheus-postfix-exporter` adds an rsyslog config that has it write logs
143+to `/var/lib/prometheus/postfix-exporter/mail.log`, which is not allowed by the
144+base rsyslog apparmor profile.
145+
146+This is what the fix for this package would look like:
147+
148+```diff
149+
150+diff --git a/debian/dirs b/debian/dirs
151+index 6d3533d..50d9ad8 100644
152+--- a/debian/dirs
153++++ b/debian/dirs
154+@@ -1,3 +1,4 @@
155+ etc/rsyslog.d
156++etc/apparmor.d/rsyslog.d
157+ var/lib/prometheus/postfix-exporter
158+ var/log/prometheus
159+diff --git a/debian/rsyslog-prometheus-postfix-exporter.apparmor b/debian/rsyslog-prometheus-postfix-exporter.apparmor
160+new file mode 100644
161+index 0000000..1b9f85f
162+--- /dev/null
163++++ b/debian/rsyslog-prometheus-postfix-exporter.apparmor
164+@@ -0,0 +1 @@
165++ /var/lib/prometheus/postfix-exporter/mail.log rw,
166+diff --git a/debian/rules b/debian/rules
167+index e8ce2f9..ffcf383 100755
168+--- a/debian/rules
169++++ b/debian/rules
170+@@ -16,3 +16,5 @@ override_dh_auto_install:
171+ dh_auto_install -- --no-source
172+ install -m644 debian/rsyslog.conf \
173+ debian/$(BINNAME)/etc/rsyslog.d/$(BINNAME).conf
174++ install -m644 debian/rsyslog-prometheus-postfix-exporter.apparmor \
175++ debian/$(BINNAME)/etc/apparmor.d/rsyslog.d
176+```
177diff --git a/debian/README.apparmor.rsyslog.d b/debian/README.apparmor.rsyslog.d
178new file mode 100644
179index 0000000..030b9b9
180--- /dev/null
181+++ b/debian/README.apparmor.rsyslog.d
182@@ -0,0 +1,16 @@
183+# This directory is meant to be used by packages that need to augment the
184+# existing rsyslogd profile with extra rules. All files in here will be
185+# included by the /etc/apparmor.d/usr.sbin.rsyslogd profile, subject to the
186+# exclusion rules defined in
187+#
188+# https://sources.debian.org/src/apparmor/3.0.8-2/libraries/libapparmor/src/private.c/#L65
189+#
190+# and
191+#
192+# https://sources.debian.org/src/apparmor/3.0.8-2/libraries/libapparmor/src/private.c/#L132
193+#
194+# Please check the README.apparmor file in the documentation directory of the
195+# rsyslog package for more information.
196+#
197+# For the usual overrides and other additions by local administrators, please
198+# use the /etc/apparmor.d/local/ mechanism.
199diff --git a/debian/apparmor/rsyslog-gnutls.apparmor b/debian/apparmor/rsyslog-gnutls.apparmor
200new file mode 100644
201index 0000000..9d5147e
202--- /dev/null
203+++ b/debian/apparmor/rsyslog-gnutls.apparmor
204@@ -0,0 +1,3 @@
205+# GnuTLS library rules
206+
207+ /etc/gnutls/config r,
208diff --git a/debian/apparmor/rsyslog-mysql.apparmor b/debian/apparmor/rsyslog-mysql.apparmor
209new file mode 100644
210index 0000000..0f9ad34
211--- /dev/null
212+++ b/debian/apparmor/rsyslog-mysql.apparmor
213@@ -0,0 +1,20 @@
214+# MySQL local server access
215+
216+include <abstractions/openssl>
217+
218+/etc/mysql/my.cnf r,
219+/etc/mysql/mysql.cnf r,
220+/etc/mysql/my.cnf.fallback r,
221+
222+/etc/mysql/conf.d/ r,
223+/etc/mysql/conf.d/mysql.cnf r,
224+/etc/mysql/conf.d/mysqldump.cnf r,
225+
226+/etc/mysql/mysql.conf.d/ r,
227+/etc/mysql/mysql.conf.d/mysql.cnf r,
228+/etc/mysql/mysql.conf.d/mysqld.cnf r,
229+
230+/usr/share/mysql/charsets/Index.xml r,
231+
232+/{,var/}run/mysqld/mysqld.sock rw,
233+
234diff --git a/debian/apparmor/rsyslog-openssl.apparmor b/debian/apparmor/rsyslog-openssl.apparmor
235new file mode 100644
236index 0000000..f561b40
237--- /dev/null
238+++ b/debian/apparmor/rsyslog-openssl.apparmor
239@@ -0,0 +1,3 @@
240+# OpenSSL library rules
241+
242+ /etc/ssl/openssl.cnf r,
243diff --git a/debian/apparmor/rsyslog-pgsql.apparmor b/debian/apparmor/rsyslog-pgsql.apparmor
244new file mode 100644
245index 0000000..3111a70
246--- /dev/null
247+++ b/debian/apparmor/rsyslog-pgsql.apparmor
248@@ -0,0 +1,9 @@
249+# PostgreSQL local access
250+
251+include <abstractions/openssl>
252+include <abstractions/ssl_certs>
253+
254+/etc/gss/mech.d/ r,
255+/etc/gss/mech.d/* r,
256+/{,var/}run/postgresql/.s.PGSQL.*[0-9] rw,
257+
258diff --git a/debian/changelog b/debian/changelog
259index b470943..b782302 100644
260--- a/debian/changelog
261+++ b/debian/changelog
262@@ -1,3 +1,45 @@
263+rsyslog (8.2210.0-3ubuntu2) lunar; urgency=medium
264+
265+ * Support apparmor profile snippets:
266+ - d/usr.sbin.rsyslogd: add "include if exists" for the rsyslog.d
267+ directory, and remove the now unnecessary mysql and postgresql
268+ sections
269+ - d/rsyslog.preinst: don't disable the apparmor profile on install
270+ - d/rsyslog.postinst: remove disabling of apparmor on upgrades if we
271+ are upgrading from a version older than $now.
272+ - d/rsyslog.dirs: install /etc/apparmor.d/rsyslog.d/
273+ - d/{apparmor/rsyslog-mysql,rsyslog-mysql.install}: add apparmor
274+ profile for mysql plugin
275+ - d/{apparmor/rsyslog-pgsql,rsyslog-pgsql.install}: add apparmor
276+ profile for postgresql plugin
277+ - d/{apparmor/rsyslog-gnutls.apparmor,rsyslog-gnutls.install}: add
278+ apparmor profile for the gnutls plugin
279+ - d/{apparmor/rsyslog-openssl.apparmor,rsyslog-gnutls.install}: add
280+ apparmor profile for the openssl plugin
281+ - New script to reload apparmor profile:
282+ + d/rsyslog.service: reload apparmor profile in ExecStartPre and
283+ set StandardError to journal so we can see errors from the
284+ script
285+ + d/rsyslog.install: install reload-apparmor-profile
286+ + d/reload-apparmor-profile: script to reload the
287+ rsyslogd apparmor profile
288+ - d/NEWS: add info about apparmor changes in the Ubuntu packaging
289+ - d/rsyslog.docs, d/README.apparmor: explains how the dynamic
290+ component of the rsyslog apparmor profile is applied
291+ - d/README.apparmor.rsyslog.d, d/rsyslog.install: install a specific
292+ README file in the apparmor include directory for rsyslog
293+ * Add DEP8 tests (LP: #1906333):
294+ - d/t/control, d/t/simple-logger: simple logger test
295+ - d/t/utils: common function(s)
296+ - d/t/control, d/t/simple-mysql: DEP8 test using rsyslog with a
297+ MySQL server
298+ - d/t/control, d/t/simple-pgsql: DEP8 test using rsyslog with a
299+ PostgreSQL server
300+ - d/t/apparmor-include-mechanism: DEP8 test for the rsyslog.d
301+ include mechanism used by the rsyslog apparmor profile
302+
303+ -- Andreas Hasenack <andreas@canonical.com> Fri, 17 Feb 2023 14:22:27 -0300
304+
305 rsyslog (8.2210.0-3ubuntu1) lunar; urgency=low
306
307 * Merge from Debian unstable. Remaining changes:
308diff --git a/debian/reload-apparmor-profile b/debian/reload-apparmor-profile
309new file mode 100755
310index 0000000..25c39e3
311--- /dev/null
312+++ b/debian/reload-apparmor-profile
313@@ -0,0 +1,14 @@
314+#!/bin/sh
315+
316+apparmor_profile="/etc/apparmor.d/usr.sbin.rsyslogd"
317+include_dir="/etc/apparmor.d/rsyslog.d"
318+
319+[ -f "${apparmor_profile}" ] || exit 0
320+[ -d "${include_dir}" ] || exit 0
321+aa-status --enabled 2>/dev/null || exit 0
322+
323+apparmor_parser -r -W -T "${apparmor_profile}" || {
324+ echo "Failed to reload the ${apparmor_profile} apparmor profile, continuing anyway" >&2
325+}
326+
327+exit 0
328diff --git a/debian/rsyslog-gnutls.install b/debian/rsyslog-gnutls.install
329index c5784ce..4579469 100644
330--- a/debian/rsyslog-gnutls.install
331+++ b/debian/rsyslog-gnutls.install
332@@ -1 +1,2 @@
333 usr/lib/${DEB_HOST_MULTIARCH}/rsyslog/lmnsd_gtls.so
334+debian/apparmor/rsyslog-gnutls.apparmor etc/apparmor.d/rsyslog.d/
335diff --git a/debian/rsyslog-mysql.install b/debian/rsyslog-mysql.install
336index 9de8064..fedff5c 100644
337--- a/debian/rsyslog-mysql.install
338+++ b/debian/rsyslog-mysql.install
339@@ -1,2 +1,3 @@
340 usr/lib/${DEB_HOST_MULTIARCH}/rsyslog/ommysql.so
341 debian/rsyslog-mysql.conf.template usr/share/rsyslog-mysql/
342+debian/apparmor/rsyslog-mysql.apparmor etc/apparmor.d/rsyslog.d/
343diff --git a/debian/rsyslog-openssl.install b/debian/rsyslog-openssl.install
344index 492defb..bc5358e 100644
345--- a/debian/rsyslog-openssl.install
346+++ b/debian/rsyslog-openssl.install
347@@ -1 +1,2 @@
348 usr/lib/${DEB_HOST_MULTIARCH}/rsyslog/lmnsd_ossl.so
349+debian/apparmor/rsyslog-openssl.apparmor etc/apparmor.d/rsyslog.d/
350diff --git a/debian/rsyslog-pgsql.install b/debian/rsyslog-pgsql.install
351index 3fb57d3..946fe3f 100644
352--- a/debian/rsyslog-pgsql.install
353+++ b/debian/rsyslog-pgsql.install
354@@ -1,2 +1,3 @@
355 usr/lib/${DEB_HOST_MULTIARCH}/rsyslog/ompgsql.so
356 debian/rsyslog-pgsql.conf.template usr/share/rsyslog-pgsql/
357+debian/apparmor/rsyslog-pgsql.apparmor etc/apparmor.d/rsyslog.d/
358diff --git a/debian/rsyslog.dirs b/debian/rsyslog.dirs
359index 93f7b6a..1fdfad8 100644
360--- a/debian/rsyslog.dirs
361+++ b/debian/rsyslog.dirs
362@@ -3,4 +3,4 @@
363 /etc/apparmor.d/force-complain/
364 /etc/apparmor.d/disable/
365 /etc/apparmor.d/local/
366-
367+/etc/apparmor.d/rsyslog.d/
368diff --git a/debian/rsyslog.docs b/debian/rsyslog.docs
369index 62deb04..336a33e 100644
370--- a/debian/rsyslog.docs
371+++ b/debian/rsyslog.docs
372@@ -1 +1,2 @@
373 AUTHORS
374+debian/README.apparmor
375diff --git a/debian/rsyslog.install b/debian/rsyslog.install
376index 5455991..66cd7b1 100755
377--- a/debian/rsyslog.install
378+++ b/debian/rsyslog.install
379@@ -3,6 +3,7 @@ debian/rsyslog.conf etc/
380 debian/00rsyslog.conf usr/lib/tmpfiles.d/
381 debian/50-default.conf /usr/share/rsyslog
382 debian/rsyslog-rotate usr/lib/rsyslog/
383+debian/reload-apparmor-profile usr/lib/rsyslog/
384 usr/sbin/
385 usr/share/man/man5/
386 usr/share/man/man8/
387@@ -39,4 +40,5 @@ usr/lib/${DEB_HOST_MULTIARCH}/rsyslog/pm*.so
388 [linux-any] usr/lib/${DEB_HOST_MULTIARCH}/rsyslog/imjournal.so
389 [linux-any] usr/lib/${DEB_HOST_MULTIARCH}/rsyslog/omjournal.so
390 debian/usr.sbin.rsyslogd etc/apparmor.d/
391+debian/README.apparmor.rsyslog.d => etc/apparmor.d/rsyslog.d/README
392 debian/dmesg.service lib/systemd/system
393diff --git a/debian/rsyslog.postinst b/debian/rsyslog.postinst
394index efc6d08..ea93fbf 100644
395--- a/debian/rsyslog.postinst
396+++ b/debian/rsyslog.postinst
397@@ -44,6 +44,13 @@ case "$1" in
398 if dpkg --compare-versions "$2" lt-nl "8.2110.0-2"; then
399 update-rc.d -f rsyslog remove || true
400 fi
401+
402+ if dpkg --compare-versions "$2" lt-nl "8.2210.0-3ubuntu2~"; then
403+ # In this version we removed the disabling of the rsyslog apparmor
404+ # profile, i.e., it's enabled by default. Gate on it to avoid
405+ # re-enabling it if the user has explicitly disabled it afterwards.
406+ rm -f /etc/apparmor.d/disable/usr.sbin.rsyslogd
407+ fi
408 ;;
409
410 triggered)
411diff --git a/debian/rsyslog.preinst b/debian/rsyslog.preinst
412index 7e86bb8..2f726ab 100644
413--- a/debian/rsyslog.preinst
414+++ b/debian/rsyslog.preinst
415@@ -6,19 +6,4 @@ if [ "$1" = "install" ] && [ -n "$2" ] ; then
416 [ -f /etc/logrotate.d/rsyslog.disabled ] && mv -f /etc/logrotate.d/rsyslog.disabled /etc/logrotate.d/rsyslog
417 fi
418
419-disable_profile() {
420- APP_CONFFILE="/etc/apparmor.d/usr.sbin.rsyslogd"
421- APP_DISABLE="/etc/apparmor.d/disable/usr.sbin.rsyslogd"
422- # Create a symlink to the yet-to-be-unpacked profile
423- if [ ! -e "$APP_CONFFILE" ]; then
424- mkdir -p `dirname $APP_DISABLE` 2>/dev/null || true
425- ln -sf $APP_CONFFILE $APP_DISABLE
426- fi
427-}
428-
429-if [ "$1" = "install" ]; then
430- # Disable AppArmor profile on install
431- disable_profile
432-fi
433-
434 #DEBHELPER#
435diff --git a/debian/rsyslog.service b/debian/rsyslog.service
436index c64a9ea..0d24b10 100644
437--- a/debian/rsyslog.service
438+++ b/debian/rsyslog.service
439@@ -7,8 +7,10 @@ Documentation=https://www.rsyslog.com/doc/
440
441 [Service]
442 Type=notify
443+ExecStartPre=/usr/lib/rsyslog/reload-apparmor-profile
444 ExecStart=/usr/sbin/rsyslogd -n -iNONE
445 StandardOutput=null
446+StandardError=journal
447 Restart=on-failure
448
449 # Increase the default a bit in order to allow many simultaneous
450diff --git a/debian/tests/apparmor-include-mechanism b/debian/tests/apparmor-include-mechanism
451new file mode 100755
452index 0000000..728d17f
453--- /dev/null
454+++ b/debian/tests/apparmor-include-mechanism
455@@ -0,0 +1,92 @@
456+#!/bin/bash
457+
458+set -e
459+set -o pipefail
460+
461+include_dir="/etc/apparmor.d/rsyslog.d"
462+apparmor_profile="/etc/apparmor.d/usr.sbin.rsyslogd"
463+declare -i ret
464+ret=0
465+
466+cleanup() {
467+ rm -f "${include_dir}"/do-not-include*
468+ rm -f "${include_dir}"/README
469+ rm -f "${include_dir}"/pkg1.apparmor
470+ rm -f "${include_dir}"/randomfile
471+}
472+
473+trap cleanup EXIT
474+
475+standard_backup_files_are_not_included() {
476+ local -a ignored_suffixes
477+ local -a exclusions
478+ local -a inclusions
479+ local -i lines=0
480+ local fname
481+ local suffix
482+ local full_profile
483+
484+ cleanup
485+
486+ # taken from https://sources.debian.org/src/apparmor/3.0.8-2/libraries/libapparmor/src/private.c/#L65
487+ # and https://sources.debian.org/src/apparmor/3.0.8-2/libraries/libapparmor/src/private.c/#L133
488+ ignored_suffixes=(.dpkg-new .dpkg-old .dpkg-dist .dpkg-bak .dpkg-remove .pacsave .pacnew .rpmnew .rpmsave .orig .rej \~)
489+ exclusions+=("README" ".somedotfile")
490+ for suffix in "${ignored_suffixes[@]}"; do
491+ exclusions+=("do-not-include${suffix}")
492+ done
493+
494+ echo "## Files with known backup extensions, that start with a dot, and a README file, are not included. Testing with:"
495+ echo "${exclusions[*]}"
496+ echo
497+
498+ for fname in "${exclusions[@]}"; do
499+ echo "# BUG this should not be included: ${fname}" > "${include_dir}/${fname}"
500+ done
501+
502+ # just a few, for a sanity check
503+ inclusions=(pkg1.apparmor randomfile)
504+ echo "## These, however, should be included: ${inclusions[*]}"
505+ for fname in "${inclusions[@]}"; do
506+ echo "# must be included: ${fname}" > "${include_dir}/${fname}"
507+ done
508+
509+ echo "## Generated test files:"
510+ ls -la /etc/apparmor.d/rsyslog.d/
511+
512+ full_profile=$(apparmor_parser -p "${apparmor_profile}")
513+
514+ echo "## Verifying that none of the excluded files were included in the apparmor profile:"
515+ if echo "${full_profile}" | grep -F "BUG this should not be included"; then
516+ return 1 # the caller will print ## FAIL
517+ else
518+ echo "## OK"
519+ fi
520+
521+ echo "## Verifying that all the allowed files were included:"
522+ lines=$(echo "${full_profile}" | grep -F "must be included" | wc -l)
523+ if [ ${lines} -ne ${#inclusions[@]} ]; then
524+ echo "## Found ${lines} inclusions, expected ${#inclusions[@]}"
525+ return 1
526+ fi
527+}
528+
529+
530+for t in \
531+ standard_backup_files_are_not_included; do
532+
533+ echo
534+ if "${t}"; then
535+ echo "## OK"
536+ else
537+ ret=1
538+ echo "## FAIL"
539+ fi
540+done
541+
542+echo
543+if [ ${ret} -ne 0 ]; then
544+ echo "## One or more tests FAILED"
545+fi
546+
547+exit ${ret}
548diff --git a/debian/tests/control b/debian/tests/control
549new file mode 100644
550index 0000000..89703c0
551--- /dev/null
552+++ b/debian/tests/control
553@@ -0,0 +1,19 @@
554+Tests: apparmor-include-mechanism
555+Depends: rsyslog, apparmor
556+Restrictions: needs-root allow-stderr
557+
558+Tests: simple-logger
559+Depends: rsyslog, bsdutils, apparmor-utils, uuid-runtime
560+Restrictions: needs-root
561+
562+Tests: simple-mysql
563+# rsyslog-mysql has to be installed by the test script, because it pulls in dbconfig-common
564+# which will be setup *before* mysql-server is configured and running, which fails.
565+Depends: bsdutils, apparmor-utils, mysql-server, uuid-runtime
566+Restrictions: needs-root
567+
568+Tests: simple-pgsql
569+# rsyslog-pgsql has to be installed by the test script, because it pulls in dbconfig-common
570+# which will be setup *before* postgresql is configured and running, which fails.
571+Depends: bsdutils, apparmor-utils, postgresql, postgresql-client, uuid-runtime
572+Restrictions: needs-root
573diff --git a/debian/tests/simple-logger b/debian/tests/simple-logger
574new file mode 100755
575index 0000000..1c38834
576--- /dev/null
577+++ b/debian/tests/simple-logger
578@@ -0,0 +1,36 @@
579+#!/bin/bash
580+
581+set -e
582+set -o pipefail
583+
584+# make sure we are confined and in enforce mode for this test, if supported
585+apparmor_profile="/etc/apparmor.d/usr.sbin.rsyslogd"
586+if [ ! -d /etc/apparmor.d/rsyslog.d ]; then
587+ echo "No /etc/apparmor.d/rsyslog directory, not touching apparmor status"
588+
589+elif [ ! -f "${apparmor_profile}" ]; then
590+ echo "No ${apparmor_profile} file, not touching apparmor status"
591+
592+elif ! aa-status --enabled 2>/dev/null; then
593+ echo "Apparmor disabled (aa-status)"
594+
595+else
596+ echo "Enforcing the ${apparmor_profile} apparmor profile"
597+ aa-enforce "${apparmor_profile}"
598+fi
599+
600+message="logger-test-value=$(uuidgen)"
601+
602+echo "Logging message: ${message}"
603+logger --id=$$ --priority user.notice "${message}"
604+
605+logs=$(tail -n 10 /var/log/syslog)
606+if echo "${logs}" | grep -qE "${message}"; then
607+ echo "Message correctly found in system logs"
608+else
609+ echo "Failed to find message \"${message}\" in /var/log/syslog"
610+ echo "Last 5 lines are:"
611+ echo "${logs}"
612+ exit 1
613+fi
614+
615diff --git a/debian/tests/simple-mysql b/debian/tests/simple-mysql
616new file mode 100755
617index 0000000..036f1af
618--- /dev/null
619+++ b/debian/tests/simple-mysql
620@@ -0,0 +1,42 @@
621+#!/bin/bash
622+
623+set -e
624+set -o pipefail
625+
626+source debian/tests/utils
627+
628+# make sure we are confined and in enforce mode for this test, if supported
629+apparmor_profile="/etc/apparmor.d/usr.sbin.rsyslogd"
630+if [ ! -d /etc/apparmor.d/rsyslog.d ]; then
631+ echo "No /etc/apparmor.d/rsyslog directory, not touching apparmor status"
632+
633+elif [ ! -f "${apparmor_profile}" ]; then
634+ echo "No ${apparmor_profile} file, not touching apparmor status"
635+
636+elif ! aa-status --enabled 2>/dev/null; then
637+ echo "Apparmor disabled (aa-status)"
638+
639+else
640+ echo "Enforcing the ${apparmor_profile} apparmor profile"
641+ aa-enforce "${apparmor_profile}"
642+fi
643+
644+# Installing rsyslog-mysql without having a mysql DB already configured on
645+# localhost fails, because the dbconfig-common postinst runs before the mysql
646+# postinst. A Depends cannot be used in the packaging because the database
647+# might be remote.
648+# Therefore we add mysql-server to the DEP8 dependency list in d/t/control, and
649+# install rsyslog-mysql from inside the test. In this way, mysql is already
650+# configured when we get here.
651+DEBIAN_FRONTEND=noninteractive apt-get install -y rsyslog-mysql
652+
653+# Values from a default install of rsyslog-mysql
654+DBNAME="Syslog"
655+TABLE="SystemEvents"
656+
657+message="logger-test-value=$(uuidgen)"
658+
659+echo "Logging message: ${message}"
660+logger --id=$$ --priority user.notice "${message}"
661+
662+check_db_for_message mysql "${message}"
663diff --git a/debian/tests/simple-pgsql b/debian/tests/simple-pgsql
664new file mode 100755
665index 0000000..9f4c163
666--- /dev/null
667+++ b/debian/tests/simple-pgsql
668@@ -0,0 +1,38 @@
669+#!/bin/bash
670+
671+set -e
672+set -o pipefail
673+
674+source debian/tests/utils
675+
676+# make sure we are confined and in enforce mode for this test, if supported
677+apparmor_profile="/etc/apparmor.d/usr.sbin.rsyslogd"
678+if [ ! -d /etc/apparmor.d/rsyslog.d ]; then
679+ echo "No /etc/apparmor.d/rsyslog directory, not touching apparmor status"
680+
681+elif [ ! -f "${apparmor_profile}" ]; then
682+ echo "No ${apparmor_profile} file, not touching apparmor status"
683+
684+elif ! aa-status --enabled 2>/dev/null; then
685+ echo "Apparmor disabled (aa-status)"
686+
687+else
688+ echo "Enforcing the ${apparmor_profile} apparmor profile"
689+ aa-enforce "${apparmor_profile}"
690+fi
691+
692+# Installing rsyslog-pgsql without having a postgresq DB already configured on
693+# localhost fails, because the dbconfig-common postinst runs before the
694+# postgresql postinst. A Depends cannot be used in the packaging because the
695+# database might be remote.
696+# Therefore we add postgresql to the DEP8 dependency list in d/t/control, and
697+# install rsyslog-pgsql from inside the test. In this way, postgresql is
698+# already configured when we get here.
699+DEBIAN_FRONTEND=noninteractive apt-get install -y rsyslog-pgsql
700+
701+message="logger-test-value=$(uuidgen)"
702+
703+echo "Logging message: ${message}"
704+logger --id=$$ --priority user.notice "${message}"
705+
706+check_db_for_message postgresql "${message}"
707diff --git a/debian/tests/utils b/debian/tests/utils
708new file mode 100644
709index 0000000..5d503ef
710--- /dev/null
711+++ b/debian/tests/utils
712@@ -0,0 +1,41 @@
713+check_db_for_message() {
714+ local db="${1}"
715+ local message="${2}"
716+ local -i counter=10
717+
718+ case "${db}" in
719+ mysql)
720+ dbname="Syslog"
721+ table="SystemEvents"
722+ cmd="mysql -uroot ${dbname} --batch -N -e \"SELECT COUNT(*) FROM ${table} WHERE trim(Message) = \\\"${message}\\\";\""
723+ ;;
724+ postgresql)
725+ dbname="Syslog"
726+ table="systemevents"
727+ cmd="sudo -u postgres -i psql -At -d ${dbname} -c \"SELECT COUNT(*) FROM ${table} WHERE trim(message) = '${message}';\""
728+ ;;
729+ *)
730+ echo "Unrecognized db: ${db}"
731+ return 1
732+ ;;
733+ esac
734+ echo -n "Checking ${db} for the message (${counter} attempts): "
735+ while [ ${counter} -gt 0 ]; do
736+ count=$(eval "${cmd}")
737+ if [ ${count} -eq 1 ]; then
738+ echo
739+ echo "Message correctly found in the ${db} ${dbname}.${table} table"
740+ break
741+ else
742+ echo -n "."
743+ counter=$((counter-1))
744+ sleep 1s
745+ continue
746+ fi
747+ done
748+ if [ ${counter} -eq 0 ]; then
749+ echo
750+ echo "Failed to find message \"${message}\" in the ${db} ${dbname}.${table} table"
751+ return 1
752+ fi
753+}
754diff --git a/debian/usr.sbin.rsyslogd b/debian/usr.sbin.rsyslogd
755index ab130da..3d80417 100644
756--- a/debian/usr.sbin.rsyslogd
757+++ b/debian/usr.sbin.rsyslogd
758@@ -45,14 +45,8 @@ profile rsyslogd /usr/sbin/rsyslogd {
759 # 'r' is needed when using imfile
760 /var/log/** rw,
761
762- # Add these for mysql support
763- #/etc/mysql/my.cnf r,
764- #/{,var/}run/mysqld/mysqld.sock rw,
765-
766- # Add thes for postgresql support
767- ##include <abstractions/openssl>
768- ##include <abstractions/ssl_certs>
769- #/{,var/}run/postgresql/.s.PGSQL.*[0-9] rw,
770+ # apparmor snippets for rsyslog from other packages
771+ include if exists <rsyslog.d>
772
773 # Site-specific additions and overrides. See local/README for details.
774 #include <local/usr.sbin.rsyslogd>

Subscribers

People subscribed via source and target branches