クイックスタート

余っているコンピューターで、数分のうちに Town OS を動かせます。必要なのは USB-C メモリ(4 GB 以上)と、それを書き込むための Linux マシンだけです。

1. USB メモリに書き込む

podmancurlbzip2ddlsblktar がインストールされた Linux マシンで、 インストーラースクリプトを実行します。スクリプトはインストーラーイメージを 取得するために Podman を使うので、Podman は必須です (入っているだけでなく、動作している必要があります)。スクリプトは最新の Town OS イメージをダウンロードし、USB メモリへ直接書き込みます。

curl -sSLO https://town-os.github.io/install.sh && bash install.sh

スクリプトは接続された USB デバイスを検出し、デバイス名とサイズの一覧を表示して、 どれを使うか尋ねます。確認すると、圧縮イメージをストリーミングしながら 一度の処理でドライブへ書き込みます。全体の所要時間は、インターネット接続の 速度にもよりますが数分程度です。

Raspberry Pi(4 / 400 / CM4、5 / CM5): RPI=1 を渡すと、 通常の PC 用イメージではなく、ネイティブ起動する Raspberry Pi 用イメージを SD カード、USB メモリ、NVMe に書き込みます。

curl -sSLO https://town-os.github.io/install.sh && RPI=1 bash install.sh

Pi 用イメージは常に 64 ビット Arm で、UEFI なしで起動するため、x86_64 のマシンから インストーラーを実行しても問題ありません。Raspberry Pi は挿したカードやドライブから ブートメニューなしで直接起動します。Pi 5 の NVMe 起動では、ブートローダーの EEPROM の 起動順に NVMe が含まれていることを確認してください(rpi-eeprom-config で設定します)。

データ消去に関する警告

Town OS は検出したローカルストレージデバイスをすべてフォーマットして使用します (NVMe、SATA、SAS、SD カード)。マシンで Town OS を起動すると、すべての内蔵ドライブ上の 既存データは完全に失われます

残しておきたいデータがない専用マシンでのみ起動するか、まずは VM の手順で安全に試してください。 make qemu-usb を使えば、書き込んだばかりの USB メモリを実際のディスクに一切触れずに QEMU 内で(読み取り専用で)起動できます。

2. USB から起動する

USB メモリを対象のコンピューターに挿し、そこから起動します。ブートメニューを 出すために、起動中にキーを押す必要がある場合があります。よく使われるのは F12F2EscDel などで、ハードウェアによって異なります。

3. 初回起動: sledgehammer を使う

対象のマシンを以前ほかの用途で使っていた場合は、初回起動時にブートメニューから sledgehammer の起動オプションを選んでください。sledgehammer は 検出したすべてのストレージデバイスを消去し、Town OS を完全にまっさらな状態から 始められるようにします。これにより、以前の OS が残したパーティションテーブル、 ファイルシステム、RAID のメタデータが原因となる問題を避けられます。

sledgehammer が終わると、マシンは自動的に再起動し、Town OS がストレージを新規に 構成します。詳細は sledgehammer 起動オプションを参照してください。

4. 起動時に何が起こるか

Town OS は USB メモリから RAM 上へすべて読み込まれ、その後 ttyforce を起動します。これは対話形式の TUI インストーラーで、マシンのコンソール上で 直接セットアップを案内してくれます。

  • ネットワークの設定 — ttyforce が利用できるインターフェースを検出します。リンクのある有線接続があれば自動的に次へ進みます。ない場合は、電波強度、セキュリティ情報、WPA2/WPA3 のパスワード入力を伴う WiFi ネットワークの選択画面が表示されます。
  • ディスクのプロビジョニング — ttyforce は検出したディスクを種類とサイズでグループ化し、適切な RAID レベルを自動的に選びます。1 台なら単体、2 台なら RAID1(ミラー)、3 台以上なら RAID5(パリティ付きストライプ)です。ストレージはすべて btrfs を使います。
  • SSH 鍵の取り込み — GitHub のユーザー名を入力すると、安全なリモートアクセスのために公開 SSH 鍵を取り込めます。

プロビジョニングが終わるとシステムは再起動し、ttyforce は getty モードに切り替わります。 これはコンソール上でサービスの稼働状況、システムのメトリクス、ジャーナル出力を リアルタイムに表示する画面です。ここからログインしたり、ネットワークを再設定したり、 sledgehammer による消去を実行したりできます。

5. アカウントを作って使い始める

同じネットワーク上の任意の端末でブラウザーを開き、 http://town-os.local にアクセスします。うまくいかない場合は、 ルーターの DHCP クライアント一覧から "town-os" という名前の端末を探し、 その IP アドレスを直接使ってください。管理者アカウントの作成を求められます。 ログインすると、ダッシュボードからパッケージのインストール、ストレージの管理、 サービスの設定ができます。

6. ルーターの DNS を Town OS に向ける

Town OS には rolodex が同梱されています。パッケージのホスト名を解決し、それ以外は上位へ転送する DNS サーバーです。 ネットワーク上のすべての端末に自動的に使わせるには、Town OS のマシンに静的 IP (または DHCP の予約)を割り当て、ルーターのプライマリ DNS サーバーを そのアドレスに設定します。メーカーごとの手順と確認方法は ルーターで DNS を設定するを参照してください。

ソースから USB イメージをビルドする

Town OS の USB イメージは install リポジトリからビルドされます。ビルドの過程で、squashfs のルートファイルシステムと GPT のパーティション構成を持つ起動可能イメージが生成されます。

事前に必要なもの

Linux ホストと USB メモリ(4 GB 以上)が必要です。ビルドには Arch Linux のツール (pacstrapmkinitcpioarch-chroot)を使いますが、 Arch を動かしている必要はありません。ほかのディストリビューションでは、 make image が同じアーキテクチャの Arch コンテナー内で自動的にビルドを実行します。 ホスト側の依存関係は、お使いのディストリビューション向けの同梱ターゲットで インストールしてください。

  • make deps — Arch(および派生)または Fedora/RHEL
  • make deps-debian — Debian または Ubuntu

これらは、ビルドと VM ツールに必要なものをすべて導入します。makepodmanarch-install-scriptssquashfs-toolspartede2fsprogsdosfstoolsqemulibvirt です。

クローンとビルド

git clone https://gitea.com/town-os/install.git
cd install
make image

make または make image を実行すると、完全な USB イメージが ビルドされます。この処理では、ベースシステムをダウンロードし、Town OS の コンポーネントをインストールし、すべてを squashfs ファイルシステムへ圧縮して、 GPT のパーティションテーブルを持つ最終的なディスクイメージを組み立てます。

パーティションと squashfs

できあがるイメージは、次の構成の GPT レイアウトになります。

  • レガシー BIOS 起動用の BIOS ブートパーティション(1 MiB)
  • UEFI 起動用の EFI システムパーティション(64 MiB、FAT32)
  • squashfs のルートファイルシステムと GRUB を含むデータパーティション(ext4)

起動時、Town OS は squashfs を読み取り専用の下位レイヤーとしてマウントし、その上に tmpfs のオーバーレイを重ねます。つまり OS はすべて RAM 上で動作し、USB メモリ自体は 起動時に読み込まれるだけです。実行中の変更はすべてメモリ上で行われ、再起動時に 破棄されるため、毎回まっさらな状態から始まります。

イメージの書き込み

いちばん簡単なのは make flash です。イメージが古ければビルドし直し、 USB デバイスへ書き込みます。手作業で行う場合、ビルドは日付とアーキテクチャが 付いたファイル名(例: town-os-2026-07-25-x86_64.img)を生成するので、dd で書き込みます。

# USB デバイスを探す(例: /dev/sdb)
lsblk

# イメージを書き込む(ファイル名と /dev/sdX は自分のデバイスに置き換える)
sudo dd if=town-os-YYYY-MM-DD-x86_64.img of=/dev/sdX bs=4M status=progress conv=fsync

対象のデバイスは必ず確認してください。dd は指定された先を、確認なしに 上書きします。

起動の流れ
USB メモリ
GPT パーティションテーブル
EFI システム squashfs ルート
起動
稼働中のシステム
tmpfs オーバーレイ 読み書き
squashfs 読み取り専用
RAM
OS はすべてメモリ上で動作

sledgehammer 起動オプション

