Skip to content

Commit

Permalink
增加通过本地网卡获取IP地址。 (#30)
Browse files Browse the repository at this point in the history
fix #24 
fix #21
  • Loading branch information
sanjusss authored Jul 3, 2020
1 parent 2ffcb97 commit 5cd5830
Show file tree
Hide file tree
Showing 13 changed files with 239 additions and 87 deletions.
14 changes: 13 additions & 1 deletion .github/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@

FROM mcr.microsoft.com/dotnet/core/runtime:3.1 AS final
MAINTAINER sanjusss <[email protected]>
LABEL maintainer="[email protected]"
ENV AKID="access key id"
ENV AKSCT="access key secret"
ENV DOMAIN="my.domain.com"
ENV REDO=300
ENV TTL=600
ENV TIMEZONE=8
ENV TYPE=A,AAAA
ENV CNIPV4=false
ENV WEBHOOK=
ENV CHECKLOCAL=false
ENV IPV4NETS=
ENV IPV6NETS=
WORKDIR /app
COPY ./out .
ENTRYPOINT ["dotnet", "aliyun-ddns.dll"]
13 changes: 13 additions & 0 deletions ReadMe.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@
[![GitHub forks](https://img.shields.io/github/forks/sanjusss/aliyun-ddns.svg)](https://github.com/sanjusss/aliyun-ddns/network)
[![GitHub stars](https://img.shields.io/github/stars/sanjusss/aliyun-ddns.svg)](https://github.com/sanjusss/aliyun-ddns/stargazers)

# 功能
- 通过在线API获取公网IPv4地址
- 通过在线API获取公网IPv6地址
- 通过本地网卡获取公网或内网IPv4地址
- 通过本地网卡获取公网或内网IPv6地址
- Docker容器支持
- IP发生变化时,使用WebHook通知

# 使用方法

Expand All @@ -33,6 +40,9 @@ docker run -d --restart=always --net=host \
|TYPE|需要更改的记录类型,可以用“,”隔开,只能是“A”、“AAAA”或“A,AAAA”。|A,AAAA|
|CNIPV4|检查IPv4地址时,仅使用中国服务器。|false|
|WEBHOOK|WEBHOOK推送地址。||
|CHECKLOCAL|是否检查本地网卡IP。此选项将禁用在线API的IP检查。<br>网络模式必须设置为host<br>(Windows版docker无法读取本机IP)|false|
|IPV4NETS|本地网卡的IPv4网段。格式示例:“192.168.1.0/24”。多个网段用“,”隔开。||
|IPV6NETS|本地网卡的IPv6网段。格式示例:“2001:0db8::/64”。多个网段用“,”隔开。||

以上环境变量均存在默认值,添加需要修改的环境变量即可。

Expand Down Expand Up @@ -69,5 +79,8 @@ dotnet aliyun-ddns.dll \
|type|需要更改的记录类型,可以用“,”隔开,只能是“A”、“AAAA”或“A,AAAA”。|A,AAAA|
|cnipv4|检查IPv4地址时,仅使用中国服务器。|false|
|webhook|WEBHOOK推送地址。||
|checklocal|是否检查本地网卡IP。此选项将禁用在线API的IP检查。|false|
|ipv4nets|本地网卡的IPv4网段。格式示例:“192.168.1.0/24”。多个网段用“,”隔开。||
|ipv6nets|本地网卡的IPv6网段。格式示例:“2001:0db8::/64”。多个网段用“,”隔开。||

以上参数均存在默认值,添加需要修改的参数即可。
2 changes: 1 addition & 1 deletion aliyun-ddns/Common/Log.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public static class Log
/// <param name="msg">日志信息</param>
public static void Print(string msg)
{
Console.WriteLine($"[{ DateTime.UtcNow.AddHours(Options.Instance.TIMEZONE) }]{ msg }");
Console.WriteLine($"[{ DateTime.UtcNow.AddHours(Options.Instance.Timezone) }]{ msg }");
}
}
}
8 changes: 4 additions & 4 deletions aliyun-ddns/DomainUpdater.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ private enum IpType
/// </summary>
public void Run()
{
TimeSpan maxWait = new TimeSpan(0, 0, Options.Instance.REDO);
string[] domains = Options.Instance.DOMAIN.Split(',', StringSplitOptions.RemoveEmptyEntries);
TimeSpan maxWait = new TimeSpan(0, 0, Options.Instance.Redo);
string[] domains = Options.Instance.Domain.Split(',', StringSplitOptions.RemoveEmptyEntries);
HashSet<IpType> targetTypes = GetTargetTypes();
if (targetTypes.Count == 0)
{
Expand Down Expand Up @@ -154,7 +154,7 @@ private void Update(string[] domains, HashSet<IpType> targetTypes)
/// <returns>目标记录类型的集合</returns>
private HashSet<IpType> GetTargetTypes()
{
HashSet<string> inputTypes = new HashSet<string>(Options.Instance.TYPE.Split(',', StringSplitOptions.RemoveEmptyEntries));
HashSet<string> inputTypes = new HashSet<string>(Options.Instance.Type.Split(',', StringSplitOptions.RemoveEmptyEntries));
HashSet<IpType> targetTypes = new HashSet<IpType>();
if (inputTypes.Contains("A"))
{
Expand Down Expand Up @@ -242,7 +242,7 @@ private DefaultAcsClient GetNewClient()
//var clientProfile = DefaultProfile.GetProfile(Options.Instance.ENDPOINT, Options.Instance.AKID, Options.Instance.AKSCT);
//return new DefaultAcsClient(clientProfile);
return new DefaultAcsClient(DefaultProfile.GetProfile(),
new Aliyun.Acs.Core.Auth.BasicCredentials(Options.Instance.AKID, Options.Instance.AKSCT));
new Aliyun.Acs.Core.Auth.BasicCredentials(Options.Instance.Akid, Options.Instance.Aksct));
}

/// <summary>
Expand Down
103 changes: 103 additions & 0 deletions aliyun-ddns/IPGetter/BaseLocalIPGetter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;

namespace aliyun_ddns.IPGetter
{
public abstract class BaseLocalIPGetter : IIPGetter
{
public abstract string Description { get; }
public abstract int Order { get; }

/// <summary>
/// IP网段字符串。
/// </summary>
protected abstract string IPNetworks { get; }

/// <summary>
/// 检查IP信息是否符合要求。
/// </summary>
/// <param name="info">IP信息</param>
/// <returns>是否符合要求</returns>
protected abstract bool CheckIPAddressInformation(IPAddressInformation info);

public async Task<string> GetIP()
{
return await Task.Run(() =>
{
try
{
var nets = GetIPNetworks();
string ip = null;
//获取所有网卡信息,返回最后一个地址。
NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();
foreach (NetworkInterface adapter in nics)
{
try
{
//获取网络接口信息
IPInterfaceProperties properties = adapter.GetIPProperties();
//获取单播地址集
UnicastIPAddressInformationCollection ips = properties.UnicastAddresses;
foreach (UnicastIPAddressInformation i in ips)
{
if (CheckIPAddressInformation(i) == false)
{
continue;
}

bool success = false;
foreach (var net in nets)
{
if (net.Contains(i.Address))
{
success = true;
break;
}
}

if (success)
{
ip = i.Address.ToString();
}
}
}
catch
{
continue;
}
}

return ip;
}
catch
{
return null;
}
});
}

private IEnumerable<IPNetwork> GetIPNetworks()
{
List<IPNetwork> nets = new List<IPNetwork>();
string text = IPNetworks;
if (string.IsNullOrEmpty(text) == false)
{
string[] subs = text.Split(',', StringSplitOptions.RemoveEmptyEntries);
foreach (var i in subs)
{
if (IPNetwork.TryParse(i, out IPNetwork net))
{
nets.Add(net);
}
}
}

return nets;
}
}
}
12 changes: 10 additions & 2 deletions aliyun-ddns/IPGetter/IPv4Getter/IPv4GetterCreator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,16 @@ public static class IPv4GetterCreator
public static IEnumerable<IIPv4Getter> Create()
{
List<IIPv4Getter> getters = new List<IIPv4Getter>();
getters.AddRange(InstanceCreator.Create<IIPv4Getter>(Ignore.CheckType));
getters.AddRange(_definedGetters);
if (Options.Instance.CheckLocalNetworkAdaptor)
{
getters.Add(new LocalIPv4Getter());
}
else
{
getters.AddRange(InstanceCreator.Create<IIPv4Getter>(Ignore.CheckType));
getters.AddRange(_definedGetters);
}

return getters;
}
}
Expand Down
26 changes: 26 additions & 0 deletions aliyun-ddns/IPGetter/IPv4Getter/LocalIPv4Getter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Text;

namespace aliyun_ddns.IPGetter.IPv4Getter
{
/// <summary>
/// 获取所有网卡信息,返回最后一个IPv6地址。
/// </summary>
[Ignore]
public sealed class LocalIPv4Getter : BaseLocalIPGetter, IIPv4Getter
{
public override string Description => "读取网卡IPv4设置";

public override int Order => 200;

protected override string IPNetworks => Options.Instance.IPv4Networks;

protected override bool CheckIPAddressInformation(IPAddressInformation info)
{
return info.Address.AddressFamily == AddressFamily.InterNetwork;
}
}
}
12 changes: 10 additions & 2 deletions aliyun-ddns/IPGetter/IPv6Getter/IPv6GetterCreator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,16 @@ public static class IPv6GetterCreator
public static IEnumerable<IIPv6Getter> Create()
{
List<IIPv6Getter> getters = new List<IIPv6Getter>();
getters.AddRange(InstanceCreator.Create<IIPv6Getter>(Ignore.CheckType));
getters.AddRange(_definedGetters);
if (Options.Instance.CheckLocalNetworkAdaptor)
{
getters.Add(new LocalIPv6Getter());
}
else
{
getters.AddRange(InstanceCreator.Create<IIPv6Getter>(Ignore.CheckType));
getters.AddRange(_definedGetters);
}

return getters;
}
}
Expand Down
64 changes: 9 additions & 55 deletions aliyun-ddns/IPGetter/IPv6Getter/LocalIPv6Getter.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Text;
Expand All @@ -11,65 +12,18 @@ namespace aliyun_ddns.IPGetter.IPv6Getter
/// <summary>
/// 获取所有网卡信息,返回最后一个IPv6地址。
/// </summary>
public sealed class LocalIPv6Getter : IIPv6Getter
[Ignore]
public sealed class LocalIPv6Getter : BaseLocalIPGetter, IIPv6Getter
{
public string Description => "读取网卡设置";
public override string Description => "读取网卡IPv6设置";

public int Order => 200;
public override int Order => 200;

public async Task<string> GetIP()
{
return await Task.Run(() =>
{
Thread.Sleep(3000);
try
{
string ip = null;
//获取所有网卡信息,返回最后一个IPv6地址。
NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();
foreach (NetworkInterface adapter in nics)
{
try
{
if (adapter.NetworkInterfaceType != NetworkInterfaceType.Ethernet &&
adapter.NetworkInterfaceType != NetworkInterfaceType.Wireless80211 &&
adapter.NetworkInterfaceType != NetworkInterfaceType.Ppp)
{
continue;
}

//获取网络接口信息
IPInterfaceProperties properties = adapter.GetIPProperties();
//获取单播地址集
UnicastIPAddressInformationCollection ips = properties.UnicastAddresses;
foreach (UnicastIPAddressInformation i in ips)
{
if (i.Address.AddressFamily != AddressFamily.InterNetworkV6 ||
i.Address.IsIPv6LinkLocal ||
i.Address.IsIPv6Multicast ||
i.Address.IsIPv6SiteLocal ||
i.Address.IsIPv4MappedToIPv6 ||
i.Address.IsIPv6Teredo)
{
continue;
}
protected override string IPNetworks => Options.Instance.IPv6Networks;

ip = i.Address.ToString();
}
}
catch
{
continue;
}
}

return ip;
}
catch
{
return null;
}
});
protected override bool CheckIPAddressInformation(IPAddressInformation info)
{
return info.Address.AddressFamily == AddressFamily.InterNetworkV6;
}
}
}
Loading

0 comments on commit 5cd5830

Please sign in to comment.