====== Web Mail System ====== refer: * http://acidx.net/wordpress/2014/06/installing-a-mailserver-with-postfix-dovecot-sasl-ldap-roundcube/ * https://wiki.archlinux.org/index.php/Virtual_user_mail_system ===== Overview about webmail architecture ===== Overview about features in webmail system: * User will use roundcube website to send and receive email * Roundcube backend will: * integrate with **postfix for sendding email** * and integrate with **dovecot for authenticating user, receiving email, and get all email received** will be stored in mailbox of dovecot **/onec/vmail** * Postfix: Postfix * integrate with **dovecot mailbox** to save sent email * integrate with **postfixadmin database** to load config about virtual mailboxes * Dovecot: Integrate with **postfixadmin database** to authenticate users created from postfixadmin receive email----------->110(POP) | (Store email accounts) 143(IMAP) |-dovecot(IMAP)-------3306------->mysql(postfix database)<--3306--Postfixadmin roundcube--store--------->| | | | (sent, drafts) | |--->virtual mailbox | <--Receive--------| | | roundcube send mail---25-->postfix server--------------------->| ===== Postfixadmin ===== refer: http://sourceforge.net/p/postfixadmin/code/HEAD/tree/trunk/DOCUMENTS/ ==== Config nginx with php-fpm for running Postfixadmin ==== server { listen 123.30.173.67:80; server_name postfixadmin.tolava.com; root /data/www/email/postfixadmin; index index.php; charset utf-8; location / { try_files $uri $uri/ index.php; } location ~* \.php$ { try_files $uri =404; fastcgi_split_path_info ^(.+\.php)(/.+)$; include fastcgi_params; fastcgi_pass 127.0.0.1:9000; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_index index.php; } } ==== Config nginx with http backend for running Postfixadmin ==== nginx config server { listen 123.30.173.67:80; server_name postfixadmin.tolava.com; root /data/www/email/postfixadmin; index index.php; charset utf-8; location / { try_files $uri $uri/ index.php; } location ~* \.php$ { proxy_pass http://10.20.50.69:8080/; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; client_max_body_size 10m; client_body_buffer_size 128k; proxy_connect_timeout 90; proxy_send_timeout 90; proxy_temp_file_write_size 64k; } location ~* ^.+.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf)$ { root /data/www/email/postfixadmin; } } httpd backend config ServerName postfixadmin.tolava.com DocumentRoot "/data/www/email/postfixadmin" DirectoryIndex index.php index.html index.htm index.php5 AddDefaultCharset utf-8 ErrorLog /onec/logs/postfixadmin_error_log CustomLog /onec/logs/postfixadmin_access.log common Options FollowSymLinks AllowOverride All Require all granted ==== Install Postfix Admin ==== (Default config file of postfixadmin is **config.inc.php**) - Step1: Create database postfix create database postfix; - Step2: Create new user to grant all privilleges to database postfix: GRANT ALL privileges ON postfix.* TO 'postfix'@'localhost' IDENTIFIED BY 'xxxxx'; FLUSH PRIVILEGES; - Step3: Create file **config.local.php** for custom config connect to db: - Step4: Go to link http://yourdomain/setup.php to check **setup status** ==== Create setup password and Admin User ==== Go to link http://yourdomain/setup.php to check **setup status and set password** for user admin. Below are detail steps for creating admin user: - Step1: In the first install, you go to link http://yourdomain/setup.php to create setup password. - Step2: After setup password created, postfix will generate hash string as **$CONF['setup_password'] = 'd81xxxxxxxxxxxxxxxx41be:8c06c9debe226105811cac5429796a4d8a0591aa';**. You only update this config to **config.local.php** $CONF['setup_password'] = 'd81xxxxxxxxxxxxxxxx41be:8c06c9debe226105811cac5429796a4d8a0591aa'; - Step3: You use link http://yourdomain/setup.php to create super admin user which secure by setup password ===== Postfix ===== ==== Install and config Postfix ==== refer: [[linux:mailconfigwithpostfix|Postfix config]] - Install pre dev packages: yum install mysql-devel yum install db4-devel yum install openldap-devel - Add postfix users: useradd -s /sbin/nologin postfix useradd -s /sbin/nologin postdrop - Build postfix from source: wget http://mirror.postfix.jp/postfix-release/official/postfix-3.1.0.tar.gz tar xf postfix-3.1.0.tar.gz cd postfix-3.1.0 make makefiles CCARGS='-DDEF_COMMAND_DIR=\"/onec/postfix/sbin\" \ -DDEF_CONFIG_DIR=\"/onec/postfix/conf\" \ -DDEF_DAEMON_DIR=\"/onec/postfix/libexec/postfix\" \ -DDEF_MAILQ_PATH=\"/onec/postfix/bin/mailq\" \ -DDEF_NEWALIAS_PATH=\"/onec/postfix/bin/newaliases\" \ -DDEF_SAMPLE_DIR=\"/etc/postfix/samples\" \ -DDEF_SENDMAIL_PATH=\"/onec/postfix/sbin/sendmail\" \ -DHAS_MYSQL -I/usr/include/mysql' \ AUXLIBS='-L/usr/lib64/mysql -lmysqlclient' make make install make install with change options below: install_root: [/] daemon_directory: [/onec/postfix/libexec/postfix] /onec/postfix/libexec data_directory: [/var/lib/postfix] /onec/postfix/data manpage_directory: [/usr/local/man] /onec/postfix/man mail_owner: [postfix] queue_directory: [/var/spool/postfix] /onec/postfix/mailqueue setgid_group: [postdrop] - Create script /etc/init.d/postfix: #!/bin/sh # # /etc/rc.d/rc.postfix # # Postfix init script for Slackware Linux # # Author: Sean O'Donnell # # define the path to the postfix executable POSTFIX=/onec/postfix/sbin/postfix CONF=/onec/postfix/conf function start_postfix() { echo "Starting Postfix..." $POSTFIX -c $CONF start } function stop_postfix() { echo "Stopping Postfix..." $POSTFIX stop } function restart_postfix() { stop_postfix sleep 5 start_postfix } case "$1" in 'start') start_postfix ;; 'stop') stop_postfix ;; 'restart') restart_postfix ;; *) echo "usage $0 start|stop|restart" ;; esac ==== Config postfix store mails to mailbox directly ==== update path of mailbox in main.cf # if you let postfix store your mails directly (without using maildrop, dovecot deliver etc.) virtual_mailbox_base = /onec/vmail # or whereever you want to store the mails ==== Config integrate Postfix with postfixadmin with virtual domains ==== refer: http://sourceforge.net/p/postfixadmin/code/HEAD/tree/trunk/DOCUMENTS/POSTFIX_CONF.txt Below are steps: - Step1: Get script postfix_conf.txt from http://sourceforge.net/p/postfixadmin/code/HEAD/tree/trunk/DOCUMENTS/POSTFIX_CONF.txt - Step2: Run script to generate sql postfix config to integrate with postfixadmin: bash POSTFIX_CONF.txt - Step3: Copy all configs generated to directory **/onec/postfix/config/sql** - Step4: Go to directory **/onec/postfix/config/sql** and replace string **hosts = localhost** to **hosts = 127.0.0.1** for fixing error **"Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock'"**: sed -i 's/hosts = localhost/hosts = 127.0.0.1/g' * - Step5: Edit /onec/postfix/conf/main.cf for mysql server and using virtual mailbox: mydestination = virtual_minimum_uid = 5000 virtual_uid_maps = static:5000 virtual_gid_maps = static:5000 virtual_mailbox_base = /onec/vmail virtual_transport = virtual virtual_mailbox_domains = proxy:mysql:/onec/postfix/conf/sql/mysql_virtual_domains_maps.cf virtual_alias_maps = proxy:mysql:/onec/postfix/conf/sql/mysql_virtual_alias_maps.cf, proxy:mysql:/onec/postfix/conf/sql/mysql_virtual_alias_domain_maps.cf, proxy:mysql:/onec/postfix/conf/sql/mysql_virtual_alias_domain_catchall_maps.cf virtual_mailbox_maps = proxy:mysql:/onec/postfix/conf/sql/mysql_virtual_mailbox_maps.cf, proxy:mysql:/onec/postfix/conf/sql/mysql_virtual_alias_domain_mailbox_maps.cf Note: **5000** is userid and groupid of user vmail.vmail - Step6: Check config in postfix for connecting to database: /onec/postfix/sbin/postmap -q cuuthien2.com mysql:/onec/postfix/conf/sql/mysql_virtual_alias_maps.cf Fix error: connect to mysql server 127.0.0.1: access denied for user 'postfix'@'localhost' => After we check the connect to MySQL server with account postfix/xxxxx OK but postfix can't connect to MySQL Server. Fix: You can re-create all sql files in **sql/*.cf** of postfix for current version of postfix ==== Debug Postfix with postconf ==== * Show modules which was compiled with postfix: /onec/postfix/sbin/postconf -m output: /onec/postfix/sbin/postconf: warning: smtputf8_enable is true, but EAI support is not compiled in btree cidr environ fail hash inline internal memcache mysql nis pcre pipemap proxy randmap regexp socketmap static tcp texthash unionmap unix * Check config parameters in postfix: /onec/postfix/sbin/postconf | grep local_recipient_maps output: local_recipient_maps = proxy:unix:passwd.byname $alias_maps proxy_read_maps = $local_recipient_maps $mydestination $virtual_alias_maps $virtual_alias_domains $virtual_mailbox_maps $virtual_mailbox_domains $relay_recipient_maps $relay_domains $canonical_maps $sender_canonical_maps $recipient_canonical_maps $relocated_maps $transport_maps $mynetworks $smtpd_sender_login_maps $sender_bcc_maps $recipient_bcc_maps $smtp_generic_maps $lmtp_generic_maps $alias_maps $smtpd_client_restrictions $smtpd_helo_restrictions $smtpd_sender_restrictions $smtpd_relay_restrictions $smtpd_recipient_restrictions ===== Dovecot ===== ==== Install dovecot and create script stop, start ==== - Step1: Build and Install dovecot: wget http://www.dovecot.org/releases/2.1/dovecot-2.1.17.tar.gz tar xf dovecot-2.1.17.tar.gz cd dovecot-2.1.17 ./configure --prefix=/onec/dovecot/ --with-mysql make make install - Step2: Create Script stop, start dovecot: #!/bin/bash # # /etc/rc.d/init.d/dovecot # # Starts the dovecot daemon # # chkconfig: - 65 35 # description: Dovecot Imap Server # processname: dovecot # config: /etc/dovecot.conf # config: /etc/sysconfig/dovecot # pidfile: /var/run/dovecot/master.pid ### BEGIN INIT INFO # Provides: dovecot # Required-Start: $local_fs $network # Required-Stop: $local_fs $network # Should-Start: $remote_fs # Should-Stop: $remote_fs # Default-Start: # Default-Stop: 0 1 2 3 4 5 6 # Short-Description: start and stop Dovecot Imap server # Description: Dovecot is an IMAP server for Linux/UNIX-like systems, # written with security primarily in mind. It also contains # a small POP3 server. ### END INIT INFO # Source function library. . /etc/init.d/functions if [ -f /etc/sysconfig/dovecot -a $UID -eq 0 ]; then . /etc/sysconfig/dovecot fi RETVAL=0 prog="Dovecot Imap" exec="/onec/dovecot/sbin/dovecot" config="/onec/dovecot/etc/dovecot/dovecot.conf" pidfile="/onec/dovecot/var/run/dovecot/master.pid" lockfile="/var/lock/subsys/dovecot" start() { [ $UID -eq 0 ] || exit 4 [ -x $exec ] || exit 5 [ -f $config ] || exit 6 echo -n $"Starting $prog: " daemon --pidfile $pidfile $exec $OPTIONS RETVAL=$? [ $RETVAL -eq 0 ] && touch $lockfile echo } stop() { [ $UID -eq 0 ] || exit 4 echo -n $"Stopping $prog: " killproc -p $pidfile $exec RETVAL=$? [ $RETVAL -eq 0 ] && rm -f $lockfile echo } reload() { [ $UID -eq 0 ] || exit 4 echo -n $"Reloading $prog: " killproc -p $pidfile $exec -HUP RETVAL=$? echo } # # See how we were called. # case "$1" in start) start ;; stop) stop ;; reload) reload ;; force-reload|restart) stop sleep 1 start RETVAL=$? ;; condrestart|try-restart) if [ -f $lockfile ]; then stop sleep 3 start fi ;; status) status -p $pidfile $exec RETVAL=$? ;; *) echo $"Usage: $0 {condrestart|try-restart|start|stop|restart|reload|force-reload|status}" RETVAL=2 [ "$1" = 'usage' ] && RETVAL=0 esac exit $RETVAL ==== Basic Configure ==== Minimal config for running dovecot(copy config **dovecot.conf** from **doc/example-config/** to **/onec/dovecot/etc/dovecot/**) and edit: ssl=no #!include conf.d/*.conf => We can start dovecot after this step ==== Create and Config basic Mailbox for dovecot ==== - Step1: Create user used to store the mail: groupadd -g 5000 vmail useradd -u 5000 -g vmail -s /usr/bin/nologin -d /home/vmail -m vmail - Step2: Create directory to store the mail: mkdir -p /onec/vmail chown -R vmail.vmail /onec/vmail - Step3: Config mailbox in dovecot.conf: mail_location = maildir:/onec/vmail/%d/%n/ => %d: domain, %n: username ==== Config Mailbox auto-create some basic mailboxes to allow delete email from roundcube ==== Fix error: **Server Error: UID COPY: Mailbox doesn't exist: Trash** when user delete email from roundcube website - Step1: Copy **doc/example-config/conf.d/10-mail.conf** and **doc/example-config/conf.d/15-mailboxes.conf** from dovecot source to config directory **conf.d** of dovecot - Step2: Edit **15-mailboxes.conf** to au-create mailboxs **Drafts, Junk, Trash** below(Use field **auto=create**): mailbox Drafts { auto=create special_use = \Drafts } mailbox Junk { auto=create special_use = \Junk } mailbox Trash { auto=create special_use = \Trash } - Step3: Config include these files above in **dovecot.conf**: !include conf.d/*.conf ==== Integrate dovecot authenticate user with Postfixadmin ==== refer: http://sourceforge.net/p/postfixadmin/code/HEAD/tree/trunk/DOCUMENTS/DOVECOT.txt - Step1: Create file **dovecot-sql.conf** connect = host=localhost dbname=postfix user=postfix password=postfix driver = mysql # Default password scheme - change to match your Postfixadmin setting. # depends on your $CONF['encrypt'] setting: # md5crypt -> MD5-CRYPT # md5 -> PLAIN-MD5 # cleartext -> PLAIN default_pass_scheme = MD5-CRYPT # Query to retrieve password. user can be used to retrieve username in other # formats also. password_query = SELECT username AS user,password FROM mailbox WHERE username = '%u' AND active='1' # Query to retrieve user information, note uid matches dovecot.conf AND Postfix virtual_uid_maps parameter. user_query = SELECT maildir, 5000 AS uid, 5000 AS gid FROM mailbox WHERE username = '%u' AND active='1' => **5000 is uid and gid of user vmail** - Step2: **edit dovecot.conf** to load userdb and passdb from dovecot-sql.conf: protocols = imap pop3 auth_mechanisms = plain userdb { driver = sql args = /onec/dovecot/etc/dovecot/dovecot-sql.conf } passdb { driver = sql args = /onec/dovecot/etc/dovecot/dovecot-sql.conf } ===== Roundcube ===== refer: http://trac.roundcube.net/wiki Basic about config files in roundcube: * **config/defaults.inc.php** -> default configs * **config/config.inc.php** -> custom configs You **copy more options from defaults.inc.php to config.inc.php** for overriding the defaults ==== Nginx config with php-fpm ==== server { listen 123.30.173.67:80; server_name roundcube.tolava.com; root /data/www/email/roundcubemail; if ($http_host != "roundcube.tolava.com") { rewrite ^ http://roundcube.tolava.com$request_uri permanent; } index index.php index.html; location ~ ^/favicon.ico$ { root /data/www/email/roundcubemail/skins/default/images; log_not_found off; access_log off; expires max; } location = /robots.txt { allow all; log_not_found off; access_log off; } location ~ ^/(README|INSTALL|LICENSE|CHANGELOG|UPGRADING)$ { deny all; } location ~ ^/(bin|SQL)/ { deny all; } # Deny all attempts to access hidden files such as .htaccess, .htpasswd, .DS_Store (Mac). location ~ /\. { deny all; access_log off; log_not_found off; } location ~ \.php$ { try_files $uri =404; include fastcgi_params; fastcgi_pass 127.0.0.1:9000; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_index index.php; } } ==== Nginx with httpd backend config ==== Nginx Config: server { listen 123.30.173.67:80; server_name roundcube.tolava.com; root /data/www/email/roundcubemail; if ($http_host != "roundcube.tolava.com") { rewrite ^ http://roundcube.tolava.com$request_uri permanent; } index index.php index.html; location ~ ^/favicon.ico$ { root /data/www/email/roundcubemail/skins/default/images; log_not_found off; access_log off; expires max; } location = /robots.txt { allow all; log_not_found off; access_log off; } location ~ ^/(README|INSTALL|LICENSE|CHANGELOG|UPGRADING)$ { deny all; } location ~ ^/(bin|SQL)/ { deny all; } # Deny all attempts to access hidden files such as .htaccess, .htpasswd, .DS_Store (Mac). location ~ /\. { deny all; access_log off; log_not_found off; } location ~ \.php$ { proxy_pass http://10.20.50.69:8080/; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; client_max_body_size 10m; client_body_buffer_size 128k; proxy_connect_timeout 90; proxy_send_timeout 90; proxy_temp_file_write_size 64k; } location ~* ^.+.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf)$ { root /data/www/email/roundcubemail; } } httpd backend config: ServerName roundcube.tolava.com DocumentRoot "/data/www/email/roundcubemail" DirectoryIndex index.php index.html index.htm index.php5 AddDefaultCharset utf-8 ErrorLog /onec/logs/roundcubemail_error_log CustomLog /onec/logs/roundcubemail_access.log common Options FollowSymLinks AllowOverride All Require all granted ==== Install roundcubemail ==== - Step1: Create database roundcubemail create database roundcubemail; - Step2: Create new user to grant all privilleges to database roundcubemail: GRANT ALL privileges ON roundcubemail.* TO 'roundcubemail'@'localhost' IDENTIFIED BY 'xxxxx'; FLUSH PRIVILEGES; - Step3: Change roundcubemail config connect to db: cp config.inc.php.sample config.inc.php And Edit **config.inc.php** $config['db_dsnw'] = 'mysql://roundcubemail:xxxx@localhost/roundcubemail'; => you must change xxxx to password which created in step3 above - Step4: add variable below to allow install roundcube: $config['enable_installer'] = true; - Step5: update path to use mysql and pdo_mysql in **php.ini**: .......................... mysql.default_socket = /onec/mysql/tmp/mysql.sock .......................... pdo_mysql.default_socket = /onec/mysql/tmp/mysql.sock .......................... - Step6: go to http://yourdomain/installer -> install roundcube - Step7: click **initial database** if connect DB OK - Step8: remove directory **installer** in web directory of roundcube: rm -rf installer/ ==== Config Integrate with dovecot via IMAP(143) protocol(Store Sent data, Receiving, Authenticate) ==== In default config of roundcube **config/defaults.inc.php** $config['default_host'] = 'localhost'; @include "/etc/psa-webmail/roundcube/mailhosts.php"; // TCP port used for IMAP connections $config['default_port'] = 143; // IMAP AUTH type (DIGEST-MD5, CRAM-MD5, LOGIN, PLAIN or null to use // best server supported one) $config['imap_auth_type'] = null; => roundcube will **authenticate user** via dovecot ==== Config Integrate with postfix ==== Default Config: $config['smtp_server'] = '127.0.0.1';//You must change to IP local to fix error can't send email with roundcube $config['smtp_port'] = 25; $config['smtp_user'] = ''; $config['smtp_pass'] = ''; ==== Allow Roundcube user change your password in postfix database ==== - Step1: Enable the password plugin by adding this line to **config/config.inc.php**: $rcmail_config['plugins'] = array('password'); - Step2: Configure the password plugin and make sure you alter the settings accordingly in **plugins/password/config.inc.php** to update database postfix $config['password_driver'] = 'sql'; $config['password_db_dsn'] = 'mysql://user:pass@localhost/postfix'; $config['password_query'] = 'UPDATE mailbox SET password=%c WHERE username=%u'; ==== Fix roundcube error ==== Fix error not redirect to mail after login success by update $OUTPUT->redirect($redir, 0, true); to //$OUTPUT->redirect($redir, 0, true); header('Location: /?_task=mail'); ===== Config Mail Server Security and Mail Exchange ===== ==== Config Mail Server Security ==== Config postfix limit IP for connecting to postfix SMTP Server by edit **main.cf**: mynetworks = 127.0.0.0/8,10.20.50.69/32,10.20.50.69/32,10.20.50.71/32,123.31.47.39/32 ==== Config Mail Exchange for new domain ==== Add new MX record for new domain and point it to SMTP Server ===== Merge Email ===== Below are steps form merge mail server from database postfix1 to database postfix2: Backup database postfix1 prepare for merge: - Backup postfix mysqldump -hlocalhost -uroot -p --add-drop-table --quote-names --opt --routines --extended-insert=FALSE --complete-insert --add-locks --quick --compress postfix > postfix.sql - Backup mail config data: cat postfix.sql | grep "INSERT INTO \`domain\`" > domain.sql cat postfix.sql | grep "INSERT INTO \`alias\`" > alias.sql cat postfix.sql | grep "INSERT INTO \`mailbox\`" > mailbox.sql - Remove line Insert All from domain.sql INSERT INTO `domain` (`domain`, `description`, `aliases`, `mailboxes`, `maxquota`, `quota`, `transport`, `backupmx`, `created`, `modified`, `active`) VALUES ('ALL','',0,0,0,0,'',0,'0000-00-00 00:00:00','0000-00-00 00:00:00',1); ===== Email Spam ===== SPF(Sender Policy Framework) is a method of fighting spam: http://www.openspf.org/FAQ/What_is_SPF ==== Email sent was filtered(Have not sent to spam or Inbox) ==== How to Fix error below: * Yahoo email: to= => Connections will not be accepted from 123.31.47.39, because the ip is in Spamhaus's list; see https://help.yahoo.com/kb/postmaster/SLN5070.html (in reply to MAIL FROM command)) And error detail: * Dynamic or residential IP addresses as determined by [[https://www.spamhaus.org/pbl/|Spamhaus PBL]] (Error: 553 5.7.1 [BL21]) * IP addresses listed as spam sources on the [[https://www.spamhaus.org/sbl/|Spamhaus SBL]] (Error: 553 5.7.1 [BL22]) * IP addresses listed as a possible open proxy or spam-sending Trojan Horse on [[https://www.spamhaus.org/xbl/|Spamhaus XBL]] (Error: 553 5.7.1 [BL23]) * Check exactly error with tool: https://www.spamhaus.org/lookup/ * 123.31.47.39 is listed in the PBL, in the following records: Ref: PBL1544985 123.31.0.0/16 is listed on the Policy Block List (PBL) => Fix follow link: https://www.spamhaus.org/pbl/removal/ * 123.31.47.39 is not listed in the SBL * 123.31.47.39 is not listed in the XBL * Gmail: May 17 18:50:54 vdo postfix/qmgr[28464]: 8658699A03D: from=, size=984, nrcpt=1 (queue active) to= => The IP you're using to send mail is not authorized to 550-5.7.1 send email directly to our servers. Please use the SMTP relay at your 550-5.7.1 service provider instead. Learn more at 550 5.7.1 https://support.google.com/mail/answer/10336. => Fix: Verify your ownership of cuuthien2.com on https://postmaster.google.com/managedomains with txt Record v=spf1 a mx ~all And point MX to SMTP Server ==== Fix Email sent to google were marked spam ==== View email sent from anhvc@tolava.com with header below((To see this, simply send email to a Gmail account, and then select ‘See Original’ in the little menu at the top of the email message. You get to see all the headers for the email.)): Received-SPF: neutral (google.com: 123.30.173.67 is neither permitted nor denied by best guess record for domain of anhvc@tolava.com) client-ip=123.30.173.67; Authentication-Results: mx.google.com; spf=neutral (google.com: 123.30.173.67 is neither permitted nor denied by best guess record for domain of anhvc@tolava.com) smtp.mailfrom=anhvc@tolava.com => What this is saying is that when **they check the IP address we’re sending from**, they **get back neither a “confirm” nor a “deny” message**. That is, there is **no SPF record** at all. Fix: - Step1: Create SPF record for your domain on DNS supplier: https://www.mail-tester.com/spf/godaddy. For example: v=spf1 a mx include:123.30.173.67 ~all Or: v=spf1 a mx include:tolava.com ~all - Step2: Check SPF record which you have configured: http://www.kitterman.com/spf/validate.html ==== Filter Email Spam ====