阅读视图

发现新文章,点击刷新页面。

是 IPv6 吖 — V6 重生记

上周五的时候,在杜老师的聊天室聊天,hehe 提到一个关于家里 ipv6 地址申请的问题。这时候才想到自己家里的网络应该也是有 ipv6 的地址的。至于地址是不是公网的那就不知道了。

而至于想要弄这个东西,其实还有一个原因是 he.net 的 ipv6 徽章已经很久没更新了,还差最后一步 ipv6 only 的网络访问测试,而测试的域名就是 h4ck.org.cn。
IPv6 Certification Badge for obaby

为了通过这个测试,自然要折腾一下。通过之后,he说会免费邮寄一个 T 恤衫,尺码和地址都更新了。不过这跨国的快递,不知道能不能收到。

至于能不能收到,这就只能耐心等待啦。

远程登录路由器,直接访问 ip 地址,然后高级的一幕就出现了,竟然直接打开了路由器的登录页面:

那么也就是说联通在 v6 协议下竟然没有封禁 80 端口,这样的话我忽然就有了个大胆的想法。如果路由器将 v6 的映射打开,直接访问 v6 的地址,忽略证书错误。然后网站就顺利打开了:

既然如此,那么这一来也解决了自己的 cdn 流量超限的问题。

这个月流量超限之后,买了 100G 的扩展包,结果就用了四天就又没了。为了解决流量问题,文章中的视频,直接通过 url 转发了。而至于首页右下角的图片就直接去掉了。不知道是访问量还是神马问题,这些图片一天跑十几个 G 的流量。

然而,到现在就出现了另外几个问题,要想让网站直接在互联网上访问,没有任何的防护措施,的确感觉不怎么靠谱。

1.家里的 V6 地址也是动态的,需要能够动态更新 ipv6 的 AAAA 记录。

2.在家里的主机上安装 waf 系统,提供基础的防御功能。

3.其他的未知问题。

AAAA 记录

在测试的时候,添加 AAAA 记录,会因为存在 cname 记录而导致添加失败,AAAA 记录和 CNAME 记录有冲突,请先删除或暂停现有的 CNAME 记录后重试:

此时针对不同的线路分别添加解析就 ok 了:

那么,在这之后就来到了第二个问题,怎么获取本地的公网 ipv6地址。

最直接的想法是直接通过获取 ipv4 地址类似的写法,来获取 ipv6 的地址,让 cursor 给写了类似的代码:

def get_ipv6_by_httpbin():
    """通过 httpbin.org 获取 IPv6 地址"""
    url = 'https://api6.ipify.org?format=json'
    try:
        resp = request.urlopen(url=url, timeout=10).read()
        data = json.loads(resp.decode("utf-8"))
        if 'ip' in data:
            return data['ip']
        return None
    except Exception as e:
        logging.warning("get_ipv6_by_httpbin FAILED, error: %s", str(e))
        return None

def get_ipv6_by_icanhazip():
    """通过 icanhazip.com 获取 IPv6 地址"""
    url = 'https://icanhazip.com'
    try:
        resp = request.urlopen(url=url, timeout=10).read()
        ip = resp.decode("utf-8").strip()
        if regex_ipv6.match(ip):
            return ip
        return None
    except Exception as e:
        logging.warning("get_ipv6_by_icanhazip FAILED, error: %s", str(e))
        return None

def get_ipv6_by_ident_me():
    """通过 ident.me 获取 IPv6 地址"""
    url = 'https://v6.ident.me'
    try:
        resp = request.urlopen(url=url, timeout=10).read()
        ip = resp.decode("utf-8").strip()
        if regex_ipv6.match(ip):
            return ip
        return None
    except Exception as e:
        logging.warning("get_ipv6_by_ident_me FAILED, error: %s", str(e))
        return None

实际证明,代码写的不错,在自己的 mac 电脑上的确可以获取到 ipv6 的地址。

然而,在家里的服务器上却使用无法获取 ip 地址,所有 v6 协议的服务都是超时状态。搜索了一堆,问了一大圈的 ai,最终都没解决问题。

后来猜测是不是路由器的问题,于是重新登录路由器的 v6 配置页面,来回切换配置:

看网上有文章会所需要改为 slaac 模式,改过去之后无效,切换成原来的自动,继续沿用上面的配置。断线重连结果网络就好啦。注意,这两个 dns 是腾讯的 dns,不是联通默认的 dns。

然而,此时就出现了另外一个问题,直到这时候我才发现,获取到的这个地址是本地的 v6 地址,而不是路由器的 v6 地址,当然,更恐怖的是这个 v6 地址也是可以在互联网直接访问的。

那么怎么自动更新这个 dns 记录就成了问题,总不能自己去天天改啊。

问小杜无果之后,继续尝试通过路由或者 tracerout 的方式获取,最终都以失败告终。至此,简单的方法算是彻底没了招了,那么就剩下一条路了,之计通过路由器获取,然鹅,tplink 的企业路由器并没有开放相关的 api。只能自己去找接口。

结果在登录页面就被来了个下马威,获取到接口,让 cursor 写完代码之后登录不了。

看起来页面很简单不是,但是这个东西恶心的地方在于登录的密码是加密过得,直接使用明文密码是登录不了的。不过好在这个密码不是动态加密的,直接使用密码登录,截取登录的加密后密码进行登录就 ok 了。剩下的就是获取 ipv6 地址,更新 dnspod 的aaaa 记录:

tplink 相关代码:

import requests
import json
import urllib.parse

def login_tplink(ip, username, password):
    """
    Login to TP-Link router
    :param ip: Router IP address
    :param username: Login username
    :param password: Login password
    :return: Response from the router and stok if successful
    """
    url = f"http://{ip}/"
    
    headers = {
        'Accept': 'text/plain, */*; q=0.01',
        'Accept-Language': 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7',
        'Cache-Control': 'no-cache',
        'Connection': 'keep-alive',
        'Content-Type': 'application/json; charset=UTF-8',
        'Origin': f'http://{ip}',
        'Pragma': 'no-cache',
        'Referer': f'http://{ip}/login.htm',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36',
        'X-Requested-With': 'XMLHttpRequest'
    }
    
    data = {
        "method": "do",
        "login": {
            "username": username,
            "password": password
        }
    }
    
    try:
        response = requests.post(
            url,
            headers=headers,
            json=data,
            verify=False
        )
        if response.status_code == 200:
            try:
                response_data = response.json()
                if 'stok' in response_data:
                    return response_data['stok']
            except json.JSONDecodeError:
                print("Failed to parse login response as JSON")
        return None
    except requests.exceptions.RequestException as e:
        print(f"Login error occurred: {e}")
        return None

