当前位置:   article > 正文

Openwrt IPV6设置详解

openwrt ipv6设置

硬件配置

光猫:ZXHN F650(GPON ONU)

硬件环境:openwrt x86

openwrt固件版本:21.02.0 r16279-5cc0535800

网络连接方式

由光猫拨号,openwrt直接使用DHCP客户端连接。光猫具体配置如下图:

 

 

 防火墙讲道理应该是不用设置的。因为看说明好像只是ipv4的设置。

而openwrt的应设置3个接口。分别为与光猫连接的WAN口,这个口只是用于ip4协议使用DHCP4客户端,然后再在这个接口上添加WAN6,协议使用DHCP6客户端用于获取光猫下发的ipv6。而LAN口除了正常的ip4的配置外,还应该添加ipv6 DHCP6服务。如下图

WAN

WAN6

LAN

防火墙 

PC侧的防火墙我就不演示了,实在不行可以直接关掉试试。

openwrt的防火墙可以在网络->防火墙->常规设置。将forward设置为accept。然后再讲区域中的都改成accept。这样就可以连接到你ipv6上的每一个端口。但是这样设置几乎就完全暴露自己了。但是可以先这样试试看是否能连接常用的一些端口。

正常做法是自定义规则来,避免完全暴露。如下

在Firewall - Traffic Rules中添加规则

这里的目标地址可以不填。当然你也可以指定IP,避免lan口上所有的设备都暴露下面的端口。

Openwrt 阿里云DDNS设置

 我这里是直接用的阿里云,因为官方固件对阿里的ddns不是很友好,用阿里云的DDNS API来做。具体做法

1、在openwrt中安装python环境

2、python pip 安装阿里云Python API

3、编写脚本,查询本机IP,如有更改就调用阿里云API更新DNS

4、使用openwrt的定时脚本,定时执行

        使用openwrt opkg安装python3,当然也可以用web管理界面安装。其中需要安装 python3、python3-pip、python3-dev、python3-cffi、python3-cff3-src。黑体字这3个会影响到阿里云SDK的正确安装。

       按照阿里云的说明,先安装pip install alibabacloud_tea_openapi,然后安装pip install alibabacloud_alidns20150109==2.0.2。到这里阿里云API的环境搭建完成。

        脚本可以按照说明书下面的示例写,需要用到AccessKey,这个直接在阿里云的网站上面设置。下面给出一个我自己写的脚本。

        Openwrt路由的IP可以通过连接2400:da00:2::29获得,而我个人PC的IP是直接通过ping我PC的计算机名称来获取,我的计算机名为HomeComputer,所以有一行代码是

    val = os.popen('ping -6 -c 1 HomeComputer').read()

