The lines that the user needs to enter or customize will be in red in this tutorial!
The rest should mostly be copy-and-pastable.
The PHP mail() function uses the program in sendmail_path configuration directive to send emails. This is set up as sendmail by default.
While most Linux installations have sendmail preinstalled, there is always a hassle of setting up SPF/PTR records, generating DKIM keys and a lot more to ensure that the email sent by your PHP script is not flagged as spam. A SMTP client called MSMTP can be used to send emails using third-party SMTP servers, this can also be used by PHP's mail() in the place of sendmail.
To install MSMTP on Fedora Linux use yum:
yum install msmtp
CentOS repository doesn't have a RPM package for MSMTP so we need to install it from source:
yum install make gcc pkgconfig wget http://sourceforge.net/projects/msmtp/files/msmtp/1. tar -xvf msmtp-1.4.31.tar.bz2 cd msmtp-1.4.31 ./configure make make install4.31/msmtp-1.4.31.tar.bz2/ download
The latest version is 1.4.31 at the time of this writing but it may change in future so to get the latest version, visit this sourceforge page.
On Ubuntu/Debian distribution use apt-get:
apt-get install msmtp
Arch Linux users:
sudo pacman -S msmtp
The configuration file of MSMTP is stored in ~/.msmtprc for each user and /etc/msmtprc is the system wide configuration file. Open the configuration file in your directory.
vi ~/.msmtprc
Add the following lines for a Yahoo account:
account yahoo tls on tls_starttls off tls_certcheck off auth on host smtp.mail.yahoo.com user user1 from user1@yahoo.com password yourYahooPa5sw0rd
For Gmail, use the following settings:
account gmail tls on tls_certcheck off auth on host smtp.gmail.com port 587 user user1@gmail.com from user1@gmail.com password yourgmailPassw0rd
This file can also have more than one account, just ensure that the "account" value is unique for each section. Save the file and use chmod to make this file readable only by the owner since it contains passwords. This step is mandatory because msmtp won't run if the permissions are more than 600.
chmod 600 ~/.msmtprc
Before implementing this in PHP, check from the command-line to ensure it works properly. To do this, create a plain text file containing a simple email:
echo -e "From: alice@example.com \n\ To: bob@domain.com \n\ Subject: Hello World \n\ \n\ This email was sent using MSMTP via Gmail/Yahoo." >> sample_email.txt
Now send this email:
cat sample_email.txt | msmtp --debug -a gmail bob@domain.com
Replace the word "gmail" with "yahoo" or whatever you entered for the "account" option. You'll see a lot of messages because of the "--debug" parameter. This is to make troubleshooting easy if things don't work as expected. If bob@domain.com receives this email, everything is setup correctly so copy this file to the /etc directory:
cp -p ~/.msmtprc /etc/.msmtp_php
Change the ownership to the username under which the web server is running. This can be "apache", "www-data", or "nobody" depending on the Linux distribution on your VPS and web server installed:
chown www-data:www-data /etc/.msmtp_php
Open the php.ini file, its location varies according to the OS and PHP type installed (PHP CGI, mod_php, PHP-FPM etc):
vi /etc/php5/php.ini
Find the following line:
sendmail_path =
Modify it by adding the path to the msmtp command:
sendmail_path = "/usr/bin/msmtp -C /etc/.msmtp_php --logfile /var/log/msmtp.log -a gmail -t"
Manually create a log file and change its ownership to the username your web server is running as:
touch /var/log/msmtp.log chown www-data:www-data /var/log/msmtp.log
Restart your web server to apply the changes:
service httpd restart
In Arch Linux, this is done using the systemctl command:
systemctl restart httpd
Depending on your OS and web server, replace "httpd" with the appropriate name. If PHP is running as a separate process (like PHP-FPM), restart it instead:
service php5-fpm restart
Create a PHP script with a simple mail() to test this setup:
<?php if(mail("receipient@domain.com","A Subject Here","Hi there,\nThis email was sent using PHP's mail function.")) print "Email successfully sent"; else print "An error occured"; ?>
Access this file from the web browser.
http://www.example.com/file.php
If this email wasn't sent you can check the msmtp log file for errors.
tail /var/log/msmtp.log
If the email was not sent when using the PHP script, troubleshoot as follows:
php /var/www/html/file.php
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!
Hi,
Thanks for the tutorial, it’s very clear and easy to follow. I have a problem though, and I’ve exhausted every method I can think of to solve it.
When using the sample PHP script above to send the message (through gmail), I get the following error:
errormsg=‘authentication failed (method PLAIN)’ exitcode=EX_NOPERM
I have followed the config settings to the letter, checked the php.ini path, etc. but to no avail. Any suggestions on where to start looking to solve this?
By the way, I can tell than an attempt to send the message through gmail was made because I received a message from Google about an unauthorized attempt to send email through my account. I double checked the password, file settings, file location, but all seems correct.
@wizardware: Google prevented the login so php was unable to send the message. Try to see if you can whitelist your app from your gmail account’s settings.
Bingo! That did the trick, problem solved. Thank you Kamal, I doubt I would have ever thought of this.
It looks like msmtp expects to see the system wide config file in /etc/msmtprc in spite of what you put in the sendmail path. You also need to change the SMTP port to 587 to work with gmail - at least for my paid Google Apps account.
Ignore my comment - i’d missed out the chown. After some sleuthing, I found the reason!
CentOS 6.4 x32 does not send e-mail in error: “msmtp: support for TLS is not compilled in”. How to fix the problem?
I had the same problem on CentOS 7 with msmtp version 1.6.2 this is how I solved it: In the directory where the source code of msmtp is located run these commands
make uninstall make clean yum install -y openssl* ./configure --with-tls=openssl make make install
That’s all =)
This method is not safe to use on shared environments, since the gmail/yahoo password is exposed and readable by any apache user.
@dmmd Add “tls_certcheck off” to the msmtp configuration file.
Hi there, great guide! It’s helped a lot, but I seem to be having issues getting the actual PHP to work.
Using command line msmtp command seems to work correctly, however using the PHP file sends back the failiure message. Just running “php mail.php” sends a “Authentication Failed (xxx Too Many Login Attempts)” which really confuses me. How could the command line email pass authentication but not the php file?
Thanks!
@em.apparition That error is displayed by the SMTP server (usually Gmail’s SMTP) if you’re using Google Apps without a DKIM record.
Read this http://serverfault.com/questions/543007/google-smtp-error-454-4-7-0-too-many-login-attempts-please-try-again-later
As to why it succeeds with the msmtp command I’m guessing that you’re using different email accounts in the ~/.msmtprc file and the one in /etc
something missing that make me crazy
yum install openssl yum install openssl-devel
and check send mail path
msmtp --version
I couldn’t send it from file.php but it worked on php /var/www/html/file.php What did I do wrong?
did you solve it?
I made it work. But not on 465 port. Actually I’m on 587… but would be more secure to use 465? I tried to exchange from 587 to 465 but with no success. I tried add ssl:// on smtp.gmail.com and no email wass ent
I cant get it working… Tryed postfix, sendmail, exim and now this, none work. Unnistalled everything before testing and followed the many tutorials. Using unbutu 12.4
On this one im having problem on step cat sample_email.txt | msmtp --debug -a gmail bob@domain.com
msmtp: cannot connect to smtp.gmail.com, port 587: Network is unreachable msmtp: could not send mail (account gmail from /home/username/.msmtprc)
This is the first time I’m doing stuff like this, so I almost don’t have any idea. My msmtprc file looks like this:
account killaribyte host mail.killaribyte.com port 587 from contacto@killaribyte.com user contacto password **********
When I run the command: dig MX killaribyte.com +short @ns1.digitalocean.com I got: 50 mail.killaribyte.com.
When I run: host mail.killaribyte.com ns1.digitalocean.com I got: Using domain server: Name: ns1.digitalocean.com Address: 198.199.120.125#53 Aliases:
mail.killaribyte.com has address ... (my IP)
And finally when I want to test it with: cat sample_email.txt | msmtp --debug -a killaribyte contacto@killaribyte.com I got: msmtp: cannot connect to mail.killaribyte.com, port 587: Connection refused msmtp: could not send mail (account killaribyte from /etc/msmtprc)
@lfna23 Try changing the port to 25
@luanpersini I think iptables is configured incorrectly to block outgoing connections or to prevent TCP connections. Try clearing the rules
<pre>iptables -X iptables -F</pre>
The command line of sending e mail works for me but when it comes to using the file.php, I encountered the error msg in the browser "Failed to connect to ssl://foeapp.com:465 [SMTP: Failed to connect socket: Connection refused (code: -1, response: )]”
Any idea? I thought i have changed it to 587 on the msmtp file.
I got it work. Used the wrong file.php. Apologies
Thank you for this tutorial! It was very helpful and did exactly what I needed!
Hi, followed and successfully configured.
However, its rather slow even for the test mail. Takes 3-5 mins, is it normal?
@erwin: What’s the latency between your server and the SMTP server you’re connecting to?
or
Ok … managed to nail the problem, droplet is in Singapore 1 with IPv6 enabled. It takes 3-5 minutes with IPv6 and after disabling IPv6 within OS (nothing else changed), it takes 2-4 seconds with IPv4.
I do not know if it is Google or DigitalOcean but I really hope that DigitalOcean will look into and check if there is a IPv6 routing or speed issue.
msmtp: TLS handshake failed: An unexpected TLS packet was received. msmtp: could not send mail (account gmail from /home/pi/.msmtprc)
I have no idea what this means, could someone help? I would greatly appreciate it!
When I run the test php command it throws this error.
sh: 1: /usr/sbin/sendmail: not found
Why is it even setting it to sendmail path? how can I change it to make it use the msmtp? Also it’s not logging this error. I had to run the php in putty to get this error msg =\
Please help
If you run php scripts from the command line the following configuration file is used:
So you have to make those changes here.
Thanks jesin. I did the change to the apache2 php.ini so thanks for pointing out that its in the cli folder. Ok it sent the email successfully through putty but when trying to run it through the browser it gives an error. Problem if I go to the log now it just shows the one that got sent.
UPDATE It’s loggin under Apache2 though: msmtp: /etc/.msmtp_php: Permission denied
I have allowed myself to change it but now it gives this msg.
msmtp: /etc/.msmtp_php: must be owned by you
You’re welcome!
It must be owned by the user under which the Apache/php5-fpm process is running.
This could be
www-data
orapache2
. Try changing the file’s ownership to one of them and alsochmod
this file to600
.This comment has been deleted
www-data worked! Thank you!
One last question.
How can I make it work with my process.php for my contact form? It’s using phpMailer.
Example masked. Appreciate your help.
PHPMailer can be used to directly send emails via SMTP. Add these before
$mail->Send()
:They were there already and tried to send with it and didn’t work so I removed them assuming it will use the settings in the msmtp but still, didn’t work. =\
Enable debugging with the following code:
See what you get without the SMTP settings and with them.
I’m having the same issue as dmmd running CentOS… Everything works up until I try to send the test email.
[root@first msmtp-1.4.32]# cat sample_email.txt | msmtp --debug -a yahoo bob@domain.com ignoring system configuration file /usr/local/etc/msmtprc: No such file or directory loaded user configuration file /root/.msmtprc using account yahoo from /root/.msmtprc host = smtp.mail.yahoo.com port = 465 timeout = off protocol = smtp domain = localhost auth = choose user = myUserName password = * passwordeval = (not set) ntlmdomain = (not set) tls = on tls_starttls = off tls_trust_file = (not set) tls_crl_file = (not set) tls_fingerprint = (not set) tls_key_file = (not set) tls_cert_file = (not set) tls_certcheck = off tls_force_sslv3 = off tls_min_dh_prime_bits = (not set) tls_priorities = (not set) auto_from = off maildomain = (not set) from = myUserName@yahoo.com dsn_notify = (not set) dsn_return = (not set) keepbcc = off logfile = (not set) syslog = (not set) aliases = (not set) reading recipients from the command line msmtp: support for TLS is not compiled in
Any suggestions? I already had the tls_certcheck set to off.
Thanks.
I guess you need to install OpenSSL and then reinstall MSMTP.
Thank you for this. Skipped sendmail for this. However I would suggest not disabling TLS cert check.
Run this command to find cert issuer of your SMTP host.
Then simply locate appropriate cert to be used by msmtp.
Now I just need to figure out how to use
passwordeval
+gpg
with this so password is not plaintext.It works for me exactly as described. I’m using an Archlinux and
msmtp
in version 1.4.32.Thanks, it’s very useful.
I get to the part to enter my data into vi ~/.msmtprc however I cannot figure out how to save it and move to the next screen. Im a total noob with the terminal. Please help someone :)
nevermind I figured this one out
i am getting “The program ‘php’ is currently not installed. You can install it by typing: apt-get install php5-cli”
I have the current LEMP stack installed
That is exactly what you have to do:
When I run php /var/www/html/file.php I get this in the terminal"Could not open input file: /var/www/html/file.php". The email sends if I send it from the terminal but no through the mail script, I also get a 404 error when I try to view the file.php in the browser
HI, i’m having a problem with this. It was going ok until I tested in the browser and it did’nt send a email, now i’m getting this message back /usr/bin/msmtp: invalid option – ‘c’ when I run php /var/www/html/mailtest.php on the command line, Any ideas how I can sort this…
@Razor303: Make sure that the
C
is in uppercase:not
Don’t forget to restart Apache or php5-fpm after updating php.ini.
@jeff781158 If you see a 404 error on the browser the wrong file is being edited. Are you using Apache or Nginx?
@kamain7 thanks dude, I can’t believe I missed that. anyway it’s worked with php from the command line I’m ssh in to my server from my phone when I get home I’ll test it properly, but it’s looking good
@jeff781158 i’m using Apache2 at the min ! but i will be using Nginx when I move from testing, tinkering & developing to production. I’m not getting a 404 error, it sends it ok with php on the command line but not from the browser, php echo’s An error occured from the sample script. I haven’t got a domain name yet because i’m testing that wouldn’t matter, would it? below is the php script i’m using
<?php if(mail(“myemail@gmail.com”,“Test messsage”,“Hi there Sh*t it worked !,\nThis email was sent using PHP’s mail function.”)) print “Email successfully sent”; else print “An error occured”; ?>
I have saved the file as index.php in /var/www/html then in my browser I put servers-ip/index.php
@Razor303: What OS are you running? You might need to edit a different
php.ini
file depending on where the distribution’s packages store the configuration files by default. Are there any errors in/var/log/mail.err
?@kamaln7 i’m using Ubuntu LAMP on 14.04. had a look in mail log there are a few entries because i’ve been sending a lot of test email some end with EX__OK they must be from the php command line because I can send mail from there, there are also some ending with --Header:
EXAMPLE BELOW:
[23-Nov-2014 23:37:08 America/New_York] mail() on [/var/www/html/index.php:2]: To: Myemail@gmail.com – Headers:
@Razor303 Must be a problem with the permissions. Check who owns the config file:
Also check MSMTP’s config file for errors:
Hi, @jeff781158 this is what I get back when I check who owns the config file
-rw------- 1 www-data www-data 155 Nov 22 18:04 /etc/.msmtp_php
I can’t see any errors on the log file ???
@Razor303 Just to confirm that the right php.ini file was edited, create a
phpinfo
file and access it on your browser. Check for the value ofsendmail_path
, if it shows the default value check for the php.ini file location in Loaded Configuration File and edit this file.Hi, @jeff781158 this is what I get back when I check who owns the config file
-rw------- 1 www-data www-data 155 Nov 22 18:04 /etc/.msmtp_php
I can’t see any errors on the log file ???
@Razor303 Just to confirm that the right php.ini file was edited, create a
phpinfo
file and access it on your browser. Check for the value ofsendmail_path
, if it shows the default value check for the php.ini file location in Loaded Configuration File and edit this file.This is a great article. I’ve used replacement modules for PHP mail before, and I’ve configured SMTP servers before… but I like this no-nonsense approach.
Email sent this way is more reliable/deliverable because other mail servers will see the traffic coming from a well-known SMTP service like Google (instead of directly off my webhosting IP, which some sites will spam score or at least treat with skepticism).
Hmm, odd problem occurring. I have only created an /etc/msmtprc file for config testing, not created a ~/.msmtprc. In this I have
Then I send this text message:
When I test with debug, it authorises great thru google apps, but I get this:
Question: Where is it getting **RCPT TO: ** value from - there is no sam@ anywhere in this config.
David
Hi David,
Please provide the entire
msmtp
command along with its arguments.Aaaaah. My bad, sorry. You are exactly right: I was specifying wrong recipient in msmtp command line, and expecting To: part to override, without specifying --read-recipient option.
Thanks Jesin.
Great tutorial - thanks!
Only works by the terminal.
What do I do?
Are you using mod_php with Apache or PHP-FPM?
Based on that you may have to edit /etc/php5/fpm/php.ini or /etc/php5/apache2/php.ini and modify
sendmail_path
.Thanks for this tutorial! Works great!!!
Took a fair amount of time and hair pulling between figuring out exactly what parameters I needed to change, and remembering to uncomment the darn sendmail path >.<, but got everything working eventually!
Everyone getting blocked by google may try this solution
if you don’t have w3m text browser - install it with this command: sudo apt-get install w3m
w3m https://www.google.com/accounts/DisplayUnlockCaptcha
authorize with the e-mail you are using on the server confirm
press q to quit w3m
Great tutorial! But I’m running on a small problem that I don’t quite understand.
I’ve installed msmtp, and configured everything of my Google account (Google apps account) above, (email and password are correct).
Created the small email test php script. restarted apache2 and php5-fpm services (even my droplet after several attempts). But my email has never arrived.
Strange this is. When I execute the test script via command line I get the my success message and when I go to the same test script via the browser (script is located in www directory), I get the error message, msmtp.log file is for some reason empty, maybe permissions problem?
Oh yes: cat sample_email.txt | msmtp --debug -a gmail “myemail@myemail.com” works…
Any help is welcome :)
Never mind, forgot the part where I had to copy the .msmtprc file to the /etc directory d’oh!
Hi,
thank you for your great tutorial. I followed your tutorial and manage to send email when executing the php command line but not when I access the file from the web browser, what does this mean?
I don’t understand why I cannot send email from Wordpress (ie. fail to send a password from the interface Wordpress). How about Apache config ‘ServerAdmin’ ?
Thank you in advance for your help
Check if the
sendmail_path
is set correctly.Thank you Jesin for your quick reply.
This is what I got when running the suggested command: sendmail_path = “usr/bin/msmtp -C /etc/.msmtp_php --logfile /var/log/msmtp.log -a gmail -t”
However, in the /var/log/apache2/error.log, I saw this error
sh: 1: usr/bin/msmtp: not found
Maybe this is the reason that I cannot send email using msmtp. My user is in the group www-data and mail and I think that I set the permissions correctly. By the way, what user (role) should we use?
Thanks again for your help. cheers,
You missed out a
/
at the beginning. It should be:Thank you so much Jesin for your great support. I added the ‘/’ as you suggested and it works like a charm.
Hi, Thanks for the tutorial. Recently I have taken a gmail domain account (like support@domain.com). I want to send a mail from this account whenever the user register in my website. For this, I have followed the above steps and configured things as mentioned. When I run the given file sample_email.txt the mail is delivered to the user with the correct details like (from: namesupport@domain.com mailed-by : domain.com ). But when I run the php script it is giving different values (like, from : www-data “www-data@user@gmail.com via ******(some domain)” mailed-by: ******(that same name as mentioned after via) ). Please help me to correct these columns.
Never mind, I made something wrong while configuring the php.ini file. Now it is fine. Thanks, for the article once again. :)
Hello. how are you? I wanted to install smtp but I wanted to ask you what directory should I do the configuration? in fact I use centos 7 and wanted to make ntopng alerts by email with php. I really need your help. I am an amateur in linux I wanted to clarify it. thank you in advance!!!