做了一个用来生成中国大陆路由的容器

背景

因为在研究BGP,也有中国大陆与其他地区进行路由选路的需求,所以在琢磨着要不在互联网上整一个bgp speaker,然后这个bgp speaker向所有连过来的对端通告全部的中国大陆路由,这样路由器就不需要配置大量的静态路由,减少配置量,而且更新的话也能够应用到所有出口路由器。

实时全球路由表?

某天,根据这篇文章试了一下,确实可行,但是吧……这效果强虽强,但是资源消耗也有点离谱。

这个容器实时从RIPE读取全球路由表的变更,一整天下来平均带宽有1.78Mbit/s,相当于一天就跑了18G的流量(单向)。要是放在vps上的话,一个月估计的流量500G。

我是放在家里出口的RouterOS上以容器的方式跑的,算上容器本身和加的路由表,需要吃掉大约400M的内存。我就想想,有没有一些更加轻量级的方案呢?

记得之前是见到过一个chnroute的东西,可以生成中国的路由表。然后灵机一动,要不我也用脚本写个差不多的玩意吧,看起来也不是很难。bgp软件话似乎可以用bird,可以直接重载,也不会闪断。

脑袋一拍,开干,结果就弄了个这样的玩意出来。

设计思路

github上的README也已经写了设计思路的,非常简单,以bird软件作为核心然后主要的配置有3个:

一个是手动写的需要配置的静态路由,比如说苹果的7.0.0.0/8,实测如果走VPN的话会遇到各种各样奇奇怪怪的问题,可能和我用的是自建的DNS递归服务器,然后我又用国区账号,部分苹果业务由云上贵州来负责的原因。反正就是会有这样的需求,先预留着。

一个是通过脚本生成中国的路由表,从网上搜一搜就找到类似的了,核心是从APNIC下载分发的资源表,过滤出属于中国的部分,然后通过文本处理格式化成bird能够读取的配置文件。然后定期重新加载就行了。

最后一个是协议的配置,我现在选择的是用bgp来输出,有其他需要的话可以考虑ospf或者isis之类的,不过bgp作为各ISP之间互联用的协议,又是我的学习目标,果断选择BGP来输出了。这块的配置我放在了custom.conf,有需要可以灵活修改。

最后,为了方便部署,选择了容器化,用docker打个包,就可以到处用了。现在是托管在dockerhub,未来可能放在其他地方。

如何使用

这里强烈推荐一下claw cloud的白嫖,只要有一个注册时间超过180天的github账号就可以使用他们的免费等级的服务,可以有5刀的credit,不绑信用卡也可以用。他们目前有新加坡,日本,美西岸,美东岸,德国几个区域。每个区域最高能放4个vcpu,8G内存,和10G的磁盘。(当然,如果拉满的话,价格是绝对会超5刀每月的),限制了每个月10G的流量。也限制了每个机器只能有1个端口(tcp或者udp)。

限制是挺多的,特别是流量,不过对于我这个拍脑袋整出来的东西,已经可以算得上是奢华了。从APNIC下载delegation的文件大概3.8M,每天一次,然后算上bgp的连接,一天估计跑不了10M。

于是,噔噔蹬蹬。

膨胀了啊,在k8s上直接replica 2!然而内存使用量还是太少了,都识别不出来。

下面贴一下过程:

先去注册,然后切换到需要部署的区域,然后点击App Launchpad。

在右上角点击create App进入部署的界面。

Application Name随便填,image选择public,然后填入ferrets/cn_route-bird。没错我已经预编译了一份并且上传到了dockerhub。

Usage里面CPU和RAM都拉到最低(为啥RAM不能选16M?)。Replica建议大于1,反正价格你也看到了,每天0.02刀,30天就是……0.6刀(手动狗头)。

Network里面Container Port写179,这是bgp的默认端口。打开互联网访问,完了之后会分配一个。

Advanced Configuration里面有一个需要填的,就是Configmaps。点击Add。

File Name写/etc/bird.d/custom.conf

File content就复制粘贴github上的内容就行,填完了之后confirm。

最后右上角Deploy Application就行。过一阵子,你就有了能够直接用bgp订阅的,能够自动更新的中国大陆路由表了。

考虑到高可用,和剩余的credit……找另外一个区域重复上述过程,避免一个区炸了之后就直接丢了路由。

