授予 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
我的服务器上一波不间断的分布式 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