AlmaLinux 10.1 セットアップメモ
Section 6.1 Webサーバー(nginx)構築編 nginx
About
Webアプリケーションを作るために……という事でWebサーバー構築を行っていきます。 ここでは、nginx(https://nginx.org/)を用いたWebサーバーになっています。
環境は、Section 1.1~Section 1.3で作成したvirtualboxの環境で、Section 2.1 の PostgreSQL をインストールした環境で進めていきます。 そのため、SELinuxは有効な状態で作業を進めています。
起動後、rootアカウントになって作業を進めます。
パッケージの確認
リポジトリに登録されているものからパッケージ名とバージョンを指定してインストールすることになります。 まずは、提供されているかどうかを調べます。
[root@localhost ~]# dnf search nginx
================================================================================= Name Exactly Matched: nginx ==================================================================================
nginx.x86_64 : A high performance web server and reverse proxy server
(略)
[root@localhost ~]# dnf repoquery nginx
nginx-2:1.26.3-1.el10.x86_64
[root@localhost ~]#
特に変わったものは登録されていないようなので、インストールを進めます。
インストール
[root@localhost ~]# dnf -y install nginx
Dependencies resolved.
========================================================================================================================
Package Architecture Version Repository Size
========================================================================================================================
Installing:
nginx x86_64 2:1.26.3-1.el10 appstream 36 k
Installing dependencies:
almalinux-logos-httpd noarch 100.3-3.el10_0 appstream 18 k
nginx-core x86_64 2:1.26.3-1.el10 appstream 659 k
nginx-filesystem noarch 2:1.26.3-1.el10 appstream 11 k
Transaction Summary
========================================================================================================================
Install 4 Packages
(中略)
Complete!
[root@localhost ~]#
まずはインストールまで。
サービスの登録 と firewall 設定
まずは、サービスを有効化して起動します。
[root@localhost ~]# systemctl enable nginx
Created symlink /etc/systemd/system/multi-user.target.wants/nginx.service → /usr/lib/syst//system/nginx.service.
[root@localhost ~]# systemctl start nginx
このままでは、firewallによってアクセスできないようにされているので、そちらも開放します。
[root@localhost ~]# firewall-cmd --zone=public --add-service=http --permanent
success
[root@localhost ~]# firewall-cmd --zone=public --add-service=https --permanent
success
[root@localhost ~]# systemctl reload firewalld
[root@localhost ~]# firewall-cmd --list-all
public (default, active)
target: default
ingress-priority: 0
egress-priority: 0
icmp-block-inversion: no
interfaces: enp0s3
sources:
services: cockpit dhcpv6-client http https ssh
ports:
protocols:
forward: yes
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
[root@localhost ~]#
OSのFirewallはポートを開けましたが、仮想マシン側は閉じたままです。
ホストマシンのブラウザからアクセスするためには、Vagrantfile の forwarded port の設定を変える必要があります。
1024より小さいポートにマッピングすると Vagrant up 中に警告が出ますが、複数起動したり、ホストマシンでWebサーバーを起動しなければ問題はないでしょう。
config.vm.network "forwarded_port", guest: 80, host: 80
config.vm.network "forwarded_port", guest: 443, host: 443
設定を修正後に、仮想マシンを再起動すれば、ネットワーク的に問題が無ければブラウザでアクセスできると思います。
document root を変更する
document root は /usr/share/nginx/html になっていますが、FHSを知っていたりすると、いろいろ思うところがあるので、apache を使う場合と同様に /var/www/html にファイルを置くように変更します。
FHS (Filesystem Hierarchy Standar) とは
Filesystem Hierarchy Standar(FHS)は、Linuxを含むUnix系OSでの主なディレクトリとその内容を定めたものです。
Filesystem Hierarchy Standard - Wikipedia
RHEL(Redhat Enterprise Linux)も、おおむねそれに準拠しているのでそれに沿ってファイルを配置したほうが良いということになります。 FHS的には /usr 下はあまり変わらないもの。内容がちょいちょい変わるようなら /var 下という感じになっています。Webページが固定されることはないということを考えれば、/var 下だろうということで、そうしたいということになります。
まずは、nginx.conf をsedで編集します。
[root@localhost ~]# cp --preserve=context /etc/nginx/nginx.conf /etc/nginx/nginx.conf.org
[root@localhost ~]# cat /etc/nginx/nginx.conf.org \
| sed -E "s/(^[ ]+root[ ]+)\/usr.*$/\1\/var\/www\/html;/" \
> /etc/nginx/nginx.conf
[root@localhost ~]#
rootの変更とerror_pageの設定をコメントアウトしたので、diff で確認します。
[root@localhost ~]# diff -cT /etc/nginx/nginx.conf.org /etc/nginx/nginx.conf
*** /etc/nginx/nginx.conf.org YYYY-mm-dd hh:ii:ss.000000000 +0900
--- /etc/nginx/nginx.conf YYYY-mm-dd hh:ii:ss.000000000 +0900
***************
*** 38,44 ****
listen 80;
listen [::]:80;
server_name _;
! root /usr/share/nginx/html;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
--- 38,44 ----
listen 80;
listen [::]:80;
server_name _;
! root /var/www/html;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
フォルダの作成
フォルダが存在していないと思うので作成して、権限を変更します。
[root@localhost ~]# mkdir -p /var/www/html
[root@localhost ~]# chown nginx:nginx /var/www/html
このままだと、SELinuxコンテキストが異なり、パーミッションエラーになってしまうので、それも変更します。
コピーやディレクトリ作成しただけだと、var_t になってしまいます。これを Webサービスから変えようと思うと、httpd_sys_content_t にする必要があります。変更はいろいろな手段がありますが、もともとOS設定で /var/www のコンテキストは登録済みなので、restorecon を使用して復元するという方法で変更します。ついでに、他とユーザー部分が異なるのも気持ちが悪いので合わせます。
[root@localhost ~]# ls -laZ /var/www/
total 4
drwxr-xr-x. 3 root root unconfined_u:object_r:var_t:s0 18 MMM dd hh:mm .
drwxr-xr-x. 20 root root system_u:object_r:var_t:s0 4096 MMM dd hh:mm ..
drwxr-xr-x. 2 nginx nginx unconfined_u:object_r:var_t:s0 6 MMM dd hh:mm html
[root@localhost ~]# restorecon -v -r /var/www
Relabeled /var/www from unconfined_u:object_r:var_t:s0 to unconfined_u:object_r:httpd_sys_content_t:s0
Relabeled /var/www/html from unconfined_u:object_r:var_t:s0 to unconfined_u:object_r:httpd_sys_content_t:s0
[root@localhost ~]# chcon -R -v -u system_u /var/www
changing security context of '/var/www/html'
changing security context of '/var/www'
[root@localhost ~]# ls -laZ /var/www
total 4
drwxr-xr-x. 3 root root system_u:object_r:httpd_sys_content_t:s0 18 MMM dd hh:mm .
drwxr-xr-x. 20 root root system_u:object_r:var_t:s0 4096 MMM dd hh:mm ..
drwxr-xr-x. 2 nginx nginx system_u:object_r:httpd_sys_content_t:s0 6 MMM dd hh:mm html
[root@localhost ~]#
まずはフォルダ移動までで確認していきましょう。
サービス再起動
サービスを再起動してブラウザで確認します。
[root@localhost ~]# systemctl stop nginx
[root@localhost ~]# systemctl start nginx
/var/www/html の中身が空っぽなので、よく見るかもしれない「403 Forbidden」が表示されるだけだと思います。 もし表示されない場合はブラウザのキャッシュが残ってるかもしれないので、Ctrl+F5などでリロードしてみてください。
コンテンツ配置とSELinux
よくハマる事例を少し試してみましょう。
まずは、 /home/root に適当なファイルを二つ作成します。
[root@localhost ~]# echo 'COPY' > ~/copy_file.html
[root@localhost ~]# echo 'MOVE' > ~/move_file.html
次にファイル名通り、それぞれのファイルを copy と mv で /var/www/html に持っていきます。
[root@localhost ~]# cp ~/copy_file.html /var/www/html/
[root@localhost ~]# mv ~/move_file.html /var/www/html/
どうなっているか確認してみましょう。
[root@localhost ~]# ls -lZ /var/www/html/
total 8
-rw-r--r--. 1 root root unconfined_u:object_r:httpd_sys_content_t:s0 5 MMM dd hh:mm copy_file.html
-rw-r--r--. 1 root root unconfined_u:object_r:admin_home_t:s0 5 MMM dd hh:mm move_file.html
[root@localhost ~]#
SELinuxコンテキストのタイプがそれぞれ異なっていることが分かると思います。それぞれのファイルに対してブラウザなどからアクセスしてみましょう。
おそらく、move_file.html のほうは、403 Forbidden になってしまうと思います。この辺りがSELinuxのパーミッション問題です。コピーならディレクトリに設定されているコンテキストが引き継がれますが、移動になると元のものが使われてしまうという問題がでます。
こうなってしまった場合は、restorecon を使用してコンテキストをOS標準の状態に復元するという方法で変更するのが簡単な方法で正しいやり方となります。
[root@localhost ~]# restorecon -v -r /var/www/html
Relabeled /var/www/html/move_file.html from unconfined_u:object_r:admin_home_t:s0 to unconfined_u:object_r:httpd_sys_content_t:s0
[root@localhost ~]#
tar等で圧縮したファイル群を、適当な src あたりで展開して、それを移動させる……という運用があると思いますが、こういう罠が待っています。 基本的には移動は、コピーして元のファイルを削除するという運用に切り替えると何かと幸せです。
なお、FTP/SFTPでアップロードする場合はコピーと同じ効果を発揮するので、気にしなくて済みます。