配置订阅

下一步就是用出口路由器去连了这个bird。首先去App Launchpad,找到分配了啥网址和端口

然后,手动解析一下这个域名。(或者你的路由器可以直接填域名而不是ip地址来建立bgp会话,那就填域名)

从里面挑几个出来建立bgp会话,参考的mikrotik的配置脚本如下:

记得先写到中国大陆的静态路由。根据配置,bgp吐出来的ipv4的路由下一跳是114.114.114.114,ipv6的路由下一跳是240c::6666。必须先写静态路由以保证递归之后,从bgp会话收到的路由是从你想要的出口出口,避免路由震荡。或者你可以先在connection里面写上input.filter,先把路由全部过滤。搞好之后再取消过滤,应用到实际环境里面。

/ip route
add dst=114.114.114.114 gateway=wan
/ipv6 route
add dst=240c::6666 gateway=wan
/routing bgp template
add address-families=ip,ipv6 as=65000 cluster-id=192.168.0.0 disabled=no multihop=yes name=feed output.filter-chain=block .no-client-to-client-reflection=yes routing-table=main
/routing bgp connection
add template=feed connect=yes local.role=ibgp name=cn_route_feed-1 remote.address=[刚才解析出来的ip1] .as=65000 .port=[分配的端口]
add template=feed connect=yes local.role=ibgp name=cn_route_feed-1 remote.address=[刚才解析出来的ip2] .as=65000 .port=[分配的端口]
add template=feed connect=yes local.role=ibgp name=cn_route_feed-1 remote.address=[刚才解析出来的ip3] .as=65000 .port=[分配的端口]
add template=feed connect=yes local.role=ibgp name=cn_route_feed-1 remote.address=[刚才解析出来的ip4] .as=65000 .port=[分配的端口]

然后……为啥RouterOS不能去重路由……明明我都在bird上配置了cluster id。囧

如此一来,就有了相对稳定的,免费的,可以自动更新的,资源消耗相对低的中国路由表订阅了。

虽然订阅了8份之后,RouterOS里面的路由表数量高达85k+,都比实时全球路由表的数量(45k+)高一倍了。但……但这有高贵的ipv6啊!

MacOS上iscsi的替代方案

有时候,MacOS想要扩容,而且不是单纯的存放文件,而是要存放应用软件之类的,这时候,samba就不好使了,文件读写权限什么的,非常难搞。所以就需要考虑一下从基于文件的网络共享切换到基于块的网络共享了。

但是众所周知,MacOS不像windows那样,内置iscsi-initiator,而支持iscsi-initiator的软件,我在网上搜索一番之后,并没有找到什么开源(可以白嫖)的方案。唯一有的一两个看起来也是安装使用非常麻烦的那种,其他的商用方案,价格都比较离谱。唯一价格比较亲民点的DAEMON tools(没错!就是很久之前装机必备的虚拟光驱!),价格不贵,如果单纯只要iscsi-initiator一个功能的话,最低可以只买1个高级版,价格只要2.99刀,价格完全可以接受。不过网上有评论说DAEMON-tools的iscsi功能性能存在问题,千兆以太网只能跑到50MB/s左右,这就有点难受了。

在继续溜达的时候,偶尔看到一篇帖子,里面提到一种解决方案,就是不考虑iscsi,而是使用一种MacOS特有的磁盘格式——稀疏捆绑磁盘映像。

这种稀疏捆绑磁盘映像,就是Time Machine目前在使用的磁盘格式,可以存放在任意MacOS支持的文件系统上,这就包括了cifs(也就是samba啦)。所以,四舍五入一下,也算是另类的块共享了。

使用方法很简单,先从“启动台-其他”文件夹里面启动“磁盘工具”,然后新建一个空白映像。

然后,就是设置磁盘映像的具体属性:

  • 格式选择“稀疏捆绑磁盘映像”
  • 存储为这里是磁盘映像在文件系统上的名字,后续默认是.sparsebundle
  • 大小是这个磁盘映像的大小,稀疏捆绑磁盘映像实际上是一个文件夹,里面是一堆小的文件块,是按实际使用增长的,不是分配了就立马占用的。
  • 格式建议选择MacOS扩展(区分大小写,日志式)
  • 是否需要加密就看你自己需要
  • 分区随便选择
  • 最后位置选择在你的smb共享上

