6年振りの自宅Webサーバー(IPv4,IPv6両対応)

いやあ、苦労しました。
やりたいことはある程度分かっていても、どうしたらそれを実現できるのか?
また、思ったとおりに動かなくてどこが悪いのか原因を追求して、対処を行う。
プログラミングで言うところのバグ取りみたいなことを延々とする必要があって疲労困憊しました。
しかも、通信絡みだとハードが散らばることもあってその検証も複雑で面倒でどうやったら良いのか途方に暮れる日々でした。
今どき、PVも全く少ない、広告置いてもレンタルサーバー代は勿論のことドメイン維持代すら回収できないようなサイトをわざわざ自宅Webサーバーを構築してまで続ける意味なんてものは体外的には全く無いのですが、他のサービスに頼っていてもそのサービスが突然終了したりなんてことも当たり前のように起こる昨今ですので、まあそうやって個人のページはどんどんと駆逐されてしまったのが現在だといえます。

そんな中でも個人サイトを続けていこうなんて奇特な方は少なく、もう自宅Webサーバーに関する情報を発信してくれている方もほぼいません。
例えば、まだ自宅Webサーバーがそれなりに運用されていた時代にはDDNSツールなんかもそこそこ存在していましたが、当然のように放置されていたり消えていたりしています。
時代が進んで便利になった部分もある一方で、自前でどうにかしなくてはならない領域も増えていて、昔に比べてIPv6やSSLの対処などが必要になった分複雑で大変になった部分も大きくありました。

ここではそんな苦労を振り返っておきたいと思います。
なお、具体的な作業方法を順を追って説明とかはしないしできません。
結局、いくらそういう事例を示したところで、その作業方法がそのまま適用できるケースなんてまず無いんです。
筆者もいつもいろいろとググらせていただいてはいますが、そうして得られた情報がそのまま利用できるなんてことはほとんど無く、結局自分の場合はどうしたら良いのか? という組み立ては自分でするはめになります。
これは自宅Webサーバー構築に限らずプログラミングなんかでもいつもそうです。
育ってきた環境が違うからすれ違いは否めない。じゃなくて、完全に同一な環境で作業しているわけではないので、どうしても異なる部分があり、異なる事象が発生して、異なる対処が必要になってしまうのです。
この、完全に同一な環境というのは時間の経過だけで崩れます。各種アプリなど仕様変更が随時行われていますからね。
だから、ここで頑張って全ての作業を逐一示したところで、そのマニュアルは公開した時点でもう過去の記録にしかならないのです。(参考にはできましょうが)

というのと、後からちゃんとした作業記録をもう一度録るというは非常に苦痛な作業ですし、あっちこっち壁にぶつかりながら自宅Webサーバー公開にまで漕ぎ着けたのでそんなスマートな記録は無いんですよ、そもそも。
というわけで、ここでは苦労した点を愚痴ろうと思います。
そんな愚痴でも、同じように壁にぶち当たって途方に暮れている人には「あっ!」と思うようなヒントになるかもしれません。
むしろ、お決まりの作業について丁寧に書いてくれている記事はそこそこあれど、イレギュラーに如何に対処して克服したかという情報には本当にお目に掛かれません(というか検索では似て非なる事象ばっかり引っかかるので「これだ!」という情報にはなかなか辿り着けません)。
ので、そういう情報の一つにでもなれれば、と思います。

デル株式会社

今回使用したPCはAndroid TV BoxであるVontar X3です。
IPv4,IPv6両対応をしていますが、追加機器はありません。
LANの配線も1本きり。WiFiやBTは使用しておりません。
この辺り、ルーターを追加する情報ばかりがネットには転がっていましたし、筆者もなかなか上手くいかないところがあって何度も心が折れたのですが、そもそもインターネットに繋げているルーターが1本の配線でIPv4,IPv6両対応が出来ているわけでして、それがPCでは不可能なんてそんなことは無いはずですので、そこは根気強く頑張りました。
1台でやりきったという情報があまりにも無いんですよ。というか、筆者は見つけられなかった。

だから、ここに宣言しておきます。
IPv6(IPoE)とPPPoEブリッジが使用できるルーターでインターネット接続をしていて、ISP側がPPPoEでの接続を許してくれている場合、自宅WebサーバーはPC1台にLAN1本だけで構築できます!
変にPPPoE専用ルーターの増設とか必要ありません。
さらに言うと、ルーターのIPv4 over IPv6の機能もそのまま働いています。

