释放小七猫的分享欲

Nginx 搭建 Emby 认证服务器 - 以 OpenWRT 为例

tags: NAS
@ 18/11/2025

Nginx 搭建 Emby 认证服务器 - 以 OpenWRT 为例

以前使用 Emby 一直采用别人的补丁文件,一件替换后就可以实现破解,但……

  1. 使用别人的破解补丁,感觉不太放心(其实是多虑了,存的都是正经电影)
  2. Emby 出新版本之后,必须等到补丁作者更新,我才能更新

我是一个爱用新版本的人,前几天 Emby 更新了 4.9.1.90 版本,我苦等补丁作者更新许久,但其博客一直停留在一个多月前,似乎也没有更新的迹象,所以只能自己动手了。

CA 自签证书

先解决证书问题,

第三方网站签发

最简单的方法就是找个网站:

gmcert.org

  • 证书算法:选 RSA 算法,长度至少 2048
  • 主题名称:mb3admin.com
  • 有效天数:3650
  • 证书链选项:勾选自动包含 CA 证书链
  • 输出格式:一般就用 pem 格式或 cer(crt)/key 格式就行

但我使用的 cer/key 证书链,后面用这两个格式做示例,操作方法都是一样的。

生成两个证书:mb3admin.cer,mb3admin.key,下载下来保存好。

linux OpenSSL 签发

mkdir -p <username>/<docker-file-path>/nginx/cert/mb3admin.com && cd <username>/<docker-file-path>/nginx/cert/mb3admin.com

# 生成 CA 密钥
openssl genrsa -out ca.key 2048
# 生成 CA 证书
openssl req -x509 -new -nodes -key ca.key -subj "/C=CN/ST=Beijing/L=Beijing/O=<username>/OU=<username>/CN=<username>/emailAddress=<user-email>" -days 36500 -out ca.crt
# 将 CA 转换成 p12 格式,并指定密码 (<username>)
openssl pkcs12 -export -clcerts -in ./ca.crt -inkey ca.key -out ca.p12 -password pass:<username>
# 将 p12 格式的证书 Base64 编码
base64 ca.p12
# Base64 一行不能超过 76 字符,超过则添加回车换行符。如果因为换行的原因,不能安装证书,可以使用 -w 参数
base64 -w 0 ca.p12
# 将 CA 转换成 pem 格式
openssl x509 -outform pem -in ca.crt -out ca.pem
# 生成服务端私钥 server.key
openssl genrsa -out server.key 2048
# 生成服务端证书请求 server.csr
openssl req -new -sha256 -key server.key -out server.csr -subj "/C=CN/L=Beijing/O=<username>/OU=<username>/CN=mb3admin.com/CN=*.mb3admin.com"
# 生成服务端证书 server.crt
openssl x509 -req -extfile <(printf "subjectAltName=DNS:mb3admin.com,DNS:*.mb3admin.com") -days 3650 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt

上述代码中替换一下自己的相关信息即可(也可以直接去参考资源中获取直接执行的代码):

<username>
<user-email>
<docker-file-path>

Nginx 搭建认证服务器——OpenWRT 为例

OpenWRT 的配置文件路径为 /etc/nginx/conf.d/,假设你已经搭建好了反向代理环境,仅需配置假的 mb3admin.com 认证站点。

假设把证书放置在 /etc/nginx/conf.d/certs/ 下:

root@OpenWRT:/etc/nginx/conf.d/certs# ls
mb3admin.cer      mb3admin.key

新建一份配置文件 mb3admin.conf,内容如下,需要注意的地方已经添加了注释

server {
    listen 443 ssl;
    listen [::]:443 ssl;
    http2 on;

    server_name mb3admin.com;

    # mb3admin 专用证书(使用你指定的路径)
    ssl_certificate     /etc/nginx/conf.d/certs/mb3admin.cer;
    ssl_certificate_key /etc/nginx/conf.d/certs/mb3admin.key;
    ssl_protocols       TLSv1.2 TLSv1.3;
    ssl_ciphers         ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
    ssl_prefer_server_ciphers off;
    ssl_session_cache shared:SSL:32k;
    ssl_session_timeout 64m;

    # 跨域和安全头配置(确保 Emby 客户端正常请求)
    add_header Strict-Transport-Security "max-age=63072000" always;
    add_header Access-Control-Allow-Origin *;
    add_header Access-Control-Allow-Headers *;
    add_header Access-Control-Allow-Methods *;
    add_header Access-Control-Allow-Credentials true;

    # Emby 认证破解核心接口(仅对 mb3admin.com 生效)
    location /admin/service/registration/validateDevice {
        default_type application/json;
        return 200 '{"cacheExpirationDays": 3650,"message": "Device Valid","resultCode": "GOOD"}';
    }

    location /admin/service/registration/validate {
        default_type application/json;
        return 200 '{"featId":"","registered":true,"expDate":"2099-01-01","key":""}';
    }

    location /admin/service/registration/getStatus {
        default_type application/json;
        return 200 '{"deviceStatus":"","planType":"Lifetime","subscriptions":{}}';
    }

    location /admin/service/appstore/register {
        default_type application/json;
        return 200 '{"featId": "","registered": true,"expDate": "2099-01-01","key": ""}';
    }

    location /emby/Plugins/SecurityInfo {
        default_type application/json;
        return 200 '{"SupporterKey": "", "IsMBSupporter": true}';
    }
}