点击存储确认。

在访达可以看到这个磁盘映像的属性。

双击可以在磁盘工具打开。可以在访达看到已经挂载,在磁盘工具也能看到这个磁盘映像的属性。

如果需要调整大小,可以先卸载磁盘映像,然后在磁盘工具的菜单“映像-调整大小”,然后选择对应的磁盘映像,再输入变更后的大小,就可以了。

修复TimeMachine备份错误

今天在timemachine备份过程中,因为某些意外中断了,导致备份失败,无法继续备份,只能删掉备份链接然后重新添加。但是在重新添加的过程中,发现怎么添加都添加不上,历经一番辛苦,终于修复,这里记录一下遇到的几种故障情况与修复方法。

备份损坏

可以先尝试在“访达”程序里面找到对应的备份文件夹,是以.sparsebundle结尾的,可以用默认的DiskimageMounter打开,稍等个20秒,再打开“磁盘工具”就可以在磁盘工具中看到这个备份的镜像,然后右键选择这个备份的镜像,选择“急救”,可以进行尝试校验并修复这些备份文件。

如果修复失败……我没有继续研究修复方法,因为我是备份到TrueNAS上的,遇到这样的问题我就直接回滚了快照,回滚到了备份前的状态。(快照救我!)

对于没有快照回滚或者其他原因没法修复的童鞋,那就只能删掉旧备份了。

OSStatus 错误80

这个错误卡了我足足一天时间,翻来复去都没找到什么解决方法。有少量网页提到过,需要在keychain.app里面删掉对应的密码就能修复了,但是我用的是MacOS 15 sequioa,直接在启动台里面搜索是找不到keychain.app的,我以为已经没有这个东西了。

但是我灵机一动,搜索了一下,MacOS 15依旧是有这个app的,只是没有被显示出来。

你需要打开访达,然后从菜单栏里面选择“前往”-“前往文件夹”,或者使用快捷键shift+command+g,然后手动输入路径“/System/Library/CoreServices/Applications/”

然后你就能看到这个钥匙串访问了

打开会提示建议你不要使用钥匙串访问,试试他们新的密码app吧,忽略,就要打开钥匙串访问,输入密码,进去了。

搜索“.spar“,会列出timemachine备份的加密密码,手动删掉。OSstatus 错误 80就没啦~

磁盘镜像被占用

这个最简单,命令行登陆到TrueNAS,进入对应的.sparsebundle文件夹,删掉里面的lock文件就可以了。

于是timemachine备份就恢复正常啦~

在TrueNAS中给虚拟机直通磁盘

参考:https://www.truenas.com/community/threads/using-cli-to-passthrough-hdd-to-a-vm.98549/post-679949

刚给NAS加了几块硬盘,在导数据的时候不知道为啥,重启了好几次之后,旧磁盘的整个池都没法导入了,一导入就整个机器卡死重启,重启之后卡在ix-etc服务,没法进入系统。

不得已,只能在TrueNAS里面开个虚拟机,把磁盘直通给虚拟机,重新导入池然后scrub一次试试捞数据。但是TrueNAS的虚拟机功能,只能说有,和好用是一点边都沾不上。

幸好,在truenas的论坛上有人po出了操作方法,这里做个翻译和记录。

首先,需要使用root登录到Truenas。

然后,使用这个命令来查找所有磁盘:

find /dev/disk/by-id/ -type l|xargs -I{} ls -l {}|grep -v -E '[0-9]$' |sort -k11|cut -d' ' -f9,10,11,12

以下是输出结果的例子

