投稿

ラベル(NGINX)が付いた投稿を表示しています

OpenWrt で Let's Encrypt (with acme.sh)

イメージ
このブログ記事を最初にまとめた当時(2020-11-11)には気付かなかったが、現在(2023-12-06)ではいつの間にか、OpenWrt のパッケージモジュールとして acme が用意されており、さらには LuCI から使うための luci-app-acme までも存在している。以前の僕はこれらの OpenWrt パッケージについて知らなかったので、acme.sh の 公式サイト の説明に従って一般的な Linux マシンとしてインストールし、コマンドを実行して使用してと、愚直に自力の作業をしていたものである。今では OpenWrt の acme.sh についての 公式の説明 も存在するので、それに従って作業すれば、ほとんど苦もなく完了できる。 だが、acme.sh の実行による Let's Encrypt からの証明書の発行が半自動化されたとはいえ、DNS や NGINX などと連携させる必要があり、総合的な話としては一定の知識を要するので、ここにまとめておきたいと思う。 Web ルートの準備 acme.sh では証明書の発行時の身元確認の方式として、Web ルートに .well-known/acme-challenge という一時的な隠しフォルダを作成し、そこにユニークな文字列からなるファイル名を持ったファイルを設置して、インターネット側から http://(ドメイン名)/.well-known/acme-challenge/(ファイル名)にアクセスできるかどうかで、確認するという形になっている。 このため、いきなり、acme を使うのではなくて、先に DNS 側でドメインが OpenWrt ルーターの IP を指し示すように設定しておき、さらに OpenWrt ルーター側では、NGINX の設定で、そのドメイン名での http アクセスが /www 以下に対応付けられるようにしておかなければならない。 DNS の設定 A レコードでデフォルトドメインがルーターの IP アドレスを指し示すように設定している他、CNAME で www がデフォルトドメインの別名であるようにしている。CAA レコードは今回の趣旨とは全く関係がないオマケで、無関係の他者が勝手にこのドメイン名を使った証明書を作成することを防ぐためのものである( 参考 )

NGINX の SSI