Town OS の USB メモリには sledgehammer という起動オプションがあり、 検出したすべてのストレージデバイスを消去してシステムをまっさらな状態に戻します。 テストのあと、新しいハードウェアへ展開する前、ストレージが壊れてしまったときなど、 一から始めたい場合に便利です。

何をするのか

起動時に sledgehammer を選ぶと、Town OS は次の処理を行います。

  • ローカルストレージデバイス(NVMe、SATA/SAS、SD カード)をすべて検出します。通常起動時と同じ検出処理です
  • 検出したすべてのデバイスのパーティションテーブルとファイルシステムを消去します
  • システムを再起動し、初回起動と同じようにストレージを新規に構成します

sledgehammer は、検出されたすべてのストレージデバイス上のデータをすべて破棄します。 USB メモリ自体は影響を受けず、内蔵ディスクだけが対象です。このオプションを使う前に、 必要なもののバックアップを取っておいてください。

使い方

  1. Town OS の USB メモリを対象マシンに挿し、そこから起動します
  2. ブートメニューで、既定の起動オプションではなく sledgehammer の項目を選びます
  3. システムが検出したストレージをすべて消去し、自動的に再起動します
  4. 次の起動で、Town OS が town-os.yaml の設定を使ってストレージを一から構成します

どんなときに使うか

  • 初期化 — 新規に展開したときと同じ、まっさらな状態にシステムを戻す
  • ストレージバックエンドの変更 — btrfs から ZFS へ(またはその逆へ)切り替えるには、まず既存のストレージを消去する必要があります
  • ストレージの破損 — ファイルシステムが修復不能なほど壊れている場合、sledgehammer がきれいな出発点を用意してくれます
  • 再展開 — 別の Town OS 構成のためにハードウェアを転用する
sledgehammer によるリセットの流れ
ブートメニュー
sledgehammer を選択
sledgehammer
消去
ストレージの消去
検出したディスクをすべて消去
NVMe SATA SD
再起動
新規セットアップ
ストレージを一から構成
town-os.yaml

ルーターで DNS を設定する

Town OS には rolodex が含まれています。パッケージ用の権威ゾーンを管理し、上位への問い合わせを転送する DNS サーバーです。これをネットワークの DNS サーバーとして使うには、Town OS マシンの IP アドレスをネットワークの DNS サーバーとして配るよう、ルーターに指示する必要があります。 こうすれば、ネットワーク上のすべての端末が自動的に rolodex を使うようになり、 端末ごとの設定は不要です。

Town OS の IP アドレスを調べる

Town OS マシンのローカル IP アドレスが必要です。次の方法で調べられます。

  • 初回起動のセットアップ後に http://town-os.local でダッシュボードにログインし、表示されている内部 IP を確認する。これが DNS サーバーとして使うアドレスです
  • VM を使っている場合は make vm-ip を実行する
  • ルーターの DHCP クライアント一覧から "town-os" という名前の端末を探す
コピーボタン付きで外部 IP と内部 IP を表示する Town OS のダッシュボード

DNS を安定して動かすには、Town OS マシンに静的 IP アドレスか、ルーター上の DHCP 予約を割り当てておく必要があります。IP が変わると、ネットワーク全体の DNS が使えなくなります。

静的 IP または DHCP 予約を割り当てる

たいていのルーターでは、MAC アドレスをもとに特定の端末へ IP アドレスを予約できます。 通常は LAN 設定DHCPアドレス予約といった項目にあります。クライアント一覧から Town OS の マシンを見つけ、現在の IP を予約してください。

ルーターが DHCP 予約に対応していない場合は、town-os.yaml に追記することで Town OS マシン側に静的 IP を設定できます。

ルーターの DNS サーバーを変更する