接下来需要让 Emby 将域名 mb3admin.com 劫持到 OpenWRT 上,这对于 OpenWRT 来说非常简单。

现在 IPv6 已经基本普及,所以,如果你的 Emby 服务器有 IPv6 地址的话,就需要把 IPv6 的解析也加上,否则服务器还是会优先解析到 mb3admin.com 的 IPv6 地址上,因为它是双栈的。

在 Emby 服务器上 ping 一下:

root@testing:~# ping mb3admin.com
PING mb3admin.com(mb3admin.com (fd40:f27e:ca6::1)) 56 data bytes
64 bytes from mb3admin.com (fd40:f27e:ca6::1): icmp_seq=1 ttl=64 time=0.251 ms
64 bytes from mb3admin.com (fd40:f27e:ca6::1): icmp_seq=2 ttl=64 time=0.660 ms
^C
--- mb3admin.com ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 0.251/0.455/0.660/0.204 ms

root@testing:~# ping4 mb3admin.com
PING  (10.0.0.1) 56(84) bytes of data.
64 bytes from xunlei.550293.xyz (10.0.0.1): icmp_seq=1 ttl=64 time=0.630 ms
64 bytes from xunlei.550293.xyz (10.0.0.1): icmp_seq=2 ttl=64 time=0.941 ms
^C
---  ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 0.630/0.785/0.941/0.155 ms

可以看到,的确优先返回了 IPv6 地址,但没关系,双栈都已经被我劫持到路由器上了。

然后我们用浏览器访问,或者通过 curl 工具访问:

  1. https://mb3admin.com/admin/service/registration/validateDevice/
  2. https://mb3admin.com/admin/service/registration/validate/

查看返回信息是否正确:

root@OpenWRT:/etc/nginx/conf.d# curl -kl https://mb3admin.com/admin/service/registration/validateDevice/
{"cacheExpirationDays": 3650,"message": "Device Valid","resultCode": "GOOD"}

root@OpenWRT:/etc/nginx/conf.d# curl -kl https://mb3admin.com/admin/service/registration/validate/
{"featId":"","registered":true,"expDate":"2099-01-01","key":""}

如果和我一样就正确了。

在网页端激活 Emby

如果你是刚安装好的 Emby,那么直接进入后台,Emby Premiere 选项,随便输入一个密钥,保存。注意,这里不会提示已经激活啥的,但其实已经起作用了。

如果你之前已经通过别的方式激活过 Emby,比如替换破解文件,那么直接进入后台可能会激活不了,请按以下步骤操作:

  1. 卸载 Emby:apt remove emby-server,并删除残留文件 rm -rf /opt/emby-server/,这一步只是删除程序,不会清除用户数据。
  2. 删除旧的激活文件:rm -rf /var/lib/emby/data/activitylog*
  3. 重新安装 Emby:apt install ./emby-server-deb_4.9.1.90_amd64.deb

然后再进入后台激活,激活后最好重启一下 Emby 服务:

sudo systemctl restart emby-server

不出意外的话,控制台会出现金牌标识。

但很遗憾,这种方式的激活只能在内网使用,因为 Emby 的客户端也会进行正版验证,在外网当然很难把 mb3admin.com 劫持到我们的路由器上,但幸运的是我们还有一计。

Emby Server 修改认证站点

要使用这个方法,首先你要满足以下几个条件

  1. 确保自己已经有能力搭建一个私有域名的假认证站点,公网无法劫持 mb3admin.com,只能每个设备都去劫持,很麻烦
  2. 假认证站点必须可以公网访问,考虑到家庭宽带一般封禁了 443 端口,因此可以考虑采用加端口号和内网穿透的方案
  3. 关于 SSL,经过我的测试,证书只要有就行(必须 https 访问),匹不匹配域名不重要

在前文,我们已经在 OpenWRT 上搭建好了一个假的 mb3admin.com 服务器,但由于这次我们要上公网,因此得改改域名。

