MoreRSS

site iconLala | 荒岛修改

一个应用分享、教程类的博客,主要是那些需要自部署的。
请复制 RSS 到你的阅读器,或快速订阅到 :

Inoreader Feedly Follow Feedbin Local Reader

Lala | 荒岛的 RSS 预览

Anubis:基于工作量证明 (PoW)的Web防火墙

2026-06-03 12:37:53

Anubis介绍(摘自项目页面):

Anubis是一款Web防火墙,它使用一个或多个挑战来衡量您的连接安全性,以保护上游资源免受爬虫机器人的侵害。该项目旨在帮助保护小型互联网免受人工智能公司源源不断的请求冲击。Anubis力求轻量级。

Anubis的推出相当于采取了核打击措施。这将导致您的网站无法被小型爬虫程序访问,并可能影响像 Internet Archive 这样的“优质机器人”。您可以配置机器人策略定义,将它们明确列入允许列表。我们正在努力完善一套精选的“已知优质”机器人,以便在可发现性和正常运行时间之间取得平衡。

大多数情况下,您不需要这样做,使用Cloudflare保护特定源站即可。但是,如果您无法或不愿使用 Cloudflare,Anubis可以满足您的需求。

简单总结:

不是完整的WAF,更像一个CloudFlare的挑战页面,主要用来防御爬虫,应该也能防御一定量的CC攻击。主要采用PoW机制进行挑战(也可以调整为别的挑战方式)

这篇文章记录下Anubis部署与NGINX集成的步骤,其实坑还是有点多的,如果你选择用套接字配置的话。。可能会遇到各种权限问题,以及各种奇葩BUG。。

Debian安装Anubis、NGINX、CertBot:

wget https://github.com/TecharoHQ/anubis/releases/download/v1.25.0/anubis_1.25.0_amd64.deb
apt install ./anubis_1.25.0_amd64.deb
apt update
apt install nginx python3-certbot-nginx

anubis的systemd单元配置文件采用多实例配置,意味着你可以同时运行多个anubis实例,并且官方推荐的是一个anubis实例对应保护一个上游服务。

假设现在要运行一个保护wordpress的anubis实例,复制一份默认的.env文件:

cp /etc/anubis/default.env /etc/anubis/wordpress.env

编辑.env文件:

nano /etc/anubis/wordpress.env

写入如下内容:

BIND=/run/anubis/wordpress/instance.sock
BIND_NETWORK=unix
SOCKET_MODE=0777
DIFFICULTY=5
METRICS_BIND=:9090
SERVE_ROBOTS_TXT=0
POLICY_FNAME=/etc/anubis/wordpress.botPolicies.yaml
TARGET=unix:///run/nginx-wordpress.sock

因为我用了套接字配置,这里遇到了很多坑,我详细说一下吧。。

1. BIND=套接字的路径必须是:

/run/anubis/{path}/instance.sock

不能用官方文档指出的路径:

/run/anubis/instance.sock

否正你会遇到permission denied报错:

"level":"INFO","msg":"failed to bind to unix:/run/anubis/instance.sock: listen unix /run/anubis/instance.sock: bind: permission denied"}

原因是systemd单元配置文件里面有一行这个配置导致的,见此issue

RuntimeDirectory=anubis/%i

2. SOCKET_MODE=权限务必设置为0777或者0666。默认是0770,这意味着其它用户没有权限访问套接字,Debian的NGINX worker进程默认使用www-data用户运行,与anubis运行使用的用户不相同也不在同一个组里面,所以必须为其它用户设置6(读/写)或者7(读/写/执行)权限,否则NGINX会没有权限访问anubis的套接字。

为什么不把www-data加到同一个组里面?或者把NGINX worker改为anubis相同的用户运行?因为systemd单元配置文件里面有一行这个配置:

DynamicUser=yes

这代表anubis运行时使用的是动态用户,你不知道它运行时会使用什么用户/组。而且这样操作也不够优雅。

接下来复制默认的策略文件:

cp /usr/share/doc/anubis/botPolicies.yaml /etc/anubis/wordpress.botPolicies.yaml

我没有用默认的策略文件,因为里面有很多我不需要用到的规则,所以我自己搓了一份配置:

bots:
  # RSS Feed 放行
  - name: allow-feed
    path_regex: ^/feed/?$
    action: ALLOW

  # 静态资源放行,避免反复 challenge
  - name: allow-static
    path_regex: \.(css|js|jpg|jpeg|png|gif|svg|ico|webp|woff|woff2|ttf)$
    action: ALLOW

  # robots.txt 放行
  - name: allow-robots
    path_regex: ^/robots\.txt$
    action: ALLOW

  # favicon 放行
  - name: allow-favicon
    path_regex: ^/favicon\.ico$
    action: ALLOW

  # 放行正常搜索引擎
  - import: (data)/crawlers/_allow-good.yaml

  # 保持互联网正常工作(ACME/健康检查等)
  - import: (data)/common/keep-internet-working.yaml

  # 明显自动化工具直接拒绝
  - name: deny-bad-useragents
    user_agent_regex: ^$|curl|wget|python|httpclient|go-http-client|scrapy|nikto|sqlmap|masscan|zgrab|nmap
    action: DENY
  
  # 兜底 全站挑战 防CC攻击的关键
  - name: fallback
    path_regex: .*
    action: CHALLENGE
    challenge:
      algorithm: fast
      difficulty: 4

在搓规则的时候记住一个定律即可:anubis规则是从上到下依次匹配的。第一个规则不匹配才会进入到下一个规则再次进行匹配,以此类推。

启动anubis:

systemctl enable --now [email protected]

配置NGINX站点:

nano /etc/nginx/sites-available/wordpress

我的完整配置如下:

upstream anubis-wordpress {
  server unix:/run/anubis/wordpress/instance.sock;
}

server {
  server_name anubis.example.com;
  listen [::]:443 ssl ipv6only=on http2; # managed by Certbot
  listen 443 ssl http2; # managed by Certbot
  ssl_certificate /etc/letsencrypt/live/anubis.example.com/fullchain.pem; # managed by Certbot
  ssl_certificate_key /etc/letsencrypt/live/anubis.example.com/privkey.pem; # managed by Certbot
  include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
  ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

  location / {
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Http-Version $server_protocol;
    proxy_pass http://anubis-wordpress;
  }
}

server {
  listen unix:/run/nginx-wordpress.sock;
  server_name anubis.example.com;
  root "/var/www/wordpress";
  index index.html index.php;

  # 获取客户端真实IP
  set_real_ip_from unix:;
  real_ip_header X-Real-IP;

  location / {
    try_files $uri $uri/ /index.php?$args;
  }

  location ~ \.php$ {
    include snippets/fastcgi-php.conf;
    fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
  }
}