正確な手順はルーターのメーカーによって異なりますが、大まかな流れは同じです。

  1. ルーターの管理画面にログインします(通常は 192.168.1.1192.168.0.1
  2. DHCP 設定LAN 設定DNS 設定のいずれかの項目を探します
  3. プライマリ DNS サーバーを Town OS マシンの IP アドレスに変更します
  4. 必要なら予備としてセカンダリ DNS サーバーを設定します(例: 1.1.1.18.8.8.8)。Town OS に到達できないときに使われます
  5. 設定を保存して適用します

保存後、ネットワーク上の端末は次に DHCP のリース更新を行ったときに新しい DNS サーバーを 受け取ります。ネットワークに接続し直すか、端末を再起動すれば、すぐに反映できます。

よくあるルーターの管理画面

ルーターのメーカーDNS 設定の場所
ASUSLAN → DHCP Server → DNS Server
TP-LinkDHCP → DHCP Settings → Primary DNS
NetgearInternet → Domain Name Server (DNS) Address
LinksysConnectivity → Local Network → DHCP Server → Static DNS
UniFiSettings → Networks → (対象のネットワーク) → DHCP Name Server
pfSense / OPNsenseServices → DHCP Server → DNS Servers
OpenWrtNetwork → Interfaces → LAN → DHCP Server → Advanced → DHCP-Options: 6,<town-os-ip>

ブラウザー内蔵の DNS を無効にする

ほとんどのブラウザーは独自の DNS リゾルバーを持っており、ルーターを完全に迂回します。 Firefox の DNS over HTTPS(DoH)や、Chrome・Edge の同等の「セキュア DNS」機能は、 問い合わせを Cloudflare や NextDNS といった公開プロバイダーへ直接送ります。その結果、 Town OS には問い合わせが届かず、ネットワークのほかの部分では問題なく解決できるのに、 パッケージ名だけ「サーバーが見つかりません」となります。サービスに名前でアクセスしたい 端末では、次の設定をすべてオフにしてください。

  • Firefox設定 → プライバシーとセキュリティ → DNS over HTTPSオフを選びます。(既定の保護でも DoH が黙って有効になることがあるため、既定のままにせずオフを選んでください。)
  • Chrome設定 → プライバシーとセキュリティ → セキュリティセキュア DNS を使用するをオフにします。
  • Edge設定 → プライバシー、検索、サービス → セキュリティセキュア DNS を使用してネットワーク アドレスの参照方法を指定するをオフにします。
  • Brave、Vivaldi、Opera — Chrome と同じ設定で、プライバシーとセキュリティ → セキュリティにあります。
  • Safari — 内蔵の DoH はなく、システムのリゾルバーを使います。システム設定 → 一般 → VPN とデバイス管理に DNS プロファイルが入っていないか確認してください。

システム全体で暗号化 DNS を設定している場合も同様です。Android の プライベート DNS、iOS/macOS の DNS プロファイル、ローカルの systemd-resolved/dnscrypt の設定などは、いずれもルーターが 配る DNS サーバーを上書きします。上位への問い合わせを暗号化したい場合は、Town OS に 任せてください。rolodex はローカルの名前に答えつつ、上位に対して DoH/DoT を使えます (下記の解決モードを選ぶを参照)。

動作を確認する

端末が新しい DNS 設定を受け取ったら、rolodex が DNS の問い合わせを処理していることを 確認します。

# どの DNS サーバーを使っているか確認する
nslookup example.com

# または Town OS に直接問い合わせる
dig @<town-os-ip> example.com

# パッケージのドメインを問い合わせる(パッケージをインストール済みの場合)。
# 名前は <name>.<repo>.<tld> の形式で、.home が既定のネットワークの TLD
dig @<town-os-ip> gitea.default.home

example.com が正しく解決されれば、rolodex は動作しており、 ネットワークの DNS を処理できています。

解決モードを選ぶ

自分のネットワークに属さない名前は解決モードに従って解決されます。 モードはダッシュボードの 設定 → DNS 解決で指定します。 3 つのモードがあります。

  • 自動(推奨) — 既定のモードです。まずルートサーバーから反復的に解決しようとし、うまくいかない場合は DoH/DoT、ローカルのフォワーダー、最後に公開リゾルバーへと順に切り替え、最後に成功した段階を維持します。ネットワークが許す限り再帰解決のプライバシーを保ちつつ、外向きの DNS がフィルタリングされる環境でも無理なく機能を落として動きます。
  • 再帰のみ — すべてをルートサーバーから反復的に解決し、代替手段は使いません。第三者のリゾルバーに問い合わせが渡らないことを保証できますが、外向きのポート 53 を遮断・乗っ取るネットワーク(ホテル、キャプティブポータル、一部の ISP)では外部の名前がすべて解決できなくなります。
  • 転送 — 一致しない問い合わせを常に上位のリゾルバー(既定では Google Public DNS)へ送ります。従来からある転送の動作です。

この設定は、この機器がインターネットへ到達する方法についてのものである点にご注意ください。 逆方向の暗号化 DNS、つまりお使いの端末がこの機器へ到達するために使うものについては、次に説明します。

お使いの端末から暗号化 DNS を使う

Town OS は自分自身のためだけでなく、お使いの端末に対しても暗号化 DNS を提供します。 利用できるエンドポイントは三つあり、いずれもポート 53 の平文 DNS とまったく同じ名前に応答します。

  • DNS over HTTPS(DoH)https://dns.<tld>/dns-query。これは ingress を経由して標準の HTTPS ポートを使うので、制限の厳しいネットワークでも最も通りやすいものです。
  • DNS over TLS(DoT)dns.<tld> のポート 853
  • DNS over QUIC(DoQ)dns.<tld> のポート 853、UDP 上。

三つとも、この機器自身の認証局が発行した証明書を提示します。名前もアドレスも、 システムのほかの部分が使っているものと同じです。端末にルート CA を既にインストールしてあるなら (認証局を信頼するをご覧ください)、ほかに設定するものはなく、 そのまま検証が通ります。

お使いの CA を一度も信頼したことがない端末でも、これらのエンドポイントを検証できます。 Town OS は、自分が権威を持つゾーンの中に、証明書を固定する DANE レコードを _853._tcp.dns.<tld>_853._udp.dns.<tld> の両方に公開します。 トランスポートごとに一つずつ置くのは、DANE に対応したクライアントが、自分の選んだトランスポートの レコードを見つけられないと接続を拒否してしまうからです。その端末はこのリゾルバーに到達できるのですから、 固定情報も取得でき、事前に何もインストールすることなく、渡された証明書を確かめられます。

DDR に対応したクライアントは、これらを自分で見つけます。Town OS は _dns.resolver.arpa(RFC 9462)に指定レコードを公開し、DoH の URL と DoT・DoQ の ポートを、その優先順で示します。DoH が先頭なのは、853 を遮断するフィルタリングでもポート 443 なら 通り抜けられるからです。DDR 対応の端末を通常の DNS としてこの機器に向けておけば、 あとは自分で暗号化エンドポイントを見つけて切り替えます。

この三つのリスナーは、起動時にインストールイメージの設定から開かれます。そのため、ほとんどの DNS 設定とは 異なり、ダッシュボードから有効にすることはできません。その背後にある証明書は、機器が動いてさえいれば バックグラウンドで更新され、再起動は要りません。新しい DANE の固定情報は古いものを取り下げる前に 公開されるので、検証するクライアントが接続を拒む瞬間は生じません。

悪意あるドメインをブロックする

rolodex はすべての問い合わせを公開ブロックリストと照合できるので、 別途 Pi-hole を用意しなくてもネットワーク全体で脅威をブロックできます。 設定は DNS → ブロックリストで管理します。プロバイダーには 2 種類あり、それぞれ対象が異なります。

  • DNSBL(ドメインのブロックリスト) — 問い合わせられた名前と照合します。普段のウェブ閲覧に効いてくるのはこちらです。
  • RBL(Realtime Blackhole List) — IP アドレスと照合し、逆引き DNS の問い合わせにのみ適用されます。

どちらも既定では無効で、プロバイダーの一覧も空です。また、どちらも 必要になったときにだけ問い合わせます。Town OS がブロックリストのフィードを ダウンロードしたり、解析したり、あらかじめキャッシュしたりすることはありません。 カテゴリーを有効にしてゾーンを 1 つ以上追加するまで、何も照合されません。

DNSBL の照合の仕組み

解決しようとしている名前がプロバイダーのゾーンの前に付けられ、通常の DNS 問い合わせとして照会されます。dbl.spamhaus.org を有効にした状態で badsite.example を解決すると、 badsite.example.dbl.spamhaus.org への問い合わせが発行されます。

  • 応答があれば掲載されている — プロバイダーは掲載されている名前に対してアドレスレコード(通常は 127.0.0.x)を返します。rolodex はそのとき、問い合わせた端末へ NXDOMAIN を返します。
  • NXDOMAIN なら問題なし — 解決は通常どおり続きます。エラーやタイムアウトを起こしたプロバイダーは、掲載されていないものとして扱われるため、到達できないブロックリストがネットワークを止めることはありません。
  • ブロックリストは外の世界には勝つが、自分のレコードには勝たない — 照合はローカルとパッケージのレコードのあと(したがって gitea.default.home は常に解決されます)、上位のキャッシュとフォワーダーの前に行われます。そのため、転送された応答がすでにキャッシュされていても、掲載されている名前は拒否されます。
  • 照合は名前単位で、サフィックス単位ではないdoubleclick.net が掲載されていても、プロバイダーがその名前も掲載していない限り stats.g.doubleclick.net はブロックされません。1 つのホストが掲載されたことでドメイン全体を落とすかどうかは、フィードではなくあなたが決めることです。
  • 結果は短時間キャッシュされます — 掲載はプロバイダーの TTL の間、問題なしの結果は 5 分間です。

DNSBL のプロバイダー

以下はダッシュボードでワンクリックで追加できるものです。いずれも現在も稼働中で、 無料であり、登録の手続きなしに自前で再帰解決するリゾルバーへ応答します。Town OS の マシンはまさにそれに当たります。ほかのゾーンを手で入力することもできます。

プロバイダーゾーン対象
Spamhaus DBLdbl.spamhaus.org最も広く使われているドメインリスト。スパムで観測されたドメインに加え、フィッシング、マルウェア配布、ボットネットの指令 (C&C) ドメインを収録。5 つの中で最も網羅性が高い。
SURBLmulti.surbl.org迷惑メールの本文に現れるドメインをまとめたリスト。フィッシングサイト、マルウェア、乗っ取られたサイト、悪用されたリダイレクターや URL 短縮サービスを含む。
URIBLblack.uribl.comスパムメールの本文で見つかった URI。black ゾーンは保守的なもので、実際にスパムに現れているドメインを、誤検知を強く避ける方針で収録している。
NordSpam DBLdbl.nordspam.comスパムで見られたドメインを、上記のリストとは独立した情報源から収集。主軸ではなく、セカンドオピニオンとして使うのが向いている。
Spam Eating Monkeyuribl.spameatingmonkey.netスパムの URI から抽出したドメイン。登録されたばかりのものや、短期間で捨てられるドメインも含む。

RBL の照合の仕組み

IP アドレスを逆順にして、プロバイダーのゾーンの前に付けます。 192.168.1.100zen.spamhaus.org で確認すると、 100.1.168.192.zen.spamhaus.org への問い合わせが発行されます。IPv6 アドレスは ニブル単位に展開してから同じように逆順にします。応答があれば掲載、NXDOMAIN なら問題なしで、結果は DNSBL とまったく同じようにキャッシュされます。

注意点として、RBL のゾーンは逆引き DNS の問い合わせin-addr.arpaip6.arpaに現れた IP に対してしか 参照されません。そして普通のウェブ閲覧では、そうした問い合わせはほとんど 発生しません。これらのリストは、メールサーバーが接続してきた送信者を拒否するために 存在し、そこでこそ役に立ちます。家庭用ルーターではほぼ何もしないに等しく、実際に閲覧に 効いてくるのは上記の DNSBL のほうです。Town OS の背後でメールサービスを運用している なら有効にしてください。そうでなければ、注目すべきはドメインのリストです。

RBL のプロバイダー

プロバイダーゾーン対象
Spamhaus ZENzen.spamhaus.orgSpamhaus の 4 つのリストを 1 回の問い合わせで参照: SBL(確認済みのスパム送信元)、CSS(スノーシュースパムの活動)、XBL(乗っ取られた・感染したマシン、オープンプロキシ)、PBL(直接メールを送るべきでない動的・エンドユーザー向けの範囲)。
SpamCopbl.spamcop.netSpamCop の利用者による報告ネットワークから寄せられた IP。報告が止まると掲載は自動的に失効するため、反応が速く、忘れるのも速い。
PSBLpsbl.surriel.comPassive Spam Block List。スパムトラップのアドレスに接触した IP を、自動失効付きで収録。意図的に保守的で件数も少なめ。

あえて用意していないリスト

よく知られた 3 つのゾーンは、意図的にワンクリック追加の一覧から外しています。 いずれも静かに失敗するためです。プロバイダーが設定されているのを見て、 守られていると思い込んでしまいます。仕組みを理解しているなら、手で追加することは できます。

  • SORBSdnsbl.sorbs.net) — 2024 年 6 月 5 日に運用を終了し、ゾーンは空になりました。応答はしますが、何も掲載されません。保護されているように見えて、実際には永久に何もしない状態です。
  • Barracudab.barracudacentral.org) — 無料ですが、問い合わせ元の IP をあらかじめ登録する必要があります。未登録のマシンはしばらく使えたあと、予告なく遮断されることがあります。
  • UCEPROTECT のレベル 2 と 3 — ネットブロックや AS 単位で掲載するため、同じ ISP に迷惑な利用者が 1 人いるだけで ISP 全体がブロックされます。