root@datacenter[~]# find /dev/disk/by-id/ -type l|xargs -I{} ls -l {}|grep -v -E '[0-9]$' |sort -k11|cut -d' ' -f9,10,11,12 | sort
/dev/disk/by-id/ata-KINGSTON_SA400M8120G_50026B7685357785 -> ../../sdn
/dev/disk/by-id/ata-ST16000NM001G-2KK103_ZL2KB41G -> ../../sdb
/dev/disk/by-id/ata-ST16000NM001G-2KK103_ZL2KG36H -> ../../sdd
/dev/disk/by-id/ata-ST16000NM001G-2KK103_ZL2KG8BD -> ../../sda
/dev/disk/by-id/ata-ST16000NM001G-2KK103_ZL2KGSRT -> ../../sdc
/dev/disk/by-id/ata-Samsung_SSD_850_EVO_500GB_S21JNSAG158509B -> ../../sdj
/dev/disk/by-id/ata-Samsung_SSD_850_EVO_500GB_S2RBNX0H937583L -> ../../sdk
/dev/disk/by-id/ata-WDC_WD10JFCX-68N6GN0_WD-WX11A15ET12E -> ../../sdm
/dev/disk/by-id/ata-WDC_WD10JFCX-68N6GN0_WD-WX11A15ETRZ9 -> ../../sdl
/dev/disk/by-id/ata-WDC_WD40EFRX-68N32N0_WD-WCC7K1DFDE54 -> ../../sdi
/dev/disk/by-id/ata-WDC_WD40EFRX-68WT0N0_WD-WCC4E0135118 -> ../../sde
/dev/disk/by-id/ata-WDC_WD40EFRX-68WT0N0_WD-WCC4E0185240 -> ../../sdh
/dev/disk/by-id/ata-WDC_WD40EFRX-68WT0N0_WD-WCC4E0243702 -> ../../sdg
/dev/disk/by-id/ata-WDC_WD40EFRX-68WT0N0_WD-WCC4ENSDRE27 -> ../../sdf
/dev/disk/by-id/wwn-0x5000c500dbd815d2 -> ../../sdb
/dev/disk/by-id/wwn-0x5000c500dbe1b5b7 -> ../../sdd
/dev/disk/by-id/wwn-0x5000c500dbe40981 -> ../../sdc
/dev/disk/by-id/wwn-0x5000c500dbe46e89 -> ../../sda
/dev/disk/by-id/wwn-0x50014ee209112b98 -> ../../sde
/dev/disk/by-id/wwn-0x50014ee20b01a0fc -> ../../sdf
/dev/disk/by-id/wwn-0x50014ee210a8b4bc -> ../../sdi
/dev/disk/by-id/wwn-0x50014ee25e74959c -> ../../sdg
/dev/disk/by-id/wwn-0x50014ee2b3bbed86 -> ../../sdh
/dev/disk/by-id/wwn-0x50014ee6b01bee55 -> ../../sdl
/dev/disk/by-id/wwn-0x50014ee6b01bfbaa -> ../../sdm
/dev/disk/by-id/wwn-0x5002538d414b3774 -> ../../sdk
/dev/disk/by-id/wwn-0x5002538da015f254 -> ../../sdj
/dev/disk/by-id/wwn-0x50026b7685357785 -> ../../sdn

其中/dev/disk/by-id/wwn-0x5002538da015f254就是一个磁盘目标(sdj)。

然后,创建一个alias命令,方便virsh连接到TrueNAS的qemu。

alias virsh='virsh -c "qemu+unix:///system?socket=/run/truenas_libvirt/libvirt-sock" $1'

然后用virsh list --all来列出所有vm,注意TrueNAS的在命令行里面的虚拟机名称会有一个编号在前头。

root@datacenter[~]# virsh list --all
 Id   Name      State
-------------------------
 7    1_mover   running

知道虚拟机名称之后,就可以将设备直通给虚拟机了,命令如下

virsh attach-disk <VM Name> <Disk ID> <Target Name>

举个例子

virsh attach-disk 1_mover /dev/disk/by-id/wwn-0x5002538da015f254 vdj

然后就能在虚拟机里面看到这个直通的磁盘了。

要注意的是,这个直通是临时的,关闭虚拟机会失去这个直通,需要重新配置。重启则不需要重新配置。

安利个新玩意-开源的WAF

简介

WAF-是Web Application Firewall的简称,工作在第7层。之前的iptables/nftables都是基于4层的,通过ip和端口来拦截未授权的访问,但是,不可能拦截http(s)所用的端口的是吧?放通了http(s)的访问之后,有坏东西通过http协议对你的系统搞东搞西,那iptables就无能为力了。但是,WAF,就能用来保护你的网站,不让这些坏东西来搞你。让你的系统更安全。

介绍

雷池WAF

上面就是这东西的官网,名字叫做雷池,口号是“不让黑客越雷池一步”,号称还能防0day漏洞,听起来还是挺厉害的,但实际上……完全防护所有的攻击是不可能的。他们自己报出来的测试结果里面,都没法100%拦截所有攻击的流量,误报的数据也不是0,只能说套个带80%闪避的甲,比裸奔高到不知道哪里去了。

