php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #78916 php-fpm 7.4.0 don't send mail via mail()
Submitted: 2019-12-05 14:23 UTC Modified: 2019-12-08 18:07 UTC
From: ilya at ilya dot pp dot ua Assigned: bukka (profile)
Status: Closed Package: FPM related
PHP Version: 7.4.0 OS: systemd/linux
Private report: No CVE-ID: None
 [2019-12-05 14:23 UTC] ilya at ilya dot pp dot ua
Description:
------------
After update to 7.4.0 php-fpm don't send mail via mail()/
In postfix mail log: fatal: inet_addr_local[getifaddrs]: getifaddrs: Address family not supported by protocol
nginx log empty.

php-fpm.service
CapabilityBoundingSet=CAP_CHOWN CAP_SETGID CAP_SETUID

What else needs to be added here so php can send mail again?

Test script:
---------------
protected static function mail($to,$subject,$body)
	{
		$from = escape(CONFIG['mail']['name']).' <'.CONFIG['mail']['mail'].'>';
		$headers =
		[
			'MIME-Version' => '1.0',
			'Content-Type' => 'text/html; charset=UTF-8',
			'Content-Transfer-Encoding' => 'binary',
			'From' => $from,
			'Reply-To' => $from,
		];
		return mail($to, $subject, $body, $headers, '-f'.CONFIG['mail']['mail']);
	}

Expected result:
----------------
Send mail

Actual result:
--------------
fatal: inet_addr_local[getifaddrs]: getifaddrs: Address family not supported by protocol

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2019-12-05 14:37 UTC] sjon@php.net
-Status: Open +Status: Feedback
 [2019-12-05 14:37 UTC] sjon@php.net
Thank you for this bug report. To properly diagnose the problem, we
need a short but complete example script to be able to reproduce
this bug ourselves.

A proper reproducing script starts with <?php and ends with ?>,
is max. 10-20 lines long and does not require any external
resources such as databases, etc. If the script requires a
database to demonstrate the issue, please make sure it creates
all necessary tables, stored procedures etc.

Please avoid embedding huge scripts into the report.

I run php-fpm using the same version and CapabilityBoundingSet and mail works fine - so we need more details.

Since the error is logged by postfix I don't think this is caused by php-fpm, who provides /usr/bin/sendmail on this machine?
 [2019-12-05 14:58 UTC] retertertert at fgfgfg dot com
> To properly diagnose the problem, we need a short 
> but complete example script to be able to reproduce
> this bug ourselves

this is sonsense 

obviously the namespace/capabilities options used in the systemd unit are killing the communiction of the postfix processes runnin on hebalv the server, that's how sendmail prcoess works, it opens other postfix related processes which need capabilities

this sounds more than RestrictAddressFamilies is also used now and "AF_UNIX AF_NETLINK" is missing, without a spamass-milter can't send BCC mails too

RestrictAddressFamilies=AF_INET AF_INET6 AF_LOCAL AF_UNIX AF_NETLINK
 [2019-12-05 16:05 UTC] ilya at ilya dot pp dot ua
-Status: Feedback +Status: Open
 [2019-12-05 16:05 UTC] ilya at ilya dot pp dot ua
<?php
$to_mail = 'user@user.server.com';
$from_mail = 'you@your.server.com';
$from = 'You <'.$from_mail.'>';
$headers =
[
	'MIME-Version' => '1.0',
	'Content-Type' => 'text/html; charset=UTF-8',
	'Content-Transfer-Encoding' => 'binary',
	'From' => $from,
	'Reply-To' => $from,
];
mail($to_mail, 'Test message', <p>Test message.</p>, $headers, '-f'.$from_mail);
?>
 [2019-12-05 16:05 UTC] ilya at ilya dot pp dot ua