ローカルの登録と許可リスト

  • ローカルの登録DNS → ブロックリスト) — 特定のドメインや IP を、理由を添えて手動でブロックします。ドメインの登録は正引きに対して NXDOMAIN を返し、即座に反映されます。これは外部のどのプロバイダーよりも先に照合されるので、フィード全体を導入せずに特定のホストだけをブロックしたいときに使います。
  • 許可リストDNS → 許可リスト) — 誤検知からの逃げ道です。許可された名前は、名前ベースの照合を丸ごと飛ばします。DNSBL のプロバイダーにもローカルの登録にも照合されず、プロバイダーへの問い合わせも一切発行されません。ブロックとは違い、許可はサフィックス単位で照合されます。vendor.example を許可すると cdn.vendor.example も許可されます。登録できるのは名前だけで IP は登録できないため、逆引き IP の RBL の経路には影響しません。

期待できること

これらのフィードはメール向けに作られており、広告向けではありません。 フィッシング、マルウェア、スパムのペイロードとなるドメインには非常に有効ですが、 広告やトラッカーに対しては平凡です。そちらはダウンロード型の hosts 形式のフィードの 仕事であり、Town OS はそれを意図的に取り込みません。定期的な取得も、解析も、 知らないうちに行われるキャッシュもありません。特定の広告やトラッカーのドメインを 消したい場合は、ローカルの登録として追加してください。

DNS でサービスを公開する

既定では、インストール済みのすべてのパッケージのサービスが、その ネットワークの TLD の下に DNS で公開されるため、 名前でアクセスできます。DNS → サービスでは、サービスごとに公開を 切り替えられます。非公開にしたサービスは動き続けますが、名前では解決できなくなります。 各サービスの完全修飾名は <name>.<repo>.<tld> の形式です(既定のネットワークでは TLD は .home です)。

DNS の流れ
端末
スマートフォン、ノート PC など
DNS 問い合わせ
DHCP
ルーター
Town OS を DNS として配布
DNS = Town OS の IP
転送
Town OS
rolodex DNS サーバー
権威ゾーン 上位への転送

認証局を信頼する

Town OS は、内部サービス向けの TLS 証明書を rolodex の内蔵認証局を通じて発行します。ブラウザーが警告ではなく鍵マークを表示するには、 端末ごとに Rolodex のルート CA を一度だけ信頼させる必要があります。 取得方法は 3 通りあります—端末に合ったものを選んでください。

方法 1: DNS から取得する(DNS が使える場所ならどこでも)

rolodex は CA のチェーンを DNS そのもので公開しているため、ゾーンを解決できる 端末であれば CA を取得できます—登録ポータルへのアクセスは不要です。 ルートとゾーンごとの中間証明書は _ca.<zone>CERT レコード(RFC 4398)として提供され、 _rolodex-ca.<zone> には分割された TXT の代替もあります。

# 公開されている CA レコードを見る
dig @<town-os-ip> CERT _ca.example.home

# ルート CA を PEM ファイルへ取り出す(ルート = 自己署名のもの)
dig @<town-os-ip> +short CERT _ca.example.home

