DEV Community

Cover image for PHP mail() function fails with PHP-FPM in OpenBSD's httpd
nabbisen
nabbisen

Posted on • Updated on

PHP mail() function fails with PHP-FPM in OpenBSD's httpd

* The cover image is originally by Kdsphotos and edited with great appreciation.

Introduction

I was seriously in trouble to use PHP mail() function via PHP-FPM in OpenBSD.
The reason of the failure was very simple; /bin/sh didn't exist in the environment after chroot by PHP-FPM!

My case

I have used Contact Form 7, one of WordPress's plugins, to enable visitors to send requests.
After migrating the server, submitting the form always failed. I debugged it and found the error message in the browser console, which was as url: https://$FQDN/wp-json/contact-form-7/v1/contact-forms/28/feedback. It said, "{"code":"rest_no_route","message":"URL [...]","data":{"status":404}}".

Body

Environment

  • OS: OpenBSD 6.5
  • Web: OpenBSD's httpd
  • App: PHP 7.3 via PHP-FPM

Backgrounds

My php code was like this:

$mail = mail($to, $subject, $message, $headers);
if ($mail) {
    ...
Enter fullscreen mode Exit fullscreen mode

It failed and all the errors I managed to get were difficult for me to understand.
For example, putting error_get_last() behind mail() returned only 1.
Also, I couldn't find any useful log.

I checked the PHP core config files aka /etc/php-7.3.ini and /etc/php-fpm.ini again and again, which seemed correct.
Then I got lost...

After a while to struggle, I found Joel Carnat's article of this and got the solution thanks to it!

In OpenBSD's PHP-FPM as well as httpd, chroot defaults to /var/www defined in /etc/php-fpm.conf.
In this case, /var/www/bin/sh, the executable, was necessary in order to execute PHP mail() function.

How To Solve It

My solution was just to copy /bin/sh to the environment after chroot:

# cp -p /bin/sh /var/www/bin/
Enter fullscreen mode Exit fullscreen mode

After doing it, I opened the website with my browser and then a mail was successfully sent :)

Conclusion

OpenBSD's httpd and PHP-FPM use chroot, which defaults to /var/www.
Therefore, as developing apps behind them, the environment under /var/www is worth to pay attention to.

Thank you for your reading.
Happy computing.

Top comments (0)