以下是完整的python刷新openwrt IP的脚本

  1. from socket import AddressFamily
  2. from socket import SocketKind
  3. from socket import socket
  4. from typing import List
  5. import os
  6. import time
  7. import traceback
  8. from alibabacloud_alidns20150109 import client
  9. from alibabacloud_alidns20150109.client import Client as Client
  10. from alibabacloud_alidns20150109 import models as alidns_20150109_models
  11. from alibabacloud_tea_openapi import models as open_api_models
  12. def CalculateComputerIP(ipv6):
  13. newIP = ''
  14. val = os.popen('ping -6 -c 1 HomeComputer').read() #此处使用自己的计算机名称
  15. if 'bad address' in val: #电脑关机休眠的情况
  16. newIP = ipv6
  17. else:
  18. newIP = val[val.rfind('(') + 1:val.rfind(')')]
  19. return newIP
  20. def UpdateRecord():
  21. localtime = time.asctime( time.localtime(time.time()))
  22. print(localtime)
  23. s = socket(AddressFamily.AF_INET6,SocketKind.SOCK_DGRAM)
  24. s.connect(('2400:da00:2::29',80))
  25. ip = s.getsockname()[0]
  26. print('current openwrt ip6->' + ip)
  27. config = open_api_models.Config(
  28. # 您的AccessKey ID,
  29. access_key_id='-----------------',
  30. # 您的AccessKey Secret,
  31. access_key_secret='----------------'
  32. )
  33. config.endpoint='alidns.cn-hangzhou.aliyuncs.com'
  34. client = Client(config)
  35. request = alidns_20150109_models.DescribeDomainRecordsRequest()
  36. request.domain_name = '*******.cn'
  37. request.lang = 'en'
  38. response = client.describe_domain_records(request)
  39. #for record in response.body.domain_records.record:
  40. #print(record.value)
  41. results = [r for r in response.body.domain_records.record if r.type == 'AAAA']
  42. computerResult = results[0]
  43. openwrtResult = results[1]
  44. computerIP = CalculateComputerIP(computerResult.value)
  45. print('current computer ip->' + computerIP)
  46. print('ali computer ip->' + computerResult.value + '\t' + "ali openwrt id->" + openwrtResult.value)
  47. print('ali computer id->' + computerResult.record_id + '\t' + "ali openwrt id->" + openwrtResult.record_id)
  48. isUpdateOpenwrt = False
  49. isUpdateComputer = False
  50. if(openwrtResult.value!=ip):
  51. print('current openwrt ip != ali ip,will be update ddns.')
  52. # 更新AAAA纪录
  53. update_openwrt_request = alidns_20150109_models.UpdateDomainRecordRequest(
  54. rr='openwrt',
  55. type='AAAA',
  56. record_id=openwrtResult.record_id,
  57. value=ip
  58. )
  59. print('update openwrt AAAA record.')
  60. try:
  61. #print('update_openwrt_request:' + update_openwrt_request.__str__)
  62. updateOpenwrtIPReponse = client.update_domain_record(update_openwrt_request)
  63. isUpdateOpenwrt = True
  64. print('update openwrtIP is ok.')
  65. except Exception as e:
  66. print('update openwrtIP record except:' + e.args)
  67. UpdateRecord()

然后使用crontab来设置定时启动上面这个文件就好了。

PC端 阿里云DDNS代码

而PC端的IP可以直接改上面的Python代码来实现,但是经过测试很不稳定,所以我在PC端写了一个服务定时刷新IP进行DDNS。主要的代码如下

  1. public partial class AliDDNSService : ServiceBase
  2. {
  3. Client _ddnsClient;
  4. DescribeDomainRecordsRequest _request;
  5. DescribeDomainRecordsResponse _response;
  6. bool _running = false;
  7. Timer _timer;
  8. public AliDDNSService()
  9. {
  10. InitializeComponent();
  11. _ddnsClient = CreateClient("-------------", "-------------------");
  12. _request = new DescribeDomainRecordsRequest();
  13. _response = new DescribeDomainRecordsResponse();
  14. _timer = new Timer(10 * 60 * 1000);
  15. _timer.Elapsed += RefreshDNS;
  16. }
  17. protected override void OnStart(string[] args)
  18. {
  19. _timer.Start();
  20. }
  21. private void RefreshDNS(object sender, ElapsedEventArgs e)
  22. {
  23. if (_running) return;
  24. try
  25. {
  26. _running = true;
  27. _request.DomainName = "*********.cn";
  28. _request.Lang = "en";
  29. _response = _ddnsClient.DescribeDomainRecords(_request);
  30. var results = _response.Body.DomainRecords.Record.Where(w => w.Type == "AAAA");
  31. var result = results.ElementAt(0); //设计第一个IP为PC的IP
  32. string recordIP = result.Value;
  33. string currentIP = GetCurrenIPV6();
  34. if (recordIP == currentIP) return;
  35. _ddnsClient.UpdateDomainRecord(new UpdateDomainRecordRequest
  36. {
  37. RR = "computer",
  38. Type = "AAAA",
  39. RecordId = result.RecordId,
  40. Value = currentIP
  41. });
  42. }
  43. catch (Exception exp)
  44. {
  45. }
  46. finally
  47. {
  48. _running = false;
  49. }
  50. }
  51. protected override void OnStop()
  52. {
  53. _timer.Stop();
  54. }
  55. protected override void OnPause()
  56. {
  57. _timer.Stop();
  58. }
  59. protected override void OnContinue()
  60. {
  61. _timer.Start();
  62. }
  63. protected override void OnShutdown()
  64. {
  65. _timer.Stop();
  66. }
  67. private Client CreateClient(string accessKeyId, string accessKeySecret)
  68. {
  69. Config config = new Config
  70. {
  71. // 必填,您的 AccessKey ID
  72. AccessKeyId = accessKeyId,
  73. // 必填,您的 AccessKey Secret
  74. AccessKeySecret = accessKeySecret,
  75. };
  76. // 访问的域名
  77. config.Endpoint = "alidns.cn-hangzhou.aliyuncs.com";
  78. return new Client(config);
  79. }
  80. private string GetCurrenIPV6()
  81. {
  82. var hostName = Dns.GetHostName();
  83. var addresses = Dns.GetHostAddresses(hostName);
  84. var list = addresses.Where(w => w.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6);
  85. list = list.Where(l => l.ToString().First() == '2');
  86. return list.OrderBy(l=>l.ToString().Length).First().ToString();
  87. }
  88. }

