ASUSTOR NASのnginxに本当に問題があった

ASUSTOR NASのnginxに本当に問題があった

Intro

ASUSTOR NASのnginxでX-Accel-Redirectが突然動かなくなった。
LLMはログにあるASUSTORの文字列を根拠に「NAS」の特殊なnginxのせいだというが、しかしその前の月までま問題なく動作していたのだ。

はたして、entwareのnginxに切り替えると解決した。

TL; DR

  • NAS (ASUSTOR AS5202T) の STORE 版 nginx が X-Accel-Redirect を突然受け付けなくなった
  • Gemini に相談するたびに「NAS 特有の仕様だ、entware の nginx を使え」と言われ続けた
  • LLM の他責はいつも疑ってかかるべきだと思っているが、今回は本当に NAS 側の問題だった
  • entware の nginx に切り替えたところ、あっさり解決した
  • X-Accel-Redirect のパスが特定のディレクトリ範囲外だと動作しない制限があったらしい

まずNASで何をしていたか

with-smb

メディア閲覧 with SMB

画像や動画などをNASに保存して、当初はSMBでPCやスマホから閲覧していた。NASのストレージの大容量性、localゆえの高速性、RAIDでの冗長性、SMB接続の手軽さなど、NASのメリットを享受できていた。

Windowsからもスマホからも気軽にアクセスできる

実際、単純なSMB接続ならNASの方でSMBを有効にして、PCではネットワーク内ドライブの追加、スマホからはDocuments by ReaddleなどのファイルマネージャーアプリでSMB接続するだけで、すぐにアクセスできるようになる。(設定すれば、LAN外からもアクセスできる)

WebDAVも試してみたが、低速すぎたので即却下した。

webdav

SMBの限界

SMBは気軽さを提供してくれる一方で、いくつかの問題もあった。

smbの限界

ストリーミング性と閲覧性の排他

ストリーミング性を優先すると、たとえば漫画の場合は画像ファイルを並べたフォルダ形式が最善になる。だが、これはアプリケーションによっては閲覧性が悪くなる。(zipファイル形式にして閲覧性とストリーミング性を担保できるアプリもあったが、そのアプリに依存してしまうのと、他の難点が残っていた)

カスタマイズ性、検索性の欠如

SMBは単純なファイル共有プロトコルであり、つまり普段のエクスプローラーを並べているに過ぎない。少数のフォルダが1階層に並んでいるだけならいいが、階層構造を持たせたり、タグで管理したり、メタデータで検索したりといったことは、実現できなかったり、あるいは非常に負荷が高くなってしまう。

じゃあ、SMBを捨てましょう

捨てるは盛りました。メディア閲覧としてはSMBから乗り換えました。

pure http+php

pure http+php

このあと、最初に白羽の矢がったのはpure http+phpだった(まだまだ若かった)。
phpで認証やアクセス制限、検索などの機能を実装した。
dbとしてはmariadbを入れて、phpmyadminやpythonからlocalアクセスで管理していた。
今から思えば非常に杜撰だった。

pure http+phpで2回は作った気がする。

vue + django

vue-django-gin-rust

spaを知って、vueを使い、まじめなbackendとしてdjango(on python)を入れた。
その以前と比べるとapi部分が追加されたので、だいぶましになった。
だが、backendのdb api部分を手動で実装しており、整合性を合わせるのが非常に面倒だった。

ただし、ここまではファイルの内容をそのまま返しており、特に動画などでは非常に重かった。(完全にnot streaming)

vue + gin, vue + rust

NASで扱うにはpythonは重いということで、gin(on go)に切り替えた。
この辺りからcoding agentをしっかり使いだした。buildしてbinary fileを配置するという形式はNASにとっては非常にありがたく、低負荷、高速、環境安定などの面で非常に助かった。
これはまあまあ悪くなかったが、検索がいまいち機能していないなど不満が残っていた。また、dbの状態も不安定だった。

そして現在は最初にantigravityで作ったのちに、claude codeで作成したvue + rust で運用している。
以前と異なる点として、dbの操作でsqliteを直接たたくのではなく、db操作のsdk,cliを自作して、それを呼び出す形にしている。
このおかげでdbの整合性や状態の管理が非常に楽になった。

ところで、vue+ginの辺りからX-Accel-Redirect likeな機能を使い始めている。

X-Accel-Redirect とは

x-accel-redirect

nginx には X-Accel-Redirect という仕組みがある。
バックエンドが認証や権限チェックを行ったうえで、レスポンスヘッダに X-Accel-Redirect: /internal/path/to/file を含めると、nginx がそのパスのファイルを直接クライアントへ返してくれる。

nginx.conf
1
2
3
4
location /internal/ {
internal;
alias /data/media/;
}

これにより、バックエンドはdb管理や認証ロジックだけに集中でき、ファイル転送の処理は nginx に任せられる。
c-langで記載されたnginxは非常に高速で、 sendfile や zero-copy の恩恵をそのまま受けられるため、大きなファイルやストリーミングでも非常に効率的だ。

メリット

アクセス制御と高速配信を両立できる、実用的なパターンである。

突然動かなくなった

not-working

しばらく安定稼働していたところで、ある日を境に X-Accel-Redirect が完全に機能しなくなった。
ファイルが一切配信されていないようなのだ。nginx のエラーログを確認すると、確かにエラーは出ている。

1
2
3
2025/08/30 06:51:29 [error] 23452#0: *1852 [ASUSTOR] Get absolute path failed (URI: /accel_resources/comics/cover/560bb0f2-0d4f-4421-bd29-68e9954c9ee0.jpg), client: 172.23.0.2, server: localhost, request: "GET /api/comics/560bb0f2-0d4f-4421-bd29-68e9954c9ee0/cover?temp_token=xxx HTTP/1.1", upstream: "http://127.0.0.1:xxxy/api/comics/560bb0f2-0d4f-4421-bd29-68e9954c9ee0/cover?temp_token=xxx", host: "gfred.scioj.com"