def get_network_info(ip, stok):
    """
    Get network information from TP-Link router
    :param ip: Router IP address
    :param stok: Session token from login
    :return: Network information response
    """
    url = f"http://{ip}/stok={stok}/ds"
    
    headers = {
        'Accept': 'text/plain, */*; q=0.01',
        'Accept-Language': 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7',
        'Cache-Control': 'no-cache',
        'Connection': 'keep-alive',
        'Content-Type': 'application/json; charset=UTF-8',
        'Origin': f'http://{ip}',
        'Pragma': 'no-cache',
        'Referer': f'http://{ip}/',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36',
        'X-Requested-With': 'XMLHttpRequest'
    }
    
    data = {
        "method": "get",
        "network": {
            "table": "if_info"
        }
    }
    
    try:
        response = requests.post(
            url,
            headers=headers,
            json=data,
            verify=False
        )
        return response
    except requests.exceptions.RequestException as e:
        print(f"Network info error occurred: {e}")
        return None

def get_wan1_pppoe_addresses(response_data):
    """
    Parse IPv4 and IPv6 addresses from network info response
    :param response_data: JSON response data
    :return: Dictionary containing IPv4 and IPv6 addresses
    """
    addresses = {
        'ipv4': None,
        'ipv6': None
    }
    
    try:
        if_info = response_data.get('network', {}).get('if_info', [])
        for interface in if_info:
            if 'wan1_pppoe' in interface:
                wan_data = interface['wan1_pppoe']
                if 'ipaddr' in wan_data:
                    addresses['ipv4'] = wan_data['ipaddr']
                if 'ip6addr' in wan_data:
                    addresses['ipv6'] = urllib.parse.unquote(wan_data['ip6addr'])
                break
    except Exception as e:
        print(f"Error parsing wan1_pppoe addresses: {e}")
    
    return addresses

def update_ipv6_nat_mapping(ip, stok, dest_ip):
    """
    Update IPv6 NAT mapping on TP-Link router
    :param ip: Router IP address
    :param stok: Session token from login
    :param dest_ip: Destination IPv6 address
    :return: Response from the router
    """
    url = f"http://{ip}/stok={stok}/ds"
    
    headers = {
        'Accept': 'text/plain, */*; q=0.01',
        'Accept-Language': 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7',
        'Cache-Control': 'no-cache',
        'Connection': 'keep-alive',
        'Content-Type': 'application/json; charset=UTF-8',
        'Origin': f'http://{ip}',
        'Pragma': 'no-cache',
        'Referer': f'http://{ip}/',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36',
        'X-Requested-With': 'XMLHttpRequest'
    }
    
    # URL encode the IPv6 address
    encoded_dest_ip = urllib.parse.quote(dest_ip)
    
    data = {
        "method": "set",
        "firewall": {
            "redirect_4313056213": {
                "name": "mac_server_v6",
                "ip_proto": "IPv6",
                "if": ["WAN"],
                "src_dport": "443",
                "dest_port": "443",
                "dest_ip": encoded_dest_ip,
                "proto": "ALL",
                "loopback_ipaddr": "",
                "enable": "on",
                "src_dport_start": "65536",
                "src_dport_end": "65536",
                "dest_port_start": "65536",
                "dest_port_end": "65536"
            }
        }
    }
    
    try:
        response = requests.post(
            url,
            headers=headers,
            json=data,
            verify=False
        )
        return response
    except requests.exceptions.RequestException as e:
        print(f"Error updating IPv6 NAT mapping: {e}")
        return None

if __name__ == "__main__":
    # Disable SSL warnings
    requests.packages.urllib3.disable_warnings()
    
    # Router credentials
    ip = '192.168.1.1'
    username = 'obaby'
    password = '123456***加密后密码'
    
    # First login to get stok
    stok = login_tplink(ip, username, password)
    
    if stok:
        print(f"Login successful! Got stok: {stok}")
        
        # Get network information using the stok
        network_response = get_network_info(ip, stok)
        
        if network_response:
            try:
                response_data = network_response.json()
                addresses = get_wan1_pppoe_addresses(response_data)
                
                print("\nWAN1 PPPoE Addresses:")
                if addresses['ipv4']:
                    print(f"IPv4: {addresses['ipv4']}")
                if addresses['ipv6']:
                    print(f"IPv6: {addresses['ipv6']}")
                    
                    # Update NAT mapping with the IPv6 address
                    nat_response = update_ipv6_nat_mapping(ip, stok, addresses['ipv6'])
                    if nat_response:
                        print(f"NAT mapping update response: {nat_response.text}")
                    else:
                        print("Failed to update NAT mapping")
            except json.JSONDecodeError:
                print("Failed to parse network response as JSON")
        else:
            print("Failed to get network information")
    else:
        print("Login failed!")

至此第一个问题解决了。

开始第二个小问题,更新 aaaa 记录,这个就比较简单了,直接让 curosr 写就行了:

def get_record_id(domain, sub_domain, record_type='A', record_line='默认'):
    """获取记录ID,支持A和AAAA记录,以及不同的记录线路"""
    url = 'https://dnsapi.cn/Record.List'
    params = parse.urlencode({
        'login_token': cfg['login_token'],
        'format': 'json',
        'domain': domain
    })
    req = request.Request(url=url, data=params.encode('utf-8'), method='POST', headers=header())
    try:
        resp = request.urlopen(req).read().decode()
    except (error.HTTPError, error.URLError, socket.timeout):
        return None
    records = json.loads(resp).get('records', {})
    for item in records:
        if (item.get('name') == sub_domain and 
            item.get('type') == record_type and 
            item.get('line') == record_line):
            return item.get('id')
    return None

def update_ipv6_record(current_ipv6):
    """更新IPv6记录,支持多个记录和不同的记录线路"""
    ipv6_count = int(cfg.get('ipv6_count', '1'))
    ipv6_pool = cfg.get('ipv6_pool', '').split(',')[:ipv6_count]
    cfg['current_ipv6'] = current_ipv6
    
    if current_ipv6 not in ipv6_pool:
        logging.info("new IPv6 found: %s", current_ipv6)
        ipv6_pool.insert(0, current_ipv6)
        cfg['ipv6_pool'] = ','.join([str(x) for x in ipv6_pool[:ipv6_count]])
        
        # 获取所有需要更新的AAAA记录配置
        aaaa_records = cfg.get('aaaa_records', '').split(',')
        for record in aaaa_records:
            if not record.strip():
                continue
            try:
                sub_domain, record_line = record.strip().split(':')
                if update_record('AAAA', current_ipv6, record_line, sub_domain):
                    logging.info(f"成功更新AAAA记录: {sub_domain}.{cfg['domain']} 线路: {record_line}")
                else:
                    logging.error(f"更新AAAA记录失败: {sub_domain}.{cfg['domain']} 线路: {record_line}")
            except ValueError:
                logging.error(f"无效的AAAA记录配置: {record}")
        save_config()
    else:
        logging.info('IPv6 地址无变化,跳过更新')

到这里网站就能正常访问了。

WAF:雷池&南墙

至于 waf 系统,其实自己之前也没怎么系统了解过,也是杜老师推荐了这两个。首先尝试的是雷池,也是杜老师最开始推荐的。

