从域中获取SPF记录

nim*_*imi 10 c# asp.net spf

在域上检查SPF记录的方法有哪些?

有一个网站,我可以使用 - http://www.mxtoolbox.com/SuperTool.aspx手动完成

我怎么能通过ASP.NET和C#来做到这一点?基本上我想验证/检查域上的SPF记录,如果它支持自己的邮件Web服务器.

Cri*_*scu 13

我有同样的问题,并设法找到两个三个解决方案:

nslookup解决方案

您可以通过在命令行中键入以下命令来获取SPF:

nslookup -type=TXT <hostname>
Run Code Online (Sandbox Code Playgroud)

您可以使用C#自动执行此操作System.Diagonstics.Process,如本博客文章中所述.

DNS.NET解析器项目

我找到了有关DNS解析的CodeProject文章.它附带演示项目.我运行该项目并获得以下结果stackexchange.com:

DNS Dig screeenshot

注意:确保在按"发送"按钮之前将 QType字段设置为 TXT

以黄色突出显示的部分代表SPF记录.我还没有深入研究代码,看看它是如何完成的,但这似乎是上述nslookup解决方案的一个很好的替代方案.

[更新] ARSoft.Tools.Net项目

如果您只需要检查域是否支持邮件服务器,您可以使用ARSoft.Tools.Net库(也可以作为NuGet包使用).

安装软件包后,我设法使用以下代码执行SPF检查:

var spfValidator = new ARSoft.Tools.Net.Spf.SpfValidator();

var mailIpAddress = IPAddress.Parse("X.X.X.X");
var domain = "example.com";
var senderAddress = "sender@example.com";

ARSoft.Tools.Net.Spf.SpfQualifier result = 
    spfValidator.CheckHost(mailIpAddress, domain, senderAddress);
Run Code Online (Sandbox Code Playgroud)


Mar*_*age 6

尽管.NET对网络有很多支持,包括对主机名进行地址映射,但它缺乏查询DNS的一般方法.

但是,您可以使用P/Invoke 直接调用DnsQuery函数.API有点麻烦但是根据您的要求创建正确的P/Invoke签名并非不可能.

SPF记录存储为DNS中的TXT记录.您必须使用的相应结构是DNS_TXT_DATA结构.如果您可以找到查询MX记录的示例,则可以重用该代码并将其DNS_TYPE_TEXT用于查询类型并将数据解组到DNS_TXT_DATA结构中.

或者您可以使用此代码:

using System.ComponentModel;
using System.Runtime.InteropServices;

public String DnsGetTxtRecord(String name) {
  const Int16 DNS_TYPE_TEXT = 0x0010;
  const Int32 DNS_QUERY_STANDARD = 0x00000000;
  const Int32 DNS_ERROR_RCODE_NAME_ERROR = 9003;
  const Int32 DNS_INFO_NO_RECORDS = 9501;
  var queryResultsSet = IntPtr.Zero;
  try {
    var dnsStatus = DnsQuery(
      name,
      DNS_TYPE_TEXT,
      DNS_QUERY_STANDARD,
      IntPtr.Zero,
      ref queryResultsSet,
      IntPtr.Zero
    );
    if (dnsStatus == DNS_ERROR_RCODE_NAME_ERROR || dnsStatus == DNS_INFO_NO_RECORDS)
      return null;
    if (dnsStatus != 0)
      throw new Win32Exception(dnsStatus);
    DnsRecordTxt dnsRecord;
    for (var pointer = queryResultsSet; pointer != IntPtr.Zero; pointer = dnsRecord.pNext) {
      dnsRecord = (DnsRecordTxt) Marshal.PtrToStructure(pointer, typeof(DnsRecordTxt));
      if (dnsRecord.wType == DNS_TYPE_TEXT) {
        var lines = new List<String>();
        var stringArrayPointer = pointer
          + Marshal.OffsetOf(typeof(DnsRecordTxt), "pStringArray").ToInt32();
        for (var i = 0; i < dnsRecord.dwStringCount; ++i) {
          var stringPointer = (IntPtr) Marshal.PtrToStructure(stringArrayPointer, typeof(IntPtr));
          lines.Add(Marshal.PtrToStringUni(stringPointer));
          stringArrayPointer += IntPtr.Size;
        }
        return String.Join(Environment.NewLine, lines);
      }
    }
    return null;
  }
  finally {
    const Int32 DnsFreeRecordList = 1;
    if (queryResultsSet != IntPtr.Zero)
      DnsRecordListFree(queryResultsSet, DnsFreeRecordList);
  }
}

[DllImport("Dnsapi.dll", EntryPoint = "DnsQuery_W", ExactSpelling = true, CharSet = CharSet.Unicode, SetLastError = true)]
static extern Int32 DnsQuery(String lpstrName, Int16 wType, Int32 options, IntPtr pExtra, ref IntPtr ppQueryResultsSet, IntPtr pReserved);

[DllImport("Dnsapi.dll")]
static extern void DnsRecordListFree(IntPtr pRecordList, Int32 freeType);

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
struct DnsRecordTxt {
  public IntPtr pNext;
  public String pName;
  public Int16 wType;
  public Int16 wDataLength;
  public Int32 flags;
  public Int32 dwTtl;
  public Int32 dwReserved;
  public Int32 dwStringCount;
  public String pStringArray;
}
Run Code Online (Sandbox Code Playgroud)


Pet*_*hie 0

您基本上需要执行 DNS 请求,询问域的 MX/SPF 记录。有一些在 C# 中执行此操作的示例。http://mailsystem.codeplex.com/上有一个库,其中有一个ValidatorGetMxRecords可以执行此操作,您可能会发现有用