OSはArmbianです。筆者の所持しているVontar X3はAmlogic S905X3搭載でHK1と同じものです。(基板にHK1と印刷されていた)
このSBCは割とメジャーな方だったらしく、Armbianのインストールはラクラクでした。
正しくUSBにインストーラーを書き込めていたら、インストール作業は聞かれたことに答えるだけでOKです。
Androidとの共存とか考えずにArmbian一本にしてしまって良いのであれば質問に5,6個答えるだけでeMMCをArmbian専用に書き換えてくれます。

WebサーバーにはOpenLiteSpeedを選択しました。
Arm系に向けたパッケージは無いので自力でコンパイルする必要はありますが、コンパイルに必要なパッケージが揃っていればOpenLiteSpeedの書いてくれているとおりに動いてくれると思います。
不足しているパッケージもError吐くときに示してくれますので、ログを良くみましょう。
また、要求しているパッケージは○○○-devと、後ろに-devが付くパッケージであることが多いですので、パッケージ入れても落ちるじゃんかとお嘆きの貴兄は-dev付きのパッケージもインストールしましょう。
これはOLS(OpenLiteSpeedの略)で使用するLSPHPをコンパイルするときも同様です。というか、むしろLSPHPの方が不足パッケージが多かった気がする。

OLSでは.htaccessでRewriteEngineが使える。
ただし、ここで一点、筆者の設定が悪い可能性もあるのだか、大きく引っかかったところがあった。
コンテンツを置くディレクトリに配置する.htaccessとWebAdminの中で指定するRewriteRulesは完全同一ではない。
ディレクトリに置く.htaccessファイルはApacheと同じで良かったが、WebAdminに指定する方ではURIのパスに先頭の「/」を付けないと正常に機能しなかった。
この「/」付けるか付けないか問題はRewriteRulesに限らずあらゆる設定で誤動作の原因になり得るので、思ったとおりの結果にならないときは「/」の有無の違いも頭の片隅に置いておくと良いだろう。
例えば、筆者はわざと存在しないURIを指定してくる輩に丁寧なエラーページなど返したくは無いのでエラーページをカスタムして最低限のサイズにしているのだが、このカスタムエラーページの指定でも当初「/」を付けていなかったせいで、エラーページは確かに表示されるのだがログの方には404ではなくて302(リダイレクト)と200(OK)が記録されるという不気味な現象に遭遇して、なんじゃこのクソ仕様こんなんじゃカスタムエラーページとして機能しねえだろログは404で記録しておけよ!とか息巻いていたのですが、この点に付いては同じように引っかかった人の情報にぶち当たることができまして、「/」を付けたらちゃんと404で記録されるようになりました。

OLSで他に苦労したのはArmbianと設定との兼ね合いになるが、コンテンツを正しく置いても403になってしまうという現象にぶち当たって、筆者はVirtualBOXや他のPCでもある程度までOLSを導入して同じように作業していたので、Armbianだけ403になってなんでや!? ってなってたんですが、どうもコンテンツを置いたディレクトリよりも上の階層で権限が付いていなくて単純にコンテンツの読み出しに失敗して結果403となっていたようです。
Linuxの基本やろ、言われればそれまでなんですが、他のPCではAntixで同じようなディレクトリ構成していてもAntixでは普通に権限があって見れていたので、がっつり引っかかりました。
Armbianて基本Debianだからそういうとこ厳しいんだよね、きっと。良く知らんけど。……あれ?AntixもDebian系じゃん。謎……

SSL対応は自宅Webサーバーの味方、Let'sEncryptで。
こちらはcertbotなる便利なツールが出来ていて、こちらで楽に導入できました。ここは楽できた部類。
ただ、自動更新はまだ導入してないので、まだ作業は残ってますねえ。
認証に当たってWebサーバー上に認証ファイル置くと悪質アクセス対処が面倒(筆者割とタイトに.htaccess書いているもので)なのでDNS認証にしました。

IPv6半固定化はnmtuiでラクラク。
半固定にまでしかならないのはプリフィックス部分の変更が行われる可能性をゼロにできないため。
ルーターにこの半固定化したアドレスの80,443ポート宛のアクセスだけは通してあげるように設定します。
こちらでは変更することは無いため、プリフィックスが変更になってしまった場合はIPv6アドレスの設定とルーターのファイアウォール設定の変更が必要になります。
ここは自動化できないので手動でどうにかするしかないですな。(いつ気付くかという問題があるが)
仮にアドレスとDDNSの自動化が出来てもルーター設定の自動化ができないのでどうしても手動部分が残るんですよ。(できるルーターもありそうですがうちのは無理)

