• 【老李瞎折腾】001、折腾一下DDNS


    去年就申请了电信的公网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}");
            }
        }
    }
    

    这样就可以安心连接自己的树莓派了,比如老李的代码世界

  • 相关阅读:
    计算机 ------- 网络基础
    设计模式------单例模式
    svn 客户端查看用户名和密码
    Docker:DockerFile(DockerFile解析)
    Docker:容器数据卷(命令方式、DockerFile方式)
    SpringBoot再总结
    Docker:镜像(镜像原理)
    Docker:Docker命令(帮助命令、镜像命令、容器命令)
    Docker(Docker的概念与安装)
    ZooKeeper:zookeeper的常用命令(节点的新增、更新、删除)
  • 原文地址:https://www.cnblogs.com/oldli/p/13728039.html
Copyright © 2020-2023  润新知