分类 技术 下的文章

RouterOS单系统实现透明网关

20231218更新:优化hysteria启动脚本。

自从接触mikrotik公司的RouterOS系统以来,一直都想以routeros单系统实现内外网自动分流、dns防污染的透明网关。
由于routeros是商业公司开发的闭源路由系统,虽然是基于linux内核,但是并不像openwrt一样可以安装任意软件。
所以在v6版本时代尝试过ipsec、ipip、gre隧道等方式穿墙,效果并不是很好,要么会受到墙的干扰,要么运营商qos太厉害,
要么协议本身限制再公网跑不起速度来。

所以引入了openwrt旁路由,routeros导入国内IP地址表,通过rooting mark的方式实现国内外IP地址分流,把国外IP地址转发给openwrt,openwrt通过ssr+或者passwall等使用ss、ssr、trojen、vless、hysteria等穿墙协议实现国外流量送出墙。

由于openwrt自身的复杂、开源软件质量,以及编译时的细节选项的各种问题,导致openwrt并不是十分稳定,且排查较为困难。
一直认为使用openwrt作为旁路由并不完美。后来routeros系统增加了wireguard,选择合适线路的vps后,可以实现勉强能做到单系统的透明网关,但是最近一段时间wireguard被墙阻断越来越严重,更换端口勉强能用几天。
再后来routeros内置了容器功能,极大的增大了发挥空间,虽然是个严重严格的容器功能。

通过以容器方式起mosdns实现了dns防污染、IPv4和IPv6自定义优先级等功能。
最近研究了一些前人的教程方法后,实现了容器内clash、sing-box、hysteria等程序路由功能。

RouterOS容器实现路由方式穿墙的方法,以hysteria这个简单程序为例。
1,通过hub.docker.com远程仓库拉去镜像或者导入tar文件方式创建容器。
以tar文件方式为例
电脑安装docker desktop并启动
命令行

docker pull alpine
docker save -o alpine.tar alipine

如果routeros是arm版的话

docker pull alpine@sha256:30e6d35703c578ee703230b9dc87ada2ba958c1928615ac8a674fcbbcbb0f281
#sha256:30e6d35703c578ee703230b9dc87ada2ba958c1928615ac8a674fcbbcbb0f281可在docker hub的网页上找到

2,然后把tar文件上传到routeros,建议开启smb功能,通过smb新建的文件权限比sftp或者scp要高
3,然后是创建容器,详细参考官方文档
创建完后,修改cmd属性

tail -f /dev/null

然后启动容器
4,通过shell 0 容器编号进入容器字符界面
使用wget命令下载hysteria,并解压
创建hysteria的配置文件,供参考,以服务端配置为准

{
  "insecure": true,
  "protocol": "wechat-video",
  "down_mbps": 330,
  "server": "x.x.x.x:x",
  "tun": {
  "name": "tun0"
  },
  "auth_str": "xxxx",
  "disable_mtu_discovery": false,
  "up_mbps": 110,
  "alpn": "h3",
  "server_name": "wechat.com"
}

5,然后创建tun

apk update
apk add iproute2
ip tuntap add mode tun dev tun0
ip addr add 198.18.0.1/15 dev tun0
ip link set dev tun0 up

6,修改路由,可以通过修改默认路由metric方式
假设 eth0 是原本的网卡,网关地址为 192.168.1.1,x.x.x.x是vps的IP地址

ip route del default
ip route add default via 198.18.0.1 dev tun0 metric 1
ip route add default via 192.168.1.1 dev eth0 metric 10
ip route add 192.168.0.0/16 via 192.168.1.1
ip route add 10.0.0.0/8 via 192.168.1.1
ip route add x.x.x.x via 192.168.1.1

也可以通分解0.0.0.0/0方式添加路由

ip route add 0.0.0.0/1 via 198.18.0.1
ip route add 128.0.0.0/1 via 198.18.0.1
ip route add 192.168.0.0/16 via 192.168.1.1
ip route add 10.0.0.0/8 via 192.168.1.1
ip route add x.x.x.x via 192.168.1.1