これらのレコードをブラウザーで扱うには、Rolodex のブラウザー拡張機能が いちばん簡単です(rolodex リポジトリの extension/ にあり、 chrome://extensions や Firefox の about:debugging から 展開して読み込みます)。ポップアップの CA via DNS の欄で DoH の URL (https://<town-os-ip>/dns-query)とゾーンを入力すると、 DNS over HTTPS でチェーンを取得します。CERT レコードを優先し、必要に応じて TXT に 自動でフォールバックし、ホスト名を指定すれば公開されている DANE の TLSA レコードで 検証したうえで、ルート、中間、完全なチェーンを PEM としてダウンロードできます。

方法 2: 登録ポータルから取得する

信頼されたネットワーク上で登録ポータル(既定では https://<town-os-ip>:8500)を開き、 Download root CA (PEM) をクリックします。同じ拡張機能や rolodex-ca-ui のローカルコンソールからも取得できます。

方法 3: コマンドラインから取得する

# 管理 CLI 経由(ルートと中間の PEM を出力)
rolodex-dns-cli ensure-zone-ca --zone example.home

# あるいはポータルのダウンロードを直接取得
curl -k https://<town-os-ip>:8500/api/ca -o rolodex-root-ca.pem

端末にルート CA をインストールする

rolodex-root-ca.pem を入手したら、信頼ストアへ追加します。

プラットフォーム手順
Firefox設定 → プライバシーとセキュリティ → 証明書 → 証明書を表示 → 認証局 → インポート(“この認証局によるウェブサイトの識別を信頼する” にチェック)
Chrome / Edge(デスクトップ)OS の信頼ストアを使います—下の OS の行に従ってインストールし、ブラウザーを再起動してください
macOSPEM をダブルクリックしてキーチェーンアクセスに追加し、SSL の項目を “常に信頼” に設定します
Linux(Fedora/RHEL)sudo cp rolodex-root-ca.pem /etc/pki/ca-trust/source/anchors/ && sudo update-ca-trust
Linux(Debian/Ubuntu)sudo cp rolodex-root-ca.pem /usr/local/share/ca-certificates/rolodex.crt && sudo update-ca-certificates
Windowsダブルクリック → 証明書のインストール → ローカル コンピューター → “信頼されたルート証明機関”
Android設定 → セキュリティ → 暗号化と認証情報 → 証明書をインストール → CA 証明書
iOSPEM を開き(AirDrop やメール)、プロファイルをインストールしてから、設定 → 一般 → 情報 → 証明書信頼設定で有効にします

Rolodex の ACME エンドポイントを通じて発行されたサーバーは、このルートで検証できる リーフ + 中間のチェーンを提示します。DANE に対応したクライアントは、 発行時に rolodex が自動的に公開する TLSA レコードで中間証明書を 追加で検証できます。

ネットワークとリモートアクセス

Town OS はサービスをネットワーク単位でまとめます。どのマシンにも home という組み込みのネットワークが最初からあります。これは LAN 専用で、 .home の下の名前を解決し、トンネルは持ちません。自宅の外から安全に サービスへアクセスするには、ネットワークを追加してください。追加したネットワークは それぞれ、独自の DNS の TLD と対になった WireGuard のオーバーレイで、 ダッシュボード → ネットワークから管理します(管理者のみ)。

組み込みの home ネットワークを TLD、サブネット、ピア数、リモートアクセスの切り替えとともに一覧表示し、ネットワークを作成ボタンも備えたネットワークのページ

既定のネットワーク

  • 常に存在し、削除できません。 home ネットワークは自動的に作成され、ほかを選ばない限りパッケージはここに配置されます。
  • ローカル専用です。 WireGuard の経路を持たないため、.home の名前は LAN 上でのみ解決され、リモートのピアには意図的に一切公開されません。
  • .home の TLD を使います。これは dns_tld 設定から来ています。

リモートアクセス用のネットワークを作る

ネットワークを作成をクリックし、名前(例: office)と、 任意で TLD(既定はネットワーク名)を指定します。すると Town OS は次を行います。

  • 10.64.0.0/10 の範囲から決定的に導いたオーバーレイのサブネットで WireGuard インターフェースを生成し、マシン自身を .1 のアドレスにします。
  • そのネットワークの TLD を確保します(TLD はマシン内で一意です。ほかのネットワークがすでに持つ TLD でネットワークを作ろうとすると拒否されます)。
  • オーバーレイ上でネットワークごとの DNS リゾルバーを動かし、参加した端末がそのネットワークの名前を解決できるようにします。
名前と TLD の入力欄を持ち、TLD の既定値がネットワーク名であることを示すネットワーク作成ダイアログ

各行のリモートアクセスのスイッチで、WireGuard インターフェースを 起動・停止できます。オフにすると、コンテナーは動いたままローカルからは到達できる状態で、 リモートアクセスだけが遮断されます。

端末を登録する

ネットワークのピアダイアログを開き、端末名を入力して ピアを追加をクリックします。Town OS はそのまま取り込める WireGuard の 設定を返すので、スマートフォンやノート PC の WireGuard アプリに貼り付けてください。

設定はその場でコピーしてください。そこには生成されたばかりの秘密鍵が 含まれており、保存されることはありません。あとから取得することはできず、 失った場合は端末を登録し直す必要があります。

生成された設定は端末の DNS をマシンのオーバーレイアドレスに向けるので、トンネルが つながればネットワークの名前が自動的に解決されます。通常の端末では rolodex DNS を実行するのスイッチはオフのままにしてください。 オンにするのは、転送先にしたい rolodex DNS サーバーをそのピア自身が動かしている 場合だけです。

WireGuard 専用アカウント

ダッシュボード全体を触らせずに、自分の端末だけを登録してもらいたい場合は、 WireGuard 専用アカウントを作成します(ユーザー作成画面の チェックボックスです)。このアカウントは、

  • 特定のネットワークに限定されます — そのネットワークでのみピアを登録でき、home ネットワークには決して登録できません。
  • フェイルクローズです。認証、自分のピアの登録と更新、CA の取得はできますが、コントロールプレーンのそれ以外の操作は一切できません。
  • 期限付きのピアを登録します。登録ごとに TTL(既定は 2 時間、設定 → WireGuard ピアの TTL で変更)があり、接続を保つには更新が必要です。放置された端末は自動的に期限切れになります。管理者が追加したピアは恒久的です。

ピアの監視と切断

ネットワークのページにある接続中のピアのパネルには、すべての ネットワークにまたがる登録済みのピアが、ハンドシェイクの状態、オーバーレイの IP、 転送量、期限とともに一覧表示されます。端末を強制的に切り離すには 切断を使います。ピアが削除され、トンネルは直ちに落とされ、鍵は 失効するため、その端末は再び登録されるまで接続できません。

ネットワークを指定してパッケージをインストールする

インストールのダイアログ(および ページのダイアログ)には ネットワークの選択欄があります。 どのネットワークを選ぶかによって、そのサービスの DNS 名と TLS 証明書が決まります。office に インストールしたパッケージは .office の下で解決され、証明書もその名前で 発行されます。既定以外のネットワーク上のサービスはデュアルホームになり、トンネル越しの ピアにはオーバーレイのアドレス、ローカルのクライアントには LAN のアドレスとして 解決されます。別のネットワークでパッケージを入れ直すと、DNS と証明書もその ネットワークの TLD へ移ります。

パッケージの設定項目の上に「このパッケージを提供するネットワーク」と書かれたネットワーク選択欄がある jitsi のインストールダイアログ

たとえば fart という TLD のネットワークに Jitsi をインストールすると、 jitsi.default.fart で公開されます。起動すると、そのサービスは ダッシュボードにそのアドレスへのリンクとして表示され、ネットワーク上の どの端末からでも開けます。

https://jitsi.default.fart/ へのリンク付きで jitsi を表示するダッシュボードのインストール済みサービス一覧
ネットワーク越しのリモートアクセス
あなたの端末
スマートフォンやノート PC
WireGuard
トンネル
Town OS
ネットワークのオーバーレイと DNS
office のサブネット .office の TLD
名前解決
あなたのサービス
名前でアクセスできる
gitea.default.office

Android 版 Town OS

Town OS の Android クライアントは、スマートフォンを WireGuard 経由であなたの ネットワークのひとつに接続し、DNS を設定してサービスを名前で 解決できるようにします—どこからでも。端末をピアとして自動的に登録してくれる 本格的な WireGuard クライアントなので、設定ファイルを手でコピーする必要はありません。

Town OS Android クライアントのログイン画面 — マシンのアドレス、管理者のユーザー名、パスワードの入力欄を持つ接続カード
マシンにログインする
Town OS Android クライアントの接続画面 — DNS リゾルバー設定カードの上に、接続と このネットワークを削除 のボタンを備えた未接続の状態表示
接続と DNS を管理する

アプリのインストール

アプリはプロジェクトの リリースページ から APK として配布されています。Play ストアや F-Droid にはありません。

  • デバッグ版の APKtown-os-client-<version>-debug.apk)をダウンロードしてください。同じリリースにある -unsigned.apk はそのままではインストールできません。プロジェクトは署名鍵を配布していないため、入手すべきはデバッグ版です。
  • Android 8.0(Oreo)以降が必要です。
  • 自分でビルドしたい場合は、リポジトリをクローンし、USB で端末を接続して USB デバッグを有効にしたうえで make deps && make debug && make install を実行します。make help にすべてのターゲットが載っています。

インストールの方法は 2 通りあります。スマートフォンだけで行う方法と、コンピューターから USB 経由で行う方法です。前者に必要なのはスマートフォンだけです。

スマートフォンだけでインストールする

コンピューターもケーブルも、開発者モードも不要です。開発者向けオプションと USB デバッグが関係するのは、後述の adb を使う方法だけです。Android が求めるのは、 ストア以外から来たアプリをインストールする許可だけです。

  1. スマートフォンのブラウザーで APK をダウンロードします。リリースページを開き、town-os-client-<version>-debug.apk のアセットをタップします。ブラウザーは「この種類のファイルは端末に有害な可能性があります」と警告しますが、これはどの APK でも表示されるものです。ダウンロードを続行を選んでください。
  2. ダウンロードの通知、ブラウザーのダウンロード一覧、またはファイルアプリから開きます
  3. 提供元を許可します。初回は、開こうとしたアプリに不明なアプリをインストールする権限がないと表示され、設定ボタンが示されます。それをタップして、そのアプリ(ブラウザーやファイルマネージャー)に対してこの提供元を許可をオンにし、戻ります。同じ設定は設定 → アプリ → 特別なアプリアクセス → 不明なアプリのインストールにもあります。
  4. インストールをタップします。Play プロテクトがスキャンを提案したり、提供元が不明な開発者であると警告したりすることがありますが、サイドロードしたビルドでは想定どおりです。インストールを選んでください。
  5. インストールが終わったら、アプリ一覧から Town OS を開きます。

先にコンピューターから APK をコピーしておき(USB のファイル転送、adb push、 各種の同期アプリなど)、ファイルマネージャーで開く方法でもまったく同じように動作します。

開発者モードを有効にする

これが必要なのは adb を使う方法だけで、スマートフォン自身のダウンロードから APK をインストールするなら不要です。adb installmake install は どちらも USB デバッグ経由で端末とやり取りしますが、これは Android の隠された 開発者向けオプションのメニューの中にあります。

  1. 設定 → デバイス情報を開きます。Samsung の端末では設定 → デバイス情報 → ソフトウェア情報です。
  2. ビルド番号を 7 回タップします。Android は「開発者になるまであと 3 ステップです」のようにカウントダウンし、完了前に PIN、パターン、パスワードの入力を求めます。
  3. これでデベロッパーになりましたというメッセージが表示されます。その後開発者向けオプション設定 → システムに現れます。端末によっては設定の最上位に置かれることもあるので、見当たらない場合は設定内を検索してください。
  4. 開発者向けオプションを開き、USB デバッグをオンにします。
  5. スマートフォンをコンピューターに接続します。Android がコンピューターの鍵のフィンガープリントとともにUSB デバッグを許可しますか?というダイアログを表示するので、このパソコンからのアクセスを常に許可するにチェックを入れて許可します。adb devices を実行し、端末が unauthorized ではなく device として表示されることを確認してください。

作業が終わったら USB デバッグはオフに戻してください。許可したすべての コンピューターに、デバッグブリッジ経由でスマートフォンへの完全なアクセスを与えるため、 日常的にオンのままにしておくのは不要なリスクです。

リポジトリなしで adb からインストールする

USB 経由でインストールするのに、クライアントのソースツリーは必要ありません。 make install は単なる便利なラッパーです。adb を使う方法に必要なのは、 公開された APK と adb のバイナリだけで、後者は Google の Android SDK Platform Tools に含まれています。

  • Ubuntu / Debiansudo apt install adb android-sdk-platform-tools-common。2 つ目のパッケージには、root なしで自分のユーザーアカウントから端末へアクセスするための udev ルールが入っています。インストール後はスマートフォンを挿し直してください。
  • Arch / Manjarosudo pacman -S android-tools android-udev を実行し、sudo usermod -aG adbusers $USER で自分を adbusers グループに入れて、ログインし直します。
  • macOSbrew install --cask android-platform-tools。ほかに設定は不要で、macOS はドライバーなしで端末とやり取りできます。
  • Windows — PowerShell で winget install Google.PlatformTools を実行するか、下記の ZIP を入手します。ほとんどの端末は Windows が自動で入れるドライバーで動作しますが、一部のメーカー(Samsung、Xiaomi)は独自の USB ドライバーを入れないと adb が端末を認識しません。
  • その他のシステム — Google の platform-tools の ZIP をダウンロードして、好きな場所に展開します。インストール作業はありません。そのフォルダーから adb を実行してください(Windows では .\adb.exe)。

adb version で導入できたことを確認します。続いて リリースページ からデバッグ版の APK をダウンロードし、上記のとおり USB デバッグを有効にして、 スマートフォンを接続してから次を実行します。

# 端末が接続され、許可されていることを確認する
adb devices

# APK をインストールする
adb install town-os-client-<version>-debug.apk

つまずきやすい点をいくつか挙げます。

  • no devices/emulators found — ケーブルが充電専用であるか、端末側でこのコンピューターを許可していません。ケーブルを挿し直し、端末の画面に出るUSB デバッグを許可しますか?の確認を探してください。
  • Linux での no permissions — 上記の udev ルールのパッケージが入っていないか、それを入れる前に端末を接続していました。パッケージを入れ、端末を挿し直して、adb kill-server && adb devices を実行してください。
  • INSTALL_FAILED_UPDATE_INCOMPATIBLE — 別の鍵で署名されたものがすでにインストールされています。以前に自分でビルドした場合に起こります。古いアプリを削除して(アプリ一覧で長押しするか、adb shell pm list packages town で調べたパッケージ名を adb uninstall に渡します)、もう一度インストールしてください。
  • 上書き更新adb install -r town-os-client-<version>-debug.apk は、既存のインストールをデータを保ったまま置き換えます。どちらもリリースページから入手したものである必要があります。
  • ここでの操作は端末のストレージに何も残しません。adb install は転送とインストールを 1 度に行うため、あとからファイルマネージャーでファイルを探す必要はありません。

接続する前に

  • 先にネットワークを作成してください。アプリが参加できるのは WireGuard のオーバーレイを持つネットワークだけです。組み込みの home ネットワークは LAN 専用なので表示されません。リモートアクセス用のネットワークを作るを参照してください。
  • 管理者アカウントを用意しておいてください。端末の登録は管理者の操作なので、アプリは管理者の資格情報でサインインします。

ネットワークに接続する

  1. マシンにログインします。アドレス(IP だけ、IP:port、完全な URL のいずれか。ポートは 5309 が既定です)と、管理者のユーザー名・パスワードを入力します。
  2. ネットワークに参加します。アプリは参加できるネットワークを、TLD、サブネット、ピア数とともに一覧表示します。端末に名前を付けて(既定はスマートフォンの機種名)、参加をタップします。WireGuard の鍵ペアは端末上で生成され、送られるのは公開鍵だけなので、秘密鍵が端末から出ることはありません。
  3. 接続します。接続をタップし、Android の接続リクエスト(VPN)の確認を許可します。アプリがトンネルを張り、ネットワークの TLD を検索ドメインとして設定するので、gitea でも gitea.default.<tld> でも解決できます。
  4. これでどこからでも名前でネットワークにアクセスできます。トンネルを切るには切断を、保存された登録を消すにはこのネットワークを削除を使います。

トラブルシューティング

  • トンネルはつながっているのに名前が解決されない。たいていの原因は Android の厳格なプライベート DNS です。特定のプロバイダーのホスト名に設定されていると、Android はすべての問い合わせをそこへ送りトンネルを無視するため、Town OS の名前は「見つかりません」となります。設定 → ネットワークとインターネット → プライベート DNS自動オフに切り替えてください。アプリはこれを検出し、その設定への近道つきで警告を表示します。(自動モードなら問題なく、警告も出ません。)
  • それでも解決しない場合は?アプリの DNS のカードで、リゾルバーの上書きにマシンの LAN アドレスを設定してください。アプリがトンネル経由で転送するので、スプリットホライズン DNS もそのまま機能します。
  • マシンの再起動後にログアウトされる。Town OS は再起動時にすべてのセッションを消去します。もう一度ログインしてください。

USB イメージから VM を作る

install リポジトリには、Town OS を仮想マシンで起動するためのスクリプトが含まれており、 テストや開発に便利です。ソースからビルドした イメージからでも、すでに書き込んだ物理 USB メモリから 直接でも起動できます。 make help にすべてのターゲットと変数が載っています。

QEMU

make qemu-fg

イメージが古ければビルドし直したうえで、シリアルコンソールを接続し、KVM による アクセラレーションと、ストレージのテスト用の 4 台の仮想データディスクを備えた QEMU の VM をフォアグラウンドで起動します。まずはこのターゲットを 使ってください。起動とインストーラーの様子を端末上で直接確認でき、Ctrl-C で VM を 止められます。バックグラウンドで動かしたい場合は make qemu を使い (あとから make serial で接続します)、 停止・クリーン・再ビルド・再起動を一度に行うには make rebuild-qemu を使います。

VM は virbr0 上の libvirt の default NAT ネットワークに接続され、 VM_IP(既定は 192.168.122.50)に固定されるため、同時に動かす VM にはそれぞれ別のアドレスを割り当ててください。

ゲストは NAT 配下にあるため、VM_LAN=1(既定)は制御 API (5309)、UI(80/443)、ssh (2222)、WireGuard の UDP ポートを、ホストの LAN アドレスから ゲストへ中継します。これにより、Android クライアントを 動かしているスマートフォンから VM へアクセスできます。中継を無効にするには VM_LAN=0 を設定します。

物理 USB から起動する(qemu-usb)

make qemu-usb USB_DEV=/dev/sdX

ビルドしたイメージではなく、書き込み済みの物理 USB メモリから直接 QEMU を フォアグラウンドで起動します。書き込んだばかりのメモリが実際に起動するかを 確かめるのに便利です。デバイスは読み取り専用(スナップショット)で 開かれるため、ゲスト側の書き込みは破棄され、実際の USB は変更されません。 ストレージのテスト用に 4 台の仮想データディスクも接続されます。このターゲットは 何もビルドしません。install リポジトリをクローンし、install.shmake flash でメモリに書き込んでから、USB_DEV をそれに 向けてください。x86_64 のホストでは、TARGET=aarch64(または rpi)を指定するとシステム全体のエミュレーションでメモリを起動できるので、 対応するハードウェアがなくても別アーキテクチャのイメージをテストできます。

停止と後片付け

# VM を停止する
make stop

# VM を停止し、イメージと仮想ディスクを削除する
make clean

環境変数

変数既定値説明
IMAGE_SIZE12GUSB イメージのビルド時のスパースサイズ(イメージはあとで縮小されます)
VM_DISK_SIZE50G4 台の仮想データディスクそれぞれのサイズ(town-os.yamlvm_disk_size から読み取られます)
VM_MEMORY4GVM のメモリ
VM_CPUS4VM の vCPU 数。QEMU の既定である 1 では rolodex のワーカープールが枯渇します
VM_BRIDGEvirbr0ネットワーク用のホストブリッジのインターフェース
VM_NAMEtown-osVM の名前。停止時の検索にも使われます
VM_IP192.168.122.50libvirt の DHCP 予約。同時に動かす VM にはそれぞれ別のアドレスを割り当ててください
VM_LAN1NAT 配下のゲストのポートをホストの LAN アドレスへ中継します。0 で無効
USB_DEVmake flash(書き込み)と make qemu-usb(読み取り専用の起動)で使う物理ブロックデバイス

シリアルコンソール

# VM のシリアルコンソールに接続する
make serial

# または socat で手動で接続する
socat -,rawer,escape=0x1d unix-connect:/tmp/town-os-serial.sock

# Ctrl-] で切断

VM を見つける

# VM の IP アドレスを取得する
make vm-ip

# またはホストから mDNS で接続する
ssh root@town-os.local
VM のネットワーク
ホストマシン
virbr0 — libvirt の default ネットワーク
QEMU
NAT
Town OS の VM
Town OS のスタック一式
192.168.122.50 eth0
VM_LAN の中継
ローカルネットワーク
スマートフォンや LAN の端末から VM へ
5309 · 80 · 443 · WireGuard

RAID のインストール

ディスクのプロビジョニングは、初回起動時に ttyforce が対話形式で行います。ストレージはすべて btrfs を使います。

RAID の自動選択

ttyforce は利用できるディスクを検出し、転送方式(NVMe、SATA など)とサイズの近さで グループ化してから、ディスクの台数に応じて RAID レベルを自動的に選びます。

  • 1 台 — single モード(冗長性なし)
  • 2 台 — RAID 1(btrfs のミラー)
  • 3 台以上 — RAID 5(btrfs のパリティ付きストライプ)

既定のマウントポイントは /town-os です。ttyforce は overlayfs 互換の 永続化のために @etc@var のサブボリュームを作成します。

ディスクの検出

ttyforce は利用できるストレージデバイスを自動的に検出します。NVMe ドライブ、 SATA/SAS ドライブ、SD カードを識別する一方で、起動元の USB デバイスとリムーバブル メディアは除外します。この検出により、Town OS が起動元のドライブに触れることは 決してありません。

オーバーレイファイルシステム

ストレージのバックエンドにかかわらず、Town OS は /var/etc の永続化にオーバーレイマウントを使います。下位のレイヤーは squashfs のルートから来ており、上位のレイヤーは RAID/ZFS のストレージ上にあります。 これにより、ベースの OS はイミュータブルなまま、システムの設定とサービスのデータは 再起動をまたいで保持されます。

ストレージの構成
NVMe
高速 SSD
SATA / SAS
HDD または SSD
SD カード
リムーバブル
検出
btrfs single
1 台
btrfs RAID 1
2 台(ミラー)
btrfs RAID 5
3 台以上(パリティ)
サブボリューム
パッケージごとのストレージ
pkg-a pkg-b
オーバーレイマウント
永続化するシステムのディレクトリ
/var /etc

ユーザーインターフェースの使い方

Town OS には、サーバーを管理するためのすっきりしたウェブダッシュボードが用意されています。 起動後、ブラウザーを開いて Town OS マシンの IP アドレスか http://town-os.local にアクセスしてください。

初回起動: アカウントの作成

初回起動時に、管理者アカウントの作成を求められます。ユーザー名とパスワードを 決めてください。このアカウントはシステムを完全に制御できます。

アカウント作成画面

ダッシュボード

ダッシュボードにはシステムの概要が表示されます。インストール済みのパッケージが 状態インジケーターとクイック操作を備えたサービスカードとして並び、システムの状態が ひと目でわかります。

ダッシュボードの概要

パッケージの閲覧とインストール

パッケージのビューでは、利用できるパッケージを検索し、詳細を確認し、案内に沿って インストールできます。各パッケージの質問はフォームとして表示されるので、ホスト名、 ポート、その他の設定を入力してインストールをクリックします。

パッケージの一覧
パッケージのインストール時の入力
インストールの詳細

サービスの管理

インストール済みのサービスは、サービスのビューから開始、停止、再起動できます。 状態インジケーターは、各サービスが稼働中か、停止中か、エラー状態かを示します。

サービスの管理

ログの表示

ログのビューでは、ジャーナルの出力をリアルタイムに表示し、フィルタリングや grep が 行えます。サービス、優先度で絞り込んだり、特定の文字列を検索したりできます。

ログビューアー

ストレージの管理

btrfs のサブボリュームを確認・管理し、パッケージごとのクォータを設定し、 ストレージプール全体のディスク使用量を監視できます。

ストレージの管理

モニタリング

Town OS には Prometheus と Node Exporter による監視機能が組み込まれており、 システムのメトリクス、サービスの状態、リソース使用量の推移を追跡できます。 既定では軽量な組み込みダッシュボードが使われ、任意で Grafana に切り替えられます。

モニタリングのダッシュボード

設定と監査ログ

設定のページでは、システム全体のオプションを構成できます。監査ログは、インストール、 アンインストール、サービスの状態変更、設定の変更など、すべての管理操作を記録するので、 何がいつ変わったのかを常に把握できます。

設定
監査ログ

静的サイトのホスティング

コンテナー化されたパッケージ以外に、Town OS には静的サイトのホスティングが 組み込まれています。常時有効で、ダッシュボード → ページから 管理します。各ページはイングレスの背後にある共有のウェブサーバーが配信し、 パッケージと同じようにネットワークの TLD の下で DNS 名と TLS 証明書を得ます。

コンテンツのソース

ページを作成するときは、名前ドメイン (既定は名前と同じ)、ネットワーク(既定は home)と、 3 種類のコンテンツソースのいずれかを選びます。

  • アーカイブのアップロード — サイトの tarball をアップロードします。アーカイブをアップロードするまで、ページは保留状態で待機します。
  • git リポジトリ — リポジトリの URL からクローンします。ブランチを指定できるので(既定は main)、gh-pages に公開しているサイトにも便利です。
  • コンテナーイメージ — OCI イメージからディレクトリを取り出します。

git とコンテナーのページは非同期にプロビジョニングされます。一覧には プロビジョニング中…のバッジが表示され、有効かエラーに変わります。 git とコンテナーのページで最新のコンテンツを取得するには再ビルドを 使います。アーカイブのページの場合は、新しい tarball をアップロードしてください。

ページの配信のしくみ

各ページは専用のストレージのサブボリューム上にあり、ポート 80 の HTTP で直接配信されます。 一方、パッケージのサービスはポート 80 を HTTPS へリダイレクトします。ページはネットワークを 持つため、その名前はネットワークの TLD の下で解決され、LAN から、そしてネットワークが WireGuard のオーバーレイであれば登録済みのリモート端末からもアクセスできます。

Town OS の更新

Town OS は、ダッシュボードからコアサービスをその場で更新します。 システム管理にあるコアサービスの更新ボタンを押すと、 最新のコンテナーイメージを取得し、すべてのコアサービスを再起動します。システム コントローラー自身も対象で、これがマシンの自己更新の仕組みです。

更新中に何が起こるか

  • イメージの取得とサービスの再起動は依存順に行われます。まずシステムコントローラー(自身を再起動する前に新しいイメージを用意するため)、次に DNS、最後にそれ以外です。
  • コントローラーが再起動するとログインセッションは意図的にリセットされます。そのためダッシュボードは、更新中はログイン画面へ飛ばす代わりに、通常のセッション確認を控えます。
  • 進捗は 5 段階のステッパーで表示されます: システムコントローラーの起動DNS の起動システムサービスの開始パッケージの再起動(インストール済みパッケージごとに 1 行)→ 完了
  • 更新が終わると、ダッシュボードは勝手に再読み込みするのではなく再読み込みボタンを表示します。

この 5 段階は通常の起動時のプロビジョニング画面にも表示されるので、パッケージごとに 起動の進み具合を確認できます。

パッケージを作る

Town OS のパッケージは、コンテナー化されたサービスの動かし方を記述した YAML ファイルです。 完全な仕様はパッケージング形式のリファレンスを 参照してください。この節では実際の作業の流れを説明します。

リポジトリの構造

パッケージリポジトリは、packages/ ディレクトリを持つ git リポジトリです。 各パッケージは、バージョンごとの YAML 定義を収めたサブディレクトリを持ちます。

my-packages/
  packages/
    my-app/
      1.0.yaml
      2.0.yaml

パッケージ定義を書く

最小限のパッケージに必要なのは image フィールドだけです。一般的な パッケージには、説明、ネットワーク、ボリューム、利用者向けの質問が含まれます。

image: myapp:latest
description: My custom application
supplies: ["http"]
network:
  external:
    "@port@": "8080"
volumes:
  data:
    mountpoint: /app/data
    quota: 5gb
questions:
  port:
    query: "What external port should this app use?"
    type: port
    default: "9000"
notes:
  URL:
    value: "http://@LOCAL_EXTERNAL_HOST@:@port@"
    type: url

質問には、自由入力のテキストや port のほかにもいくつかの型があります。 secret(空欄なら自動生成)、boolean(チェックボックスとして表示)、 oauth(提供元のデバイスフローを実行してトークンを取得する 接続ボタン)などで、どの質問も optional: true を指定すれば 空欄のままにできます。すべての一覧は、パッケージング形式のリファレンスの 質問を参照してください。インストール時には、 そのパッケージを提供するネットワークも 運用者が選びます。

テンプレートの仕組み

質問の回答や組み込み変数(@LOCAL_EXTERNAL_HOST@@LOCAL_INTERNAL_HOST@)を参照するには @variable@ 構文を使います。 テンプレートは環境変数、ポートマッピング、クォータ、ノートの値で機能します。

ローカルでテストする

パッケージのテストには開発環境を使ってください。 リポジトリをディスク上に置き、UI か repositories.json から追加して、 自分のパッケージをインストールします。開発環境は、テスト用に Town OS のスタック一式を 提供します。

リポジトリを追加する

自分のパッケージリポジトリは、UI から (パッケージ → リポジトリ → リポジトリを追加)、または repositories.json を直接編集して Town OS に追加します。

[
  {"name": "default", "url": "https://github.com/town-os/default-packages"},
  {"name": "my-packages", "url": "https://github.com/myuser/my-packages"}
]
パッケージのライフサイクル
YAML 定義
image、volumes、questions
1.0.yaml
インストール
設定の入力
利用者が質問に答える
hostname port
デプロイ
稼働中のコンテナー
ボリュームとともにサービスが動作
@variable@ → 値

セルフホストできるもの

Town OS は、コンテナーイメージとして配布されているものなら何でも動かせるように 作られています。始めるためのアイデアをいくつか挙げます。多くは 既定のパッケージリポジトリ で提供されており、どんなコンテナーイメージでも簡単な YAML 定義でパッケージ化できます。

メディアとエンターテインメント

  • Plex / Jellyfin — 映画やテレビ番組のライブラリをどの端末にも配信
  • Navidrome — 個人用の音楽ストリーミングサーバー
  • Calibre-web — 電子書籍のコレクションを管理して読む

コードと共同作業

  • Gitea / Forgejo — 軽量なセルフホスト型の Git
  • GitLab — 本格的な DevOps プラットフォーム
  • Nextcloud — ファイル、カレンダー、連絡先など
  • Wiki.js / BookStack — ドキュメントとナレッジベース

コミュニケーション

  • Jitsi Meet — プライベートなビデオ会議
  • Matrix / Synapse — フェデレーション対応の暗号化チャット
  • Mattermost / Rocket.Chat — チームのメッセージング

ゲームサーバー

  • ValheimMinecraftTerrariaSatisfactory の専用サーバー
  • GloriousEggroll のコンテナーによる Proton/Steam のサポート
  • Linux バイナリやコンテナーとして配布されているゲームサーバー全般

ホームオートメーション

  • Home Assistant — スマートホームの制御ハブ
  • Node-RED — 視覚的に組み立てる自動化のワークフロー
  • Mosquitto — IoT 機器向けの MQTT ブローカー

プライバシーとセキュリティ

  • Pi-hole / AdGuard — ネットワーク全体の広告ブロック
  • WireGuard / OpenVPN — リモートアクセス用の VPN サーバー
  • Vaultwarden — セルフホスト型のパスワードマネージャー

生産性

  • Paperless-ngx — 文書管理と OCR
  • Immich — セルフホスト型の写真・動画管理
  • Planka / Wekan — かんばんボードとプロジェクト管理

開発環境とテストスイート

Town OS の開発環境は、Podman のコンテナーを使ってスタック一式をローカルで動かします。 変更の確認、パッケージの開発、テストスイートの実行を行うには、これがいちばん速い方法です。

事前に必要なもの

  • Linux — btrfs と Podman の rootful コンテナーに必要です
  • Podman — コンテナーランタイム(sudo を使う rootful モード)
  • Go 1.25 以降 — バックエンドの API サーバー用
  • Bun — フロントエンドのビルドと開発サーバー用
  • btrfs-progs — ストレージ管理用
  • QEMU — VM パッケージのサポートに必要な qemu-system-x86_64 と qemu-img
  • libsystemd — systemd 連携のための開発用ヘッダー
  • golangci-lint — Go の lint 用
  • Python 3 — ビルドとテストのスクリプト用

開発環境を起動する

git clone https://gitea.com/town-os/town-os.git
cd town-os
make dev

これでホットリロード付きの開発スタック一式が起動します。準備ができたら、端末に 表示された URL を開いて Town OS のダッシュボードにアクセスしてください。

開発環境のコマンド

コマンド説明
make dev開発環境一式を起動する
make dev-stop開発用コンテナーをすべて停止する
make dev-logs開発用コンテナーのログを追う
make dev-clean開発用コンテナーとボリュームを削除する

テストを実行する

コマンド説明
make testユニットテストを実行する
make test-integration統合テストを実行する(特権付きの Podman が必要)
make test-ui-integrationUI の統合テストを実行する
make test-fullすべてのテストを実行する(ユニット + 統合 + UI)
make auto-test変更を監視してテストを自動的に再実行する

統合テスト

統合テストは、実際の btrfs ファイルシステム、systemd、Podman-in-Podman を備えた 特権付きの Podman コンテナー内で実行されます。これにより、本番環境のインストールと 同じコード経路をテストできます。テスト用コンテナーは使い捨てで、テスト実行ごとに 新しく作られ、終了後に片付けられます。

開発の流れ
エディター
コードを編集
Go + Bun
保存
auto-test
保存時にテストが実行
make auto-test
再読み込み
ブラウザー
リアルタイムのプレビュー
localhost:5173
↻ 繰り返す — バックエンド :5309 · フロントエンド :5173

バグを報告する

おかしなところを見つけましたか。良いバグ報告は、問題の修正を早めます。ここでは 必要な情報の集め方と、効果的な報告の出し方を説明します。

API でログを集める

Town OS はREST API を通じてジャーナルのログを 公開しています。Claude Code を使って API に接続し、最近のエラーの要約を作ることもできます。

# Town OS からエラー優先度のジャーナルエントリーを取得する
curl -s http://town-os.local:5309/api/systemd/logs/tail?priority=err | jq .

または Claude Code で対話的にエラーを要約させます。

# Claude Code へのプロンプトの例:
"http://town-os.local:5309 の Town OS API に接続し、
 /api/systemd/logs/tail からエラー優先度のジャーナルエントリーを
 最新 100 件取得してください。エラーを要約し、サービスごとに
 グループ化して、考えられる原因を挙げてください。"

issue を登録する

issue は Town OS の Gitea インスタンス gitea.com/town-os/town-os/issues に登録してください。

記載すべき内容

  • ジャーナルの要約 — エラーログの出力、または最近のエラーの Claude Code による要約
  • 再現手順 — 問題を引き起こすまでに行ったことを、順を追って
  • Town OS のバージョン — 起動画面に表示されるビルド日付またはコミットハッシュ
  • ストレージのバックエンド — btrfs、btrfs-mdadm、ZFS のいずれかと、ディスクの台数
  • 環境 — 実機か QEMU か。RAM とディスクのサイズ
バグ報告の流れ
問題を検知
何かが壊れた
⚠ エラー
API を curl
ログを集める
ジャーナルのエントリーを取得
:5309/api/systemd/logs
要約
要約する
サービスごとにまとめる
Claude Code
登録
Gitea に登録
詳細を添えて issue を作成
✓ 報告済み