ファイアウォールはIPTablesできめ細かく設定できたら格好良さそうなのですが、とてもそこまで余力ないですし、今のところはufwにお世話になります。
筆者はWebサーバーしか置いていませんので、外部からの通信は80,443ポートだけ許します。
SSH等は内部のLANからしか作業しないのでローカルアドレスのみの許諾です。

さて最後の難関PPPoE。
これもしかしたらnmtuiでDSL接続を作るだけでもイケたかもしれないのですが、良く分からない設定があるので、ちょっとここは不明です。
筆者はpppoe,pppoeconfパッケージを導入してそちらで進めました。
ググると良く出てくるrp-pppoeはArmbianには無かったのよん。
で、実はほとんどこれはスムーズに機能していたのですが、ちょっと紛らわしい部分と一点だけ上手く行って無かった部分があったせいでかなりここは悩まされました。

というのも、接続状況を確認してみると、まるで接続出来ていないかのような表示が出るんです。
例えばnmcli deviceって打ってみます。pppのところを見ると……

DEVICE         TYPE      STATE         CONNECTION
ppp0           ppp       disconnected  --                 

disconnected……。
nmcli device showって打ってみると……(部分抜粋)

GENERAL.DEVICE:                         ppp0
GENERAL.TYPE:                           ppp
GENERAL.HWADDR:                         (unknown)
GENERAL.MTU:                            1454
GENERAL.STATE:                          30 (disconnected)
GENERAL.CONNECTION:                     --
GENERAL.CON-PATH:                       --

disconnected……。
ip addrって打ってみると……(部分抜粋)

11: ppp0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1454 qdisc fq state UNKNOWN group default qlen 3
    link/ppp 
    inet xxx.xxx.xxx.xxx peer yyy.yyy.yyy.yyy/32 scope global ppp0
       valid_lft forever preferred_lft forever

UNKNOWN……。
当然のことながらIPv6等が接続しているeth0の方は「UP」となっています。

混乱するわなこんなん。(いや、知っている人にとっては当たり前な話なのかもしれませんが)
しかし不思議なことにpppoeのアドレスに向けて悪質なアクセスがバンバン飛んで来ていてUFWのBlockログがバンバン出てくるんですよ。

あ、じゃあ、実際には繋がっているんだな、と思ってPPPoE向けにHTTPアクセスを飛ばしてみます。……無応答。
ここでさらに問題を難しくしているのが、果たして自宅のPCからPPPoEに向けたアクセスが正常に自宅Webサーバーまで届くのかという問題。
というのも、IPv6導入前のIPv4時代ではLAN内から同じLAN内に向けてグローバルアドレス打っても通信できなったので、今回も届くのかどうかはっきりしません。(今はもう届いた実績があるので届くって分かるのですが当時はまだ一度も通信成功したことが無かったので分からなかった)
というわけで別の唯一持っている通信手段。スマホのLTEからのアクセスを試みています。
ここでさらに問題を混乱させたのが筆者はスマホにnoroot firewallを導入しているのですが、このアプリLTEには対応していないんですね。noroot firewallが動いているとLTE通信によるHTTPアクセスは失敗します。(これも今は分かったけど当時は分かってなかったので問題を酷くした一因でした)
なんでスパムアクセスはバンバン来るのに正規アクセスが通らんのや!と

OLSがPPPパケットを受け付けてくれない? とか考えたりもしましたが、そもそもOLS側にポートの設定はあってもPPPだのETHだのを振り分けるような仕組みがあるようには見えません。
tracepathとかtracerootとかいろいろ試してみます。
どうも、ブロックされるようなポートで試したときとHTTPポートで試したときとで結果が違います。これも混乱の種でした。
万が一自宅Webサーバーが乗っ取られてしまったときのことを考えてあまりいろんな機能を導入したくは無かったのですがここはもうこらえて通信系のパッケージを導入してtcpdumpを取ってみました。
あっ……
pppで受けたパケットがeth0に返っている……
route設定に問題あり!ですわ!

んでもググってもpppを開通させたときにはデフォルトルートを切り替えるとか、いわゆる切り替えの話ばかりがヒットして、筆者のやりたい「pppで受けたものはpppで返す」というただそれだけのことをやる手段の情報になかなかぶち当たれません。
やっと見つけたぞこのコマンド!

sudo route add default ppp0

