www-data user access to non-www folders in php file

Discussion in 'Server Operation' started by Jotillas, Jul 23, 2020.

  1. Jotillas

    Jotillas New Member

    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.
     
  2. ahrasis

    ahrasis Well-Known Member HowtoForge Supporter

    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.
     
  3. Jotillas

    Jotillas New Member

    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
     
  4. nhybgtvfr

    nhybgtvfr Well-Known Member HowtoForge Supporter

    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/
     
  5. Jotillas

    Jotillas New Member

    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?
     
  6. Steini86

    Steini86 Active Member

    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
     
  7. Jotillas

    Jotillas New Member

    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 namespace
    use 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 that
    date_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 errors
    if (!$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.
     
    Last edited: Jul 25, 2020
  8. Steini86

    Steini86 Active Member

    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
     

Share This Page