去年就申请了电信的公网IP,现在终于可以用起来了,当时是通过电信的官方公众号申请的,直接就给开通了,也没有人上门核对,但是现在申请好像要上门核对了~
端口映射
想要把树莓派的上的服务开放到公网,首先要做的就是端口映射,把本地服务的端口映射到公网,方法很简单,登录电信网关后台,找到高级设置 > 端口映射
如上所示,我的源码托管平台就可以通过电信分配公网IP访问了~
DDNS
虽然是公网IP,但不是静态的,每隔一段时间或者重启网关后都会更改,每次更改了都要去查一下新的IP,关键是不在家还查询不了,所以为了更好的稳定的连接家里的服务器,我们需要使用DDNS技术。
所谓DDNS,就是动态域名解析,流程上就是定时查询公网IP,如果发现变更了,则调用域名所在服务商的域名解析API,来更新域名的解析IP。
下面是我用C#做的,使用阿里云做的DDNS代码示例,该示例是使用开源.Net模块化快速开发框架 NetModular 中的任务调度模块开发的,仅供参考:
using System.ComponentModel;
using System.Linq;
using System.Net.Http;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Aliyun.Acs.Alidns.Model.V20150109;
using Aliyun.Acs.Core;
using Aliyun.Acs.Core.Profile;
using NetModular.Lib.Config.Abstractions;
using NetModular.Lib.Quartz.Abstractions;
using NetModular.Module.MyJob.Infrastructure;
using Newtonsoft.Json;
namespace NetModular.Module.MyJob.Quartz
{
[Description("DDNS任务")]
public class DdnsTask : TaskAbstract
{
private readonly IConfigProvider _configProvider;
public DdnsTask(ITaskLogger logger, IConfigProvider configProvider) : base(logger)
{
_configProvider = configProvider;
}
public override async Task Execute(ITaskExecutionContext context)
{
var config = _configProvider.Get<MyJobConfig>().Ddns;
var profile = DefaultProfile.GetProfile(config.RegionId, config.AccessKeyId, config.Secret);
var client = new DefaultAcsClient(profile);
var request = new DescribeDomainRecordsRequest
{
DomainName = config.Domain,
PageNumber = 1,
PageSize = 50,
AcceptFormat = Aliyun.Acs.Core.Http.FormatType.JSON
};
try
{
var response = client.GetAcsResponse(request);
var json = System.Text.Encoding.Default.GetString(response.HttpResponse.Content);
var model = JsonConvert.DeserializeAnonymousType(json, new
{
DomainRecords = new
{
Record = new[] { new { RecordId = "", RR = "", Value = "" } }
}
});
var record = model.DomainRecords.Record.FirstOrDefault(m => m.RR.EqualsIgnoreCase(config.RR));
if (record != null)
{
await Update(profile, client, record.RecordId, record.Value, config);
}
else
{
await Add(profile, client, config);
}
}
catch
{
//
}
}
/// <summary>
/// 获取公网IP
/// </summary>
/// <returns></returns>
private async Task<string> GetIP()
{
string url = "https://202020.ip138.com/";
var client = new HttpClient();
client.DefaultRequestHeaders.Add("User-Agent", "abcdefg");
var html = await client.GetStringAsync(url);
return Regex.Match(html, "<title>[^:]+:([^<]+)</title>").Groups[1].Value;
}
/// <summary>
/// 添加
/// </summary>
private async Task Add(IClientProfile profile, IAcsClient client, DdnsConfig config)
{
var ip = await GetIP();
var request = new AddDomainRecordRequest
{
DomainName = config.Domain,
RR = config.RR,
Type = "A",
Value = await GetIP()
};
var response = client.GetAcsResponse(request);
await Logger.Info($"新增解析记录:{response.RecordId},IP:{request.Value}");
}
//修改
private async Task Update(IClientProfile profile, IAcsClient client, string recordId, string value, DdnsConfig config)
{
var ip = await GetIP();
if (ip == value)
return;
var request = new UpdateDomainRecordRequest
{
RecordId = recordId,
RR = config.RR,
Type = "A",
Value = await GetIP()
};
var response = client.GetAcsResponse(request);
await Logger.Info($"修改解析记录:{response.RecordId},IP:{request.Value}");
}
}
}
这样就可以安心连接自己的树莓派了,比如老李的代码世界