ppp0用のデフォルトルートを追加する(多分)コマンド。
これで一応今のところ不具合は発見しておらず、eth0に来たものはeth0に返り、ppp0に来たものはppp0に返すことが出来るようになってようやく自宅Webサーバー開通と相成りました。

ちなみに、自宅のPCから自宅Webサーバーに向けてアクセスする際にIPv6通信が出来るメインPCではIPv6で直に通信します。IPv4時代みたいにNATとか挟まずにグローバルアドレスでダイレクトアクセスできます。
IPv6通信ができない古い機種や、スマホからLTEではなくWiFiでアクセスした場合にはルーターのIPv4 over IPv6の機能が働いてIPv4のグローバルアドレスでPPPoEのアドレスに通信するようでこちらもアクセス可能です。
昔は自宅LAN内から自宅Webサーバーへのアクセスはローカルアドレスでするしかなかったのでグローバルアドレス通信が機能していることの確認って結構骨だったのですが、今はその点だけはちょっと楽になりましたかねえ。

こうして一応IPv4,IPv6両対応の自宅WebサーバーをサーバーPC1台の追加だけで実現したわけですが、まだ残課題があります。
チューニングとかもありますが、まずはIPアドレス変更に対する策ですよね。
以前に比べてIPアドレスは変わり難くはなっていますが、まれに変わる可能性もあるようなのです。
そういうものに対してスクリプトを組んでおくべきかどうか? 今どき筆者のニーズにピタリと合うようなツールは絶対に存在しないので、ここは自力で組む必要があります。
IPv6は上記にも書いたとおり全自動にはできません。IPv4のアドレスはWebサーバーPCを再起動したりすると必ず変わるので再起動時もしくはpppoe接続時にDDNS登録しにいくようなスクリプトを組めば良いような気もします。
いずれにしろ、昔割と一般的だった数分おきに確認するスクリプトなんてのは不要だろうなぁ。

ちなみに、今のところIPv6で来る割合はそんなに高くないです。というか大体自分のアクセスかAppleくらいかなぁ。
IPv6を導入していてもWebアクセスはIPv4 over IPv6決め打ちってなっている人も多いだろうから仕方無いかもしれませんね。

2023-06-22追記:
IPv6の方はどのみち手動作業が必要なので何も対策を施してはいませんが(なんかググった感じだと変更があっても数年に一度レベルっぽい感じだったので。&予測も不可能だし)、pppoeのアドレス変更とLet's Encryptの自動更新については対処を一応施してみました。

