Re: systemd-analyze security as a release goal

2023-07-17 Thread Trent W. Buck
Matthew Garrett  writes:

> On Thu, Jul 13, 2023 at 08:03:39PM +0200, Timo Röhling wrote:
>
>> qemu is basically an interpreter for foreign machine code. If your
>> threat model allows access to qemu-user-static for an attacker, they
>> can run pretty much any binary is if it were native, and the whole
>> SystemCallArchitectures hardening becomes meaningless.
>
> My understanding of the threat is that compatibility syscalls (eg, x32
> on amd64) are less well-tested than the local architecture syscalls, and
> so allowing apps to call them increases the risk - a compromised app
> that can make compatibility syscalls stands a higher probability of
> being able to elevate privileges, either in userland or to the kernel
> itself. Allowing qemu to translate syscalls from other architectures to
> the local syscall ABI doesn't increase that risk, so isn't a concern.
> The goal isn't to prevent code form other architectures from running,
> it's to reduce the attack surface by preventing calls to the
> compatbility syscalls.

Thanks, your user story is much better than mine:

  SystemCallArchitectures=native slightly inconveniences attackers by
  forcing them to make multiple payloads, instead of "meh, I'll just
  build for IA32; that works on regular AND embedded/old systems".



Re: systemd-analyze security as a release goal

2023-07-04 Thread Trent W. Buck
Marco d'Itri  writes:

> On Jul 04, "Trent W. Buck"  wrote:
>
>>   * If it runs its own process manager (e.g. postfix's "master"),
>> don't bother trying to harden it.
> I disagree. It may not be possible to use NoNewPrivileges, but at least 
> file system hardening is usually trivial to enable for most daemons.
>
>>   * If it sends mail via /usr/sbin/sendmail,
>> don't bother trying to harden it.
> See above.

Let me tone down my answer: rather than "don't bother",
I should have said something like "focus on other daemons first".
You've convinced me we can still do the "easy" bits of those daemons,
e.g. ProtectSystem= and ProtectHome= as you suggested.

Usually I got so annoyed that I just gave up and moved onto the next
daemon, though -- hence my initial rule of thumb :-)

For the record,
I think "can't do NoNewPrivileges=" also precludes all of:

  Importance
  2.0   SystemCallFilter= <-- these are the ones
  0.9   RestrictNamespaces=   <-- I appreciate the most
  0.9   RestrictAddressFamilies=  <--
  0.4   DynamicUser=
  0.2   SystemCallArchitectures=
  0.2   RestrictSUIDSGID=
  0.2   ProtectKernelTunables=
  0.2   ProtectKernelModules=
  0.2   ProtectKernelLogs=
  0.2   ProtectClock=
  0.2   PrivateDevices=
  0.2   NoNewPrivileges=
  0.1   RestrictRealtime=
  0.1   ProtectHostname=
  0.1   MemoryDenyWriteExecute=
  0.1   LockPersonality=
  0.0?  SystemCallLog=

Oh, before I forget:
someone pointed out to me that distros probably can't enable
SystemCallArchitectures=native, because multiarch
(e.g. if you want to use nginx/i386 on amd64,
nginx.service can't SystemCallArchitecture=native).

>> If it sends mail via smtp://localhost, that's MUCH easier.
>> Start encouraging upstreams to do that instead?
> Do you know an appropriate C library that could be used?
> Speaking proper SMTP is a bit harder than rfc821 | sendmail, so let's 
> try to not overshoot...

My solution was to use msmtp as a sendmail(8)-to-SMTP adapter.
Something like this:


https://github.com/cyberitsolutions/prisonpc-systemd-lockdown/blob/main/systemd/system/0-EXAMPLES/30-allow-mail-postfix-via-msmtp.conf

I'm using that in production, for uh... logcheck (bottom of the file):


https://bugs.debian.org/cgi-bin/bugreport.cgi?att=2;bug=1020328;filename=logcheck.service;msg=5

I'm using the same trick for a PHP5 app which uses RootImage= (instead
of docker).  Turns out Docker's PHP5 containers are ENTIRELY built
from jessie; my RootImage= mmdebstrap --variant=apt bullseye, with only
src:{php5,uwsgi-plugin-php,uwsgi}/jessie.
Anyway, inside that RootImage= is just enough msmtp to make
https://www.php.net/manual/en/function.mail.php (/usr/sbin/sendmail)
get forwarded to smtp://localhost:25 -- which is postfix OUTSIDE the RootImage=.

   'mmdebstrap', ⋯,
   '--include=msmtp-mta libnss-myhostname',
   '--customize-hook=(echo account default;
  echo syslog on;
  echo host localhost;
  echo auto_from on) >$1/etc/msmtprc',

