家庭网络配置升级

前期把家里网络整了一下,使用起来稍微有点不方便,一个是通过无线AP分配不通VLAN IP段是通过S5735S交换机MAC VLAN实现的,需要在交换机上面绑定不同MAC到不同VLAN,另一个DHCP服务也在交换机上,查看新设备的IP地址时需要登录交换机,另一个是IPv6地址是单独VLAN去分配,感觉整个网络结构不统一。

整体网络还是跟原来类似,所有内网流量都在内部,只有需要上网的数据才经过路由器。

硬件

电源

整个弱电箱里的电源全改成了使用Dell服务器电源12V进行供电,光猫、路由器、交换机、小主机使用电源待机供电,NAS主机及硬盘笼使用正常供电。当时买了两个服务器电源,一个是华为,另一个是DELL,因为DELL的Vsb最大能提供3A电流,现在弱电箱待机电源最大使用大约24W,NAS部分最大用电大概90W,最后用了DELL的495W,用于弱电箱已经足够。DELL电源供电板使用嘉立创开源社区的板子进行修改,6层板嘉立创免费打板,其中增加ESP8266读取电源的信息,其中输入功率和输出功率非常有用,在HomeAssistant中进行统计,积分后可以得到用电量,其他风扇转速、电流、电压等可以实时观察。ESPHome中ESP8266的部分代码

另外买了一个山特TG600的UPS,PVE主机USB连接UPS并当NUT Server,其他主机通过NUT Client进行连接,UPS供电后延迟几分钟后自动关机。

路由器

原来使用EdgeRouter ER-X SFP与猫棒一起使用,后来发现猫棒还是有点热,高温还是会影响稳定性,后来改成了光猫加RB750Gr3。改成RB750Gr3的最大一个原因是因为,RouterOS 7.18后终于支持IPv6 Fasttrack了,之前没有Fasttrack测试IPv6的时候最大只有几十M,而且CPU占用很高,所以一直用ER-X SFP(它的IPv6非常正常)。

而且RouterOS使用起来还是非常好用,便于网络管理。

交换机

主交换机还是原来的S5725S-L8T4S-QA2,放弱电箱里面,管理VLAN,管理网段DHCP服务,OSPF与路由器交换路由信息,同时ACL限制GUEST网段网速、禁IoT网段连接外网,尽量减小路由器工作量,其他网段使用DHCP Relay服务由路由器分发IP地址。

下联交换机Linksys SLM2008,连接客厅的上网设备XBOX、Apple TV 4K、电视机等,再下联另一个POE交换机连接AP。

AP

之前通过交换机的MAC VLAN对不同设备进行网段管理,比较麻烦。后来买了一个Unifi AC Pro,主要是可以通过软AC进行统一管理,用PVE的LXC就可以。在AC管理界面选择不同的国家地区可以使用不同的频谱,好像澳大利亚和加拿大的5G比较好用。

AP每个Radio可以有8个BSSID,网络分了几个主网络、访客网络、IoT内网、IoT外网,分别连接不同的VLAN,限制限网主要在交换机上实现。

NAS

原来用HP Gen8当NAS的,一个是功耗比较高,另一个是没有GPU进行视频转码,就把GEN8用来当冷备份机器了,入了一块All In Boom的板子,两个10G网卡加一张Dell H740P的RAID卡。加一个ESP8266智能开关,需要备份的时候,智能开关通电,然后通过iLO开机,系统是unRaid,直接把NAS系统的重要文件备份过来。