雷池:

个人版是免费的,相对来说配置也比较简单。

官网地址:https://waf-ce.chaitin.cn

自动安装一行命令即可:

bash -c "$(curl -fsSLk https://waf-ce.chaitin.cn/release/latest/manager.sh)"

安装为 docker 模式,相对来说侵入性比较小一些。并且不需要占用 80,443 端口,这一点其实相对比南墙安装配置要求要低一些。

安装之后就可以通过 9443 端口登录了。相关功能示例:

系统概览,不知道是不是因为是 v6 地址的原因,左侧地图都是空白的。

同样,这个地球上也是空白的,底部的功能都需要专业版才能查看

防护模块是全部可用的

加强防御需要专业版

通用配置模块也是 ok 的。

整体来说安装过程比较顺畅也没遇到什么问题,不过访问 ip 由于是通过路由转发进来的需要从 x-forward-for中取这个信息。

南墙

开源免费的 waf 系统

官网地址:https://waf.uusec.com/#/

在使用过程中遇到点问题,不过最后在他们的技术帮助下顺利解决了。在安装之后,首先遇到的问题就是获取的 ip 地址有问题,都是本地的地址。并且不管怎么选择地址,最后都是同一个 ip 地址。

使用测速工具测速之后,ip 地址还是一个,这肯定是有问题的。在群里问了一下,给了个指令修复这个问题:

firewall-cmd --permanent --zone=internal --change-interface=docker0
systemctl restart firewalld && systemctl daemon-reload && systemctl restart docker

不过这么执行之后可能会出现的问题就是所有的服务都访问不了了,需要在 public 区域重新开放相关服务:

sudo firewall-cmd --zone=public --permanent --add-port=10043/tcp
sudo firewall-cmd --zone=public --permanent --add-port=14443/tcp
sudo firewall-cmd --zone=public --permanent --add-port=880/tcp
sudo firewall-cmd --zone=public --permanent --add-port=3306/tcp
sudo firewall-cmd --zone=public --permanent --add-port=9443/tcp
sudo firewall-cmd --zone=public --permanent --add-port=8443/tcp

其他需要开放的服务和端口自行添加即可。

然而,这个命令并没有解决问题。包括卸载重装,其实重装这件事情对我来说有些麻烦,因为服务器的默认 80 和 443 都映射到公网了,如果直接改了也比较麻烦,只能去工控机上停掉 80 的监听,443 的修改端口重新添加映射,毕竟这台主机上相对服务少一些。

重新安装依然没解决问题,这时候提议安装主机版。

然而,更尴尬的事情粗线了,那就是主机版不支持 ubuntu,只能作罢继续使用 docker 版本。

并且安装主机版,需要提前备份数据库,安装脚本会重装 mysql。这一点一定要注意!

这时候管理员提议远程协助,于是将端口映射出去,提供账号密码,等管理员修复。

管理说可能是映射的问题,然而,雷池的没问题,那么说明一定是有解决办法的,管理提到 docker 的网络配置不一样的,于是提议修改网络配置。

最终,亲爱的管理员,成功的修复了问题:

这样这个问题算是解决了,整体而言,感觉雷池的在 v6 测速的时候更绿一些。

好啦,相对来说雷池基本所有的模块都是开放的,除了机器学习部分:

安全态势

系统信息

用户管理

日志

证书管理,这个证书管理直接上传即可,不需要去进行绑定。

cdn 加速,其实感觉更像缓存配置。

规则管理

网站管理,得添加多个。

整体来说体验还是不错的,然而,刚才去看了配置文件感觉还是 bridge 啊。奇怪了。

不过既然问题解决了,那也就不纠结了。

官方文档说明:

https://waf.uusec.com/#/guide/problems?id=%f0%9f%8d%8b-%e5%a6%82%e4%bd%95%e8%a7%a3%e5%86%b3%e5%8d%97%e5%a2%99docker%e7%89%88%e8%8e%b7%e5%8f%96%e7%9a%84%e5%ae%a2%e6%88%b7%e7%ab%afip%e4%b8%ba172%e7%9a%84%e9%97%ae%e9%a2%98%ef%bc%9f

 

🍋 解决部分南墙容器版获取的客户端ip为网桥ip的问题?

1.将Docker网桥加入到防火墙的internal区域,以便获取到真实的IP地址, 假设Docker网桥名称为docker0

firewall-cmd --permanent --zone=internal --change-interface=docker0
systemctl restart firewalld && systemctl daemon-reload && systemctl restart docker

2.如果方法1无效,可以修改docker-compose.yml文件,将uuwaf容器的网络设置为network_mode: host,同时修改数据库连接环境变量UUWAF_DB_DSN中的wafdb为127.0.0.1,并映射wafdb容器的3306端口,重启后生效。

 

其他问题

鉴于主机获取的 ipv6 地址能直接访问,其实我一度想直接把主机的地址更新到 dns aaaa 记录上,但是这么一搞,暴露主机的确不是我最终想要的。

于是想着映射本地的链路地址,然而,端口映射通过链路地址通过路由器的 v6 地址却打不开网站,但是这个链路地址在内网的主机上又能打开网站,于是只能放弃这个做法。获取 ipv6 地址的代码:

import re
import logging
import json
import subprocess
import socket
import os
from urllib import request, error, parse

# 匹配合法 IPv6 地址
regex_ipv6 = re.compile(
    r"(?:inet6\s+)?(fe80:[0-9a-fA-F:]+|"  # 特别处理链路本地地址格式
    + r"(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|"  # 标准格式
    + r"(?:[0-9a-fA-F]{1,4}:){6}:[0-9a-fA-F]{1,4}|"  # 压缩格式
    + r"(?:[0-9a-fA-F]{1,4}:){5}(?::[0-9a-fA-F]{1,4}){1,2}|"
    + r"(?:[0-9a-fA-F]{1,4}:){4}(?::[0-9a-fA-F]{1,4}){1,3}|"
    + r"(?:[0-9a-fA-F]{1,4}:){3}(?::[0-9a-fA-F]{1,4}){1,4}|"
    + r"(?:[0-9a-fA-F]{1,4}:){2}(?::[0-9a-fA-F]{1,4}){1,5}|"
    + r"(?:[0-9a-fA-F]{1,4}:){1}(?::[0-9a-fA-F]{1,4}){1,6}|"
    + r"(?::[0-9a-fA-F]{1,4}){1,7}|"
    + r"::"
    + r")")

# 特别匹配链路本地 IPv6 地址,确保能匹配到 fe80:: 开头的地址
regex_link_local_ipv6 = re.compile(r"inet6\s+(fe80:[0-9a-fA-F:]+)")

def get_ipv6():
    """获取公网 IPv6 地址,使用多个备选方法"""
    return (get_ipv6_by_ifconfig()  # 优先使用本地接口地址
        or get_ipv6_by_httpbin()
        or get_ipv6_by_icanhazip()
        or get_ipv6_by_ident_me()
        or get_ipv6_by_socket())