I don't know whether it's reasonable to make C daemons in-house this via
a C library.  For things like python and emacs, it's pretty much just a
matter of changing "import sendmail" to "import smtpmail".
Daemons that expect to send a lot of email often have an existing config option 
for this.
Daemons that only send mail incidentally, or
have never had to deal with Windows,
are more likely to just use mail(1) or /usr/sbin/sendmail.

PS: note that msmtp-mta nowadays includes msmtpd.service which just accepts 
mail on localhost:25 and forwards it to /usr/bin/msmtp, which
can then forward it to the "real" mail server.
For my personal setups, this means I have an easy way to guarantee all hosts 
have a smtp://localhost:25 listener,
then same way I have historically guaranteed all hosts have a 
/usr/sbin/sendmail.
Again there's a big difference between "I do this by default" to "Debian should 
do this by default".
I can see a lot of pushback about having msmtpd.service on by default –
at least until it's renamed to systemd-mail-submission-agentd :-)

>> Moving pidfiles from /run/%p.pid to /run/%p/%p.pid and
>> letting systemd do the User=%p can help quite a bit.
> In general, all services should be STRONGLY encouraged to use 
> RuntimeDirectory, StateDirectory, etc...
> Also because this makes possible implementing the "file system factory 
> reset" patterns.

No argument here.

Note one gotcha is if you have something nuanced like

motion:root755  /var/lib/motion/
motion:motion  750  /var/lib/motion/incoming/
motion:adm 750  /var/lib/motion/CCTV-recordings/
motion:adm 640  /var/lib/motion/CCTV-recordings/2023-01-01T00:00:00.mkv

Then systemd can go
"oh, your owner/permissions changed -- I'll fix that for you" and
RECURSIVELY chown/chmod, messing up your inner settings.

I forget exactly how I triggered that, but
it was one of those "systemd isn't WRONG, but that was unexpected"
cases.  It might only 

Re: systemd-analyze security as a release goal

2023-07-04 Thread Marco d'Itri
On Jul 04, "Trent W. Buck"  wrote:

>   * If it runs its own process manager (e.g. postfix's "master"),
> don't bother trying to harden it.
I disagree. It may not be possible to use NoNewPrivileges, but at least 
file system hardening is usually trivial to enable for most daemons.

>   * If it sends mail via /usr/sbin/sendmail,
> don't bother trying to harden it.
See above.

> If it sends mail via smtp://localhost, that's MUCH easier.
> Start encouraging upstreams to do that instead?
Do you know an appropriate C library that could be used?
Speaking proper SMTP is a bit harder than rfc821 | sendmail, so let's 
try to not overshoot...

> Moving pidfiles from /run/%p.pid to /run/%p/%p.pid and
> letting systemd do the User=%p can help quite a bit.
In general, all services should be STRONGLY encouraged to use 
RuntimeDirectory, StateDirectory, etc...
Also because this makes possible implementing the "file system factory 
reset" patterns.

-- 
ciao,
Marco


signature.asc
Description: PGP signature


Re: systemd-analyze security as a release goal

2023-07-03 Thread Trent W. Buck
RL  writes:

> Russell Coker  writes:
>
>> https://wiki.debian.org/ReleaseGoals/SystemdAnalyzeSecurity
>>
>> I think we should make it a release goal to have as many daemons as
>> possible running with systemd security features to aim for a low score
>> from "systmd-analyze security".
>
>
> This repos from Trent Buck has a lot of research -
> https://github.com/cyberitsolutions/prisonpc-systemd-lockdown/tree/main/systemd/system/0-EXAMPLES
>
> (One of the issues for services that send email is that it is very
> easy to break exim)

Hello, I am a nosy person!

I am pleased to see everyone I have pestered about systemd hardening
since 2018 has already commented on this thread :-)