<?php
$to_mail = 'user@user.server.com';
$from_mail = 'you@your.server.com';
$from = 'You <'.$from_mail.'>';
$headers =
[
	'MIME-Version' => '1.0',
	'Content-Type' => 'text/html; charset=UTF-8',
	'Content-Transfer-Encoding' => 'binary',
	'From' => $from,
	'Reply-To' => $from,
];
mail($to_mail, 'Test message', <p>Test message.</p>, $headers, '-f'.$from_mail);
?>
 [2019-12-05 16:12 UTC] ilya at ilya dot pp dot ua
> Since the error is logged by postfix I don't think this is caused by php-fpm, who provides /usr/bin/sendmail on this machine?

php-fpm 3.7.11 work fine

#!/usr/bin/env sh
echo -e 'Subject:'`date +'%H:%M %d.%m.%Y'`'\nTest from Ilya to Google' | /usr/sbin/sendmail my_gmail_name@gmail.com

Work fine!

LC_ALL=en sudo cnf sendmail

Program 'sendmail' is present in package 'postfix', which is installed on your system.

Absolute path to 'sendmail' is '/usr/sbin/sendmail', so running it may require superuser privileges (eg. root).

postfix 3.4.8
 [2019-12-05 18:37 UTC] ilya at ilya dot pp dot ua
After
-RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX
+RestrictAddressFamilies=AF_INET AF_INET6 AF_LOCAL AF_UNIX AF_NETLINK

Error in postfix log:
fatal: mail_queue_enter: create file maildrop/508120.1166: no permission
warning: command "/usr/sbin/postdrop -r" exited with status 1
fatal: info@gricargo.com(467): unable to execute /usr/sbin/postdrop -r: Success

nginx log is empty.

What else needs to be changed in this systemd file?
 [2019-12-06 07:18 UTC] ilya at ilya dot pp dot ua
-NoNewPrivileges=true

-RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX
+RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX AF_NETLINK

Solves my problem.
 [2019-12-06 07:27 UTC] retertertert at fgfgfg dot com
or just don't use mail() - where i work that's a forbidden and disabled function for 20 years now for security reasons and before i remove "NoNewPrivileges=true" for the sake of calling sendmail i commit suicide

https://github.com/PHPMailer/PHPMailer
 [2019-12-06 07:42 UTC] ilya at ilya dot pp dot ua
For 20 years we lived without systemd and without their limitations and everything was fine, but Lenart NotABag Pottering came and brought its democracy to our sinful land ...

By default, NoNewPrivileges=false and in php 7.3.11 it is also disabled.
In the migration instructions for php 7.4, not a word about the need to coordinate reconfigure the systemd file!

I am not saying that NoNewPrivileges=true is not necessary at all.
If there is another safe way to solve my problem without turning it off, I will only be glad. But for now I do not know how.
I suspect that this could break any call to system().

As for mail() - it was there and remains the standard, basic, recommended way to send mail in php.
The only thing it is not suitable for mass mailings, which I know very well.

But if calling mail() is not safe this is a php bug.
 [2019-12-06 07:48 UTC] fgfgfgfdf at somewhere dot com
what about trying to understand what's going on when using mail()?
the sendmail command forkend in the background with *root privileges*

do what you want, the "Lenart NotABag Pottering" gave you the capabilities to make your system as unsecure as you want within /etc/systemd/system/servicename.service.d/

defaults have to be secure, if you know what you are doing which i doubt make it unsecure as you want
 [2019-12-06 08:07 UTC] ilya at ilya dot pp dot ua
I have a policy of trying to implement as much functionality as possible using the basic features of a programming language. I use third-party only when the necessary functionality is beyond the scope of this programming language (for example, export to pdf or xls).

Sending mail is necessary for any programming language aimed at server-side web scripts.

I did not know that sendmail needed root privileges to work (from the console, and from other scripts, I always sent mail via sendmail from a regular user without problems).

If the basic mail () function written in C has such problems, and a third-party function written in PHP is better and safer, then why shouldn't the PHP developers rewrite it safely, possibly even preserving its interface?
In C, can it be better and more productive, and most importantly, without third-party code?