def get_ipv6_by_ifconfig():
    """通过 ifconfig 命令获取本地 IPv6 地址"""
    try:
        # Windows 系统使用 ipconfig
        if os.name == 'nt':
            cmd = ['ipconfig']
            output = subprocess.check_output(cmd, text=True)
        # Linux/Unix 系统使用 ifconfig
        else:
            cmd = ['ifconfig']
            output = subprocess.check_output(cmd, text=True)
            
        # 按行分割输出
        lines = output.split('\n')
        for line in lines:
            # 查找包含 inet6 的行
            if 'inet6' in line:
                # 使用正则表达式提取 IPv6 地址
                matches = regex_ipv6.findall(line)
                if matches:
                    ipv6 = matches[0]
                    # 排除本地回环地址
                    if not ipv6.startswith('::1'):
                        logging.info(f"Found IPv6 address: {ipv6}")
                        return ipv6
    except Exception as e:
        logging.warning("get_ipv6_by_ifconfig FAILED, error: %s", str(e))
    return None

def get_ipv6_by_socket():
    """通过 Python socket 库获取本地 IPv6 地址"""
    try:
        # 创建一个 IPv6 socket
        s = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
        # 连接到一个外部地址(这里使用 Google 的 IPv6 DNS)
        s.connect(('2001:4860:4860::8888', 80))
        # 获取本地地址
        local_addr = s.getsockname()[0]
        s.close()
        return local_addr
    except Exception as e:
        logging.warning("get_ipv6_by_socket FAILED, error: %s", str(e))
        return None

def get_ipv6_by_httpbin():
    """通过 httpbin.org 获取 IPv6 地址"""
    url = 'https://api6.ipify.org?format=json'
    try:
        resp = request.urlopen(url=url, timeout=10).read()
        data = json.loads(resp.decode("utf-8"))
        if 'ip' in data:
            return data['ip']
        return None
    except Exception as e:
        logging.warning("get_ipv6_by_httpbin FAILED, error: %s", str(e))
        return None

def get_ipv6_by_icanhazip():
    """通过 icanhazip.com 获取 IPv6 地址"""
    url = 'https://icanhazip.com'
    try:
        resp = request.urlopen(url=url, timeout=10).read()
        ip = resp.decode("utf-8").strip()
        if regex_ipv6.match(ip):
            return ip
        return None
    except Exception as e:
        logging.warning("get_ipv6_by_icanhazip FAILED, error: %s", str(e))
        return None

def get_ipv6_by_ident_me():
    """通过 ident.me 获取 IPv6 地址"""
    url = 'https://v6.ident.me'
    try:
        resp = request.urlopen(url=url, timeout=10).read()
        ip = resp.decode("utf-8").strip()
        if regex_ipv6.match(ip):
            return ip
        return None
    except Exception as e:
        logging.warning("get_ipv6_by_ident_me FAILED, error: %s", str(e))
        return None

def get_link_local_ipv6():
    """专门获取链路本地 IPv6 地址"""
    try:
        # Windows 系统使用 ipconfig
        if os.name == 'nt':
            cmd = ['ipconfig']
            output = subprocess.check_output(cmd, text=True)
        # Linux/Unix 系统使用 ifconfig
        else:
            cmd = ['ifconfig']
            output = subprocess.check_output(cmd, text=True)
            
        # 按行分割输出
        lines = output.split('\n')
        for line in lines:
            # 查找包含 inet6 的行
            if 'inet6' in line:
                # 提取 IPv6 地址和 prefixlen
                if 'prefixlen 64' in line and 'scopeid 0x20<link>' in line:
                    # 调试输出
                    logging.debug(f"Processing line: {line}")
                    
                    # 使用特定正则表达式提取链路本地 IPv6 地址
                    matches = regex_link_local_ipv6.findall(line)
                    if matches:
                        ipv6 = matches[0]
                        logging.info(f"Found link-local IPv6 address with new regex: {ipv6}")
                        return ipv6
                    
                    # 如果特定正则表达式没有匹配到,尝试使用一般性正则表达式
                    matches = regex_ipv6.findall(line)
                    if matches:
                        ipv6 = matches[0]
                        logging.debug(f"Original regex matched: {ipv6}")
                        # 只返回链路本地地址
                        if ipv6.startswith('fe80'):
                            logging.info(f"Found link-local IPv6 address with original regex: {ipv6}")
                            return ipv6
                        elif 'fe80' in line:
                            # 如果行中包含fe80但匹配失败,记录错误
                            logging.warning(f"Regex failed to match fe80 in: {line}")
    except Exception as e:
        logging.warning("get_link_local_ipv6 FAILED, error: %s", str(e))
    return None

# 测试
if __name__ == '__main__':
    logging.basicConfig(level=logging.DEBUG)
    
    # 测试特定的 IPv6 地址匹配
    test_line = "inet6 fe80::e4d:e9ff:fec9:9de3  prefixlen 64  scopeid 0x20<link>"
    print("Testing regex with line:", test_line)
    
    # 测试链路本地特定正则
    matches = regex_link_local_ipv6.findall(test_line)
    if matches:
        print("Link-local regex matched:", matches[0])
    else:
        print("Link-local regex failed to match")
    
    # 测试一般 IPv6 正则
    matches = regex_ipv6.findall(test_line)
    if matches:
        print("General IPv6 regex matched:", matches[0])
    else:
        print("General IPv6 regex failed to match")
    
    print("\n--- Regular program output ---")
    print("Method 1 (httpbin):", get_ipv6_by_httpbin())
    print("Method 2 (icanhazip):", get_ipv6_by_icanhazip())
    print("Method 3 (ident.me):", get_ipv6_by_ident_me())
    print("Method 4 (ifconfig):", get_ipv6_by_ifconfig())
    print("Method 5 (socket):", get_ipv6_by_socket())
    print("Link-local IPv6:", get_link_local_ipv6())

获取到 v6 地址,就可以通过 tplink 的映射代码update_ipv6_nat_mapping进行地址映射了。

如果要用这个代码,需要根据自己的路由器配置获取映射的 id。

整体来说,速度还是可以的: 

 

The post 是 IPv6 吖 — V6 重生记 appeared first on obaby@mars.

双城记

早在一个月之前,老太太的生日就提上了日程。合计着哪天过生日,每年为了迎合大家的时间,都会选择一个周末提前过。然而,今年不同,自从灵儿的大姐开了养生馆之后,自由时间越来越少,也难得凑到一块。为此,老太太还颇有微词,然而,生活哪里又容易。谁还不是为了那几毛钱而奔波。

为此,也只能选在生日当天了。主要还是为了迎合大姐的时间,周五她要去县城接孩子。从六年级让孩子回到老家县城上学,到现在已经高三了,眨眼间也都成了亭亭玉立的大姑娘,而明年就要高考了。县城的教育产业,也算是解决了大姐的教育难题。