部署效果

这个Blog是加了Cloudflare的,可以拦截很多奇奇怪怪的ip直连我服务器的80/443端口,之前也觉得说上了流量过滤,时不时也看到Cloudflare报告说拦截了多少多少攻击,还是觉得挺安全的。

于是我上了这玩意试试之后发现,Cloudflare漏掉的恶意访问还真不少啊。

雷池拦截记录
详细拦截日志

部署方式

官方网站提供了一个一键脚本,可以快速部署,系统是基于docker的,所以需要docker和docker compose。这里比较注意的是,软件需要CPU支持ssse3 指令集,如果在Proxmox上跑的话,记得需要调整CPU的类别,默认的kvm64是不支持这个指令集的,需要改成x86_64v2或者更高版本。

命令行安装完毕之后。在命令行会输出随机生成的密码。默认账号是admin。

使用

添加证书

首先,需要添加一个证书,添加方法有3种,分别是

  • 上传文件
  • 复制粘贴证书/密钥文本
  • 通过ACME(http)自动签署证书

如果是80端口没有被封的话,可以走自动签署。如果80端口不幸被封(比如国内),就只能走前两种方法了。目前雷池暂时没有更新证书的API,所以只能手动操作。

添加后端服务器

首先,添加一个默认的主机,用来匹配任意的SNI,证书啥的用默认的自签署的就行。然后再创建所需的站点,写上对应的host name,如此一来,只有访问正确的域名,才会访问到对应的网站。

需要配置的内容也不多,只需要写端口,算证书,和填一下后端的地址就行。

这样,配置就通了。

其他设置

剩下的就是代理设置之类的, 全部勾选上,源ip因为我套了一层cloudflare,就只读一层。

剩下的防护配置,保持默认就行,有兴趣可以继续探索一下,反正目前可以修改的配置也不多。

DN42全攻略-part1-注册gitea

前言

最近在网上看到个很神奇的东西,叫做DN42,这是个实验性的网络,各个玩家通过VPN隧道在世界各地之间的节点建立链接,并通过BGP协议将各个玩家的网络连接到一起,模拟真实的互联网的环境。然后各个玩家可以在这个网络里面部署自己的服务,测试各种技术,实施各种一般情况下需要不少花费(比如说注册ASN,申请IP地址块,和其他人进行peer等)才能达成的操作。

这一下子就激起了我的兴趣,于是仔细阅读了官网的说明,并且根据指引,完成了注册,并peer了不少节点,完成了DNS服务的搭建,姑且算是完成了入门。于是在这里写以下文章,供后人参考。

官网的wiki关于开始的页面里面提供了相当详细的描述,这里就简单的用中文描述一下申请的流程,还有一些我踩过的坑。

准备材料

首先,你得有一些最基础的知识和材料,比如说你得知道什么是VPN、BGP等,还有需要支撑你参与到这个游戏里面的最基本的工具——一个能运行BGP的机器,你可以选择的机器有很多,从普通的x86电脑到ARM的单板机到一些家用的路由器(目前据我所知就只有Openwrt和RouterOS满足条件),都可以。主要能7*24的运行即可。

至于说其他企业级路由器就有点不幸了,因为现在网里面大家基本上都是用wireguard作为VPN隧道,而我所知的企业级路由器,绝大部分都不支持这个功能,所以强烈不推荐用企业级路由器和其他人进行互联,当然,用来做你自己的网络的核心是没问题的。

还有最后一个的话就是互联网链接,这个不多叙述,最好是有公网的ipv4和ipv6地址。

材料都准备好之后,就可以着手开搞了。

订阅消息

参考链接:https://dn42.dev/contact#contact_mailing-list

订阅的方法很简单,往dn42+subscribe /at/ groups.io发一封邮件就行,然后会有一封自动回复的邮件,让你确认是否要订阅。这时候再随便回复点什么就可以完成订阅了。

完成订阅之后就可以进行下一步,也就是正式开始申请资源了。

注册git.dn42.dev

dn42的整个registry信息都是gitea来存储的,所有人都可以pull来获取全部内容,如果想要申请点什么资源,添加点什么记录,方法就是通过PR(pull-request)来向管理员申请。在管理员审核之后,会将你的申请合并进去,就可以让大家都查看到你的信息了。一般来说,管理员每天做一次审核。

