Debian 構築記録:極小構成プロキシサーバーの探求
1. 序論:なぜ今、Debianなのか
1.1 RHEL系ディストリビューションの肥大化と迷走
かつて、サーバー用途のLinuxといえばRed Hat Enterprise Linux (RHEL) やそのクローンであるCentOSがデファクトスタンダードであった。企業のエンタープライズ環境において、長期サポートと堅牢なパッケージ管理は魅力的であった。しかし、RHEL系ディストリビューションは、個人の趣味の範囲で運用するにはあまりにも「重厚長大」になりすぎている 。
初期インストール直後から大量の管理ツール、監視エージェント、そしてクラウド環境への親和性を謳った初期化スクリプト群がメモリを占有する。特に、IBMによるRed Hat買収以降のCentOSの終了や、ソースコード公開ポリシーの変更など、オープンソースコミュニティとの摩擦も無視できない要素となっている。技術的な純粋さを求める者にとって、政治的な思惑で仕様が左右されるOSは、土台として信頼に足るものではない。
1.2 Systemd と OpenRC の相克
Linuxのinitシステムを巡る論争は、Systemdの登場以来続いている。Unix哲学である「一つのプログラムは一つのことをうまくやる (Do one thing and do it well)」という観点からすれば、Systemdはあまりにも巨大なモノリスである。起動プロセス、サービス管理、ログ収集 (Journald)、ネットワーク設定 (Networkd)、果てはDNS解決 (Resolved) までをも飲み込み、ブラックボックス化している。
対して、Gentoo LinuxやAlpine Linuxで採用されているOpenRCは、シェルスクリプトベースのシンプルで透明性の高いinitシステムである。テキストベースの設定ファイルは可読性が高く、挙動を完全に掌握できる安心感がある。本来であれば、個人的な美学としてはOpenRCを選びたいところだ。
しかし、実用面におけるSystemdの利便性は否定できない 。
- 依存関係の解決: サービス間の依存関係を並列かつ高速に処理する能力。
- Cgroupsとの統合: リソース管理の厳密さ。
- 標準化: 現代の主要なミドルウェアのほとんどがSystemdのUnitファイルを提供している事実。
DebianはSystemdを採用しているが、RHEL系ほど強引な独自拡張や、不可解なデフォルト設定が少ない。Systemdの恩恵(管理の楽さ)を享受しつつ、その支配を最小限に留めることができる妥協点として、Debianは極めて優秀である。
1.3 Debian の美学
Debian (Sid を抜く)の最大の特徴は、その圧倒的な「安定性」にある 。ここで言う安定とは、単にクラッシュしないという意味だけでなく、パッケージのバージョンが固定され、挙動が変化しないことを指す。最先端の機能を追いかけるFedoraやArch Linuxとは対極に位置するが、一度設定したサーバーを数年間放置しても動き続ける信頼性は、プロキシサーバーというインフラ的な用途に最適である。
2. 浄化の儀式:VPSテンプレートからの脱却
2.1 汚染された初期状態
VPSやクラウドプロバイダから提供されるOSイメージ(テンプレート)は、決して「素」の状態ではない。プロバイダ側の管理都合により、様々なカスタマイズが施されている。
- Cloud-init: インスタンス起動時にSSH鍵の配置やホスト名設定を行うツールだが、起動時間を遅延させ、勝手にネットワーク設定を書き換える挙動は、固定的なサーバー運用において害悪となることが多い 。
- 古いパッケージ: テンプレートが作成された時期によっては、システムコンポーネントが古く、
apt upgradeをかけた際に依存関係の不整合や、設定ファイルの競合(ucfなど)が発生するリスクがある 。
2.2 Cloud-init と Fail2ban の完全排除
まず、提供されたサーバーにSSHでログインした後、直ちに行うべきはこれらの「お節介機能」の無効化と削除である。単にサービスを停止 (systemctl stop) するだけでは不十分だ。パッケージごと削除 (purge) し、設定ファイルやデータディレクトリも抹消する。
# Cloud-initの無効化(ファイルベースのフラグ)
sudo touch /etc/cloud/cloud-init.disabled
# パッケージの削除
sudo apt-get purge cloud-init -y
# 残存ディレクトリの清掃
sudo rm -rf /etc/cloud/
sudo rm -rf /var/lib/cloud/
sudo rm -rf /var/log/cloud-init.log
sudo rm -rf /var/log/cloud-init-output.log
これにより、システムはプロバイダの管理下から離脱し、純粋なLinuxとしての挙動を取り戻す 。
3. ネットワークインストールによる再構築
3.1 Grub Imageboot の導入
既存の汚れたOS環境を利用して、メモリ上でインストーラーを起動し、ディスクをフォーマットしてクリーンなDebianを入れ直す手法をとる。これには grub-imageboot パッケージを使用する 。このツールは、/boot/images/ ディレクトリに配置されたISOファイルをGrubのメニューエントリーに自動的に追加し、memdisk モジュールを使用してISOをメモリドライブとしてマウント・起動させる仕組みを提供する。
# パッケージリストの更新とツールのインストール
sudo apt update
sudo apt install grub-imageboot
# ISO配置用ディレクトリの作成
sudo mkdir -p /boot/images
3.2 Debian netboot の取得と配置
使用するインストーラーは、Debian公式のネットブート用イメージ mini.iso である 。 通常のインストールISO(数百MB〜数GB)とは異なり、このイメージは数十MBしかない。カーネルとインストーラー(d-i: debian-installer)のみが含まれており、全てのパッケージはインストールプロセス中にインターネット上のリポジトリから取得される。これにより、インストール時点で常に最新のセキュリティパッチが適用されたパッケージが導入されることが保証される。
# Debian Stable (amd64) の最新 mini.iso を取得
cd /boot/images
wget https://ftp.debian.org/debian/dists/stable/main/installer-amd64/current/images/netboot/mini.iso
ダウンロード先は必ず ftp.debian.org の stable ディレクトリを指定する。バージョン番号(例:bookworm)を直接指定するよりも、エイリアスである stable を使うことで、その時点での安定版を確実に取得できる 。
ISO配置後、Grubの設定を更新してメニューに反映させる。
sudo update-grub
出力にISOイメージが検出された旨が表示されれば成功である 。
3.3 Expert Install の実行
再起動後、GrubメニューまたはVPSのVNCコンソールから mini.iso を選択して起動する。インストーラーのメニュー画面が表示されたら、「Advanced options」から「Expert install」を選択する 。 通常インストール(Install)では、言語設定やユーザー作成、パーティショニングなどが簡略化され、自動決定されてしまう。Expert installでは、これら全てのパラメータに対して詳細な制御が可能となる。
3.3.1 ユーザー設定:Rootのみの硬派な構成
Linuxのセキュリティガイドラインでは、一般ユーザーを作成し sudo を使用することが推奨されるのが常である。しかし、このサーバーは特定のプロキシ用途専用であり、管理者は自分一人である。いちいち sudo をタイプする手間や、sudoersファイルの設定ミスによる権限昇格のリスクを考慮すれば、Root単一アカウントでの運用が最も合理的である。
そもそも sudo はロール分離や細粒度の権限制御、ログ管理など多機能な設計となっているが、個人運用の小規模サーバーにおいてその大半の機能が活用されることはほとんどない。機能が多いということはコードベースも大きくなり、結果としてCVEが発生しやすいという側面もある。
そのため、必要最小限の権限昇格のみを目的とする場合には、よりシンプルな実装である doas を使用する方が合理的である。互換性のために
ln -s /usr/bin/doas /usr/bin/sudo
とする運用も可能であり、実態としては sudo を使っているかのように振る舞わせつつ、内部的な複雑さを排除できる。
インストーラーの「Set up users and passwords」ステップにおいて:
- Enable shadow passwords?: Yes
- Allow login as root?: Yes
- Root password: 複雑なパスワードを設定する。
- Create a normal user account?: No
これにより、/etc/passwd に余計なユーザーが作成されず、純粋なRootのみの環境が構築される 。インストーラーが「一般ユーザーを作らないと最初のログインができない云々」と警告する場合があるが、Rootログインを許可しているため問題ない。
3.3.2 パッケージリポジトリとNTP設定
- Debian archive mirror country: 日本国内のVPSであれば「Japan」を選択する。地理的な近さはダウンロード速度、ひいてはシステム更新の速度に直結する。
- Debian archive mirror:
deb.debian.orgまたはftp.jp.debian.orgなどの信頼できるミラーを選択。 - Components:
mainだけでなく、contribとnon-free(またはnon-free-firmware) も有効にする。CPUのマイクロコードや、特定のネットワークカードのファームウェアが必要になる場合があるためだ 。
時刻同期設定では、デフォルトの 0.debian.pool.ntp.org を避け、国家標準時を提供するNTPサーバーを指定する。例えば日本であれば情報通信研究機構 (NICT) の ntp.nict.jp を使用する。プールサーバーはボランティアによって運営されており、品質にばらつきがあるため、プロキシサーバーのログ整合性を保つためには信頼できるStratum 1サーバーを直接指定すべきである。
3.3.3 自動更新の有効化
「Configuring apt」のステップで、セキュリティアップデートの自動インストール (unattended-upgrades) を有効にする。管理者が手動でログインして apt upgrade を叩くまでのタイムラグこそが最大の脆弱性である。勝手に再起動されるリスクよりも、既知の脆弱性を放置するリスクの方が遥かに大きい。
4. 起動後のシステムチューニング:極限までのダイエット
4.1 Grub Console Mode:視認性と高速化
インストール完了後、再起動したシステムの設定を行う。まずはブートローダーであるGrubの調整だ。デフォルト設定は汎用性を重視しすぎており、サーバー用途には冗長である。
/etc/default/grub を編集する。
変更点1: タイムアウトの短縮 デフォルトの5秒は長すぎる。起動ごときに時間を浪費したくない。
GRUB_TIMEOUT=1
1秒あれば、緊急時にシフトキーを押してメニューに入るには十分である 。
変更点2: カーネルパラメータの最適化 GRUB_CMDLINE_LINUX_DEFAULT に以下を設定する。
loglevel=3: カーネルのログ出力を抑制する。エラーレベル以上のログのみを表示させ、画面を埋め尽くす無駄な情報を排除する。nomodeset: Kernel Mode Setting (KMS) を無効化する。サーバーに高解像度のグラフィカルなコンソールは不要である。ビデオドライバの読み込みをスキップすることで、互換性の向上と起動時間の短縮を図る。VPSの仮想ディスプレイアダプタとの相性問題もこれで回避できることが多い。
変更点3: コンソール出力の強制 グラフィカルなブート画面(Plymouthなど)を排除し、純粋なテキストコンソールを使用する。
GRUB_TERMINAL=console
設定変更後は必ず update-grub を実行し、設定を反映させる。
4.2 コンソールフォント:Terminus Bold の採用
Linuxのデフォルトコンソールフォントは、現代の高解像度モニターや、ブラウザ経由のVNCコンソールで見ると視認性が悪い。作業効率を高めるため、美しく読みやすいフォントに変更する。
sudo dpkg-reconfigure console-setup
対話的な設定画面で以下を選択する 。
- Encoding:
UTF-8 - Character set:
Guess optimal character set - Font:
TerminusBold - Font size:
16x32(または画面サイズに合わせて最大のもの)
Terminus はビットマップフォントであり、スケーリングによる滲みが発生しないため、文字の輪郭が非常にシャープである。「Bold」バリアントを選ぶことで、黒背景に白文字のコントラストが際立ち、長時間の作業でも目が疲れにくい 。
4.3 TTYの削減:リソースの節約
標準状態のDebianは、tty1 から tty6 まで6つの仮想端末 (Virtual Terminal) を起動している。物理コンソールにアクセスできる人間が一人しかいないのに、6つのログイン画面を用意しておくのは Getty プロセスとメモリの無駄である 。
/etc/systemd/logind.conf を編集し、TTYの数を制限する。
[Login]
NAutoVTs=2
ReserveVT=2
これにより、自動起動するTTYを tty1 と tty2 の2つに限定する。一つはシステムログの表示用、もう一つは緊急時のログイン用として確保しておけば十分である 。
4.4 Systemd Journal の無効化
Systemd のロギングデーモンである journald は、バイナリ形式でログを /var/log/journal に保存する。これは検索性には優れるが、ディスクI/Oを消費し、容量を圧迫する要因となる。特に、プロキシサーバーとして大量のトラフィックをさばく場合、カーネルやネットワーク関連のログが肥大化しやすい。
個人的なポリシーとして、ログは「今の瞬間」が見えればよく、過去のアーカイブは不要である(トラブル時は再現させて確認すればよい)。よって、journaldのストレージ機能を無効化する。
/etc/systemd/journald.conf:
[Journal]
Storage=none
Storage=volatile(メモリ保存)ですらなく none を選択する 。これにより、journald はログを受け取るが保存はせず、syslog への転送(もし設定されていれば)や、コンソール出力のみを行うようになる。ディスクへの書き込み負荷が激減するため、SDカード運用のラズパイなどでも有効な設定である。
4.5 ネットワークスタックの最適化:BBR + FQ
プロキシサーバーの性能を決定づけるのが、TCP輻輳制御アルゴリズムである。 従来の CUBIC や Reno アルゴリズムは、パケットロスが発生した時点で帯域を絞る挙動をするため、レイテンシが高い国際回線や、パケットロスが稀に発生する環境ではスループットが出にくい。
Googleが開発した BBR (Bottleneck Bandwidth and Round-trip propagation time) は、パケットロスではなく、実際の帯域幅とRTT(ラウンドトリップタイム)をモデル化して送信レートを決定する。これにより、回線の物理的な限界近くまでスループットを引き出すことが可能になる 。
BBRを有効にするには、パケットスケジューラとして fq (Fair Queueing) を併用する必要がある。
/etc/sysctl.d/99-bbr.conf を作成し、以下の設定を記述する。
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
設定を適用し、確認を行う。
sudo sysctl -p /etc/sysctl.d/99-bbr.conf
sysctl net.ipv4.tcp_congestion_control
出力結果が net.ipv4.tcp_congestion_control = bbr となっていれば、カーネルレベルでの爆速化が完了している 。
5. ソフトウェア構成:シンプルさと堅牢性
5.1 最小限のパッケージ構成
基本原則として、OSには必要最低限のパッケージしか入れない。「いつか使うかもしれない」ツールは、脆弱性の温床であり、アップデート時間を長引かせるノイズである。 公式リポジトリから、以下のツールのみを導入する。
sudo apt update
sudo apt install htop net-tools curl wget
- htop: 標準の
topコマンドよりも視認性が高く、プロセスツリーの確認やCPUコアごとの負荷状況を直感的に把握できる。 - net-tools: 近年では
ipコマンドへの移行が推奨され非推奨扱いだが、長年染み付いたnetstat -tulnpの手癖は矯正しがたい。ポートの開放状況を確認するためだけに導入するが、現代的にはss -tulnpコマンドでも同等の情報を確認できる。
5.2 HTTPサーバー:Caddy の採用
Webサーバー(プロキシ)として、Nginxではなく Caddy を採用する。 Nginxは高性能だが、設定ファイル (nginx.conf) の記述が複雑になりがちで、SSL証明書の取得・更新には certbot などの外部ツールとの連携が必要となる。
CaddyはGo言語で書かれた次世代のWebサーバーであり、以下の強力な特徴を持つ:
- デフォルトでHTTPS: Let's Encrypt の証明書取得、更新、適用を全自動で行う。ユーザーは何も設定する必要がない。
- HTTP/3 (QUIC) 対応: 最新のプロトコルに標準対応しており、高速な通信が可能。
- シンプルな設定:
Caddyfileは人間が読むために設計されており、数行でリバースプロキシが構築できる。
Debian標準リポジトリのCaddyはバージョンが古い場合があるため、Caddy公式リポジトリを追加してインストールする 。
# 依存パッケージのインストール
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
# 公式GPGキーのインポート
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
# リポジトリの追加
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy.list
# インインストール
sudo apt update
sudo apt install caddy
設定ファイル /etc/caddy/Caddyfile の記述例(リバースプロキシ):
:443, chobits.dev {
tls asuhara@outlook.jp
reverse_proxy localhost:8080
}
たったこれだけで、HTTPS化されたプロキシサーバーが立ち上がる。この簡潔さこそが、個人の運用において正義である。
5.3 VPN:Tailscale によるセキュアなトンネル
サーバーへの管理アクセスや、特定用途のデータ転送には Tailscale を使用する。 Tailscaleは、最新のVPNプロトコルである WireGuard をベースにしたメッシュVPNサービスである。従来のようなポート開放や、複雑な鍵交換の設定は一切不要である。NAT越え(NAT Traversal)技術により、どんなネットワーク環境下にあっても、魔法のようにP2P接続を確立する 。
インストール手順 :
# GPGキーとリポジトリの追加
curl -fsSL https://pkgs.tailscale.com/stable/debian/bookworm.noarmor.gpg | sudo tee /usr/share/keyrings/tailscale-archive-keyring.gpg >/dev/null
curl -fsSL https://pkgs.tailscale.com/stable/debian/bookworm.tailscale-keyring.list | sudo tee /etc/apt/sources.list.d/tailscale.list
# インストール
sudo apt update
sudo apt install tailscale
# 起動と認証
sudo tailscale up
コマンド実行後に表示されるURLにブラウザでアクセスし、Googleアカウント等で認証するだけで、サーバーがプライベートネットワークに参加する。SSH接続もこのVPN経由で行えば、インターネットにSSHポートを晒すリスクをゼロにできる。
5.4 SSH設定:高位ポートとRootパスワードログイン
最後にSSHサーバー (sshd) の設定を行う。 一般的には「Rootログイン禁止」「パスワード認証禁止(鍵認証のみ)」がセキュリティの定石とされる 。しかし、この構成ではあえて Rootパスワードログインを許可 する運用をとる。
理由は以下の通りである:
- 管理の簡便さ: 鍵ファイルの持ち運びや紛失時のリスクを考慮し、複雑で長いパスワードを記憶(またはマネージャで管理)して運用するスタイルを好む。
- 高位ポートによる隠蔽: デフォルトのポート22は攻撃の標的になりやすいが、例えば
50022などの高位ポートに変更するだけで、Botによるスキャンノイズは劇的に減少する。
/etc/ssh/sshd_config を編集し、以下の設定を適用する。
# ポート番号の変更
Port 50022
# Rootログインの許可(パスワード認証を含む)
PermitRootLogin yes
PasswordAuthentication yes
# その他の堅牢化設定(空パスワード禁止など)
PermitEmptyPasswords no
注意: この設定はセキュリティリスクを伴う。パスワードは十分に長く、複雑なもの(20文字以上のランダム文字列など)を設定することが絶対条件である。また、可能であればTailscaleのIPアドレスからのみ接続を許可するなどの制限を加えることが望ましい。
設定変更後はSSHサービスを再起動する。
sudo systemctl restart ssh
新しいポートでの接続確認が取れるまでは、現在のセッションを切断してはいけない。締め出しを食らう可能性があるからだ。
5.5 痕跡の消去:unset HISTFILE
サーバー管理者としての最後の作法は、ログアウト時の「掃除」である。 操作履歴 (.bash_history) には、誤って入力したパスワードや、構築の手順など、攻撃者にとって有益な情報が含まれている可能性がある。
個人の備忘録サーバーであれば、過去のコマンド履歴に頼る必要はない。全てのセッションで履歴を残さないように設定する。
/root/.bashrc または /root/.profile の末尾に以下を追記する。
unset HISTFILE
環境変数 HISTFILE を削除することで、bashは履歴をファイルに書き込まず、セッション終了とともに記憶を消去する。これにより、サーバー内には操作の痕跡が一切残らない 。
6. 結論
以上の手順により構築されたDebianサーバーは、以下のような特性を持つ。
- 軽量: 不要なデーモンやエージェントが一切存在せず、数百MBのメモリで快適に動作する。
- 高速: BBRによる最適化されたネットワークと、CaddyによるHTTP/3通信。
- 安定: Debian Stableの堅牢なパッケージベース。
- シンプル: Systemdの設定変更と最小限のツールのみで構成され、ブラックボックスがない。
これは、肥大化する現代のLinux環境に対する、一つのアンチテーゼとしての構成である。RHELの重厚さも、Ubuntuの親切さも不要だ。必要なのは、自分の意図通りに動くカーネルと、信頼できる最小限のユーザーランドだけである。