7,退出容器,停止容器
修改容器cmd参数

/root/hysteria client --config /root/hk.json

启动容器
8,配置routeros转发国外流量给容器,参考Routeros V7配置策略路由

9,容器内hysteia一键启动脚本start.sh

#!/bin/sh
GW="192.168.1.1"
cp /hysteria/hysteria /bin/
ip route replace 10.0.0.0/8 via $GW
ip route replace 192.168.0.0/16 via $GW
awk -F'"|:' '/"server"/ {cmd="ip route replace "$5" via '$GW'";system(cmd)}' /hysteria/$1
sleep 2&&ip addr add 198.18.0.1 dev tun0&&ip link set dev tun0 up&&ip route replace default via 198.18.0.1 &
hysteria client --config /hysteria/$1

在routeros上传hysteria可执行文件、hysteria配置文件和上面启动脚本到/container/etc/hysteria里
routeros新建容器命令

/container/mounts add name="hysteria" src="/container/etc/hysteria" dst="/hysteria"
/container add file=container/tmp/alpine_v3.18.2.tar interface=container-hysteria hostname=hysteria mounts=hysteria root-dir=container/root-dir/hysteria cmd="sh /hysteria/start.sh hk.json" start-on-boot=yes
/container start [find hostname=hysteria]

说明
由于routeros的容器功能细节一直在变动,有时候上一个版本还能使用,更新之后容器就不能启动了,而且日志一点信息都没有,所以采取了最保守的方式手动配置容器内应用的方式。
容器的网卡配置既不在容器内部存储,也不在routeros的veth里存储,似乎在一个容器外部不可见的地方,只能在容器内部操作,删除重建容器使用原来veth发现原有tun、静态路由居然还在。在routeros里修改veth的ip地址,居然不会同步修改容器内IP地址。
7.6版能启动的openwrt容器,新版就不能启动,一点日志都没有。
之前容器内可以写入mount的目录,新版就没有写权限,也没有执行权限,虽然容器内显示有权限。

也研究了tinyserve的bird+clash容器实现ospf动态路由透明网关方式,他使用了s6在容器内看护了几个应用,导致容器内存需求较大,小于4G内存的就别测试了。我使用rb5009,内存只有1gb,遇到routeros内存不足重启的问题。
动态路由这种透明网关方式早在ssr出现之前就有人提出,使用树莓派上跑bird+ss实现,但是我一直觉得一旦穿墙失效,所有数据包都会被运营商和墙捕捉到,为了高可用牺牲安全性不太值得,所以一直没用。

RouterOS在ESXi8.0上以UEFI方式引导启动

最近新装了虚拟化平台esxi8.0b,在创建routeros虚拟机时遇到了一系列问题:
1,esxi8.0b默认创建的ESXi 8.0(虚拟硬件版本20)版本虚拟机使用了新的api,默认以uefi引导系统,在创建完成后不能修改为bios,报错“ACPI motherboard layout requires EFI”。
2,RouterOS的CHR版磁盘镜像默认以bios引导。使用x86的iso可以正常安装使用uefi引导虚拟机,但是系统显示的是x86架构,通过升降级不能切换架构,x86架构不启用open-vm-tools服务,这个服务不启动,在esxi控制面板看不到hostname和IP地址等信息。此外x86架构和chr架构的授权和有些功能也不相同。
3,RouterOS的CHR版磁盘镜像有两个分区,第一个是efi分区,文件系统是ext2,而非uefi标准的fat。
4,RouterOS的CHR版磁盘镜像有独立的mbr和gpt分区表,既不是gpt也不是Hybrid MBR。
5,RouterOS的CHR版uefi启动不支持Secureboot。

以下是让routeros v7.8在ESXi8.0上以UEFI方式引导启动的方法,此方式只在routeros v7.8chr版测试通过,不确定后续版本升级是否可用。
1,创建没有硬盘的虚拟机,关闭secureboot。
2,下载routeros的vmdk虚拟机硬盘文件,解压上传到esxi。
3,ssh登录到esxi,转换routeros的vmdk磁盘格式,并扩展磁盘空间。