pppoeは接続確立時に/etc/ppp/ip-upが実行され、そこで各種パラメータを設定した状態でetc/ppp/ip-up.d配下のスクリプトを全て実行してくれます。
ですので、ここにDDNS発行のスクリプトを実行権限を付けて置いておけば、IPv4アドレスが変わったときにDDNSにそのアドレスが登録できるようになるのかな、と思います。(まだ一度も、テストすらしてないんですけど(^^ゞ)
pppoeのアドレスが変わるというときはかならず一回前のアドレスでの接続が切れて新しい接続が確立しているはずですので、そのタイミングでDDNS登録ができれば一定時間間隔でチェックとかは不要なんじゃないかと思います。
そして確立したアドレスはパラメータにセットされてますのでDDNS更新スクリプトの作成はラクラク。実行する行は1行で済みました。

Let's Encryptの自動更新については詳しく解説をしてくれているサイトが多くありますので、それに習って。
今のところLet's Encryptの期限は90日で60日を過ぎたら更新可能、だったかな?うろ覚えで書いているので間違っていたら済みません。
それなら2ヶ月おきに実行されるようにcronに書けば良いか、と思ってそうしたのですが、この記事書いててそれじゃダメな月が発生するなと気づきました。2月が絡むところは2ヶ月経っても59日しか経過しないため更新がされない……
うーん、強制更新にするかあるいは別の更新間隔を考えるかしないといけないなぁ。

んで、certbotのドキュメント読んでみたら有効期限30日未満になっていない場合は何もしないで終わるらしく「好きなだけ頻繁に実行できる」(DeepLによる訳)らしいので、これは実行間隔を狭くするほうが良いかもしれませんね。
また、証明書を更新したらサーバーを再起動しないといけない、というかサーバーが起動していると更新できないみたいな記事もどっかで見たなあ。
まあ、うちの場合はDNS認証でOpenLiteSpeedなのでサーバー起動したまま更新してGracefulRestartで良さそうな気もするんですけど、これもテストしてないから間違っているやも? 一応サーバー一旦落とした方が良いかな?
そんなとき用に--pre-hook --post-hook なるものを用意してくれているので、--pre-hook でサーバーを終了して--post-hook でサーバーを起動するように書くと良さそうだ。(実際に証明書更新をするときだけ実行されるらしいのでサーバー再起動も最低限で済むようにはなっている)
ので、間隔狭めてフック付けてcron実行すれば良さそうです。

2023-07-16追記:
最高気温39.4℃を記録した日、確認したのは少し最高気温からは下がってきた時刻でしたがサーバーのCPU温度は60℃と表示されていました。
自宅サーバーに切り替えてから少ないPVがさらにだだ下がりしているのでほとんどアイドル状態なのですが、この高温下でもこのレベルで済むのであればこのままファンレス運用続けていけそうですね。
また、今のところIPv4,IPv6ともにアドレス変更は発生していない模様です。

2023-09-04追記:
さて、勉強不足でした。
現状、DNS認証ですと、DNSへのTXTレコード自動更新ができないとcertbotによる証明書の自動更新が出来ないようです。
DNS認証を止めて普通のHTTPS認証に切り替えることも少し考えましたが、サブドメインごとに別々に更新処理を走らせることになるのがちょっと面倒というか、そもそもacme-challenge配下のアクセス制御が難しいというか、ここがセキュリティ的にちょっとまだ筆者が納得できていないというか。
んで、いろいろ考える以前にですね、さくっとコマンド発行して自分でTXTレコード書き換えた方が圧倒的に速いんですね。
今のところ、3ヶ月弱ごとに1回やれば済む作業ですし、期限が近づくとメールで知らせてくれたりもしますので、まあ、当面は手動更新で様子見かなぁという感じです。
ところで、現状acme-challenge配下は使用しないので、ここにアクセスきたら通信遮断したいんですけど、なぜかrewrite ruleをどう書いても遮断してくれなくてどういう仕組みになっているのが、コレガワカラナイ。
日中に必ず2セット(2,3回まとめてアクセスが来る塊が日に2セット)各サブドメインに通信が来ているのでコレ通信遮断したいんですけどね。
というか、もしかしたら筆者の発行したcertbotコマンドによりセットされたものかもしれないのでその辺も調査しなきゃいけないんだろうけどなぁ……。
筆者の能力不足とやる気不足によりなあなあになってしまっています。

2023-09-15追記:
瞬間停電が複数回発生したせいで当然自宅サーバーが落ち、PPPの接続が張り直しとなってIPv4アドレスが変わりました。
PPPの接続自体は上手くいったようなのですが、DDNSの変更ができていなさそうだったのと、DNSを変更してもWebページが見られない状態が続きました。
つまり、pppで来たものはpppで返すというルーティングの設定も都度行わないといけないっぽいです。
ちょっとPPP接続時に発行するコマンドに不備があったかもしれないので変更して次回のPPP変更時にまた確認してみたいと思います。
具体的にはファイルの所有者をrootに変更して(効果不明ですが)若干のsleepを挟み、ppp返信のデフォルトルート設定コマンドを追加してみました。

2024-07-29追記:
pppの接続がされたとき、いわゆる停電とかで一旦接続が切れた後復旧時に再接続が確立したときにDDNSのコマンドを発行しているのですが、上手く機能しないときがあります。
不思議なのはPCの再起動とかでppp再接続するとちゃんとこのコマンドが発行されてDNSもきちんと更新されているんですね。
筆者しばらく不思議に思いながらもこの問題を放置していたのですが、急に原因に気が付いたのでここに記載しておきます。
雷で停電とかするとPCだけでなくその他の機器も落ちているわけです。すると、復旧時にコールドスタートするのはPCだけじゃない……
これは、ルーターの起動が間に合っていない説!
やたらと古いレンタルルーターと、それより明らかに処理性能が高いであろうPCが停電から復旧してヨーイドンでコールドスタートして、おそらくルーターはまず先に優先して回線を繋げてくれるのでしょうが、通信がちゃんと出来るようになるまでにラグがある。その間に接続確立したPCがDDNSコマンド発行してしまうが、通信がちゃんと出来ていなくて不発!
と、こういう流れではないか? と筆者は気付いたわけです。
ってこうして得意気になって書いていたらまた気付きました。
DDNSコマンドの発行を即時にしないで遅らせれば良いだけのことでは?
こういう気付きもあるからこうして書きながら脳内整理することも無駄ではありませんのですな。(気温37℃で文章に蜃気楼が見られますが気にしないように)

2024-07-29 2023-06-13

この記事のタグ

Linux/BSD

WebServer

トライ