周五一早送宝子去上学之后,灵儿就准备驱车回老家。经过两个小时的奔波终于到家了,而此时,所有的客人算是都到齐了,每年老太太过生日的时候,大舅、舅妈、三姨,总会来一块吃个饭,这个习惯也坚持了好多年了。而姐姐们也都到齐了,不过,因为是周五的缘故,所有的小朋友都在上学,少了一些喧嚣。

农村的冬天跟夏天一样难熬,没有空调和没有炉子的屋子一样,都让人想逃。熟悉了城市的那种温度之后,有时候在那种酷热或者寒冷的环境下,内心甚至有一种本能的逃避的苗头。好在今天太阳挺大的,也没什么风,在院子里晒着,反而有种暖暖的感觉。

老太太住的那间房子,照旧依然是生了炉子。就靠炉子提供的温度来躲过冬天的寒冷,屋里人有些多,找个落脚的地方都有些困难。灵儿不想在里面挤着,拿了个小马扎跑到了院子里,坐在月台上,看三姐在那里挑苹果。这些苹果虽然摘下来有些日子了,但是套在上面的袋子还没有拆掉。拿过来的那些都是苹果商贩因为个头小而不要的,拆掉纸袋之后,淡黄色的果皮呈现了出来,看起来竟然蛮好吃的样子。

吵吵嚷嚷一个小时就过去了,驱车前往镇上的饭店吃饭。已经好多年不在家里做饭了,人太多,也没有那么大的桌子。至于是谁做饭也是个大问题,之前都是大姐夫做,连续做了好多年。而近些年,老太太的口味变化太大,在家里做饭已经到了不管怎么做,都做不到她心里去了。没能吃的菜,所以索性不如去外面,让其他人来解决这个问题。

灵儿跟三姐准备早一步出发,去镇上的学校接孩子们过去吃饭。然而在倒车的时候,灵儿忽然感觉后轮一沉,感觉应该是掉到了马路牙子下面了。然而,却也没什么办法,调整下方向,伴着刺耳的摩擦声,把轮子从马路牙子下面给拉上来了。到学校门口的时候,看了下,轮圈也给磨花了。

女司机,就是女自己,太 tm 不靠谱了。可能也是灵儿最近用脑过度了吧,最近的新项目投入了太多的精力,感觉头发都少了,有时候感觉脑子真的不好使。并且换车 之后,总感觉车头长了很多,每次在这个狭小的空间倒车的时候,总是心里各种不自信。

路边的路,右前方的树,右后方的深坑,都在考验着这个女自己的技术。下午返程回家的时候,从路边开出来,又差点被飞速开过的比亚迪给撞上,看来脑子确实是不太够用了。竟然都疏于观察,上次出现这种情况还是好多年前,项目攻坚的时候。也可能是老了,反应变得迟钝了。

有时候老太太在聊天的时候,灵儿总是很矛盾,想聊聊,但是又找不到话题。在聊天的时候,也确实能感觉到,老太太的记忆力衰退严重了。

所有的人都走了,就剩下灵儿跟老太太,“中午他们给煮没煮面条,咱们是不是没吃啊”老太太问。

“煮了啊,那么一大盆呢,给你盛上面,你还发表了一番言论不是?”灵儿答道。现在已经到了,中午做过的事情,下午就完了,甚至刚做过的事情,转眼间就忘了。时间也在摧残着老太太仅有的记忆能力。然而,一些特殊的记忆以及话题,就成她每次都要提的事情。吃饭的时候说道,现在也过得挺好的,我恨就恨老家伙死的太早。她说的老家伙是灵儿的父亲,眨眼间已经过了二十多年。作为那个懂事的孩子,这么多年,灵儿不管在外面怎么漂泊,怎么凄苦,其实家里人从来都不知道,她也不曾提过。只是偶尔那么几次在醉生梦死间,才看到那漫漫黑夜中,那一丝幽光,时明时暗。就靠着这微弱的希望,她磕磕绊绊的走到了现在,而这一切,她所有的亲人都不曾知道,因为她知道她的那些姐姐们过得也并不好,即使说了也没什么能帮上自己的,更何况,那时候太多的人等着看这个大学生的笑话,就等她混的一塌涂地。那个光鲜亮丽的大学生,其实很多年在外面活的不如一条狗。

每次聚会的时候,老太太总会喝点,也喝不多,这次还是一样,灵儿照例买了两瓶茅台王子,还有几箱青岛啤酒。当然,老太太的那个酒量也不大,每次也就二两酒就能喝的话多起来。这些年,喝开心了之后,总是回忆自己年轻的时候,可能,老了之后也的确没什么好值得回忆的吧。

周六中午三姐又来了,带着孩子过来跟二姐家的孩子一起玩,写作业。吃饭的时候,老太太又开始说一些自己的观点,还是跟昨天一样:“我觉得现在不读书最好,孩子就得在身边待着”

每当灵儿听到这个论断的时候,内心总是掀起一层波澜。人这个东西,的确是太善变了,早几年,老太太跟自己的外甥说的还是让他们都跟着灵儿学习,好好学习有目标,考个好大学。现在,眨眼就就成了上学无用。每当听到这么说的时候,灵儿总是忍不住要怼她几句,“不上学,留在身边干嘛?喝西北风?你不去看看那些和你一样大岁数的有几个跟你一样这么悠闲,不都在拼命给自己的儿女挣钱?”

“你看那些下劳务的,跟你一个岁数的有的是”三姐也说道。

“孩子不用学太好,也不能太有本事,太有本事了,见都见不到……”老太太继续说道。

“没本事,谁养他?你养?”灵儿反问道。

只是这种争论从来也没有结果,自然,灵儿也知道跟她争论这些没用。如果不是被所谓的亲情绑架,灵儿或许现在仍然在厦门,或者是另外的城市生活。只是,现在她也不恨,也没什么想法了。人生,在某刻忽然变得无欲无求了。

二姐和三姐家的孩子都在写作业,二姐家的孩子已经上三年级,农村教育三年级起点的英语课也开课了。不过这个课程,让这个从来没有接触过英语课的小朋友有些无所适从,拿过小妮手里的英语卷子,前半部分是听力。老师也没有分享听力文件,所以这一部分自然是做不了的。后面的笔试部分,直接开始区分单词的分类,简单的阅读理解。如果不是靠她手里的点读笔,这长长的一段英文对她来说,无异于天书。

这个世界想要抛弃你,从来都不会咨询你的意见。这样的英语无异于将入门的门槛提高了很大的一个高度。没有基础的孩子,想跟上这个英语学习的步伐,也只能靠强大的天赋了。青岛,在今年也开始使用三年级起点的英语教材了。不过,好在,在这改革之前,宝子已经学会了很多,并且之前完全是按照青岛的一年级起点英语施教。当然,对我来说,几年级起点的英语,对于自己和宝子来说,都不是难题。

