授予 Google 对 cPanel/WHM Centos Server 上的 SMTP 的访问权而不公布 SMTP 授权?

Grant Google Access to SMTP on cPanel/WHM Centos Server without advertising SMTP Auth?

我的服务器上一波不间断的分布式 smtp 身份验证攻击促使我禁止非指定 IP 连接到我服务器上的 smtp 并通过它发送邮件。非常有效。 (说明:http://sysadmintips.in/advanced/csf/exim

但是我现在无法使用 Google 邮件 (Gmail) 到 'Send Mail As' 新帐户,除非启用双因素身份验证(这很痛苦,因为我正在为我的远程设置客户端)或在我的服务器上重新打开 smtp 身份验证。

我的另一个选择是将 Google 邮件的 IP 地址列入白名单。

Google 搜索发现以这种方式检索 current Google IP 范围使用这些行的东西(我从这个页面复制: https://support.google.com/a/answer/60764?hl=en):

nslookup -q=TXT _spf.google.com 8.8.8.8

returns Google 的 SPF 记录中包含的域列表,例如: _netblocks.google.com、_netblocks2.google.com、_netblocks3.google.com

现在查找与这些域关联的 DNS 记录,一次一个,如下所示:

nslookup -q=TXT _netblocks.google.com 8.8.8.8
nslookup -q=TXT _netblocks2.google.com 8.8.8.8
nslookup -q=TXT _netblocks3.google.com 8.8.8.8

这些命令的结果包含当前地址范围。

我可以使用这些输出为 /etc/csf/csf.smtpauth 生成有用的内容吗?

我可以在 PHP 和 运行 中编写一些代码来作为 root 的 cron 任务来执行此操作,但是什么格式是可以接受的? csf.smtpauth 是否接受 IP 范围声明?它可以处理 IPV6 IP 吗?

进行任何更改后,我还需要自动强制重新启动 csf 和 lfd,以便使用新 IP。 PHP 运行ning 作为 root 有可能吗?

谢谢!

已解决。

我编写了以下 PHP 代码,它查询 Google 的 SPF 记录,然后,只有在需要时,才会用新的 SMTP 身份验证块替换现有的 SMTP 身份验证块。然后它创建一个文件,用作 bash 脚本的标志以重新启动防火墙。

请注意 /etc/csf/csf.smtpauth 接受 IPV4 和 IPV6 地址以及 CIDR 地址范围。

// Grab current Google SPF IPs...
$dns = dns_get_record('_spf.google.com', DNS_TXT);
if (!$dns)
{
    echo "FAILED TO RETRIEVE DNS RECORD<br />\n";
    exit;
}

// The variable in which to store the results
$ranges = array();

// Of interest in particular to us is...
$val = $dns[0]['txt'];

preg_match_all("/include:[^\s]+\s/", $val, $matches);

if (sizeof($matches[0]) <= 0)
{
    echo "BAD DATA RECEIVED OR FAILED TO DECODE DATA<br />\n";
    exit;
}

foreach ($matches[0] as $match)
{
    $match = trim($match);
    $domain = trim(preg_replace("/include\:/", "", $match));

    // Now do it all again for this domain to get the IP range
    $dns = dns_get_record($domain, DNS_TXT);

    if (!$dns)
    {
        echo "DNS LOOKUP FAILURE AT PASS 2<br />\n";
        exit;
    }

    $val = $dns[0]['txt'];
    preg_match_all("/ip\d:[^\s]+\s/", $val, $ips);

    if (sizeof($ips[0])<=0)
    {
        // At time of writing this is entirely possible as _netblocks3.google.com
        // currently holds NO IP ranges
    }
    else
    {
        foreach ($ips[0] as $ip)
        {
            $ip = trim($ip);
            if ($ip <> '')
            {
                $ip = preg_replace("/ip\d\:/", "", $ip);
                $ranges[] = $ip;
            }
        }
    }
}

// To be here means we made it without a major problem. Form the new IP range for
// the smtp auth file (/etc/csf/csf.smtpauth) and compare with the existing. Update only if there has
// been a change. Also update only if there are at least N ranges found.
// When I wrote this there were 11 IPV4 ranges and 6 IPV6 ranges so setting 
// low limit to 10
$limit = 10;
$filename  = '/etc/csf/csf.smtpauth';

if (sizeof($ranges) < $limit)
{
    echo "NOT UPDATING RANGES, TOO FEW DISCOVERED, PROBLEM?";
    exit;
}

$filerange = "# GOOGLE SPF RESULTS START\n";
$filerange .= join("\n", $ranges);
$filerange .= "\n# GOOGLE SPF RESULTS END";

// Read in existing conf file 
$econf = file_get_contents($filename);
if (sizeof($econf)<=0)
{
    echo "FAILED TO READ $filename<br />\n";
    exit;
}

// Extract the block
if (!preg_match("/\# GOOGLE SPF RESULTS START.+\# GOOGLE SPF RESULTS END/s", $econf, $matches))
{
    echo "FAILED TO FIND EXISTING BLOCK. CORRUPT AUTH FILE?<br />\n";
    exit;
}

if ($filerange == $matches[0])
{
    // IT'S THE SAME DO NOT UPDATE IT!;
    exit;
}

// Replace the block entirely
$econf = preg_replace("/\# GOOGLE SPF RESULTS START.+\# GOOGLE SPF RESULTS END/s", $filerange, $econf);

// Write out the new file contents
file_put_contents($filename, $econf);

// Trigger a CSF/LFD restart by creating trigger file.
touch("restartcsflfd"); 

然后不久之后为运行这个shell脚本创建一个CRON任务,每次上面都是运行:

#!/bin/bash
if [ -f /path-to-file/restartcsflfd ];
then
    csf -r
    /etc/init.d/lfd restart
    rm -f restartcsflfd
    echo "RE-STARTED CSF and LFD"
fi