大神burble做了一个在线的浏览工具可以查看现在registry里面的内容

registry里面的结构是这样的,不同的文件夹里面以纯文本的方式记录着不同的内容。

.
├── data
│ ├── as-block
│ ├── as-set
│ ├── aut-num
│ ├── dns
│ ├── inet6num
│ ├── inetnum
│ ├── key-cert
│ ├── mntner
│ ├── organisation
│ ├── person
│ ├── registry
│ ├── role
│ ├── route
│ ├── route-set
│ ├── route6
│ ├── schema
│ └── tinc-key
└── utils
└── schema-check

了解到大概的流程之后,就可以着手开干了。

首先,打开https://git.dn42.dev/dn42/registry,会提示登录,这时候注册一个账号,注册完成之后重新打开链接,就能看到默认的readme了。

这时候先去创建一个PGPkey,因为你必须对你提交的内容进行一个签名,于此同时,PGPkey也可以用来证明你的身份,所以要好好保存,不要泄露。

我使用的密钥管理工具是kleopatra,如果你之前没有PGPkey的话,可以用这个工具创建一个新的PGP密钥对。注意,创建的时候需要保证密钥对里面的邮箱地址是你用来注册git.dn42.dev的那个。

在创建完密钥对之后,右键选择对应的key,选择导出,可以导出对应的公钥。

导出来的文件可以直接用文本编辑器打开,就是公钥的内容了。

然后全选,复制。再打开刚完成注册的gitea,进去个人设置,找到SSH/GPG密钥,然后将复制出来的内容填到内容框里面,然后点击“增加密钥”。

保存好之后,再点击增加的密钥旁边的“验证”

系统会生成一段随机的文字,复制出来,粘贴到klepatra的记事本标签页。然后点击“签名记事本”,会找你输入生成GPG密钥对的时候的密码。

输入正确之后,会对记事本的内容进行签名。

再将记事本里面的全部内容复制出来,粘贴到网页上的GPG增强签名文本框里面,点击验证。即可完成验证,之后你就能用这个GPG密钥来对git push进行签名了。

又或者直接复制页面上那段,直接在终端里面运行。会得到一样的签名信息。

echo "911ebb86da4234f38cb65f3d670798422a03205a5cbaba25fb8e6e82da5ab468" | gpg -a --default-key A67CBCEB66739B68 --detach-sig

到此就完成了前期的准备工作,下一步就是fork整个registry,修改本地内容,然后重新push并请求PR,这个下一篇再说。

Windows简易TCP端口转发

由于某些特殊的原因,我临时需要在一个windows的机器上做一个tcp转发。网上各种奇奇怪怪的软件要下载下来还需要额外担心一下是不是有病毒什么的。不过经过一番搜索,我找到windows自带端口转发的功能,是netsh命令的一部分。

微软有一个相关的说明文档,里面有具体的说明。根据网上搜索得到的结果来看,是从windows vista的年代开始内置,不需要额外的软件。

使用方法也很简单:

#新建一个转发,监听到192.168.1.111:4422,所有进来的流量,转发到192.168.0.33:80
netsh interface portproxy add v4tov4 listenport=4422 listenaddress=192.168.1.111 connectport=80 connectaddress=192.168.0.33
#列出当前所有转发
netsh interface portproxy show all
侦听 ipv4:                 连接到 ipv4:

地址            端口        地址            端口
--------------- ----------  --------------- ----------
192.168.1.111   4422        192.168.0.33    80
#删除转发
netsh interface portproxy delete v4tov4 listenport=4422 listenaddress=192.168.1.111

网上还有控制这个端口转发的图形界面软件,可以免除手动输入命令的功夫。

另外,这个转发收到防火墙的保护,意味着你打开端口需要手动调整防火墙。所以流程就是以下的二选一

  • 增加转发->打开防火墙->重启电脑->生效;
  • 打开防火墙->增加转发->生效;

所以建议先操作防火墙。

在Linux中为主机添加一个地址段

一般情况下,一台主机只会有一个,或者几个ip地址,这种情况下,配置ip地址的方法有非常多文章可以搜索到,这里不加赘述。但是如果我想给主机配置很多ip地址,类如ipv6配置一个/64的地址块呢,这时候一个一个的在配置文件里面写配置显得非常的不实际。