吃完饭,下午喝点茶水,休息一下。周六下午,灵儿就准备走了,主要是也该剪头发了,依然约的县城的那家理发店,四点半。两点半就从老家离开了,到县城三点多,回家打开空调,看了下室温只有 14 度,虽然没那么冷。空调开了两个小时之后温度终于到了 18 度。

晚饭一个人也不想出去吃,点了个烧烤外卖。

就这么点东西,80 多块钱,属实有些离谱了,更何况那瓶大窑还是我自己的。最终这些东西也没全部都吃掉,吃到一半的时候感觉是少了东西。但是这都吃了一半了,也不少清点到底是少了什么东西。烤的五花肉也的确是难吃,最终,可能也就吃了一半而已。

一个人的时候,总是有大把的时间可以挥霍,吃完了,到公园转了一圈,不过一个人逛公园的确没什么意思。

不过在县城,冬天穿短裤的确实没有,在一路上回头率都百分之百了,这就让人很尴尬。公园依然是绿色的灯光,这个绿色的灯光灵儿的确也有点欣赏不来,路上都是一对对情侣或者是带着孩子的一家人,一个人逛公园的,可能也就灵儿自己吧。

然而,到家也才九点多,冬天的夜总是格外的长一些。长夜漫漫,孤枕难眠,那索性不如再找个地方去打球吧。没什么球友,也没什么朋友,其实一个人玩也蛮有意思的,灵儿想。

终于,一个多小时之后,可以回家睡觉啦。然而,第二天早上,却没有睡到八九点。灵儿做了一个梦,梦到自己去拿快递的时候,粉皮被别人开走了,然后灵儿到处去找粉皮,马上就要去报警的时候,终于醒了,看了下时间才七点多。

那个快递,早在周五就送到了,家里的路由器莫名其妙就坏了。刚好过保,寄回去修,过了几天售后打电话反馈,需要将设备寄回厂商,预计得一个多月。如果不返修,可以给你换新的,但是,现在那个型号没货了。要么加价换其他的型号,要么换个便宜的。

然而,现在家里的网络确实比较卡,灵儿也等不了那么久。加了 300 多块钱换了新路由器,只是这个新路由器只有 4 个 lan 口,原来的八口路由器+8 口交换机刚好够用,而现在路由器只剩四口了。只要再购买一台 16 口的交换机。昨晚这一切,总感觉自己被套路了。这换新,又忽悠自己买新设备了。

周日一早还得赶回去,给小姐姐的妈妈过生日。这一个周末,连赴两个生日宴。到家顺路从京东的网点拿上快递,回到家,把从老家带回得来东西搬到楼上。小朋友看电视的时候,一边看一边吆喝,因为那个路由器实在是性能不大行,电视都开始卡了,缓冲都得半天。

吃完饭,小朋友去睡觉了。赶紧去 更换设备,刚看到交换机,感觉小了点,好在给的支架是延长的,还能上机柜,不然这个的确有且蛋疼了。

而至于整理网线,也确实没下得去手。因为后面的电源线也有点多,不全部拆掉,也梳理不清楚,后来嘛,就勉强稍微整理了一下。而现在网速基本是 ok 了。那个次卧的路由器,由于是百兆线连过去的,所以,撑死也就是百兆带宽了。

到现在终于崩溃了几天的博客和各种业务总算是恢复了。而此时,蛋糕也切好了,正好可以吃一块蛋糕。

人生,不过是从一个城池奔赴另外一个城池,从一场宴席,奔赴另外一场宴席,修正一个个的错误,一个个的问题。

只是现在,感觉时间真的好少,过完这个月,得找时间再去拍写真了。

路由器碎碎念

周日下午,在接近要吃晚饭然后回单位之前突然想起有件事情我还没做,我打算把家里那个闲置的水星MW300R路由器带回单位。因为科室的路由器,那个TP-LINK路由器这段时间不知道为什么老是会出现连上了,但是却上不了网。跟我的那个接近同款的路由器比起来,现在用的那个TP-LINK路由器新一点,但也新不到哪里去,毕竟那种路由器性能有限。我不太确定这种能连上WiFi,但是却连不上互联网是什么原因导致的,我感觉跟同时连上那个WiFi的人数多少有关系,毕竟那只是一个很旅行路由器,没想过有很多设备同时连接。通常情况下,我的小米civi 1S跟我的红米Note11 5G都会连那个路由器,尤其是在我做任务的时候,但我的电脑连的是网线,所以没有必要连,但我不确定别人的手机是不是连的那个路由器,因为单位虽然布局了全覆盖的WiFi,但实际上那个操蛋的华为信号相当糟糕,尤其是他们把2.4和5G合并了。他们的那些连接系统会导致突然就断线,突然又连上了,于是你如果处在移动之中,你就会出现那种连上连不上的状态,什么东西都很卡,找不出原因。所以我的任何一个无线设备都不会自动连接单位的WiFi,但我会把那个WiFi保存下来,当我在某个地方不动的时候,又或者是在某个地方我没私有WiFi的时候,我就会连那个。不让自动连接,如果我在移动之中,单位的WiFi断了就验证了我前面的那个说法,WiFi虽然是系统起来了,但就是一个鸡肋。

以前科室的那个TP-LINK小WiFi没什么问题,可能用的人不多,大概就只有我,只有我的两台手机。现在估计用的人多了,所以就说不准会有什么问题。TP-LINK相对于华为,我感觉稳定一些,但是我不保证当苹果手机和安卓手机一同连接那个WiFi的时候会出现什么奇怪的事情。可以肯定的是当我的手机发现能连WiFi,但无法连接网络的时候,一加的手机也会出现同样的状况。那个时候我们就只能把WiFi拔出来再重新插回去,等于是重启了一遍。有时候一遍还不行,可能还得试一遍,有时可能一个月下来都没有问题,但有时可能一天好几回。

WiFi用久了要重启,这个很正常,但关键是我感觉近几个月这种事情频繁发生,一天可能发生一两回。我实在受不了了,所以反正家里的那个水星闲置,不如拿回来替换一下。我已经查不出家里那个水星路由器是什么时候买的了,因为估计我是在亚马逊中国买的,现在亚马逊中国已经把用户的资料都清清理掉了。就购买时间来说,我那个水星的购买时间可能会早一点,但跟TP-LINK比起来,我的那个是300M的路由器,而那个随身的TP-LINK只有150M,这样的区别我感觉是天线的差异。家里为什么要搞个水星路由器,是因为以前家里也是用天天连的那种旅行路由器,但是家里的WiFi设备多了,显然这就不够用了。以前吃WiFi的就只有我自己的手机,所以我把路由器放在我的房间里就可以了,但后来我爸我妈都有了智能手机。我还想把那个无线网络覆盖到整个屋子,显然那就不够了。买了水星路由器没多久以后。我就升级了小米粒的路由器。主路由是我的小米mini。我把水星以有线网络的方式放在客厅,这样整个屋子都能覆盖到。虽然两个路由之间的距离很近,但我没办法用无线的方式,因为我家接收到的那些WiFi干扰实在太严重,随便搜出几十个WiFi信号,无论你设置什么样的信道都会被干扰。所以为了保证两个路由器都能正常运行,我只能用有线的方式把它们连接起来。如果我家不是差不多20年前做装修的,客厅跟卧室肯定都会预留了网口,但我家装修的那个年代,客厅跟卧室预留的只是同轴线的电视接口。所以我不得不把网线从我的房间拉到客厅,之所以这样,是因为当时装宽带的时候是从我房间的那个空调孔穿进来的。正常思路应该是在我家的门那里穿进来,但那样的话要绕过客厅再到我的房间,要绕很远,当时使用网线的就只有我的电脑,所以装网络的师傅就这么干。现在如果再拉网线,一定是走客厅,因为现在我的锐捷路由器就放在客厅,能覆盖我家的任何一个地方。