另外加了一台NAS,一块ITX的板子,外加i11500T的CPU,无法使用vGPU (SR-IOV) :(,还好PVE的容器可以通过Device Passthrough(/dev/dri/renderD128)使用GPU,这样Jellyfin、Immich容器都可以非常方便使用GPU,但虚拟机就不行了。另使用一张HP P420 1i1e阵列卡,外置口非常方便接硬盘笼,小黄鱼买了一个3D打印的笼子加背板,2块16T SAS加2块16T SATA盘。

物联网设备

买了一个Zigbee协调器通过USB连接小主机的Zigbee2MQTT,另一个Zigbee路由器连接AP的USB口扩展网路,然后各房间及阳台弱电箱放温度计记录温度。使用一块ESP32-H2板子,连接2个继电器,连接NAS主机的电源、重启pin,使用Zigbee网络。

摄像头、扫地机器人连接IoT外网。暂时摄像头没有NVR,需要远程连接摄像头的卡才能看视频。扫地机器人需要连接厂家网络才能远程控制。

其他ESP8266板子使用IoT内网,DELL电源监控、NAS硬盘笼入出口温度、智能开关、风扇调速板。当时把GEN8的风扇拆下来给硬盘笼使用,使用ESP8266板子进行调速,非常好用,在HomeAssistant中使用自动化控制,高于硬盘设定的阈值就提高转速,低于阀值后就降低转速,使用起来非常不错。就是GEN8的转速高于60%以后,噪音还是非常大的。。。

软件部分

PVE

使用新的NAS硬件后,就将系统改为PVE了,比esxi还是方便不少。

OMV

PVE直通阵列卡,通过hp ssacli可以对阵列卡进行管理,可以修改阵列卡模式为RAID还是HBA,现在使用的HBA模式,2块16T SAS块单独使用,2块16T SATA各分两个分区,其中两块硬盘的4T分区使用BTRFS的RAID1模式对重要数据进行管理,剩余分区使用mergerfs统一使用,比较好利用两块盘的空间。

另外一个重要功能是提供文件共享服务,主要是NFS方式。然后另一个是OneDrive数据同步。

ApplicationServer

PT下载,NGINX网关,SMB共享(给小孩看电视),Nextcloud,定时备份重要数据到云盘(brog备份后上传)。更新内网IPv6地址至域名,同时用FRPC暴露端口到VPS,这样域名IPv4地址解析到VPS,IPv6地址为内网服务器地址,这样同一域名就可以访问内网服务,非常方便。

HAOS

刚开始使用Home Assistant,所以使用最简单容易的方式,使用虚拟机,创建方法

Immich

创建方法,通过Device Passthrough将GPU共享给immich。

Jellyfin

创建方法,同时将GPU共享,jellyfin的源改为nju。

UniFi Network Application

创建方法

Armbian

买了个Panther X2的小主机,没有视频口,有千兆网口,无线网卡,一个USB2.0,一个TF卡,非常适合使用,放弱电箱。USB连接Zigbee协调器,网卡连交换机。应用全用Docker来跑。

HomeAssistant

用来当家庭智能控制中心,所有物联网设备都统计在里面。之前虚拟机HAOS用来学习,后来习惯后就没必须使用虚拟机了,只有当需要使用ESPHome进行编译等任务时才使用虚拟机,小主机性能用来编译还是差很多的。

Zigbee2MQTT

AdguardHome

所有内网设备的DNS查询都由此服务负责,路由器禁止其他内网主机53/853 tcp/udp访问,所有内网DNS地址由DHCP下发。但有一次某国内设备不使用DHCP下发的DNS地址,然后向外网查不通,就显示上网失败,无法使用,就在路由器修改,除小主机外其他所有内网主机向外网DNS查询时都重定向到小主机。

Cups

原来是使用Windows虚拟机开Wireguard,这样在外网的时候连接过去再打印。后来用Docker跑cups,镜像用的是olbat/cupsd,这样小主机跑Wireguard,可以通过 http://10.8.8.8:631/prints/print1 这样的方式增加打印机,在外网的情况下就能直接打印,省了不少事。但一直iOS的AirPrint还没有实现,有空再试试吧。

RouterOS

IPv6

1
2
3
4
5
/ipv6 dhcp-client
add add-default-route=yes interface=pppoe-out1 pool-prefix-length=64 pool-name=ISP-Pool request=prefix use-peer-dns=no

/ipv6 address
add address=::/64 advertise=yes auto-link-local=yes eui-64=yes from-pool=ISP-Pool interface=vlan200 no-dad=no

这样通过拨号可以获取IPv6地址及PD前辍,然后在Address里设置地址。从ISP获取的PD前辍是60,这里比较关键的是pool-prefix-length=64,告诉pool可以按这个前辍进行划分网络。主要参考有在 Mikrotik RouterOS 6.48.2 上配置 DHCPv6-PD(前缀代理)使用 Mikrotik RouterOS 和 Openwrt 在 ISP 获得的 IPv6 Prefix 上配置二级 PD

DNS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/ip firewall filter
add action=drop chain=forward comment="DNS Over TLS" dst-port=853 in-interface-list=LAN protocol=tcp src-address-list=!DNS-Allow-List
add action=drop chain=forward comment="DNS Over TLS" dst-port=853 in-interface-list=LAN protocol=udp src-address-list=!DNS-Allow-List

/ip firewall nat
add action=dst-nat chain=dstnat comment=RedirectDNS dst-port=53 in-interface-list=LAN protocol=udp src-address-list=!DNS-Allow-List to-addresses=192.168.1.59
add action=dst-nat chain=dstnat comment=RedirectDNS dst-port=53 in-interface-list=LAN protocol=tcp src-address-list=!DNS-Allow-List to-addresses=192.168.1.59
add action=masquerade chain=srcnat comment=RedirectDNS dst-address-list=DNS-Allow-List in-interface-list=LAN out-interface-list=LAN src-address=192.168.0.0/16

/system script
add dont-require-permissions=yes name=enable-dns-redirect owner=admin policy=read,write,policy source="/ip firewall nat enable [find comment=\"RedirectDNS\"];"
add dont-require-permissions=yes name=disable-dns-redirect owner=admin policy=read,write,policy source="/ip firewall nat disable [find comment=\"RedirectDNS\"];"

/tool netwatch
add comment="Monitor for conditional DNS" disabled=no down-script=disable-dns-redirect host=192.168.1.59 http-codes="" interval=10s test-script="" timeout=1s type=icmp up-script=enable-dns-redirect

禁用其他主机使用853 DOT进行DNS查询,53端口内网其他主机查询重定向,需要考虑Hairpin NAT1/2,还有一个办法是重定向到路由器,路由器开启DNS服务,这样就不需要masquerade这条规则了,另外用netwatch监测小主机是否在线(更好的办法是监测ADGuard管理口),否则禁用重定向,可以使用外网的DNS查询。

DHCP Relay

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/ip pool
add name=pool-vlan200 ranges=192.168.1.10-192.168.1.200
add name=pool-vlan210 ranges=192.168.21.10-192.168.21.200
add name=pool-vlan220 ranges=192.168.22.10-192.168.22.200
add name=pool-vlan230 ranges=192.168.23.10-192.168.23.200
add name=pool-vlan240 ranges=192.168.24.10-192.168.24.200

/ip dhcp-server network
add address=192.168.1.0/24 dns-server=192.168.1.59,223.5.5.5,8.8.8.8 domain=lan gateway=192.168.1.1
add address=192.168.21.0/24 dns-server=192.168.1.59,223.5.5.5,8.8.8.8 gateway=192.168.21.1
add address=192.168.22.0/24 dns-server=192.168.1.59,223.5.5.5,8.8.8.8 gateway=192.168.22.1
add address=192.168.23.0/24 dns-server=192.168.1.59,223.5.5.5,8.8.8.8 gateway=192.168.23.1
add address=192.168.24.0/24 dns-server=192.168.1.59,223.5.5.5,8.8.8.8 gateway=192.168.24.1

/ip dhcp-server
add address-pool=pool-vlan240 interface=bridge lease-time=1d name=vlan240-dhcp-server relay=192.168.24.1
add address-pool=pool-vlan200 interface=bridge lease-time=1d name=vlan200-dhcp-server relay=192.168.1.1
add address-pool=pool-vlan210 interface=bridge lease-time=1d name=vlan210-dhcp-server relay=192.168.21.1
add address-pool=pool-vlan220 interface=bridge lease-time=1d name=vlan220-dhcp-server relay=192.168.22.1
add address-pool=pool-vlan230 interface=bridge lease-time=1d name=vlan230-dhcp-server relay=192.168.23.1

在交换机三层接口上设置好DHCP Relay,然后在路由器上设置好DHCP服务,其中最主要的一点是relay字段设置,根据giaddr来选择不同的地址段,giaddr是三层接口的IP地址,之前一直没成功,后来通过Debug Logging查看问题所在。可以通过/system logging add disabled=yes topics=dhcp设置logging,可以看dhcp的日志。

MQTT

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/iot mqtt brokers
add address=192.168.1.59 name=HA username=admin

/system script
add dont-require-permissions=yes name=ha-router-monitor owner=admin policy=read,write,policy,test source=":global haBroker \"HA\"\
\n:global haTopicPrefix \"homeassistant\"\
\n\
\n:global deviceName \"RB750Gr3 Router\"\
\n:global uniqueId \"rb750gr3_router_1\"\
\n:global manufacturer \"MikroTik\"\
\n:global model \"RB750Gr3\"\
\n:global swVersion [/system resource get version]\
\n:global interfaceName \"pppoe-out1\"\
\n:global stateTopic (\$uniqueId . \"/state\")\
\n\
\n:global deviceConfig \"{\\\
\n\\\"identifiers\\\": [\\\"\$uniqueId\\\"],\\\
\n\\\"name\\\": \\\"\$deviceName\\\",\\\
\n\\\"manufacturer\\\": \\\"\$manufacturer\\\",\\\
\n\\\"model\\\": \\\"\$model\\\",\\\
\n\\\"sw_version\\\": \\\"\$swVersion\\\"\\\
\n}\"\
\n\
\n:global cpuDiscoveryTopic (\$haTopicPrefix . \"/sensor/\" . \$uniqueId . \"/cpu_usage/config\")\
\n:global cpuDiscoveryPayload \"{\\\
\n\\\"name\\\": \\\"CPU Usage\\\",\\\
\n\\\"unique_id\\\": \\\"\$uniqueId\\_cpu_usage\\\",\\\
\n\\\"state_topic\\\": \\\"\$stateTopic\\\",\\\
\n\\\"unit_of_measurement\\\": \\\"%\\\",\\\
\n\\\"value_template\\\": \\\"{{ value_json.cpu }}\\\",\\\
\n\\\"icon\\\": \\\"mdi:cpu-32-bit\\\",\\\
\n\\\"state_class\\\": \\\"measurement\\\",\\\
\n\\\"device\\\": \$deviceConfig\\\
\n}\"\
\n\
\n:global memDiscoveryTopic (\$haTopicPrefix . \"/sensor/\" . \$uniqueId . \"/mem_usage/config\")\
\n:global memDiscoveryPayload \"{\\\
\n\\\"name\\\": \\\"Memory Usage\\\",\\\
\n\\\"unique_id\\\": \\\"\$uniqueId\\_mem_usage\\\",\\\
\n\\\"state_topic\\\": \\\"\$stateTopic\\\",\\\
\n\\\"unit_of_measurement\\\": \\\"%\\\",\\\
\n\\\"value_template\\\": \\\"{{ value_json.memory_percent}}\\\",\\\
\n\\\"icon\\\": \\\"mdi:memory\\\",\\\
\n\\\"state_class\\\": \\\"measurement\\\",\\\
\n\\\"device\\\": \$deviceConfig\\\
\n}\"\
\n\
\n:global uptimeDiscoveryTopic (\$haTopicPrefix . \"/sensor/\" . \$uniqueId . \"/uptime/config\")\
\n:global uptimeDiscoveryPayload \"{\\\
\n\\\"name\\\": \\\"Router Uptime\\\",\\\
\n\\\"unique_id\\\": \\\"\$uniqueId\\_uptime\\\",\\\
\n\\\"state_topic\\\": \\\"\$stateTopic\\\",\\\
\n\\\"unit_of_measurement\\\": \\\"s\\\",\\\
\n\\\"value_template\\\": \\\"{{ value_json.uptime_sec }}\\\",\\\
\n\\\"device_class\\\": \\\"duration\\\", \\\
\n\\\"icon\\\": \\\"mdi:progress-clock\\\",\\\
\n\\\"device\\\": \$deviceConfig\\\
\n}\"\
\n\
\n:global rxDiscoveryTopic (\$haTopicPrefix . \"/sensor/\" . \$uniqueId . \"/pppoe_rx_bps/config\")\
\n:global rxDiscoveryPayload \"{\\\
\n\\\"name\\\": \\\"pppoe Download Speed\\\",\\\
\n\\\"unique_id\\\": \\\"\$uniqueId\\_pppoe_rx_bps\\\",\\\
\n\\\"state_topic\\\": \\\"\$stateTopic\\\",\\\
\n\\\"unit_of_measurement\\\": \\\"bit/s\\\",\\\
\n\\\"value_template\\\": \\\"{{ value_json.rx_bps }}\\\",\\\
\n\\\"device_class\\\": \\\"data_rate\\\",\\\
\n\\\"icon\\\": \\\"mdi:download-network-outline\\\",\\\
\n\\\"state_class\\\": \\\"measurement\\\",\\\
\n\\\"device\\\": \$deviceConfig\\\
\n}\"\
\n\
\n:global txDiscoveryTopic (\$haTopicPrefix . \"/sensor/\" . \$uniqueId . \"/pppoe_tx_bps/config\")\
\n:global txDiscoveryPayload \"{\\\
\n\\\"name\\\": \\\"pppoe Upload Speed\\\",\\\
\n\\\"unique_id\\\": \\\"\$uniqueId\\_pppoe_tx_bps\\\",\\\
\n\\\"state_topic\\\": \\\"\$stateTopic\\\",\\\
\n\\\"unit_of_measurement\\\": \\\"bit/s\\\",\\\
\n\\\"value_template\\\": \\\"{{ value_json.tx_bps }}\\\",\\\
\n\\\"device_class\\\": \\\"data_rate\\\",\\\
\n\\\"icon\\\": \\\"mdi:upload-network-outline\\\",\\\
\n\\\"state_class\\\": \\\"measurement\\\",\\\
\n\\\"device\\\": \$deviceConfig\\\
\n}\"\
\n\
\n:global tempDiscoveryTopic (\$haTopicPrefix . \"/sensor/\" . \$uniqueId . \"/cpu_temp/config\")\
\n:global tempDiscoveryPayload \"{\\\
\n\\\"name\\\": \\\"CPU Temperature\\\",\\\
\n\\\"unique_id\\\": \\\"\$uniqueId\\_cpu_temp\\\",\\\
\n\\\"state_topic\\\": \\\"\$stateTopic\\\",\\\
\n\\\"unit_of_measurement\\\": \\\"\C2\B0C\\\",\\\
\n\\\"value_template\\\": \\\"{{ value_json.cpu_temp }}\\\",\\\
\n\\\"device_class\\\": \\\"temperature\\\",\\\
\n\\\"state_class\\\": \\\"measurement\\\",\\\
\n\\\"device\\\": \$deviceConfig\\\
\n}\"\
\n\
\n:do {\
\n /iot mqtt publish topic=\$cpuDiscoveryTopic message=\$cpuDiscoveryPayload retain=yes broker=\$haBroker\
\n /iot mqtt publish topic=\$tempDiscoveryTopic message=\$tempDiscoveryPayload retain=yes broker=\$haBroker\
\n /iot mqtt publish topic=\$memDiscoveryTopic message=\$memDiscoveryPayload retain=yes broker=\$haBroker\
\n /iot mqtt publish topic=\$uptimeDiscoveryTopic message=\$uptimeDiscoveryPayload retain=yes broker=\$haBroker\
\n /iot mqtt publish topic=\$rxDiscoveryTopic message=\$rxDiscoveryPayload retain=yes broker=\$haBroker\
\n /iot mqtt publish topic=\$txDiscoveryTopic message=\$txDiscoveryPayload retain=yes broker=\$haBroker\
\n\
\n :local resourceData [/system resource get]\
\n :local cpuLoad [/system resource get cpu-load]\
\n :local totalMem [/system resource get total-memory]\
\n :local freeMem [/system resource get free-memory]\
\n :local usedMem ([:tonum \$totalMem] - [:tonum \$freeMem])\
\n :local memPercent (([:tonum \$usedMem] * 100 / [:tonum \$totalMem]) )\
\n \
\n :local uptimeSecs [:tonum [/system resource get uptime]]\
\n\
\n :local interfaceMonitor [/interface monitor-traffic \$interfaceName once as-value]\
\n :local rxBps (\$interfaceMonitor->\"rx-bits-per-second\")\
\n :local txBps (\$interfaceMonitor->\"tx-bits-per-second\")\
\n\
\n :local cpuTemp 0\
\n :foreach v in=[/system health print as-value] do={:if ((\$v->\"name\")=\"temperature\") do={:set cpuTemp (\$v->\"value\")}}\
\n\
\n :local statePayload \"{\\\
\n \\\"cpu\\\": \$cpuLoad,\\\
\n \\\"cpu_temp\\\": \$cpuTemp,\\\
\n \\\"memory_percent\\\": \$memPercent,\\\
\n \\\"uptime_sec\\\": \$uptimeSecs,\\\
\n \\\"rx_bps\\\": \$rxBps,\\\
\n \\\"tx_bps\\\": \$txBps\\\
\n }\"\
\n\
\n /iot mqtt publish topic=\$stateTopic message=\$statePayload broker=\$haBroker\
\n} on-error={\
\n :log error \"MQTT Monitor Error: Failed to publish MQTT message or get system data.\"\
\n}"


/system scheduler
add interval=10s name=ha-monitor-run on-event="/system script run ha-router-monitor" policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon start-date=2025-10-31 start-time=00:00:00

这样就可以把路由器的CPU、内存、流量等信息发送到MQTT,这样在HomeAssistant中可以看到路由器信息了。