server {
  listen 80;
  listen [::]:80;
  server_name anubis.example.com;
    if ($host = anubis.example.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot
    return 404; # managed by Certbot
}

流量的走向是:用户访问你的站点(80端口)301跳转到(443端口),然后流量进入anubis清洗,清洗后的流量通过unix:/run/nginx-wordpress.sock到达上游(后端服务)

如果你使用certbot管理证书,可以这样配置:

upstream anubis-wordpress {
  server unix:/run/anubis/wordpress/instance.sock;
}

server {
  listen 80;
  listen [::]:80;
  server_name anubis.example.com;

  location / {
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Http-Version $server_protocol;
    proxy_pass http://anubis-wordpress;
  }
}

server {
  listen unix:/run/nginx-wordpress.sock;
  server_name anubis.example.com;
  root "/var/www/wordpress";
  index index.html index.php;

  # 获取客户端真实IP
  set_real_ip_from unix:;
  real_ip_header X-Real-IP;

  location / {
    try_files $uri $uri/ /index.php?$args;
  }

  location ~ \.php$ {
    include snippets/fastcgi-php.conf;
    fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
  }
}

启用站点:

ln -s /etc/nginx/sites-available/wordpress /etc/nginx/sites-enabled/wordpress

用certbot生成证书:

certbot --nginx

certbot会自动补全上述的完整配置,你就不需要自己去配置443那块的内容了。

这里我又遇到一个问题:由NGINX创建的套接字:unix:/run/nginx-wordpress.sock不会在NGINX重启或者停止后自动删除,这导致NGINX启动的时候失败,报错:

bind() to unix:/run/nginx-wordpress.sock failed (98: Address already in use)
bind() to unix:/run/nginx-wordpress.sock failed (98: Address already in use)
bind() to unix:/run/nginx-wordpress.sock failed (98: Address already in use)

搜了一下发现这是一个11年前的BUG,并且在6年前似乎已经修复了,但是我不知道为什么Debian 11的NGINX 1.18还有这个BUG。。要临时解决的话见此答案

将SIGQUIT“优雅关闭”,改为SIGTERM“快速关闭”即可。编辑NGINX的systemd单元配置文件:

systemctl edit nginx

在两段注释中间写入如下配置,写在其他地方是不会生效的哈,这也是systemd奇葩的地方= =:

[Service]
ExecStop=
ExecStop=-/sbin/start-stop-daemon --quiet --stop --retry TERM/5 --pidfile /run/nginx.pid

重启:

systemctl restart nginx

效果如图,说真的这个二次元吉祥物有点丑= =:

下面简单介绍一下多实例部署,多个实例通过.env文件区分:

cp /etc/anubis/default.env /etc/anubis/yourbackend.env
cp /usr/share/doc/anubis/botPolicies.yaml /etc/anubis/yourbackend.botPolicies.yaml

编辑.env:

nano /etc/anubis/yourbackend.env

配置不同的套接字:

BIND=/run/anubis/yourbackend/instance.sock
BIND_NETWORK=unix
SOCKET_MODE=0777
DIFFICULTY=5
METRICS_BIND=:9090
SERVE_ROBOTS_TXT=0
POLICY_FNAME=/etc/anubis/yourbackend.botPolicies.yaml
TARGET=unix:///run/nginx-yourbackend.sock

启动anubis:

systemctl enable --now [email protected]

NGINX也应该监听不同的套接字:

server {
  listen unix:/run/nginx-yourbackend.sock;
  server_name anubis.example.com;
  root "/var/www/wordpress";
  index index.html index.php;

  # Get the visiting IP from the TLS termination server
  set_real_ip_from unix:;
  real_ip_header X-Real-IP;
  ...
}

参考:

https://anubis.techaro.lol/docs/admin/native-install
https://anubis.techaro.lol/docs/admin/installation#environment-variables
https://anubis.techaro.lol/docs/admin/environments/nginx
https://anubis.techaro.lol/docs/admin/policies

openappsec:基于机器学习的开源WAF

2026-05-29 18:34:03

openappsec是一款基于机器学习技术的开源WAF,它可以作为插件部署到Linux、Docker或Kubernetes环境中,并支持NGINX、Kong、APISIX、Envoy等云平台。

本文记录Linux(Debian 11)下的openappsec与NGINX的配置。如果你是别的Linux发行版,首先看这个支持列表,找对应的发行版和NGINX软件包版本。

例如当前Debian 11官方repo内的1.18.0-6.1+deb11u6在列表内就是支持的,软件包版本支持的话就意味着可以用全自动的方式来安装,非常方便:

如果你的NGINX软件包还不在支持列表的话就需要自己编译了,本文暂不考虑这种情况。有机会再补充编译安装的方式。

下载安装程序:

wget https://downloads.openappsec.io/open-appsec-install && chmod +x open-appsec-install

一键自动安装:

./open-appsec-install --auto

安装完成后,首先要做的是更换高级机器学习模型,默认的模型不适用于生产环境,请访问open-appsec门户网站,注册账号,下载高级模型的压缩包,将其上传到服务器。

更换模型前先停止agent运行:

open-appsec-ctl --stop-agent

解压模型到/etc/cp/conf/waap目录:

tar -xzf open-appsec-advanced-model.tgz -C /etc/cp/conf/waap

设置所有者:

chown -R root:root /etc/cp/conf/waap/waap.data

再次启动agent:

open-appsec-ctl --start-agent

编辑openappsec默认的配置文件:

nano /etc/cp/conf/local_policy.yaml

注意这个配置文件目前有两个版本(v1beta1、v1beta2),目前新安装的默认都是用的v1beta2,并且官方也会逐步用v1beta2淘汰掉v1beta1。

下面这是我的配置,基于默认配置做的最小改动,其实也没啥好改的,因为开源版本限制了很多功能都不让用,哈哈。我甚至觉得如果你不想将每个主机(host)拆开管理(specificRules)的话,就用默认配置都行。

建议先用detect-learn模式跑7-14天降低误报率,然后将模式改为prevent-learn。如果到时候还有误报就得自己额外搓exceptions了(类似于白名单的东西)。

# open-appsec default declarative configuration file
# based on schema version: "v1beta2"
# more information on declarative configuration: https://docs.openappsec.io
apiVersion: v1beta2
policies:
  default:
    # start in detect-learn and move to prevent-learn based on learning progress
    mode: detect-learn
    threatPreventionPractices: [default-threat-prevention-practice]
    accessControlPractices: [default-access-control-practice]
    customResponses: default-web-user-response
    triggers: [default-log-trigger]
    sourceIdentifiers: ""
    trustedSources: ""
    exceptions: []
  specificRules:
    - host: "example.com"
      mode: detect-learn
      threatPreventionPractices: [default-threat-prevention-practice]
      accessControlPractices: [default-access-control-practice]
      customResponse: default-web-user-response
      triggers: [default-log-trigger]
      sourceIdentifiers: ""
      trustedSources: ""
    - host: "www.example.com"
      mode: detect-learn
      threatPreventionPractices: [default-threat-prevention-practice]
      accessControlPractices: [default-access-control-practice]
      customResponse: default-web-user-response
      triggers: [default-log-trigger]
      sourceIdentifiers: ""
      trustedSources: ""
threatPreventionPractices:
  - name: default-threat-prevention-practice
    practiceMode: inherited
    webAttacks:
      overrideMode: inherited
      minimumConfidence: high
    intrusionPrevention:
    # intrusion prevention (IPS) requires "Premium Edition"
      overrideMode: inherited
      maxPerformanceImpact: medium
      minSeverityLevel: medium
      minCveYear: 2016
      highConfidenceEventAction: inherited
      mediumConfidenceEventAction: inherited
      lowConfidenceEventAction: detect
    fileSecurity:
    # file security requires "Premium Edition"
      overrideMode: inherited
      minSeverityLevel: medium
      highConfidenceEventAction: inherited
      mediumConfidenceEventAction: inherited
      lowConfidenceEventAction: detect
    snortSignatures:
      # you must specify snort signatures in configmap or file to activate snort inspection
      overrideMode: inherited
      configmap: []
      # relevant for deployments on kubernetes
      # 0 or 1 configmaps supported in array
      files: []
      # relevant for docker and linux embedded deployments
      # 0 or 1 files supported in array
    schemaValidation: # schema validation requires "Premium Edition" 
      overrideMode: inherited
      configmap: []
      # relevant for deployments on kubernetes
      # 0 or 1 configmaps supported in array
      files: []
      # relevant for docker and linux embedded deployments
      # 0 or 1 files supported in array
    antiBot: # antibot requires "Premium Edition" 
      overrideMode: inherited
      injectedUris: []
      validatedUris: []
accessControlPractices:
  - name: default-access-control-practice
    practiceMode: inherited
    rateLimit:
    # specify one or more rules below to use rate limiting
      overrideMode: inherited
      rules: []
logTriggers:
  - name: default-log-trigger
    accessControlLogging:
      allowEvents: false
      dropEvents: true
    appsecLogging:
      detectEvents: true
      preventEvents: true
      allWebRequests: false
    extendedLogging:
      urlPath: true
      urlQuery: true
      httpHeaders: true
      requestBody: false
    additionalSuspiciousEventsLogging:
      enabled: true
      minSeverity: high
      responseBody: false
      responseCode: true
    logDestination:
      cloud: false
      logToAgent: true
      stdout:
        format: json
customResponses:
  - name: default-web-user-response
    mode: response-code-only
    httpResponseCode: 403

所有配置选项的含义和具体用法可参考官方的文档

对配置文件进行更改后,要使更改生效,必须应用新策略:

open-appsec-ctl --apply-policy

查看运行状态:

open-appsec-ctl --status

确保所有状态都是running:

查看日志:

open-appsec-ctl --view-logs

实际日志文件的路径位于:

/var/log/nano-agent/CP-nano-http-transaction-handler.log(number)

这个官方的CLI工具看日志非常不利于人类阅读,可以安装个jq:

apt install jq

然后这样看:

tail -f /var/log/nano_agent/cp-nano-http-transaction-handler.log2 | jq

openSUSE TW KDE Plasma和GUI.for.SingBox的趣事

2026-05-17 17:18:20

我一直想在openSUSE Tumbleweed下使用GUI.for.SingBox。说真的想了很久了,每次GUI.for.SingBox发布新版本我都会下载一个尝试运行,但很遗憾每次运行都会报错:

Gdk-Message: Error 71 (Protocol error) dispatching to Wayland display

我问过AI也试过Google搜索到的几乎所有解决方法,以及官方频道和讨论群组提到类似问题的解决方法,包括但不限于:

https://t.me/GUI_for_Cores/27078
https://forums.opensuse.org/t/gdk-message-error-71-protocol-error-dispatching-to-wayland-display/178886
https://discussion.fedoraproject.org/t/gdk-message-error-71-protocol-error-dispatching-to-wayland-display/127927
https://github.com/tauri-apps/tauri/issues/10702#issuecomment-2327642878

很可惜全部都不起作用,甚至我切换到x11也无法正常运行,只是在x11下不报错,但打开是白屏。

有趣的是我最近从kde plasma切换到niri了,你猜怎么着?GUI.for.SingBox竟然能够正常运行了。。。你就说神奇不神奇吧。。。似乎又多了一个让我继续使用niri的理由,哈哈。

说真的Linux有时候就是这样,真的很玄学很魔幻。

openSUSE TW Niri Hyprland N卡闭源驱动崩溃解决办法

2026-05-17 15:36:14

最近niri和hyprland这类wayland平铺窗口合成器很热门,我也想在opensuse tumbleweed上试用一下,结果安装好还没开始折腾就卡住了:

从sddm登录kde plasma一切正常,登录niri或者hyprland屏幕就一直黑屏,但也有小概率是正常的,极低概率,可能10次登录里面能有1次是正常的。黑屏的时候我通过dmesg发现会报上图所示的错误,然后我根据这个报错信息去找解决办法,以下方法全部都试了个遍,没有一个能解决的:

Failed_to_apply_atomic_modeset

flip-event-timeout-error-on-startup

nvidia-drm-error-message-on-boot

niri-wm #2236

niri-wm #2139

问ai吧就一直让我开drm,除了开drm还是drm,我也是很无语。。就当我准备放弃的时候,我在opensuse论坛偶然看到了一个帖子:lts kernel for tumbleweed available how to switch

我才知道原来tw还有一个lts内核可以使用,然后我突然想到最近tw刚上了7.0内核,这个n卡闭源驱动也是kmp包,会不会是n卡闭源驱动和最新的7.0内核有bug导致的?我就想试试看装个lts内核能不能解决,本来是不报希望的,结果你猜怎么着?还真解决了!对就是这么简单,换个内核就解决了:

sudo zypper in kernel-longterm

可以看到安装这个lts内核的时候,会自动把nvidia闭源驱动也一并安装。这个kmp包安装的驱动版本和7.0内核是完全一样的,7.0安装的也是580.159.03:

安装完成后重启系统在GRUB引导阶段选择如图所示菜单:

选择刚安装的lts内核引导即可:

说实话有点歪打正着了=。=挺有趣的,记录一下,也许能帮到和我遇到一样问题的人。

Docker部署Zulip团队协作平台

2026-04-19 15:54:12

Zulip是完全开源的,但是自托管版本有一些限制,详细对比可浏览这个网页查看。似乎只有移动推送通知限制10个用户有点蛋疼,其他的都不怎么影响体验。实际上如果配置了SMTP,离线用户是可以收到邮件通知的。

安装Docker:

apt -y update
apt -y install curl git
curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh

克隆存储库:

cd /opt
git clone https://github.com/zulip/docker-zulip.git
cd docker-zulip

Zulip的compose编排使用了docker secrets来存储敏感数据。我们需要新建一个.env文件:

nano .env

至少写入以下内容,这里包括但不限于PG数据库密码、REDIS密码、您的SMTP邮件密码等:

ZULIP__POSTGRES_PASSWORD=example_postgres_password
ZULIP__MEMCACHED_PASSWORD=example_memcached_password
ZULIP__RABBITMQ_PASSWORD=example_rabbitmq_password
ZULIP__REDIS_PASSWORD=example_redis_password
ZULIP__SECRET_KEY=example_django_secret_key
ZULIP__EMAIL_PASSWORD=example_outgoing_email_password

编辑compose.override.yaml覆盖文件:

nano compose.override.yaml

在这个覆盖文件内至少需要修改以下内容:

services:
  zulip:
    environment:
      SETTING_EXTERNAL_HOST: "zulip.example.com"
      SETTING_ZULIP_ADMINISTRATOR: "[email protected]"
      TRUST_GATEWAY_IP: True
      SETTING_EMAIL_HOST: "mail.example.com"
      SETTING_EMAIL_HOST_USER: "smtp"
      SETTING_EMAIL_PORT: "587"
      SETTING_EMAIL_USE_SSL: False
      SETTING_EMAIL_USE_TLS: True
      SETTING_ZULIP_SERVICE_PUSH_NOTIFICATIONS: True
      SETTING_ZULIP_SERVICE_SUBMIT_USAGE_STATISTICS: False

编辑compose.yaml基础文件:

nano compose.yaml

我们使用反向代理,所以在这里注释掉Zulip容器的443端口,同时将对外暴露的80端口改为8089:

---
services:
  zulip:
    image: "ghcr.io/zulip/zulip-server:11.6-1"
    restart: unless-stopped
    build:
      context: .
    ports:
      - name: smtp
        target: 25
        published: 25
        app_protocol: smtp
      - name: http
        target: 80
        published: 8089
        app_protocol: http
#      - name: https
#        target: 443
#        published: 443
#        app_protocol: https

拉取镜像并初始化Zulip:

docker compose pull
docker compose run --rm zulip app:init

如果一切正常,您应该看到类似下图的回显:

如果输出结果并非以该内容结尾:

=== End Initial Configuration Phase ===

请仔细阅读输出结果以查找警告或错误。

现在就可以启动Zulip了:

docker compose up zulip --wait

配置Ferron反向代理:

nano /etc/ferron.kdl

写入如下内容:

zulip.example.com {
   proxy "http://127.0.0.1:8089/"
   proxy_request_header_replace "Host" "{header:Host}"
}

重载Ferron:

systemctl reload ferron

生成一个链接,在浏览器访问该链接创建新组织:

docker compose exec -u zulip zulip \
    /home/zulip/deployments/current/manage.py generate_realm_creation_link

如图所示:

效果:

关于移动推送通知,除了设置SETTING_ZULIP_SERVICE_PUSH_NOTIFICATIONS: True,还需要执行如下命令注册才能使用:

docker compose exec -u zulip zulip \
    /home/zulip/deployments/current/manage.py register_server

如果您的hostname(完全限定域名fqdn)之前已经注册过,可以使用下面的命令迁移注册:

docker compose exec -u zulip zulip \
    /home/zulip/deployments/current/manage.py register_server --registration-transfer

排查错误:

docker compose exec zulip bash
cat /var/log/zulip/errors.log

sing-box服务端中转+wireguard解锁DMMTV配置

2026-04-18 19:55:32

起因:一台落地用的日本鸡DMMTV解锁掉了,但是套WARP又可以解锁,然后落地鸡直连太慢,所以用别的小鸡中转一下,就有了下面的配置。这两台机器到期我不打算续费了,所以把配置贴上来备份一下,以备不时之需= =以下配置全部基于sing-box 1.12。如sing-box更新不保证这些配置一直正确无误。

中转鸡配置:

{
  "log": {
    "level": "info"
  },
  "dns": {
    "servers": [
      {
        "type": "tls",
        "server": "8.8.8.8"
      }
    ]
  },
  "inbounds": [
    {
      "type": "anytls",
      "listen": "0.0.0.0",
      "listen_port": 8443,
      "users": [
        {
          "name": "fuckccp",
          "password": "hidden"
        }
      ],
      "padding_scheme": [
        "stop=8",
        "0=30-30",
        "1=100-400",
        "2=400-500,c,500-1000,c,500-1000,c,500-1000,c,500-1000",
        "3=9-9,500-1000",
        "4=500-1000",
        "5=500-1000",
        "6=500-1000",
        "7=500-1000"
      ],
      "tls": {
        "enabled": true,
        "server_name": "fuckccp.example.com",
        "alpn": [
          "h2"
        ],
        "acme": {
          "domain": [
            "fuckccp.example.com"
          ],
          "dns01_challenge": {
            "provider": "cloudflare",
            "api_token": "hidden"
          }
        }
      }
    }
  ],
  "outbounds": [
    {
      "type": "direct",
      "tag": "direct"
    },
    {
      "type": "shadowsocks",
      "tag": "unlock-out",
      "server": "1.2.3.4",
      "server_port": 8081,
      "method": "chacha20-ietf-poly1305",
      "password": "hidden"
    }
  ],
  "route": {
    "rules": [
      {
        "action": "sniff"
      },
      {
        "protocol": "dns",
        "action": "hijack-dns"
      },
      {
        "rule_set": [
          "geosite-dmm",
          "geosite-dmm-porn",
          "geosite-abema",
          "custom-mgstage"
        ],
        "outbound": "unlock-out"
      }
    ],
    "rule_set": [
      {
        "type": "local",
        "tag": "custom-mgstage",
        "format": "binary",
        "path": "/root/mgstage.srs"
      },
      {
        "type": "remote",
        "tag": "geosite-dmm",
        "format": "binary",
        "url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-dmm.srs",
        "download_detour": "direct",
        "update_interval": "7d"
      },
      {
        "type": "remote",
        "tag": "geosite-dmm-porn",
        "format": "binary",
        "url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-dmm-porn.srs",
        "download_detour": "direct",
        "update_interval": "7d"
      },
      {
        "type": "remote",
        "tag": "geosite-abema",
        "format": "binary",
        "url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-abema.srs",
        "download_detour": "direct",
        "update_interval": "7d"
      }
    ]
  }
}

落地鸡配置:

{
  "log": {
    "level": "info"
  },
  "dns": {
    "servers": [
      {
        "type": "tls",
        "server": "8.8.8.8"
      }
    ]
  },
  "endpoints": [
    {
      "type": "wireguard",
      "tag": "wg-unlock",
      "system": true,
      "name": "wg0",
      "mtu": 1280,
      "address": [
        "10.0.0.2/32"
      ],
      "private_key": "hidden",
      "peers": [
        {
          "address": "engage.cloudflareclient.com",
          "port": 2408,
          "public_key": "hidden",
          "allowed_ips": [
            "0.0.0.0/0"
          ],
          "persistent_keepalive_interval": 30,
          "reserved": [0, 0, 0]
        }
      ]
    }
  ],
  "inbounds": [
    {
      "type": "shadowsocks",
      "listen": "::",
      "listen_port": 8081,
      "method": "chacha20-ietf-poly1305",
      "password": "hidden"
    }
  ],
  "outbounds": [
    {
      "type": "direct",
      "tag": "direct"
    }
  ],
  "route": {
    "rules": [
      {
        "action": "sniff"
      },
      {
        "protocol": "dns",
        "action": "hijack-dns"
      },
      {
        "rule_set": [
          "geosite-dmm",
          "geosite-dmm-porn",
          "geosite-abema",
          "custom-mgstage"
        ],
        "outbound": "wg-unlock"
      }
    ],
    "rule_set": [
      {
        "type": "local",
        "tag": "custom-mgstage",
        "format": "binary",
        "path": "/root/mgstage.srs"
      },
      {
        "type": "remote",
        "tag": "geosite-dmm",
        "format": "binary",
        "url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-dmm.srs",
        "download_detour": "direct",
        "update_interval": "7d"
      },
      {
        "type": "remote",
        "tag": "geosite-dmm-porn",
        "format": "binary",
        "url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-dmm-porn.srs",
        "download_detour": "direct",
        "update_interval": "7d"
      },
      {
        "type": "remote",
        "tag": "geosite-abema",
        "format": "binary",
        "url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-abema.srs",
        "download_detour": "direct",
        "update_interval": "7d"
      }
    ]
  }
}

mgstage.srs是我自定义的一个规则,用于解锁MGSTAGE,不需要可以移除,需要的话可以新建一个json文件:

nano mgstage.json

写入如下内容:

{
  "version": 3,
  "rules": [
    {
      "domain_suffix": [
        "mgstage.com"
      ]
    }
  ]
}

编译成srs格式:

sing-box rule-set compile mgstage.json

然后落地鸡解锁用到的wiregurad配置我是使用wgcf生成的,先安装wgcf:

wget https://github.com/ViRb3/wgcf/releases/download/v2.2.30/wgcf_2.2.30_linux_amd64
mv wgcf_2.2.30_linux_amd64 wgcf
chmod +x wgcf

生成wireguard配置:

./wgcf register
./wgcf generate

查看wireguard配置,把里面的PrivateKey和PublicKey复制粘贴到sing-box的配置文件内就行了:

cat wgcf-profile.conf

这样客户端连接中转鸡的anytls节点,匹配到DMM的流量会通过shadowsocks分流到落地鸡,落地鸡再把DMM流量分流到wireguard。其他流量还是直接走中转鸡。