远程唤醒PC

注意:如果要远程连接PC,需要先使用OpenWrt的Wake On Lan唤醒我们的计算机。

当然也可以写一个脚本完成此项操作,我这里用C#写了一个控制台的程序。思路就是OpenWrt打开SSH,然后通过SSH来操作路由器,让路由器上的WakeOnLan工作。我这个引用了nuget包ssh.net

以下就是我的控制台程序

  1. namespace wakeOnLan
  2. {
  3. internal class Program
  4. {
  5. static SshClient _client;
  6. static void Main(string[] args)
  7. {
  8. try
  9. {
  10. var result = GetOpenwrtIP().Result;
  11. if (!result.Item1)
  12. {
  13. Console.WriteLine("Get openwrt ip failure.");
  14. return;
  15. }
  16. _client = new SshClient($"{result.Item2}", 2222, "root", "root密码");//使用2222作为ssh的端口,这里可以在openwrt中更改
  17. _client.Connect();
  18. var command = _client.RunCommand("/usr/bin/etherwake -D -i br-lan -b mac地址");//这里填入自己的设备MAC地址
  19. Console.WriteLine(command.Result);
  20. _client.Disconnect();
  21. _client.Dispose();
  22. }
  23. catch (Exception exp)
  24. {
  25. Console.WriteLine(exp.Message);
  26. }
  27. finally
  28. {
  29. Console.WriteLine("Wait a minute.");
  30. }
  31. }
  32. static async Task<(bool, string)> GetOpenwrtIP()
  33. {
  34. Process process = new Process();
  35. process.StartInfo.FileName = "cmd.exe";
  36. process.StartInfo.UseShellExecute = false;
  37. process.StartInfo.RedirectStandardInput = true;
  38. process.StartInfo.RedirectStandardOutput = true;
  39. process.StartInfo.RedirectStandardError = true;
  40. process.StartInfo.CreateNoWindow = true;
  41. process.Start();
  42. process.StandardInput.WriteLine("ping -6 -n 1 *****.*****.cn");//通过域名来找到IPv6
  43. process.StandardInput.Flush();
  44. process.StandardInput.Close();
  45. Thread.Sleep(1000);
  46. string content = await process.StandardOutput.ReadToEndAsync();
  47. if (!content.Contains("0% loss")) return (false, "");
  48. var contents = content.Split("\r\n");
  49. content = contents[5];
  50. content = content.Split("]")[0].Split("[")[1];
  51. return (true, content);
  52. }
  53. }
  54. }

编译后,将可执行的文件拷贝至Windows/system32文件夹下,即可在cmd或powershell中运行。

这里因为是这电脑没有ipv6所以失败了

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/932699
推荐阅读
  

闽ICP备14008679号