时代在变化,网络在变化,但其实算起来,好像我家使用路由器的历史还不算太长。

莫名其妙

不得不说最近这个天是越来越冷了,本来都不准备写东西了。就写一篇技术文拉到,象征性的摸摸鱼,然鹅,事情的发展总是能出乎意料。

平淡的周末依然平淡,周五去给宝子开家长会,老师好一通表扬,让我也不由得心花怒放。说宝子字写得好看,有时候批改作业或者心情不好的时候就去会看宝子的作业,瞬间就让人心情愉悦了。不过说实话,宝子的字写的确实是好看,哪怕跟现在自己写的字相比都毫不逊色。这也不是第一次老师当着那么多人的面表扬宝子了。在家长会之前,还专门设置了个区域,让大家去看那些优秀的作业。

晚上,看了下第二天的小记者活动,原本已经报名满额的关爱罕见病的活动,竟然又空出来一个,正好就可以重新报名参加这个活动。留住海鸥的活动就不再参与了,毕竟,那个距离也有些远。

排队领材料的时候,宝子依然一副漫不经心的样子。就那么站着,也不着急,有时候还东张西望,前面有人插队也不会去阻止。这一点真的不知道是遗传的谁,那种与世无争的状态,有时候真的让人看了来气。完全不知道维护自己的权利和利益,也从来不知道竞争是什么,这个好心态有时候也让自己无比的佩服。

拿到材料,看的还蛮认真的。后面进到屋里做手工,家长不让陪同,也就只能在外面候着了。虽然已经是冬天,但是在风和日丽的天气里,晒着太阳,懒洋洋的暖暖的倒是也颇为自在。

做完手工,后续又来了一位医生,给小朋友讲解罕见病的相关知识,还有采访环节,当然,不出意外,宝子还是在最外围。嗯,就是这么波澜不惊。

不过这短短的一个小时,竟然又认识了一个姐姐,跟那个小姐姐玩的还挺开心的。活动结束,两个人还又去游乐场玩了一个多小时。

宝子看新闻的时候,总说想去滑雪了,从高德地图看了下滑雪场,都还没开放。不过风和日丽的暖天应该也不会太多了,再有一个多月应该就可以去滑雪了。下午带宝子去公园骑自行车,有朋友推荐国学公园,长途跋涉之后直奔国学公园。

然而,公园外并没有共享单车神马的,只能宝子一个人骑自己在后面跟着,不过这个公园面积的确不大,不一会儿就转了一圈了。

不过这个小圆子好处是人不多,拍婚纱照的蛮多的。

意犹未尽,只能去另外一个公园,奥林匹克公园。

还有在草丛里吃草的猫咪:

在湖里的游船,后面跟着个大喇叭一边走一边喊:水深四米,请勿跳水……

不过真的有人会跳水吗?😂

下午回家,宝子的姥姥开始数落,:”看你们带孩子出去,把孩子给累的“

问题是她不吃饭 ,纯粹就是不想吃,跟我们没关系。

晚饭象征性的对付了过去,我也没怎么吃东西就喝了一碗豆浆。早上起床发现手机断网了,打开wifi 界面,其实所有的无线都无法上网,这尼玛就神了。

看了下网站,果然挂了,而服务器状态监控,家里的主机也都离线了。好不意外,肯定是家里的网络出问题了。重启路由器,无效,reset 依然无效,开始怀疑是不是宽带出问题了。

光猫的光信号指示灯是灭的,然而,打开电视,iptv 却是正常的。这尼玛就离谱了。

打开电脑,获取 ip 地址依然是 168.254 网段的什么东西,这么看来是彻底完犊子了。看了下二手东的购买日期,去年的双十一,刚好过保,哈哈哈。这尼玛,到公司不死心继续折腾,发现竟然可以延保,通过延保服务提交售后,最后总算是解决这个问题了。不过需要把路由器寄回去。

中午回去翻箱倒柜,把之前的路由器拿出来,先换上勉强用着,旧路由器拆下来,准备寄回。

看着这一堆线真的头大,完全不想折腾啊。

顺丰下单,两点寄件,现在三点半了还没来取,哎?人呢。

路由器碎碎念

周日下午,在接近要吃晚饭然后回单位之前突然想起有件事情我还没做,我打算把家里那个闲置的水星MW300R路由器带回单位。因为科室的路由器,那个TP-LINK路由器这段时间不知道为什么老是会出现连上了,但是却上不了网。跟我的那个接近同款的路由器比起来,现在用的那个TP-LINK路由器新一点,但也新不到哪里去,毕竟那种路由器性能有限。我不太确定这种能连上WiFi,但是却连不上互联网是什么原因导致的,我感觉跟同时连上那个WiFi的人数多少有关系,毕竟那只是一个很旅行路由器,没想过有很多设备同时连接。通常情况下,我的小米civi 1S跟我的红米Note11 5G都会连那个路由器,尤其是在我做任务的时候,但我的电脑连的是网线,所以没有必要连,但我不确定别人的手机是不是连的那个路由器,因为单位虽然布局了全覆盖的WiFi,但实际上那个操蛋的华为信号相当糟糕,尤其是他们把2.4和5G合并了。他们的那些连接系统会导致突然就断线,突然又连上了,于是你如果处在移动之中,你就会出现那种连上连不上的状态,什么东西都很卡,找不出原因。所以我的任何一个无线设备都不会自动连接单位的WiFi,但我会把那个WiFi保存下来,当我在某个地方不动的时候,又或者是在某个地方我没私有WiFi的时候,我就会连那个。不让自动连接,如果我在移动之中,单位的WiFi断了就验证了我前面的那个说法,WiFi虽然是系统起来了,但就是一个鸡肋。

