NixOS / nixpkgs

Nix Packages collection & NixOS
MIT License
16.46k stars 12.95k forks source link

fail2ban cannot send mail #156480

Open PhilippWoelfel opened 2 years ago

PhilippWoelfel commented 2 years ago

Describe the bug

On a system with service.postfix enabled, fail2ban cannot send e-mails. Using sendmail as an MTA produces

stderr: '/nix/store/vfai0jim0db67nk9rd7ziq29jxb5n79n-bash-5.1-p8/bin/sh: line 8: sendmail: command not found'

Using mail as MTA leads to a core dump and errors such as

stderr: 'mail: cannot send message: Process exited on signal'
stderr: 'mail: Cannot open file /root/dead.letter: Read-only file system'

Steps To Reproduce

Steps to reproduce the behavior:

  1. Use the following configuration file:

    {pkgs,config,...}:
    {
    services.postfix.enable = true;
    services.fail2ban = {
      enable = true;
      extraPackages = [ pkgs.mailutils ];
      jails.DEFAULT = ''
        #mta = mail
        destemail = noreply@fqdn.com
        action = %(action_mw)s
      '';
    };
    }
  2. Execute

    systemctl restart fail2ban.service
    systemctl status fail2ban.service
  3. Repeat steps 1. and 2., uncomment line mta = mail in the configuration file.

Expected behavior

An e-mail is sent to noreply@fqdn.com when fail2ban starts.

Screenshots

n/a

Additional context

I've been able to get it to work using mail as an MTA and:

{
  systemd.services.fail2ban.serviceConfig = with pkgs; {
    NoNewPrivileges = lib.mkForce false;
    ProtectSystem = lib.mkForce null;
  };
}

Perhaps related: https://github.com/NixOS/nixpkgs/issues/103446

Notify maintainers

@eelco @lovek323 @fpletz

Metadata

Please run nix-shell -p nix-info --run "nix-info -m" and paste the result.

[user@system:~]$ nix-shell -p nix-info --run "nix-info -m"
- system: `"x86_64-linux"`
- host os: `Linux 5.10.90, NixOS, 21.11 (Porcupine)`
- multi-user?: `yes`
- sandbox: `yes`
- version: `nix-env (Nix) 2.3.16`
- nixpkgs: `/nix/var/nix/profiles/per-user/root/channels/nixos`
fpletz commented 2 years ago

Thanks for the report. As you gathered, the sendmail functionality on Unix systems needs calling SUID/SGID binaries which is prohibited by settings NoNewPrivileges. I'm not sure if we should relax our default systemd service hardening for fail2ban or add an option in the fail2ban module for this use case.

Either way, you could also use an MUA like msmtp that would connect to your MTA via TCP and communicate with SMTP. This is of course no perfect solution and might require some configuration on your MTA (setting localhost as trusted sender or add an account with credentials for fail2ban).

mohe2015 commented 2 years ago

I think we should really try to harden fail2ban as much as possible as attacks against it could be quite catastrophic. As overriding is relatively easy (see the code above) I don't think it's worth it to add an option for this specific use case.

mohe2015 commented 2 years ago

Maybe document it somewhere or so

PhilippWoelfel commented 2 years ago

For sendmail there is also the problem with the sendmail binary not being found. I think I got that to work at some point by changing the fail2ban derivation so that it uses a different path replacement for the sendmail binary, but then I ran into the SUID/SGID problem.

PhilippWoelfel commented 2 years ago

@mohe2015

we should really try to harden fail2ban as much as possible as attacks against it could be quite catastrophic

I'm not sure I understand this. I thought the whole point of sandboxing a service is to protect the system from the service, and not the other way around. That's usually necessary, if the service can be attacked by the outside world, which is not the case for fail2ban. The only way it can be compromised is if the system is already compromised, or if the source code is compromised. So I don't see why it's more important to sandbox fail2ban than any other systemd service. But I'm not a security or systemd expert, so perhaps I'm missing something...?

mohe2015 commented 2 years ago

@PhilippWoelfel As I assume fail2ban is reading log files it could probably be attacked through attacker-controlled data like user-agent strings in there. Considering it's written in python and probably not doing too bad things with them its relatively unlikely that this will happen I think. Though it may be vulnerable if the python interpreter has vulnerabilities.

PhilippWoelfel commented 2 years ago

Please have a look at the PR https://github.com/NixOS/nixpkgs/pull/157364. It adds the options mail.enable, mail.destemail and mail.sender. The description of mail.enable also mentions the security implications. I feel it's a sensible compromise between a service that looks broken to a user, and relaxing systemd hardening unconditionally.

Deric-W commented 1 month ago

While solving the same problem on my system I observed the following differences:

Additionally I noticed that ProtectSystem could be left unchanged by adding ReadWritePaths = [ "/var/lib/postfix/queue/maildrop" ];.