Or am I not understanding something?
 [2019-12-06 08:18 UTC] fgfgfgfdf at somewhere dot com
> I did not know that sendmail needed root privileges 
> to work (from the console, and from other scripts, 
> I always sent mail via sendmail from a regular 
> user without problems)

so be gald that you now learned about https://en.wikipedia.org/wiki/Setuid thanks to systemd and it's capabilities to run services in a secure way

> then why shouldn't the PHP developers rewrite it safely

because the only safe way is to use smtp which typically needs configuration and authentication and there is no reason to do so given that the gold standard fpr send mail from PHP is phpMailer for many years (which can even use sendmail if the webserver is allowed to evelvate privileges

> Sending mail is necessary for any programming language 
> aimed at server-side web scripts

yeah, you can implement SMTP in wahtever language you want, phpMailer did that for PHP

so either sacrifice the security of your server and continue what you did all the years or now that you learned about the security implications (fire up a root process from the webserver) stop demand sacrifice security of the default install

the capabilities and NoNewPrivileges are fine as default, here we go *much* further 

User=apache
Group=apache
AmbientCapabilities=CAP_IPC_LOCK CAP_NET_BIND_SERVICE
CapabilityBoundingSet=CAP_IPC_LOCK CAP_NET_BIND_SERVICE
LockPersonality=yes
NoNewPrivileges=yes
PrivateDevices=yes
PrivateTmp=yes
RestrictNamespaces=yes
RestrictRealtime=yes
SystemCallArchitectures=x86-64
SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module @mount @obsolete @raw-io @reboot @swap
ProtectSystem=strict
ProtectHome=yes
ProtectControlGroups=yes
ProtectKernelModules=yes
ProtectKernelTunables=yes
ReadWritePaths=/run/httpd
ReadWritePaths=/tmp
ReadWritePaths=/var/log
ReadWritePaths=/var/www
 [2019-12-06 11:57 UTC] sjon@php.net
-Status: Open +Status: Verified -Package: *Configuration Issues +Package: Documentation problem
 [2019-12-06 11:57 UTC] sjon@php.net
> this is sonsense 

No it's not. Nowhere does PHP have a dependency on sendmail - so it makes sense that settings like CapabilityBoundingSet and NoNewPrivileges are secure by default, and only lists dependencies FPM itself actually needs.

I do agree this could be mentioned on https://www.php.net/manual/en/migration74.other-changes.php since this has become stricter in 7.4
 [2019-12-06 15:23 UTC] nikic@php.net
-Assigned To: +Assigned To: bukka
 [2019-12-06 15:23 UTC] nikic@php.net
Assigning bukka for his opinion on the topic.
 [2019-12-08 17:57 UTC] bukka@php.net
Automatic comment on behalf of bukka
Revision: http://git.php.net/?p=php-src.git;a=commit;h=ac042f839f4c4a2b8241fa69f8f3b01766814f1e
Log: Fix bug #78916 (php-fpm 7.4.0 don't send mail via mail())
 [2019-12-08 17:57 UTC] bukka@php.net
-Status: Verified +Status: Closed
 [2019-12-08 17:59 UTC] bukka@php.net
Automatic comment on behalf of bukka
Revision: http://git.php.net/?p=php-src.git;a=commit;h=ac042f839f4c4a2b8241fa69f8f3b01766814f1e
Log: Fix bug #78916 (php-fpm 7.4.0 don't send mail via mail())
 [2019-12-08 18:07 UTC] bukka@php.net
-Package: Documentation problem +Package: FPM related
 [2019-12-08 18:07 UTC] bukka@php.net
Fixed in a suggested way. We can't really break mail function in the default unit no matter how secure its usage is - that should be discussed somewhere else and it's not FPM business to decide that. The default unit has to work for all the core parts.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 09:01:32 2024 UTC