以前科室的那个TP-LINK小WiFi没什么问题,可能用的人不多,大概就只有我,只有我的两台手机。现在估计用的人多了,所以就说不准会有什么问题。TP-LINK相对于华为,我感觉稳定一些,但是我不保证当苹果手机和安卓手机一同连接那个WiFi的时候会出现什么奇怪的事情。可以肯定的是当我的手机发现能连WiFi,但无法连接网络的时候,一加的手机也会出现同样的状况。那个时候我们就只能把WiFi拔出来再重新插回去,等于是重启了一遍。有时候一遍还不行,可能还得试一遍,有时可能一个月下来都没有问题,但有时可能一天好几回。

WiFi用久了要重启,这个很正常,但关键是我感觉近几个月这种事情频繁发生,一天可能发生一两回。我实在受不了了,所以反正家里的那个水星闲置,不如拿回来替换一下。我已经查不出家里那个水星路由器是什么时候买的了,因为估计我是在亚马逊中国买的,现在亚马逊中国已经把用户的资料都清清理掉了。就购买时间来说,我那个水星的购买时间可能会早一点,但跟TP-LINK比起来,我的那个是300M的路由器,而那个随身的TP-LINK只有150M,这样的区别我感觉是天线的差异。家里为什么要搞个水星路由器,是因为以前家里也是用天天连的那种旅行路由器,但是家里的WiFi设备多了,显然这就不够用了。以前吃WiFi的就只有我自己的手机,所以我把路由器放在我的房间里就可以了,但后来我爸我妈都有了智能手机。我还想把那个无线网络覆盖到整个屋子,显然那就不够了。买了水星路由器没多久以后。我就升级了小米粒的路由器。主路由是我的小米mini。我把水星以有线网络的方式放在客厅,这样整个屋子都能覆盖到。虽然两个路由之间的距离很近,但我没办法用无线的方式,因为我家接收到的那些WiFi干扰实在太严重,随便搜出几十个WiFi信号,无论你设置什么样的信道都会被干扰。所以为了保证两个路由器都能正常运行,我只能用有线的方式把它们连接起来。如果我家不是差不多20年前做装修的,客厅跟卧室肯定都会预留了网口,但我家装修的那个年代,客厅跟卧室预留的只是同轴线的电视接口。所以我不得不把网线从我的房间拉到客厅,之所以这样,是因为当时装宽带的时候是从我房间的那个空调孔穿进来的。正常思路应该是在我家的门那里穿进来,但那样的话要绕过客厅再到我的房间,要绕很远,当时使用网线的就只有我的电脑,所以装网络的师傅就这么干。现在如果再拉网线,一定是走客厅,因为现在我的锐捷路由器就放在客厅,能覆盖我家的任何一个地方。

时代在变化,网络在变化,但其实算起来,好像我家使用路由器的历史还不算太长。

笔记本电脑升级无线网卡教程

自从我家升级 Wi-Fi 6 无线路由器更换宽带运营商后,我的炫龙(Shinelon) A41L旧笔记本电脑的无线网卡——AC3160 呈现“老牛拉大车”的窘境:连接 Wi-Fi 5G信道后,理论最高速度仅有433Mbps,实际下载速度最高只停留在1.25M/s,常有断网、断流现象……我计划花点小钱,升级旧笔记本的无线网卡。

在网上查阅过了不少技术文档,均推荐购买支持 Wi-Fi 7 或 Wi-Fi 6 的新款无线网卡:

1. 需要 Wi-Fi 7 可以购买 BE200 无线网卡;
2. 普通用户可以买 AX210 无线网卡(支持6G信道);
3. 预算吃紧的用户可以购买 AX200 无线网卡;
4. 较老型号的无线网卡,如9260AC、8265AC、8260AC、7265AC、7260AC、3160AC,则不推荐购买;
5. 尽可能不要购买 AX201 或 AX211 无线网卡,仅支持10代及更高版本 Intel CPU,旧款 Intel CPU 和 AMD CPU则不兼容这两种网卡。

本文暂不讨论主板板载的笔记本无线网卡,笔记本的无线网卡当前主要有两种接口:Mini PCI-E 和M.2接口(NGFF),前者为常见于老款笔记本电脑,尺寸约为30mmx27mm;后者为较新款电脑笔记本使用,尺寸约为22mm×30mm。如您不确定您电脑是哪个接口,可以拍下旧网卡的照片,咨询卖家。

Mini_PCI-E接口与M.2 NGFF接口笔记本无线网卡对比


Mini PCI-E / M.2接口(NGFF) 笔记本无线网卡购买链接:

M.2接口(NGFF):

BE200
AX210/AX200

Mini PCI-E:

AX210/AX200

我在某购物平台在以65元包邮的价格,购买了 AX200 单网卡,配送有螺丝和小螺丝刀。

AX200 无线网卡参数:
网卡芯片:FV-AX3000H
接口类型:Mini PCI-E
规格尺寸:半高/30mmx26.5mm
协议频段:802.11ax/ac/a/b/g/n
内置功能:蓝牙5.2 MU-MIMO
Mbps速率:2.4GHz-574M/5GHz-2400M
支持操作系统:Windows 10/11
本网卡为通用版本,但2016年之前生产的惠普牌、联想牌笔记本不适用(需要在 BIOS 刷无线网卡白名单)

Mini PCI-E接口笔记本无线网卡


如何安装替换笔记本无线网卡

首先,先下载对应型号,最新版本的 英特尔® Wi-Fi 官方驱动,避免更换新网卡后,操作系统无法识别新网卡导致驱动无法安装。

温馨提醒:安装前请根据您自己的笔记本无线网卡接口为准,以下内容与图示是以 Mini PCI-E 接口为例来展示!任何疑问请咨询您的无线网卡销售商。

其次,电脑关机断电,拔下笔记本电池,用螺丝刀拆开笔记本盖板,找到无线网卡的安装位置。无线网卡一般位于笔记本D面里,个别电脑是需拆卸笔记本键盘下,可搜索您笔记本电脑对应型号的拆机图文教程。

接着,轻轻取下 IPX 天线接头,用螺丝刀柠开固定的螺丝即可拔出网卡,将新网卡对准插槽插上,并把天线扣上,把新换上的网卡用螺丝固定好。

笔记本电脑无线网卡

通常情况下,无线网卡都有两个天线接口,分别是名为“MAIN”的主接头(接黑线)和名为“AUX”的备用接头(接白线),大家在安装的时候注意不要将天线接反。建议您拆下旧无线网卡之前先拍照,然后在安装新无线网卡时,依据照片接回原天线。

最后,安装完成,按照原拆卸的步骤装回,然后插上电源,开机后重新安装无线和蓝牙驱动即可。

无论下载游戏安装包或高清电影,还是日常浏览网页,速度明显更快,耗时更短,最大无线连接速率能达到1200Mbps,升级成功!

搭建 UniFi OS 网络控制器

Ubiquiti(优倍快)是美国一家以企业和家庭无线通讯产品为主的科技公司。其公司开发的 UniFi OS 是一款运行所有 UniFi 应用程序的操作系统,使用 UniFi Network 网络管理平台,可以配置 WiFi 网络、管理客户端…
❌