Plex 是个好东西,不仅界面美观、配置容易,上手还十分简单,是我个人媒体服务器首选。而且有公网的话,Plex 自带的远程访问服务(也就是中转)还可以直接让你在出门在外的时候,通过手机或是平板上的 Plex App 访问 Plex 媒体库,无需任何额外的设置。可美中不足的是,这玩意默认只映射 IPv4,不会自动映射到 IPv6。即使你已经在 Plex 的网络设置中勾选上 「启动支持 IPv6 的服务器」 ,它也视而不见,照样走它那 IPv4 的阳光大道。

没有公网 IPv4 的时候,Plex 的网络请求会像这样:

192-168-31-123.abcdefghjhfjkhasdafdsfecf.plex.direct

这都公网了,隔壁 Emby 直接域名解析上去就能用,就你 Plex 搞得这么娇气!

在现今 IPv4 资源枯竭的环境下,获取一个 IPv6 公网的难度绝对是要比 IPv4 小得多的多。因此,为了能充分利用手里的 IPv6 公网资源,我们需要简单地配置一下 Plex,好好治治它不老实走 IPv6 的坏毛病。

安装 DDNS-GO

使用 DDNS-GO 是为了解决动态公网的问题,毕竟 IPv6 一般不会是固定的。此外,使用 DDNS 还需要你拥有一个属于自己的域名。

这里使用 Docker Compose 进行安装,群晖用户不要忘了预创建 ddns-go 文件夹:

version: "3.9"
services:
  ddns-go:
    image: jeessy/ddns-go:latest
    container_name: ddns-go
    network_mode: host
    volumes:
      - ./ddns-go:/root
    environment:
      - TZ=Asia/Shanghai
    restart: unless-stopped

安装完后在浏览器中打开 http://主机IP:9876,配置 DDNS-GO。

选择你域名所在的 DNS 服务商。DDNS-GO 中不同的 DNS 服务商获取 Token 或是 API key 都会有相应的提示。这里以 Cloudflare 为例。

访问「创建令牌」页面,点击「创建令牌」;选择「编辑区域 DNS」,点击「使用模板」。在「区域资源」处选择「所有区域」,其余保持默认。

点击「继续以显示摘要」,完成创建后将秘钥粘贴至 DDNS GO 的 token 处即可。

这个 token 在下面的 acme.sh 中也会用到,可以保存在某处备用。

接着,启用 IPv6 配置,选择「通过网卡获取」IP 地址,在下方 Domains 里填入你想要使用的域名即可。

安装 ACME.SH

acme.sh 是一个用于签发证书的脚本,关于 ACME 协议 的相关知识,你可以自行查找资料。这里直接介绍 acme.sh 的使用方法。

你可以把 acme.sh 和 DDNS GO 安装在一个 compose.yaml 文件里,所以下面的配置我就省略掉一致的部分了。群晖用户不要忘了预创建 acme.sh 文件夹:

  acme.sh:
    image: neilpang/acme.sh
    container_name: acme.sh
    command: daemon
    volumes:
      - ./acme.sh:/acme.sh
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      - TZ=Asia/Shanghai
    restart: unless-stopped

如果网络不行,连接不到 ZeroSSL 的话(具体表现为签发证书的时候卡在 API 连接上),在拥有代理的前提下可以为容器配置 HTTP_PROXY

environment 项中增加两行:

    environment:
      - TZ=Asia/Shanghai
      - HTTP_PROXY=http://代理的IP:端口
      - HTTPS_PROXY=http://代理的IP:端口

启动容器后,进入容器的终端 sh

docker exec -it acme.sh sh

在 acme.sh 容器内部的终端执行后续的操作。

创建账户,记得改成自己的邮箱:

acme.sh --register-account -m i@example.com

使用上面 DDNS-GO 获取到的 Cloudflare 的 token,导入该 CF_Token

export CF_Token="Y_jpxxxxxxxxxx_qxxxxxxxxxxxxxxxxxxxxxxxxx"

申请证书,可以在 这里 查看更详细的 api 使用方法:

acme.sh --issue -d 'yourdomain.xx' -d '*.yourdomain.xx' --dns dns_cf

这是一个泛域名1的例子,个人建议直接签发泛域名,另外,第一个域名 -d 的域名使用根域名方便后续操作。

具体到某个域名的命令,比如本站 himiku.com 便是:

acme.sh --issue -d 'himiku.com' -d '*.himiku.com' --dns dns_cf

就可以申请到包含 himiku.com*.himiku.com 的有效期为 90 天的 SSL 证书了。