假设我们的域名是 emby-crack.com,证书已经匹配好(这是你自己的域名,要搞证书就很容易了,不用再去搞自签名证书),说到底也就是反向代理里面这几行的事:

    server_name emby-crack.com;

    # mb3admin 专用证书(使用你指定的路径)
    ssl_certificate     /etc/nginx/conf.d/certs/emby-crack.com.cer;
    ssl_certificate_key /etc/nginx/conf.d/certs/emby-crack.com.key;

还有一个我非常推荐的方案,只需要有一个域名即可,那就是使用大善人 Clouflare 的 Worker 功能。

然后编辑这个项目的 worker.js,修改为以下内容,其实和反向代理配置差不多,只能换成了 js 语言来写。

export default {
    async fetch(request, env, ctx) {
        const url = new URL(request.url);
        const path = url.pathname;

        // 定义路由对应的响应内容
        const routes = {
            "/admin/service/registration/validateDevice": {
                status: 200,
                body: JSON.stringify({
                    cacheExpirationDays: 3650,
                    message: "Device Valid",
                    resultCode: "GOOD",
                }),
            },
            "/admin/service/registration/validate": {
                status: 200,
                body: JSON.stringify({
                    featId: "",
                    registered: true,
                    expDate: "2099-01-01",
                    key: "",
                }),
            },
            "/admin/service/registration/getStatus": {
                status: 200,
                body: JSON.stringify({
                    deviceStatus: "",
                    planType: "Lifetime",
                    subscriptions: {},
                }),
            },
            "/admin/service/appstore/register": {
                status: 200,
                body: JSON.stringify({
                    featId: "",
                    registered: true,
                    expDate: "2099-01-01",
                    key: "",
                }),
            },
            "/emby/Plugins/SecurityInfo": {
                status: 200,
                body: JSON.stringify({
                    SupporterKey: "",
                    IsMBSupporter: true,
                }),
            },
        };

        // 检查请求路径是否匹配已定义的路由
        if (routes[path]) {
            const { status, body } = routes[path];
            return new Response(body, {
                status,
                headers: {
                    "Content-Type": "application/json",
                },
            });
        }

        // 对于未匹配的路由,返回 404
        return new Response(JSON.stringify({ error: "Not found" }), {
            status: 404,
            headers: {
                "Content-Type": "application/json",
            },
        });
    },
};

编辑好之后一定要保存,然后退出编辑器。

在部署页面部署好修改后的代码

然后访问 https://emby-cert.xxxx.workers.dev/admin/service/registration/validate,测试能否返回指定的json字符串即可。

Clouflare 的 workers.dev 域名在墙内无法访问,这也是我说需要有一个域名的原因,在以下位置绑定好自己的域名,用自己的子域名访问就可以了。

copy 待拷贝文件

以下内容参考 用于 Emby Server 的修改认证站点&搭建认证站点

原作者已经写得非常详细,在这里我梳理一下大概的步骤。

需要修改的文件目录如下:

├─Emby.Server.Implementations.dll
├─Emby.Web.dll
├─MediaBrowser.Model.dll
└─dashboard-ui
    ├─embypremiere
    │  └─embypremiere.js
    └─modules
        └─emby-apiclient
            └─connectionmanager.js

一个个拷贝出来有点烦,可以一键拷出:

# 先创建目标目录(如果不存在)
mkdir -p target_dir

# 复制文件并保留相对目录结构
cd /opt/emby-server/system/
cp --parents Emby.Server.Implementations.dll Emby.Web.dll MediaBrowser.Model.dll dashboard-ui/embypremiere/embypremiere.js dashboard-ui/modules/emby-apiclient/connectionmanager.js -t target_dir

然后想办法把这些文件拷贝到 Windows 电脑上。

修改 Emby.Server.Implementations.dll

下载 dnSpy 软件:dnSpy/releases,请自行下载最新版

原文的破解链接有点问题,假设你的破解服务器域名是 emby-crack.com,那么直接将 mb3admi.com 替换为 emby-crack.com 就可以了,替换之后,为避免出错,最好是把修改后的地址贴到浏览器中试一试,以免打错字。

修改 Emby.Web.dll

这份文件中的 Emby.Web.dashboard_ui.modules.emby_apiclient.connectionmanager.js 无法在软件中修改,因此需要下载到本地,改好后再传上去。

修改 MediaBrowser.Model.dll

纯为了好看,改不改都可以,嫌麻烦可以不改

不改的话高级页面不会显示已激活,但功能已经可以正常使用

修改 embypremiere.js 和 connectionmanager.js

文本文件就很简单了,直接记事本打开。替换掉 mb3admin.com,就完事。

将文件还原到原来的位置

关闭服务器,将上述文件全部替换到原文件位置,使用 cp -r * /opt/emby-server/systemc/ 直接覆盖原文件即可,然后重启 Emby 服务 systemctl restart emby-server。