The git repo mentioned above is mostly for Debian 9.
I have later work against Debian 11, but
it's mostly part of a private ansible repo.
I have pushed some into debbugs already.
(SOMEWHERE in "bts show from:trentbuck archive=both"...)

Below is a brain-dump of some new notes I wrote today.


I broadly agree with Marco and Simon sentiments.
Hardening any daemon that can run arbitary hook scripts (e.g. smartd) is going 
to inconvenience at least 1 person.

I think there's room for improvement, though.
I think at least some units can be hardened by packagers in a way that 99% of 
users don't notice, and
debian/NEWS can warn users "if you're an edge case, do X to undo this change".

We've had similar cases where e.g. sshd dropped sha1, or
where X.service gradually dropped backcompat with /etc/default/X, or
where msmtp had apparmor hardening on by default, then downgraded it to an 
opt-in debconf question.

We can also add wiki / hardening-howto documentation to help admins/users opt 
in to hardening (a la aa-genprof), but
based on my experience with aa and selinux, I don't think that will give good 
bang-for-buck.

Since systemd units support dropins, we could also provide a single
"harden-all-the-things" package that simply provides a lot of
/lib/systemd/system/X.service.d/harden-all-the-things.conf
errata.  This would work similar to how apparmor-profiles-extras works 
currently --
if you don't care about security, you just don't install that package at all.
I suspect that will also stagnate, though, so it's better to do hardening in 
each package where possible.



My rules of thumb so far are:

  * Start with the most popular units, i.e. sort by popcon.

  * Start with units with a clear "do one thing, well" mission,
e.g. e2scrub@, ntpsec-rotate-stats

  * If it runs its own process manager (e.g. postfix's "master"),
don't bother trying to harden it.

Start talking to upstream about whether this could be a generator creating 
native socket-activated systemd units?
If systemd is missing necessary capabilities (e.g. sshd's MaxStartups=), 
talk to systemd about how to add these?

  * If it sends mail via /usr/sbin/sendmail,
don't bother trying to harden it.

If it sends mail via smtp://localhost, that's MUCH easier.
Start encouraging upstreams to do that instead?

(Sysadmins can bind-mount /usr/sbin/msmtp to /usr/sbin/sendmail within the 
service,
so that a daemon calling /usr/sbin/sendmail will end up talking to 
exim/postfix/msmtpd on [::1]:25.
Packagers probably can't get away with that.)

  * If it can run arbitrary admin-configurable hooks,
don't bother trying to harden it.

For example, smartd and zfs-zed both *by default* only send email, but
in theory you can make them flash LEDs on the front panel by running 
/opt/broadcom/LSIctl.
Or make demons fly out of your nose.

  * If it's sshd or equivalent (used interactively by admin, forks "sudo" ),
don't bother trying to harden it.

  * You don't have to get the score down to 2.
Even getting most scores down from ~9 to ~6 is worthwhile.

Moving pidfiles from /run/%p.pid to /run/%p/%p.pid and
letting systemd do the User=%p can help quite a bit.
Often upstream code needs some minor massaging to make that work cleanly.

Socket activating can help, e.g. prayer (webmail) had undocumented ability 
to use socket activation,
which meant you could harden its ability to bind to low ports.

  * MariaDB upstream is a good example of a reasonableperson-test "middle 
ground" level of default hardening.

https://mariadb.com/kb/en/systemd/#useful-systemd-options

  * If you have to support both Debian N and Debian Nbpo,
with the same config file,
some hardening features in bpo are problematic and not worth your time.

(For example, SystemCallFilter= landed before SystemCallFilter=@foo.
If you tried to use SystemCallFilter=@foo on the older system,
it'd get confused and block ALL syscalls.)


Here's my most recent notes (from June 2023) about then-Debian 11 servers at 
work.
They're in production and working OK.
HOWEVER, they include quite a bit of "I know *I* don't need X, therefore I am 
OK with hardening X away."
For example, I know PHP and MariaDB run on the same host, so I can disable