-----END CERTIFICATE-----
[Sat Nov 17 20:50:29CST 2023] Your cert is in: /acme.sh/himiku.com_ecc/himiku.com.cer
[Sat Nov 17 20:50:29CST 2023] Your cert key is in: /acme.sh/himiku.com_ecc/himiku.com.key
[Sat Nov 17 20:50:29CST 2023] The intermediate CA cert is in: /acme.sh/himiku.com_ecc/ca.cer
[Sat Nov 17 20:50:29CST 2023] And the full chain certs is there: /acme.sh/himiku.com_ecc/fullchain.cer

更具体的使用方法,还请详细参考 acme.sh 官方使用文档

如果你有在使用 oh-my-zsh 之类的命令行工具,那么可以添加一条别名:

alias acme.sh="docker exec acme.sh acme.sh"

后续就可以直接使用 acme.sh ,无需再 docker exec -it acme.sh sh 了。

如果没有,不进入容器内部终端的时候,后面的例子还请自行加上 docker exec acme.sh ,例如签发证书的时候:

docker exec acme.sh acme.sh --issue -d 'yourdomain.xx' -d '*.yourdomain.xx' --dns dns_cf

安装 Plex(可选)

如果你还没有安装 Plex,可以参考下方的 Compose 配置。唯一要注意的是要使用 host 的网络模式,bridge 模式在群晖中无法使用 IPv6 网络。

  plex:
    image: linuxserver/plex:latest
    container_name: plex
    network_mode: host #网络模式必须是host 
    environment:
      - PUID=1026
      - PGID=100
      - VERSION=docker
      # - PLEX_CLAIM=your-claim #在 https://www.plex.tv/claim/ 获取该验证码
    volumes:
      - ./plex:/config
      - /volume1/media:/media
    devices:
      - /dev/dri:/dev/dri
    restart: unless-stopped

生成 PKCS #12 证书

还是要用到 acme.sh,执行以下命令:

acme.sh --to-pkcs12 -d your.domain --password your-password

按上述申请证书的例子,应当是:

acme.sh --to-pkcs12 -d himiku.com --password my-plex-p12-password

应当有如下提示:

[Sat Nov 17 20:50:29CST 2023] The domain 'himiku.com' seems to have a ECC cert already, lets use ecc cert.
[Sat Nov 17 20:50:29CST 2023] Success, Pfx is exported to: /acme.sh/himiku.com_ecc/himiku.com.pfx

生成的 PKCS #12 证书就在 /acme.sh/himiku.com_ecc/himiku.com.pfx 文件夹内。

为 Plex 配置 PKCS #12 证书

将上一步中生成的 .pfx 格式的证书放在 Plex 能读取到的地方。我嫌麻烦,直接把 acme.sh 整个文件夹挂载到了 Plex 容器内,像这样:

    volumes:
      - ./plex:/config
      - /volume1/media:/media
      - /volume1/docker/acme.sh/himiku.com_ecc:/acme.sh/himiku.com_ecc

或者你也可以使用其他更方便的方法。

接着,在 Plex 的网络设置中,点击右侧「显示高级选项」,勾选「启动支持 IPv6 的服务器」,正确无误地填入「自定义证书位置」、「自定义证书加密密钥」以及「自定义证书域」。

往下滚动,关闭「启用中转」,填写「自定义服务器访问 URL」,链接需要完整到具体端口。

然后保存修改,再重启 Plex 容器,证书应该就生效了。Plex 的中转网络也应该变成了 IPv6 的地址,就像这样:

240e-xxxx-xxxx-xxxx-xxxx-xxxx-xxxx-xxxx.abcdefghjhfjkhasdafdsfecf.plex.direct

自动更新 PKCS #12 证书

手动更新肯定是不现实且麻烦的,所以我们可以在群晖的控制面板中,新增一个定时脚本

在自定义脚本中填入以下内容:

#生成证书
acme.sh --to-pkcs12 -d your.domain --password your-password
#重启plex
docker restart plex

时间可以设置为每月每 3 个月运行一次,不必太频繁。你可以在创建完脚本后立刻运行一次测试,看看 Plex 是否用成功上了这个证书。

如此一系列操作下来,就可以享受 Plex 上由 IPv6 带来的乐趣了,快来试试吧!!

参考


  1. 泛域名即域名泛解析,指利用通配符 * (星号)作为子域名解析时,可以实现匹配所有的子域名。
  2. 本来在 A酱 的指导下学会了用 openssl 命令转换 p12 证书,哪知查了下 acme.sh 文档,人家自带这个功能!嘛,省事了倒是。