vmkfstools -i chr-7.8.vmdk routeros.vmdk -d thin
vmkfstools -X 20G routeros.vmdk

4,修改虚拟机配置,添加刚才生成的vmdk磁盘。
5,虚拟机挂载ubuntu的live-cd或其他有gdisk命令的系统iso到虚拟机。
6,开机进入ubuntu桌面,备份RouterOS Boot分区的全部文件
7,取消挂载,并使用fat格式化第一个分区

mkfs -t fat /dev/sda1

8,恢复步骤6中备份的文件到第一个分区后取消挂载routeros的两个磁盘
9,使用gdisk创建Hybrid MBR分区表,过程如下:

root@ubuntu:/home/ubuntu# gdisk /dev/sda
GPT fdisk (gdisk) version 1.0.8

Partition table scan:
  MBR: MBR only
  BSD: not present
  APM: not present
  GPT: present

Found valid MBR and GPT. Which do you want to use?
 1 - MBR
 2 - GPT
 3 - Create blank GPT

Your answer: 2
Using GPT and creating fresh protective MBR.

Command (? for help): t
Partition number (1-2): 1
Current type is EF00 (EFI system partition)
Hex code or GUID (L to show codes, Enter = EF00): 8300
Changed type of partition to 'Linux filesystem'

Command (? for help): r

Recovery/transformation command (? for help): h

WARNING! Hybrid MBRs are flaky and dangerous! If you decide not to use one,
just hit the Enter key at the below prompt and your MBR partition table will
be untouched.

Type from one to three GPT partition numbers, separated by spaces, to be
added to the hybrid MBR, in sequence: 1 2
Place EFI GPT (0xEE) partition first in MBR (good for GRUB)? (Y/N): n

Creating entry for GPT partition #1 (MBR partition #1)
Enter an MBR hex code (default 83): 
Set the bootable flag? (Y/N): y

Creating entry for GPT partition #2 (MBR partition #2)
Enter an MBR hex code (default 83): 
Set the bootable flag? (Y/N): n

Unused partition space(s) found. Use one to protect more partitions? (Y/N): n

Recovery/transformation command (? for help): w
Warning! Secondary header is placed too early on the disk! Do you want to
correct this problem? (Y/N): y
Have moved second header and partition table to correct location.

Final checks complete. About to write GPT data. THIS WILL OVERWRITE EXISTING
PARTITIONS!!

Do you want to proceed? (Y/N): y
OK; writing new GUID partition table (GPT) to /dev/sda.
The operation has completed successfully.

10,重启系统即可以UEFI方式启动RouterOS CHR

附:
初始vmdk的mbr分区表:

root@ubuntu:/home/ubuntu# gdisk /dev/sda
GPT fdisk (gdisk) version 1.0.8

Partition table scan:
  MBR: MBR only
  BSD: not present
  APM: not present
  GPT: present

Found valid MBR and GPT. Which do you want to use?
 1 - MBR
 2 - GPT
 3 - Create blank GPT

Your answer: 1

Command (? for help): p
Disk /dev/sda: 262144 sectors, 128.0 MiB
Model: VMware Virtual I
Sector size (logical/physical): 512/512 bytes
Disk identifier (GUID): F1C07EE3-729F-4E5F-8C77-AEC9BC697BD3
Partition table holds up to 128 entries
Main partition table begins at sector 2 and ends at sector 33
First usable sector is 34, last usable sector is 262110
Partitions will be aligned on 2-sector boundaries
Total free space is 4063 sectors (2.0 MiB)

Number  Start (sector)    End (sector)  Size       Code  Name
   1              34           65569   32.0 MiB    8300  Linux filesystem
   2           65570          258047   94.0 MiB    8300  Linux filesystem

Command (? for help): q

初始vmdk的gpt分区表:

root@ubuntu:/home/ubuntu# gdisk /dev/sda
GPT fdisk (gdisk) version 1.0.8

Partition table scan:
  MBR: MBR only
  BSD: not present
  APM: not present
  GPT: present