OpenWrt サーバーで運用している NGINX で SSI を試しに使ったみた感じのメモ。 Apache と違って、NGINX では SSI のサポートは消極的・限定的。何年も前から状況が変わらないので、開発中というわけではないだろう。静的コンテンツに特化した NGINX の特性や開発ポリシー的なものと思われる。また、動的コンテンツを使いたいのであれば、サーバーサイドなら PHP、フロントエンドなら JavaScript という世の中の確立された相場もあるので、「今さら SSI」という感じでもあるだろう。 NGINX の設定 SSI は一々、NGINX で HTML の内容をパースするため、NGINX のパフォーマンスに影響が大きいので、無差別に SSI をオンにしないように、NGINX の conf の location で対象を絞った方がいいと思う。例えば、index.html にどうしてもアクセスカウンターを SSI で表示させたいと思っているとしたら、次のようにする: location /index.html { ssi on; ssi_types text/plain; # デフォルトの text/html に加えて、text/plain も扱う場合 root /www } 前述のように、NGINX の SSI は、静的なファイルのインクルードか、CGI からの出力をインクルードする程度のものしか対応する気がないようである。CGI からの出力を HTML ファイルの中に埋め込んで表示する場合は、include virtual コマンドを使う: 引数を与えたい場合 ここで、アプリケーション・サーバーとしては uWSGI を使っている(👉 OpenWrt で uWSGI 環境を整える )。 CGI の場合 uWSGI の CGI モードで動かしている Python プログラムの場合、「?」の後の QUERY_STRING を「+」を 区切り文字 デリミター として使い、各 key=value のペアは urlencode して「=」は %3D となっているものを使う必要があった。 このようにすることで、uWSGI の CGI プラグインは、最初のペア(key1=value1)を sys.argv

OpenWrt で uWSGI 環境を整える

イメージ
OpenWrt(23.05)に Web サーバーとして NGINX(SSL 版)を利用し、 uWSGI ミューウィズジー をアプリケーションサーバーとして連携する方法について記す。 前提状況:USB フラッシュドライブ WWW 用のデータを置く場所として USB フラッシュの外部ドライブを用意(👉 OpenWrt での USB フラッシュドライブ )し、さらに Extroot 化(👉 OpenWrt のストレージを Extroot 化する )していることを前提としている。 LuCI もろとも Web サーバー(HTTPd)を SSL 対応 NGINX 化する 以前の OpenWrt 18.x とは飛躍的に進歩して、19.07 以降では SSL 対応版の NGINX が opkg として用意されている(以前は SSL 対応にするためには自前で Linux ソースコードからモジュールをビルドする必要があった)のみならず、NGINX 版 LuCI がセットアップされている opkg すら用意されており、OpenWrt コミュニティの旺盛な活動を感じる(👉 LuCI on other web servers > LuCI on nginx )。 opkg update opkg install luci-ssl-nginx opkg remove luci-ssl luci reboot デフォルトでインストールされている LuCI/uHTTPd の方は不要になるのでアンインストールした。 OpenWrt ルーターで websocket サーバーを運用したいと思ったので、その下準備として、アプリケーションサーバーを整えておく必要がある。Python 系のアプリケーションサーバーとしては uWSGI が定番であり、最近のバージョンでは websocket にもデフォルトで対応しているようなので、まずここでは uWSGI 環境の構築について一通り行いたいと思う。 luci-ssl-nginx luci-ssl-nginx を導入するとデフォルトの uHTTPd 環境の LuCI に代えて、NGINX(かつ SSL)環境の LuCI が動くようになる。この環境において、Lua プログラムである LuCI に NGINX

websocket サーバーを OpenWrt で運用する

イメージ
(👉 公式ドキュメント ) Quick start (ローカル PC でのテスト。OpenWrt とは無関係な websockets 自体の話) ハローワールド CUI ウィンドウを 2 つ開いて、server.py を実行すると、無限ループで強制終了するまで動き続ける。もう一つのウィンドウから client.py を実行すれば、サーバーから挨拶が返ってくる。client.py は何度でも実行し直すことができる。 server.py の websockets.serve が、(第 2、3 引数で定義される websocket の)コネクションが発生する毎に、(第 1 引数で定義される)hello コルーチンを実行する。 client.py の async with websockets.connect(uri) の記述によって、ブロック内のコードの実行後に、websocket 接続が自動的に閉じられるようになっている。 wss 化 リンクから localhost.pem をダウンロードして、サーバー&クライアント共通の暗号鍵として使う。 ハローワールドに対して、server.py は、websockets.serve にオプションの引数として ssl を追加しており、その値として使う ssl_context のために 3 行の ssl に関するコードが追加されている(それに伴う import も追加されている)。 ハローワールドに対して、client.py も、server.py と同様に、websockets.connect にオプションの引数として ssl を追加しており、その値として使う ssl_context に関しては(同じ暗号鍵を使っているわけだから)全く同じである。 次は一旦サンプルをリフィレシュして、クライアント側を Web ブラウザーの JavaScript コードに代えてアクセスする例を紹介している。 Web ブラウザーからのアクセス JavaScript 側は単にサーバーから受け取ったメッセージを ul の li として追加して表示していくだけのもの。Python 側の websockets モジュールとは直接関係がなく、JavaScript の WebS

uWSGI on OpenWrt

以下の内容は OpenWrt 19.x の時点でのやや古いものであり当面の間は残しておくが、最近の 23.05 に基いた新しい文書 を別途作成したので、通常は新しい方を参照して欲しい。 OpenWrt ルーターに Django を導入したいと思ったので、それにあたってはその下準備として、アプリケーションサーバーを整えておく必要がある。Python 系のアプリケーションサーバーとしては uWSGI が定番のようなので、まずここでは uWSGI 環境の構築について一通り行いたいと思う。 luci-ssl-nginx OpenWrt では luci-ssl-nginx というパッケージがあり、これを導入するとデフォルトの uHTTPd 環境の LuCI に代えて、NGINX(かつ SSL)環境の LuCI が動くようになる。この環境において、Lua プログラムである LuCI に NGINX が CGI としてリレーするために、uWSGI が使われている。この場合は、uWSGI はあくまでも CGI を扱うためのアプリケーションサーバーの一種として使われているだけで、Python 固有の WSGI サーバーとして使われているわけではないが、それでも NGINX ⇔ uWSGI 間のプロトコルは uwsgi プロトコルが使われている点は特筆すべき点だろう(NGINX は uwsgi プロトコルにネイティブ対応している)。 NGINX が uwsgi プロトコルを使うということは、設定ファイル中で uwsgi_* プレフィックスを使った設定が行え、uwsgi_pass でソケットを通じて uWSGI にリレーできることを意味している。 例えば、OpenWrt の luci-ssl-nginx を入れた状態では uWSGI 関連の設定は次のようになっている。 /etc/nginx/luci_uwsgi.conf(/etc/nginx/nginx.conf からインクルードされている) location /cgi-bin/luci { index index.html; include uwsgi_params; uwsgi_param SERVER_ADDR $server_addr; uwsgi_modifier1 9; uw

NGINX を Drupal 用に設定する

とりあえず Drupal のインストールは成功した が、処理時間の設定を除き、特に Drupal 用の設定を何も行っていないので、現状では少々問題が残っている。この記事ではより細かい設定を行って行こうと思う。 NGINX 公式の Drupal 用設定例 👉 NGINX 公式の Drupal 用設定例 server { server_name example.com; root /var/www/drupal8; ## <-- Your only path reference. location = /favicon.ico { log_not_found off; access_log off; } location = /robots.txt { allow all; log_not_found off; access_log off; } # Very rarely should these ever be accessed outside of your lan location ~* \.(txt|log)$ { allow 192.168.0.0/16; deny all; } location ~ \..*/.*\.php$ { return 403; } location ~ ^/sites/.*/private/ { return 403; } # Block access to scripts in site files directory location ~ ^/sites/[^/]+/files/.*\.php$ { deny all; } # Allow "Well-Known URIs" as per RFC 5785 location ~* ^/.well-known/ { allow all; } # Block access to "hi

Drupal を低スペック OpenWrt ルーターにインストール

イメージ
Buffalo WZR-HP-AG300H CPU: 680MHz; ROM: 32MB; RAM: 128MBa OpenWrt 19.07.3 HTTPd NGINX (with SSL) 1.17.7 PHP 7.2.31 (FPM) SQLite php7-mod-pdo-sqlite 3.31.1 Drupal 8.9.3 (最新は 9.0 だが、OpenWrt の最新の 19.07 では PHP 9.2 のため、要件にギリギリ届かない) USB フラッシュドライブ、NGINX + PHP (FPM) のセットアップ WordPress のインストール(👉 WordPress を低スペック OpenWrt ルーターにインストール )で行った作業に準ずるものとする。 SQLite のセットアップ 👉 core/INSTALL.sqlite.txt 単独の SQLite は不要。PHP の SQLite 関連モジュールだけで良い。 opkg update opkg install php7-mod-pdo-sqlite ファイルの置き場には、インストール過程でデフォルトとして示される ./sites/default/files/.ht.sqlite をそのまま使うものとする。留意しなければならないのは、デフォルトのパスを使うにせよ、フォルダーとファイル自身が書き込み可にパーミッションを変更しておかなければならない点である。このパーミッション変更を忘れていると、インストール自体が無事終ってから、最初にサイトの画面を表示する段階でデータベースエラーが発生する。 特に、インストーラーが自前で作成する .ht.sqlite までもがパーミッション変更が必要なことに気付くまで、当初はエラーの原因がわからずに悩む羽目になった。インストーラーが自分で作成できるのだから、こちらでパーミッションを変更せずとも、どうとでもなるんじゃないかと思うのだが、インストーラーと、インストール後の Drupal 本体では、セキュリティ的に権限が違っているからだろう。 PHP の調整 PHP 側の処理が重く時間がかかり過ぎると、NGINX が 504 Gateway Time-out にする場

WordPress を低スペック OpenWrt ルーターにインストール

イメージ
Buffalo WZR-HP-AG300H に OpenWrt をセットアップし、WordPress をインストールしてみる。 Buffalo WZR-HP-AG300H CPU: 680MHz; ROM: 32MB; RAM: 128MB OpenWrt 19.07.3 HTTPd NGINX (with SSL) 1.17.7 PHP 7.2.31 (FPM) MySQL MariaDB 10.2 WordPress 5.4.2 USB フラッシュドライブ 今回は 8GB のフラッシュドライブを使った。256MB を swap 用に割り当て、残りをデータ用(/mnt/data)に使い、続く作業で nginx の Web ルート、MariaDB のインストール場所として割り当てるために利用する。 👉 OpenWrt での USB フラッシュドライブ Web サーバーの NGINX 化と、PHP 7(FPM)との連携 WordPress をインストールする前提として、Web サーバーを通じて PHP 7 が使える環境を整えておく必要がある。ここでは Web サーバー(HTTPd)としてNGINX(SSL 対応版)を使い、PHP は FPM で NGINX と連携させた。 👉 OpenWrt で NGINX と PHP 7(FPM)環境を整える MariaDB のインストール 本当は SQLite3 にしたかったが、WordPress の SQLite 用プラグイン( sqlite-integration )が開発が停止したままとなっていて将来性が不透明なため、素直に MySQL 互換の MariaDB を使うことにする(MariaDB にするとサイズ的に 6.6MB と比較的大きいので、可能であれば避けたかったが)。 MariaDB を適切にセットアップ(👉 OpenWrt で MariaDB を使えるようにする )した後、例えば、データベース名:wordpress;ユーザー名:wordpress;パスワード:******** で WordPress 用のデータベースを用意する。そのためには下のようにする(👉 WordPress 公式 )。 CREATE DATABASE wordpress; GRAN