I have just installed PHPMailer 6.1 and managed to send a test e-mail through a simple php file using command line (php my_email_file.php). I was even able to sign it with DKIM so that Gmail flag it as signed by my domain. However, when I run the very same file through the browser (www.mydomain.com/my_email_file.php), the e-mail is sent but the DKIM signature no longer works. Debug info does not contain any hints, it simply ignores de DKIM part. If I copy and paste the private key file within my website folder (/var/www/...) everything works again but this is obviously not a good solution. So I guess the problem is that the website user is unable to access /var/amavis folder and files, hence not able to use the private key to sign. Any recommended solution? Thank you very much in advance.
I am not sure how this phpmailer works but if it is something like RoundCube or phpMyAdmin then I think it should be installed in a similar way, i.e. in /usr/share and added the app vhost for access. This is just a thought.
To the best of my knowledge, this is not needed. Indeed, I can make it work without dkim and also with dkim from CLI. My bet is that the Apache user cannot access de dkim key folder located in /var/lib/amavis/dkim Indeed, while troubleshooting I added this: $privatekey = $mail->DKIM_private; if (file_exists($privatekey)) { echo "Have access"; } else { echo "No access"; } And, once more, with CLI, it prints Have access but with web No access
just out of interest, when running the php script from the cli, are you running it as root, or as the website's ssh user? perhaps it's not actual file/folder permissions that are the problem per se, ie, you maybe don't have to actually change owner/group or actual file/folder permissions, i was thinking maybe just adding the /var/lib/amavis/dkim folder to the jailkit, if used, would be enough, but that would give them access to private keys for other domains, so that's out. maybe just symlinks from in /var/www/domain.tld/private/ to /var/lib/amavis/dkim/domain.tld.private and domain.tld.public and then set the path for Code: $email->DKIM_private = '/path/to/private_key'; to point to /var/www/$domainname/private/
Thank you! The CLI one was ran as root I tried with the symlinks but it did not work either. I guess the symlinks just take whatever permissions original files have, right?
Amavis has different mail "paths" depending on how the mail enters the system. I am wondering why the command line signing worked. Afaik in the standard settings only mail delivered via authenticated smtp is signed. In a way, dkim signing would be useless, if non-authenticated users could send signed mails. So the easy (and best) solution is to sent via authenticated smtp and not via mail() command. See official documentation on how to do that: https://github.com/PHPMailer/PHPMailer/blob/master/examples/smtp.phps
Thank you, Steini86. Although this is exactly what I am doing, using the smtp with authentication template. For reference, this is the code I am using both in CLI and web (php file located in /var/www/mywebsite/web): PHP: <?php/** * This example shows making an SMTP connection without using authentication. *///Import the PHPMailer class into the global namespaceuse PHPMailer\PHPMailer\PHPMailer;use PHPMailer\PHPMailer\SMTP;$direccion = "[email protected]";$titulo = "DKIM Test";$mensaje = "DKIM signed message";$replyto = "[email protected]";$replytoname = "MyName";//SMTP needs accurate times, and the PHP time zone MUST be set//This should be done in your php.ini, but this is how to do it if you don't have access to thatdate_default_timezone_set('Europe/Madrid');require 'new_mail/vendor/autoload.php';//Create a new PHPMailer instance$mail = new PHPMailer;//Tell PHPMailer to use SMTP$mail->isSMTP();//Enable SMTP debugging// SMTP::DEBUG_OFF = off (for production use)// SMTP::DEBUG_CLIENT = client messages// SMTP::DEBUG_SERVER = client and server messages$mail->SMTPDebug = SMTP::DEBUG_SERVER;//Set the hostname of the mail server$mail->Host = 'localhost';//Set the SMTP port number - likely to be 25, 465 or 587$mail->Port = 25;$mail->SMTPAutoTLS = false;$mail->CharSet = 'utf-8';$mail->setLanguage('es', 'PHPMailer/language');//We don't need to set this as it's the default value$mail->SMTPAuth = true;//Username to use for SMTP authentication$mail->Username = '[email protected]';//Password to use for SMTP authentication$mail->Password = 'mypassword';//Set who the message is to be sent from$mail->setFrom('[email protected]', 'MyName');//Set an alternative reply-to address$mail->AddReplyTo($replyto, $replytoname);//Set who the message is to be sent to$mail->addAddress($direccion);//Set the subject line$mail->Subject = "=?UTF-8?B?".base64_encode($titulo)."?=";//Replace the plain text body with one created manually$mail->AltBody = 'To view the message, please use an HTML compatible email viewer!';//This should be the same as the domain of your From address$mail->DKIM_domain = 'mydomain.com';//See the DKIM_gen_keys.phps script for making a key pair -//here we assume you've already done that.//Path to your private key:$mail->DKIM_private = '/var/lib/amavis/dkim/mydomain.com.private';//Set this to your own selector$mail->DKIM_selector = 'mail';//Put your private key's passphrase in here if it has one$mail->DKIM_passphrase = '';//The identity you're signing as - usually your From address$mail->DKIM_identity = $mail->From;//Suppress listing signed header fields in signature, defaults to true for debugging purpose$mail->DKIM_copyHeaderFields = false;$privatekey = $mail->DKIM_private;echo $privatekey;if (file_exists($privatekey)){ echo "Has access";}else{ echo "No access";}//send the message, check for errorsif (!$mail->send()) { echo 'Mailer Error: '. $mail->ErrorInfo;} else { echo 'Message sent!';}//} This is what I get in CLI: Code: Has access 08:05:49 SERVER -> CLIENT: 220 myserver ESMTP 08:05:49 CLIENT -> SERVER: EHLO myserver 08:05:49 SERVER -> CLIENT: 250-myserver 250-PIPELINING 250-SIZE 20480000 250-ETRN 250-STARTTLS 250-AUTH PLAIN LOGIN 250-AUTH=PLAIN LOGIN 250-ENHANCEDSTATUSCODES 250-8BITMIME 250 DSN 08:05:49 CLIENT -> SERVER: AUTH LOGIN 08:05:49 SERVER -> CLIENT: 334 VXNlcm5hbWU6 08:05:49 CLIENT -> SERVER: [credentials hidden] 08:05:49 SERVER -> CLIENT: 334 UGFzc3dvcmQ6 08:05:49 CLIENT -> SERVER: [credentials hidden] 08:05:49 SERVER -> CLIENT: 235 2.7.0 Authentication successful 08:05:49 CLIENT -> SERVER: MAIL FROM:<[email protected]> 08:05:49 SERVER -> CLIENT: 250 2.1.0 Ok 08:05:49 CLIENT -> SERVER: RCPT TO:<[email protected]> 08:05:49 SERVER -> CLIENT: 250 2.1.5 Ok 08:05:49 CLIENT -> SERVER: DATA 08:05:49 SERVER -> CLIENT: 354 End data with <CR><LF>.<CR><LF> 08:05:49 CLIENT -> SERVER: Date: Sat, 25 Jul 2020 10:05:49 +0200 08:05:49 CLIENT -> SERVER: To: [email protected] 08:05:49 CLIENT -> SERVER: From: MyName <[email protected]> 08:05:49 CLIENT -> SERVER: Reply-To: MyName <[email protected]> 08:05:49 CLIENT -> SERVER: Subject: =?UTF-8?B?SG9sYSBES0lN?= 08:05:49 CLIENT -> SERVER: Message-ID: <FbCdgC7Q8GcnzAXbC81d7aR8dGYXMjaHTPcJufflp1Y@ns300543> 08:05:49 CLIENT -> SERVER: X-Mailer: PHPMailer 6.1.7 (https://github.com/PHPMailer/PHPMailer) 08:05:49 CLIENT -> SERVER: MIME-Version: 1.0 08:05:49 CLIENT -> SERVER: Content-Type: multipart/alternative; 08:05:49 CLIENT -> SERVER: boundary="b1_FbCdgC7Q8GcnzAXbC81d7aR8dGYXMjaHTPcJufflp1Y" 08:05:49 CLIENT -> SERVER: Content-Transfer-Encoding: 8bit 08:05:49 CLIENT -> SERVER: DKIM-Signature: v=1; d=mydomain.com; s=mail; 08:05:49 CLIENT -> SERVER: a=rsa-sha256; q=dns/txt; t=1595664349; c=relaxed/simple; 08:05:49 CLIENT -> SERVER: h=Date:To:From:Reply-To:Subject:Message-ID:X-Mailer:MIME-Version:Content-Type; 08:05:49 CLIENT -> SERVER: [email protected]; 08:05:49 CLIENT -> SERVER: bh=quH/vtvt3pX5+MdRVXNLdXO5/96jjoTSgctYgk2xZJI=; 08:05:49 CLIENT -> SERVER: b=KLNeiShgq2uE2FkMqDDNuNn4w0C0ZmD9hcuhNMzE07xenka3a+Ech4i7+9+SLnOXTv30H8tq5 08:05:49 CLIENT -> SERVER: NiUjLCU4c6BsYZxfeD4MH/qKHAD02yzZHfECCj2C3T2HaQb+qbSrzkhAYfYnfRDxNhtPI34sE 08:05:49 CLIENT -> SERVER: dNHXVb6fL9ptKvv9cIBj0xUEk= 08:05:49 CLIENT -> SERVER: 08:05:49 CLIENT -> SERVER: This is a multi-part message in MIME format. 08:05:49 CLIENT -> SERVER: 08:05:49 CLIENT -> SERVER: --b1_FbCdgC7Q8GcnzAXbC81d7aR8dGYXMjaHTPcJufflp1Y 08:05:49 CLIENT -> SERVER: Content-Type: text/plain; charset=us-ascii 08:05:49 CLIENT -> SERVER: 08:05:49 CLIENT -> SERVER: To view the message, please use an HTML compatible email viewer! 08:05:49 CLIENT -> SERVER: 08:05:49 CLIENT -> SERVER: --b1_FbCdgC7Q8GcnzAXbC81d7aR8dGYXMjaHTPcJufflp1Y 08:05:49 CLIENT -> SERVER: Content-Type: text/html; charset=us-ascii 08:05:49 CLIENT -> SERVER: 08:05:49 CLIENT -> SERVER: DKIM test 08:05:49 CLIENT -> SERVER: 08:05:49 CLIENT -> SERVER: 08:05:49 CLIENT -> SERVER: --b1_FbCdgC7Q8GcnzAXbC81d7aR8dGYXMjaHTPcJufflp1Y-- 08:05:49 CLIENT -> SERVER: 08:05:49 CLIENT -> SERVER: . 08:05:49 SERVER -> CLIENT: 250 2.0.0 Ok: queued as 500561A80068 08:05:49 CLIENT -> SERVER: QUIT 08:05:49 SERVER -> CLIENT: 221 2.0.0 Bye Message sent! And this one, what I get after running the very same php file through browser Code: No access 08:06:29 SERVER -> CLIENT: 220 myserver ESMTP 08:06:29 CLIENT -> SERVER: EHLO mydomain.com 08:06:29 SERVER -> CLIENT: 250-ns300543.ip-91-121-64.eu250-PIPELINING250-SIZE 20480000250-ETRN250-STARTTLS250-AUTH PLAIN LOGIN250-AUTH=PLAIN LOGIN250-ENHANCEDSTATUSCODES250-8BITMIME250 DSN 08:06:29 CLIENT -> SERVER: AUTH LOGIN 08:06:29 SERVER -> CLIENT: 334 VXNlcm5hbWU6 08:06:29 CLIENT -> SERVER: [credentials hidden] 08:06:29 SERVER -> CLIENT: 334 UGFzc3dvcmQ6 08:06:29 CLIENT -> SERVER: [credentials hidden] 08:06:29 SERVER -> CLIENT: 235 2.7.0 Authentication successful 08:06:29 CLIENT -> SERVER: MAIL FROM:<[email protected]> 08:06:29 SERVER -> CLIENT: 250 2.1.0 Ok 08:06:29 CLIENT -> SERVER: RCPT TO:<[email protected]> 08:06:29 SERVER -> CLIENT: 250 2.1.5 Ok 08:06:29 CLIENT -> SERVER: DATA 08:06:29 SERVER -> CLIENT: 354 End data with <CR><LF>.<CR><LF> 08:06:29 CLIENT -> SERVER: Date: Sat, 25 Jul 2020 10:06:29 +0200 08:06:29 CLIENT -> SERVER: To: [email protected] 08:06:29 CLIENT -> SERVER: From: MyName <[email protected]> 08:06:29 CLIENT -> SERVER: Reply-To: MyName <[email protected]> 08:06:29 CLIENT -> SERVER: Subject: =?UTF-8?B?SG9sYSBES0lN?= 08:06:29 CLIENT -> SERVER: Message-ID: <[email protected]> 08:06:29 CLIENT -> SERVER: X-Mailer: PHPMailer 6.1.7 (https://github.com/PHPMailer/PHPMailer) 08:06:29 CLIENT -> SERVER: MIME-Version: 1.0 08:06:29 CLIENT -> SERVER: Content-Type: multipart/alternative; 08:06:29 CLIENT -> SERVER: boundary="b1_4neYS87UPhdjVyQOEiztiLiXfL6Z0XZZgTPT0tr0" 08:06:29 CLIENT -> SERVER: Content-Transfer-Encoding: 8bit 08:06:29 CLIENT -> SERVER: 08:06:29 CLIENT -> SERVER: This is a multi-part message in MIME format. 08:06:29 CLIENT -> SERVER: 08:06:29 CLIENT -> SERVER: --b1_4neYS87UPhdjVyQOEiztiLiXfL6Z0XZZgTPT0tr0 08:06:29 CLIENT -> SERVER: Content-Type: text/plain; charset=us-ascii 08:06:29 CLIENT -> SERVER: 08:06:29 CLIENT -> SERVER: To view the message, please use an HTML compatible email viewer! 08:06:29 CLIENT -> SERVER: 08:06:29 CLIENT -> SERVER: --b1_4neYS87UPhdjVyQOEiztiLiXfL6Z0XZZgTPT0tr0 08:06:29 CLIENT -> SERVER: Content-Type: text/html; charset=us-ascii 08:06:29 CLIENT -> SERVER: 08:06:29 CLIENT -> SERVER: DKIM test 08:06:29 CLIENT -> SERVER: 08:06:29 CLIENT -> SERVER: 08:06:29 CLIENT -> SERVER: --b1_4neYS87UPhdjVyQOEiztiLiXfL6Z0XZZgTPT0tr0-- 08:06:29 CLIENT -> SERVER: 08:06:29 CLIENT -> SERVER: . 08:06:29 SERVER -> CLIENT: 250 2.0.0 Ok: queued as 725A21A80068 08:06:29 CLIENT -> SERVER: QUIT 08:06:29 SERVER -> CLIENT: 221 2.0.0 Bye Message sent! So, as you can see, the message is sent in both cases and authentication works as well. The key difference is that the instance run through browser does not get access to the private key file and, hence, cannot sign the message, while the CLI one can access and can sign.
OK. So usually, you deliver a message via smtp and amavis is doing the dkim signing (if configured). You want to use PHPmailer to do the dkim signing (I have no idea why, but if you want to do that...). But the web user running the php script has no rights to read the private dkim key located in /var/lib/amavis/dkim/ (which would be a security nightmare and is blocked for good reason!) So you have two options: 1) Copy / move the private key to the clients directory where a php script has access (/var/www/domain/private for example), and use phpmailer to do the dkim singing 2) Do the dkim signing with amavis. At the moment it does not seem to work, so you have to fix your amavis problem