万幸,网上有人问过这个问题,里面提到一个叫做AnyIP的东西,可以让linux响应多个ip地址,配置方法也很简单,就写一条静态路由就行了。

ip route add local 2001:db8::/32 dev lo

和平时添加静态路由差不多,就是在目标地址前面加一个“local”,然后目标设备是lo即可。

Mikrotik动态更新从PPPOE获得的dns服务器

手里的那只RB750Gr3之前给几个出租屋的房间配置dhcp的时候,都是将客户端的dns指向RB750Gr3自己作为网关的ip地址,这样,RouterOS会作为一个DNS代理,查询和缓存DNS请求。这样设置其实没啥问题,只是这几天又突发奇想,想着要不直接分发运营商的DNS服务器地址给用户,如此一来,可以稍微的降低一下路由器的负载(其实没多少)。

Mikrotik的脚本功能其实比较强大,但是相关的文档就惨不忍睹,好在论坛上有好心人回答问题,给我提供了一些思路。以下是我写的脚本。

:local dynamic (([/ip dns print as-value]) -> "dynamic-servers" );
:local dns

:set dynamic [:tostr $dynamic]

:for i from=0 to=([:len $dynamic] - 1) do={ 
 :local char [:pick $dynamic $i]
 :if ($char = ";") do={
  :set $char ","
 }
 :set dns ($dns . $char)
}

/ip dhcp-server network set [ find comment=UserNet ] dns-server=$dns

简单的解释以下脚本内容:

  • 1.从/ip dns里面读取“dynamic-servers”的内容,这些ip地址是pppoe拨号之后,从pppoe服务器上获取到的。
  • 2.要将dynamic的内容填充到dhcp-server里面,但是因为读取到的内容是一个array,用”;”分隔,没法直接套用,所以,需要转换成string类型。
  • 3.然后将”;”替换成”,”,然后就可以在修改配置的命令行里面调用了。
  • 因为配置里面,包含了多个dhcp-server,而我不需要修改全部的network的配置,所以,我给需要修改配置的network,写了一个备注,内容是“UserNet”。这样脚本就会只修改备注内容是“UserNet”的network配置了。

脚本做好之后,就是调用了,可以选择定时执行脚本或者是在pppoe会话起来的时候执行,我选择的是在pppoe会话起来的时候执行。找到pppoe调用的ppp profile,在scripts里面调用就行了。

使用OPNsense来保护内网的服务

因为在家里部署了不少应用服务,所以,也想将一些服务暴露到公网上,但是呢,直接暴露的话,会有非常大的风险。全部走vpn也略微有点麻烦,虽然最近看到一些油管的UP主在推荐cloudflare的tunnel服务,但是我都自己托管了,还走cloudflare是不是有点……愚蠢呢。

因为工作的原因有接触过pfSense,然后也尝试过其分支OPNsense,一番测试之后,发现大有可为,不得不说真好使。

安装OPNsense

就是很普通的用iso引导,然后根据屏幕上的说明一路下一步就行。安装完毕之后,顺手更新一下系统。调整一下时区、默认语言等。

安装必要的插件

最主要的插件只有2个,一个是os-acme-client,另外一个是os-nginx。acme负责签署证书,而nginx,则负责做反向代理。

自动注册证书

从侧边栏访问“服务-ACME客户端”,默认的设置页面会报错,这时候,需要切换成英文,就能够正常打开页面了。跑去settings页面,打开启用插件和自动更新,应用。剩下的就可以切换回中文了。

下一步,就是创建一个账号,只要填一下邮箱地址,其他默认就行。

下一步是添加一个“挑战类型”,这里其实翻译成“验证类型”会比较好……

由于国内的环境,80和443端口都不用想了,所以只能走dns,具体用哪一家的dns,就根据对应的服务商的文档来配置就行。

下一步是创建一个自动操作,这里选择重启Nginx,这样证书在续签之后会自动重启nginx,并应用新的证书。

然后就是创建一个证书(申请)

注意这里的域名应该这样设计:一个通用域名(example.com),还有其下的通配符域名(*.example.com)。到时候,example.com应该返回一个404;具体对应的系统,则应该放在子域名来访问,例如nextcloud.example.com。另外,所有的应用都应该使用同一个监听端口,除非是由于某些原因,只能使用”流“(stream)代理。如此,可以最大限度地隐藏服务入口。

