#Apache


Red Hatデベロッパーアカウント作成からApache構築までの手順まとめ

tokeisan4

自宅サーバーでRHEL(Red Hat Enterprise Linux)を使ってWebサイトを公開したい人向けに、Red Hatデベロッパーアカウントの作成から、Apache httpdでのWebサーバー構築までの手順を、実際に使ったコマンドを交えてまとめます。一般的な環境を想定していますので、細部は自分の環境に合わせて読み替えてください。 ■ Red Hatデベロッパーアカウントの作成 まず、以下のサイトにアクセスしてアカウントを作成します。 https://developers.redhat.com/ メールアドレス、氏名などの基本情報を入力し、確認メールのリンクを踏めば登録完了です。法人名の入力欄がありますが、個人利用の場合は「Personal」や自分の名前を入れておけば問題ありません。 このプログラムで利用できるのは、正確には「Red Hat Developer Subscription for Individuals」という個人向けのサブスクリプションです。商用の本番環境での利用は想定されておらず、あくまで開発・学習目的での利用が前提となっている点は理解しておく必要があります。とはいえ、機能制限なくRHELのすべての機能を使えるため、自宅サーバーでの学習・検証用途には十分すぎるほどの内容です。 ■ RHELのインストール Red Hat公式サイトから、RHELのインストールISOイメージをダウンロードします。ダウンロードには、先ほど作成したデベロッパーアカウントでのログインが必要です。 ダウンロードしたISOイメージを、USBメモリに書き込んで起動ディスクを作成するか、仮想マシンで使う場合はそのままISOを読み込ませてインストーラーを起動します。 インストール中の設定でひとつ重要なのが、インストール完了後にシステムをRed Hatのサブスクリプションに登録することです。インストール完了後、以下のコマンドで登録します。 sudo subscription-manager register --username <デベロッパーアカウントのユーザー名> パスワードを求められたら入力してください。登録が成功すると、dnfコマンドでのパッケージインストールが可能になります。 登録状況は、以下のコマンドでいつでも確認できます。 subscription-manager status もし「Overall Status: Current」と表示されていれば、正しく登録が完了しています。逆に「Unknown」や「Invalid」と出る場合は、登録がうまくいっていない可能性があるため、再度登録コマンドを実行してみてください。 ■ システムの基本設定 まず、システム全体を最新の状態に更新します。 sudo dnf update -y タイムゾーンを日本時間に設定します。 sudo timedatectl set-timezone Asia/Tokyo ホスト名を設定しておくと、後々の管理がしやすくなります。 sudo hostnamectl set-hostname myserver 作業用のユーザーアカウントも、rootとは別に作成しておくことを強くおすすめします。日常的な操作をrootで行うのは、操作ミスによる被害範囲が大きくなるため避けるべきです。 sudo useradd myuser sudo passwd myuser sudo usermod -aG wheel myuser wheelグループに所属させることで、そのユーザーがsudoコマンドを使えるようになります。 ■ ファイアウォールの設定 RHELはデフォルトでfirewalldが有効になっています。Webサーバーを公開するには、httpとhttpsのポートを開放する必要があります。 sudo firewall-cmd --permanent --add-service=http sudo firewall-cmd --permanent --add-service=https sudo firewall-cmd --reload 現在開放されているサービスを確認するには、次のコマンドを使います。 sudo firewall-cmd --list-services もし特定のポート番号を直接開放したい場合(Apacheを標準の80番以外のポートで動かす場合など)は、以下のようにします。 sudo firewall-cmd --permanent --add-port=8080/tcp sudo firewall-cmd --reload firewalldはゾーンという概念で通信の許可範囲を管理しています。デフォルトでは「public」ゾーンが使われることが多いですが、現在使われているゾーンを確認したい場合は、次のコマンドで見られます。 sudo firewall-cmd --get-active-zones ■ Apache httpdのインストール いよいよApacheをインストールします。RHELの標準リポジトリからdnfで簡単に導入できます。 sudo dnf install -y httpd インストール後、サービスを起動し、OS起動時に自動起動するよう設定します。 sudo systemctl start httpd sudo systemctl enable httpd 正常に起動しているか確認します。 sudo systemctl status httpd 「active (running)」と表示されていれば成功です。 インストールされたApacheのバージョンを確認したい場合は、以下のコマンドを使います。 httpd -v RHELでは、設定ファイルは主に /etc/httpd/conf/httpd.conf に置かれ、追加の設定は /etc/httpd/conf.d/ 以下に個別のファイルとして置くのが一般的な運用です。設定ファイルを変更したら、必ず文法チェックをしてから再起動する習慣をつけておくと安心です。 sudo apachectl configtest sudo systemctl restart httpd 「Syntax OK」と表示されれば、設定ファイルの文法に問題はありません。 ■ SELinuxとの付き合い方 RHELはデフォルトでSELinuxが有効になっており、Apacheが特定のディレクトリにアクセスする際に制限がかかることがあります。基本的にはSELinuxを無効化せず、正しいコンテキスト(ラベル)を付与して運用するのが望ましい方法です。 例えば、公開したいファイルを標準の場所(/var/www/html)以外に置く場合、以下のようにコンテキストを設定します。 sudo semanage fcontext -a -t httpd_sys_content_t "/data/www(/.*)?" sudo restorecon -Rv /data/www もし semanage コマンドが見つからない場合は、以下のパッケージを追加でインストールしてください。 sudo dnf install -y policycoreutils-python-utils 現在のSELinuxの動作モードは、次のコマンドで確認できます。 getenforce 「Enforcing」であれば、ポリシー違反となる操作は実際にブロックされます。「Permissive」であれば、違反は記録されるだけでブロックはされません。学習段階では、まずログを見ながら少しずつ正しいコンテキストを設定していく方が、後々の運用が楽になります。 もし何らかの操作がSELinuxによってブロックされている疑いがある場合は、以下のコマンドで関連するログを確認できます。 sudo ausearch -m avc -ts recent SELinuxを無効化する選択肢もありますが、本番運用では推奨されません。急場をしのぐ一時的な切り分けの手段として使う程度に留め、原因が分かったら正しいコンテキスト設定に戻すのが望ましい進め方です。 ■ 動作確認用のページを作成 Apacheのドキュメントルート(デフォルトでは /var/www/html)に、簡単なテストページを置いて動作確認します。 echo "<h1>Hello from Apache on RHEL</h1>" | sudo tee /var/www/html/index.html ブラウザで、サーバーのIPアドレスにアクセスして、ページが表示されるか確認します。 http://サーバーのIPアドレス/ もしページが表示されない場合は、ファイアウォールの設定、SELinuxのコンテキスト、Apacheのプロセスが実際に起動しているかを、順番に切り分けて確認していくことになります。特に、公開したいコンテンツを標準以外の場所に置いた場合は、SELinuxのコンテキスト設定を忘れがちなので注意してください。 ■ 独自ドメイン・SSL化への道筋 ここまでで、Apacheが正常に動作する状態が整いました。実際に外部公開する場合は、この先に以下のような作業が必要になります。 ・ドメインの取得とDNS設定 ・Let's EncryptなどによるSSL証明書の取得と設定 ・VirtualHostによる複数サイトの設定 ・アプリケーションサーバー(Django、Node.jsなど)との連携設定 これらは環境や目的によって大きく変わってくるため、また別の機会に詳しく書きたいと思います。 ■ まとめ Red Hatのデベロッパーアカウントを使えば、個人でも本格的なエンタープライズLinuxディストリビューションを無償で使うことができます。firewalldとSELinuxという、Ubuntu系のディストリビューションにはあまり馴染みのない仕組みに最初は戸惑うかもしれませんが、正しく理解して付き合えば、非常に安定した環境を構築できます。 特にSELinuxは、最初のうちは「エラーの原因が分からず、とりあえず無効化してしまう」という誤った対応をしがちですが、コンテキストという考え方さえ理解してしまえば、むしろ心強い防御レイヤーとして機能してくれます。多少遠回りに感じても、正しいコンテキストを都度設定していく習慣を身につけておくと、後々の運用で大きな安心材料になります。 ここまでの手順で、外部からアクセスできる基本的なWebサーバーの土台は整いました。実際にサービスとして公開していくには、この記事で紹介した基本設定の上に、ドメインの取得、SSL証明書の設定、アプリケーションサーバーとの連携など、さらにいくつかのステップが必要になります。それらについては、また機会を改めて書いていきたいと思います。