Found valid MBR and GPT. Which do you want to use?
 1 - MBR
 2 - GPT
 3 - Create blank GPT

Your answer: 2
Using GPT and creating fresh protective MBR.

Command (? for help): r

Recovery/transformation command (? for help): p
Disk /dev/sda: 262144 sectors, 128.0 MiB
Model: VMware Virtual I
Sector size (logical/physical): 512/512 bytes
Disk identifier (GUID): 197E76F1-9677-0D46-9C33-F00032DDDBB1
Partition table holds up to 128 entries
Main partition table begins at sector 2 and ends at sector 33
First usable sector is 34, last usable sector is 258047
Partitions will be aligned on 2-sector boundaries
Total free space is 0 sectors (0 bytes)

Number  Start (sector)    End (sector)  Size       Code  Name
   1              34           65569   32.0 MiB    EF00  RouterOS Boot
   2           65570          258047   94.0 MiB    8300  RouterOS

Recovery/transformation command (? for help): q

创建hybrid mbr后的vmdk的gpt分区表:

Recovery/transformation command (? for help): p
Disk /dev/sda: 262144 sectors, 128.0 MiB
Model: VMware Virtual I
Sector size (logical/physical): 512/512 bytes
Disk identifier (GUID): 197E76F1-9677-0D46-9C33-F00032DDDBB1
Partition table holds up to 128 entries
Main partition table begins at sector 2 and ends at sector 33
First usable sector is 34, last usable sector is 258047
Partitions will be aligned on 2-sector boundaries
Total free space is 0 sectors (0 bytes)

Number  Start (sector)    End (sector)  Size       Code  Name
   1              34           65569   32.0 MiB    8300  RouterOS Boot
   2           65570          258047   94.0 MiB    8300  RouterOS

Recovery/transformation command (? for help): o

Disk size is 262144 sectors (128.0 MiB)
MBR disk identifier: 0x00000000
MBR partitions:

Number  Boot  Start Sector   End Sector   Status      Code
   1      *             34        65569   primary     0x83
   2                 65570       258047   primary     0x83
   3                     1           33   primary     0xEE

参考:
1,Router OS 7 on UEFI
2,Hybrid MBR(MBR 混合分区表)
3,Manual:CHR VMWare installation

2022年使用Youtube TV收看美国电视直播情况

不了解youtube tv的可以参考:中国大陆收看美国电视直播总结(持续更新)
youtube tv发布以来的订阅费一直在涨价,基础套餐从最初的40刀一路涨到了现在的65刀。最近又想看discovery和国家地理的生肉了,所以重新订阅了youtube tv。
订阅其实很简单,美国原生ip,一个和ip对应的zip code,可以美区付费google账号。
以我使用的美国西雅图ip为例:
基础套餐65刀,总计106个频道,其中13个频道需要位置权限,我还加购了hbo max包15刀,4k包第一年10刀,总计90刀每月,有点肉疼。
跟之前分享的一样,zip code需要和ip所在位置一致才能稳定的收看,要不然会经常弹出所在位置与登记不符。
网页和移动设备需要定位权限才能看一些本地新闻频道,网页可以参考上面我之前分享的怎么收看美国电视直播的文章。
apple tv需要用网页定位一次,之后就随便看了。
iphone目前没有好用的虚拟定位,所以那13个频道没办法看了。
现在的youtube tv 越来越好用了,大部分可以看的剧集综艺都有vod,可以直接看点播,不需要再订阅其他了。
hbo max包订阅后可以在hbo max的app里收看。
订阅4k包,看4khdr冬奥会,效果很好。

nginx+php启用quic即http/3的方法

本站已支持http/3。
屏幕截图 2021-11-03 095321.png
支持HTTP/3

http/3quic参考wiki。