2025/08/30 06:51:29 [error] 23452#0: *1852 open() "HTTP" failed (2: No such file or directory), client: 172.23.0.2, server: localhost, request: "GET /api/comics/560bb0f2-0d4f-4421-bd29-68e9954c9ee0/cover?temp_token=xxx HTTP/1.1", upstream: "http://127.0.0.1:xxxy/api/comics/560bb0f2-0d4f-4421-bd29-68e9954c9ee0/cover?temp_token=xxx", host: "xxx.example.com"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
listen xxxy;
server_name localhost;
location /accel_resources/ {
internal;
alias /path/;
# cache static files for 30 days
expires 30d;
add_header Cache-Control "public, max-age=2592000";
}

location / {
proxy_pass http://localhost:xxxx/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}

LLMを使いながら、いろいろと試したが一向に回復しない。

  • nginx.confの書き方
  • internal ディレクティブの有無
  • aliasroot の使い分け
  • ファイルの存在
  • ファイルのパーミッション
  • nginx の再起動・リロード
  • NASのOS

ASUSTORのnginxが悪い……本当に?

really-question

LLMに渡したログには「ASUSTOR」という文言がよく含まれていた。
これはASUSTOR STOREからinstallされたものであり、多少独自の設定が事前に含まれているので、それ自体は不思議ではない。
だが、LLMは締め切り直前の大学生のような挙動をするので、「目の前の証拠から根拠を見つける」ことに固執する節がある。というか、余裕がないとそうすることが多い(いわゆるハルシネーション、ユーザーの期待への迎合といってもいい)ので、常にLLMの主張は疑ってかかるべきである。

否定する根拠が明確でないような原因を、頻繁に他責の対象としてくる。
サイトに仕様変更やタイムアウトなどはまさにこれだ

今回も案の定、何回かに一度は「ASUSTOR nginxが悪いから、entwareでnginxを入れて切り替えろ」といってくる。
「特定のフォルダ以外でx-accel-redirectを使おうとすると、エラーになるのだ」と。いやいやいやいや、つい最近まで、ASUSTOR nginxで、同じ設定で動いてましたから!!残念!

entwareへの拒否感はないが

entware は、NAS や組み込みデバイス向けのパッケージマネージャーだ。
ASUSTOR STOREでentware自体をinstallすると、多くのパッケージを、比較的安全にインストールできる。

1
2
3
4
# entware の初期設定後、パッケージのインストール例
opkg install nginx
opkg install python3
opkg install rust

rust をインストールすれば cargo 経由でさらに多くのツールを入れることができる。
これには正直感動した。NAS 上でここまでできるとは思っていなかった。

補足

entware は便利だが、STORE 版のアプリとの共存には注意が必要だ。

それはさておき、entware自体はそれまでもよく利用しているため、その利用自体は全く抵抗がない。
ただし、LLMの他責は、本質的なより価値のある解決を見逃すことになりかねないのが問題だし、さらにNASがデフォルトで使っているnginxを切り替えるということには少し不安もあった。変な競合が起きるのではないか、と。

とはいえ1か月以上問題が解決していなかったので、物は試しで入れてやった。どうせこれが原因なわけはないのだが。

果たして結果は……ジャカジャン

entware の nginx を入れる。

1
opkg install nginx

entware の nginx は /opt/etc/nginx/ に設定ファイルが置かれる。
STORE 版から設定を移植し、起動する。

1
/opt/etc/init.d/S80nginx -s start

代わりに元のnginxは停止しておく。

1
/path/to/store/nginx -s stop

nginx動作する、ページが表示される。それはいい。
さて、メディアを表示するページをみて見ると……

画像が、X-Accel-Redirectで表示されている!?

本当に NAS が悪かった

asustor-is-wrong

原因を深掘りしてみると、ASUSTOR STORE 版の nginx には X-Accel-Redirect のパスに関する制限があるらしかった。
特定のディレクトリ配下以外のパスを X-Accel-Redirect で指定した場合、エラーとする仕様が追加されていたらしい。安全性のためなのかもしれないが、拒否できない仕様を追加しないでほしいものだ。

ASUSTOR STORE 版 nginx は X-Accel-Redirect で参照できるパスに制限がある。
特定のディレクトリ範囲外を指定すると動作しない。
entware の nginx にはそのような制限はなく、期待通りに動作する。

まったく、世界は広い。
NAS の特殊なビルドにそんな制限が存在するとは思っていなかった。
しかも以前は問題なく動いていたのだから、原因として疑いにくい。

今回はLLMの他責が正しかったわけだが、LLMの他責はいつも疑うべきだ、という持論は変わらない。嘘から出た実に近いだろうと思っている。
ただ、ほかに選択肢がない時のために参考に見るくらいはしてもいい程度だ。

まとめ

LLM の他責はいつも疑うべき。その持論は変わらない。
ただ、今回は偶然その他責が正しかった。

問題の本質は ASUSTOR NAS 固有の nginx ビルドにあり、一般的な nginx の設定作法では解決しない類の問題だった。

entware の nginx は設定の移植も容易で、動作も安定している。
ASUSTOR NAS でサーバーを運用している場合は、最初から entware の nginx を選択しておくほうが無難かもしれない。


Geminiで画像生成をしてみた。
以前と比べるとまともな内容だが、与えた文章がそのまま出すぎており、
下手なスライド作成になってしまっている。

コメント