Apache設定まるわかり!よく使うディレクティブ解説

tokeisan4

このサイトを自宅サーバー(RHEL + Apache httpd)で運用する中で、実際に使ってきたApacheの設定項目(ディレクティブ)を、体系立ててまとめてみます。公式ドキュメントは網羅的すぎて最初はとっつきにくいので、「実際に何のために使うのか」という視点で整理していきます。 ■ そもそもディレクティブとは Apacheの設定ファイル(httpd.confや、conf.d以下の個別ファイル)に書く、1行1行の設定項目のことをディレクティブと呼びます。「このURLパスにはこの権限が必要」「このドメインが来たらこのアプリを表示する」といった、Apacheの振る舞いを決める命令文だと考えると分かりやすいです。 ■ VirtualHost:1台のサーバーで複数サイトを扱う 同じサーバー上で、異なるドメインや異なるポートごとに別々のサイトを配信するための仕組みです。 <VirtualHost *:443> ServerName example.com ServerAlias www.example.com SSLEngine on SSLCertificateFile /etc/httpd/ssl/server.crt SSLCertificateKeyFile /etc/httpd/ssl/server.key </VirtualHost> ServerNameで、このVirtualHostがどのドメインへのリクエストに反応するかを指定します。ServerAliasは、追加で反応させたい別名(wwwありなし等)を指定する際に使います。 ■ WSGIDaemonProcess・WSGIScriptAlias:Pythonアプリとの連携 DjangoのようなPython製Webアプリケーションを動かすには、mod_wsgiというモジュールを使います。 WSGIDaemonProcess myapp python-home=/path/to/venv python-path=/path/to/project WSGIProcessGroup myapp WSGIScriptAlias / /path/to/project/project/wsgi.py WSGIDaemonProcessは、Apacheの本体プロセスとは別に、Pythonアプリ専用の子プロセスを立ち上げる設定です。python-homeには仮想環境(venv)のパス、python-pathにはDjangoプロジェクトのパスを指定します。WSGIScriptAliasは、どのURLパスにアクセスされたら、どのwsgi.pyファイルを呼び出すかを紐付けます。 なお、WSGIApplicationGroup %{GLOBAL} という設定を追加しないと、「populate() isn't reentrant」というエラーが出ることがあります。これは、複数のPythonアプリケーションが同じインタプリタ内で衝突しないようにする設定で、Django単体で運用する場合は基本的に付けておくとトラブルを避けられます。 ■ Alias:静的ファイルの配信場所を指定する 画像やCSSなど、Pythonを介さずそのまま配信したいファイル群のために使います。 Alias /static/ /data/static/ <Directory /data/static/> Require all granted </Directory> Aliasで「このURLパスへのアクセスは、実際にはこのディレクトリの中身を見せる」という対応関係を作ります。続くDirectiveブロックで、そのディレクトリへのアクセス許可を明示的に与える必要があります。 ■ Require:アクセス制御 誰がそのURLパス・ディレクトリにアクセスできるかを制御します。 <Location /admin/> Require ip 192.168.11.0/24 </Location> この例では、管理画面へのアクセスを、自宅LAN内のIPアドレス帯だけに制限しています。全世界に公開したくない管理系のパスには、このような制限をかけておくと安心です。全員に許可したい場合はRequire all grantedを使います。 ■ SSLEngine・SSLCertificateFile:HTTPS化 <VirtualHost *:443> SSLEngine on SSLCertificateFile /etc/httpd/ssl/server.crt SSLCertificateKeyFile /etc/httpd/ssl/server.key </VirtualHost> SSLEngine onで、そのVirtualHostにSSL/TLSによる暗号化通信を有効にします。証明書ファイルと秘密鍵ファイルのパスを、それぞれ指定します。自己署名証明書を使う場合、ブラウザに警告が出ますが、リバースプロキシ(Cloudflareなど)を前段に置いている場合は、オリジンサーバー同士の通信としては許容されることもあります。 ■ RewriteEngine・RewriteRule:URLの書き換え RewriteEngine On RewriteCond %{HTTPS} off RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L] httpでのアクセスを、httpsへ自動的にリダイレクトする、よくあるパターンです。RewriteCondで条件(この場合「HTTPSが使われていない場合」)を指定し、RewriteRuleで実際の書き換えルールを定義します。ただし、特定のパス(Zabbixの管理画面など)だけリダイレクトの対象から除外したい場合は、RewriteCondに除外条件を追加する必要があります。 ■ ModSecurity関連ディレクティブ:WAF(Webアプリケーションファイアウォール) SecRuleEngine On SecAuditLog /data/log/httpd/modsec_audit.log SecDebugLog /data/log/httpd/modsec_debug.log SecRuleEngineは、ModSecurityの動作モードを指定します。Onにすると実際に攻撃をブロックし、DetectionOnlyにすると検知だけ行いブロックはしません。運用開始直後は、誤検知が多くないか確認するためDetectionOnlyで様子を見て、問題なければOnに切り替えるという段階的な進め方がおすすめです。個別のルールを除外したい場合は、以下のように書きます。 SecRuleRemoveById 931120 SecRuleRemoveById 942360 長文投稿など、特定の入力パターンで実行時エラー(PCRE limits exceeded)が起きるルールがある場合、こうしてIDを指定して個別に無効化できます。 ■ ログ関連ディレクティブ ErrorLog /data/log/httpd/error_log CustomLog /data/log/httpd/access_log combined ErrorLogはApache自体のエラーや、アプリケーション側の例外(Djangoのトレースバックなど)が記録される場所です。CustomLogは、誰がいつどのURLにアクセスしたかというアクセスログを記録します。combinedというのは、記録するログの書式(フォーマット)の名前です。 ■ MPM(Multi-Processing Module)関連ディレクティブ <IfModule mpm_event_module> StartServers 3 MinSpareThreads 75 MaxSpareThreads 250 ThreadsPerChild 25 MaxRequestWorkers 400 MaxConnectionsPerChild 0 </IfModule> Apacheが同時にどれだけのリクエストをさばけるかを制御する設定です。StartServersは起動時に立ち上げる子プロセスの数、ThreadsPerChildは1つの子プロセスが持つスレッド数、MaxRequestWorkersは全体で同時に処理できる最大リクエスト数です。サーバーのメモリ・CPUに余裕がある場合は、これらの数値を大きめに設定することで、アクセス集中時の余裕を持たせられます。逆に、小規模なサーバーで数値を大きくしすぎると、メモリ不足でサーバー全体が不安定になることもあるため、搭載メモリとの兼ね合いで調整する必要があります。 ■ セキュリティ関連ヘッダーのディレクティブ(Django側での設定が主だが参考として) Apache単体でも、以下のようなヘッダー付与用ディレクティブがあります。 Header always set X-Frame-Options "DENY" Header always set X-Content-Type-Options "nosniff" X-Frame-Optionsは、自分のサイトが他サイトの中にiframeとして埋め込まれることを防ぐ、クリックジャッキング対策の定番設定です。今回はアプリケーション側(Django)で同等の設定をしていますが、Apache側でも二重に設定しておくと、より確実な防御になります。 ■ まとめ Apacheの設定は、最初は項目数の多さに圧倒されますが、「誰に」「何を」「どう見せるか」という3つの軸で整理すると理解しやすくなります。VirtualHostとServerNameで「誰宛のリクエストか」を決め、AliasやWSGIScriptAliasで「何を見せるか」を決め、RequireやModSecurityで「どう制御するか」を決める、という構造を意識すると、設定ファイル全体の見通しが良くなるはずです。 今回紹介したディレクティブは、実際にこのサイトの運用の中で使ってきたものばかりです。設定ファイルをいじる際は、必ずapachectl configtestで文法チェックをしてから再起動する習慣をつけておくと、設定ミスによるサービス停止を防げます。