【问题标题】:Grant Google Access to SMTP on cPanel/WHM Centos Server without advertising SMTP Auth?授予 Google 访问 cPanel/WHM Centos 服务器上的 SMTP 而不宣传 SMTP Auth?
【发布时间】:2015-08-28 05:22:34
【问题描述】:

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

但是,如果不启用双因素身份验证(这很痛苦,因为我正在为我的客户远程设置)或切换 smtp 身份验证,我现在无法使用 Google Mail (Gmail) 为新帐户“发送邮件”重新打开我的服务器。

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

Google 搜索发现了这种方式来检索 当前 Google IP 范围,使用这些内容(我从该页面复制:https://support.google.com/a/answer/60764?hl=en):

nslookup -q=TXT _spf.google.com 8.8.8.8

这会返回包含在 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。以 root 身份运行的 PHP 有可能吗?

谢谢!

【问题讨论】:

    标签: smtp gmail cpanel whm two-factor-authentication


    【解决方案1】:

    解决了。

    我编写了以下 PHP 代码,用于查询 Google 的 SPF 记录,然后,仅在需要时,才会用新的 SMTP Auth 块替换现有的 SMTP Auth 块。然后它会创建一个文件,用作 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"); 
    

    然后创建一个 CRON 任务以在每次运行上述内容之后不久运行此 shell 脚本:

    #!/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
    

    【讨论】:

      猜你喜欢
      • 2016-08-04
      • 2012-10-03
      • 2016-06-20
      • 2016-09-10
      • 1970-01-01
      • 2015-07-23
      • 2015-03-02
      • 1970-01-01
      相关资源
      最近更新 更多