最后,自动操作里面选择一下刚创建的重启nginx的操作。保存。

保存之后出来可以手动触发一下证书签署,顺利的话就直接拿到一个可以用的证书了。

配置NGINX

OPNsense使得nginx的配置简单的很多,只要点点点就行,而且附加了很多安全方面的设置,有很多值得学习的内容。

创建错误提示页面

为了误导可能的攻击者,我们需要整点花活,因为默认情况下,被策略拦截之后,会向客户端返回一个页面,提醒被OPNsense上的策略拦截了。这可不行,怎么能让对方知道我们用了什么东西的呢对吧。我们来创建一个错误页面,整一个Nginx默认的500错误页面。并且匹配所有的状态码。

这样,无论是什么错误,用户都只能看到一个500的错误。(邪恶)

创建一个默认的服务器

设计的思路在证书那里已经说过了,首先,创建一个默认的服务器,在访问域名不正确的情况下,所有的访问都会跑到这里来:

位置

首先创建一个位置(HTTP(s)-位置),打开高级模式,修改以下的内容,确认保存:

  • 描述:随便填写
  • 网址格式:/
  • 强制HTTPS:勾选
  • honeypot:勾选

这里解释一下这个honeypot,在打开这个参数之后,如果访问了这个位置,就只会返回一个403,并且源地址将会被记录,然后屏蔽。具体屏蔽的时间,可以在“常规设置”的页面,打开高级选项,就可以自定义屏蔽的时间了。

HTTP服务器

然后创建一个服务器(HTTP(s)-HTTP服务器),修改这些内容:

  • HTTP监听地址:空
  • HTTPS监听地址:0.0.0.0:8443(你应该换个别的端口号)
  • TLS证书:(刚签署的那个)
  • 仅HTTPS:勾选
  • 错误页面:刚创建的糊弄人的默认错误页面

配置好DNS之后就可以测试一下是否生效了。尝试访问一下这个服务器,会得到一个空白页。然后在禁止的页面上就能看到这个ip进入了拦截清单了。

调整防火墙策略

最后一步就是调整防火墙策略,新增一个策略,拦截掉这些坏东西的访问:

  • 操作:阻止
  • 源:nginx_autoblock

这样,那些来源不明的访问就会被拦截。

应用保存之后,一个基本的拦截就做好了,攻击者在不知道你有什么域名的情况下,如果访问了OPNsense,就会被关小黑屋,被防火墙拦截,而被防火墙拦截的情况下,其他的端口也会无法访问。

另外,由于我们签署的证书包含2个域名,一个是example.com,另外一个是*.example.com。所以,即便是通过这次的访问,拿到了SSL证书,也不会知道我们用的是什么域名。这就能最大限度地隐藏访问入口。

添加需要暴露的服务器

基础搭建好了之后,就是增加需要通过nginx反向代理的服务了。一共有4个步骤,简单的说法:

  1. 添加一个“上游服务器”
  2. 添加一个“上游”
  3. 添加一个“位置”
  4. 添加一个“HTTP服务器”

上游服务器

需要填写的一共4项,描述、服务器、端口还有优先级。这里特别说明以下,因为设计上,是有多个后端的,所以必须要填上一个优先级。因为一般只有1个后端,所以……随便填一个数字就行。

上游

这里的话,只要填写描述,然后,服务器条目选择刚创建的上游服务器即可。值得注意的是,如果被反代的服务器是使用https的,则需要勾选上“启用TLS(HTTPS)”

位置

位置的话,刚才在创建一个默认的服务器的时候已经讲过了,这次稍有不同的地方,就是有一个额外的选项需要选择,就是“上游服务器”,这里选择刚才创建的“上游”即可。

HTTP服务器

可以参考上面的创建http服务器,和之前的主要差别,只有1个,那就是需要指定一个你自己才知道的属于*.example.com的子域名。由于证书是泛域名证书,所以所有子域名都能够使用。

应用配置

一切搞定之后,点击应用,保存并生效。

最后,在调整完dns之后,你就能用https://private.example.com:8443/来访问你需要暴露的服务了。有多个应用的情况下,重复创建上游服务器、上游、位置、http服务器,即可。