1.QUIC简单流程介绍
当浏览器向之前从未发过请求的服务端发出请求时,它不知道对方是否支持QUIC,因此先通过TCP发送第一个请求。服务器响应该请求以后,要发送 Alt-Svc 的HTTP响应头告诉浏览器它支持QUIC。浏览器知道服务端支持 QUIC后尝试使用 QUIC 来进行下一个请求。浏览器下一个请求采取QUIC和TCP竞争的方式与服务端建立连接,如果请求通过TCP发出,TCP赢得竞争,请求将通过TCP发出。后续如果QUIC连接成功,之后所有请求都将通过QUIC连接发送。
当浏览器向之前使用过QUIC的服务器发出请求时,它还会与TCP进行竞争。 对于启用QUIC并支持0-RTT握手的服务器,由于浏览器将能够进行0-RTT握手,因此QUIC还会立即获胜,并且继续在QUIC连接上发出请求。
如果QUIC握手失败,则浏览器会将QUIC标记为该主机broken。后续请求都将通过TCP重新发送。5分钟后,broken的QUIC标记为recently broken。当向服务器发出下一个请求时,浏览器又将继续让TCP和QUIC进行竞争。由于QUIC recently broken,因此将禁用0-RTT握手。如果握手再次失败,则QUIC将在此次再次标记为该连接已损坏10分钟,将QUIC标记为已损坏的前一周期的2倍,如此往后都会不断的标记为2倍。如果握手成功,请求将通过QUIC发送,QUIC将不再标记为recently broken。

2.浏览器启用QUIC或者HTTP/3
chrome浏览器,地址栏打开chrome://flags,搜索quic,Experimental QUIC protocol选择enabled,重启浏览器。edge等chromium内核浏览器类似。
safari浏览器,实验功能,启用HTTP/3,重启浏览器。
打开https://http3.is或者https://quic.nginx.org或者https://cloudflare-quic.com可以检查浏览器是否能使用quic。
chrome可以安装QUIC indicator插件检测网页是否以quic打开。

3.网站配置
启用http/3或者quic需要反代服务器支持即可,即nginx,caddy等支持http/3。nginx官方主线版本还未支持,可以使用cloudflare的插件quiche重新编译nginx源码实现支持。caddy可以通过实验功能开启http3,但是截至v2.4.5版还存在问题
所以这里使用docker-nginx-http3替换原nginx。
配置文件需要参考作者提供的nginx.conf和h3.nginx.conf

systemctl stop nginx
apt update
apt install docker.io
docker pull ranadeeppolavarapu/nginx-http3
docker run -d -t --restart always --name "nginx-http3" -p 80:80 -p 443:443/tcp -p 443:443/udp -v /var/run/php:/var/run/php -v [映射nginx的配置文件,网页代码文件,证书等] ranadeeppolavarapu/nginx-http3

修改php-fpm监听的unix socket的权限,修改www.conf的listen.mode = 0666,给映射进容器的php7.2-fpm.sock赋予权限。
然后重启php-fpm服务。

4.检查网站是否启用HTTP/3
https://http3check.net/

5.其他
quic使用的端口号需要和tcp相同,否则网页地址会变,网页会出现跨域问题。
通过使用chrome的quic indicator插件发现很多网站都启用了http/3,尤其使用cloudfare CDN的网站,比如www.google.com,youtube.com,cloudflare.com,whatismyipaddress.com,whatismyip.com,ip.sb等

M1芯片的macos使用H3C的inode连接SSL VPN

M1芯片的macos使用inode需要关闭SIP(System Integrity Protection系统完整性保护),安全性问题请自行评估。
以下方法在M1芯片的MacBook pro 13寸macos 11 big sur下经过测试验证。
1,进入恢复模式。关闭mac后长按开机键,直至出现《选项》
屏幕截图 2021-10-25 163805.png
2,恢复模式,左上角实用工具选择终端
3,输入“csrutil disable”,按提示输入密码。如果报错,输入“csrutil clear”,然后左上角苹果图标选择关机,然后再次进入恢复模式输入“csrutil disable”
4,左上角苹果图标选择重启
5,双击inode安装包,在设置-安全-通用允许运行
6,安装完成后重启电脑
7,打开inode,配置网关,账号密码。

ps:macos的app store里的inode sslvpn是ios版,在macos下可以安装但是不能连接。
下面附件是inode_for_macos_7.3(e0584)
iNodeClient_MacOS_2.zip