30歳からのプログラミング

30歳無職から独学でプログラミングを開始した人間の記録。

ウェブエンジニアがサーバーを管理していくための初歩

インフラについて調べていたので、その備忘録。
調べていく上で重視したのは、概念や概要を知ること。細かい知識はあとでいくらでも調べることが出来るが、土台となるものがなければ調べることすら出来ない。
「公式ガイドやハウツー記事に従って設定したけど、俺は今、一体何をしているんだ?」という状態から抜け出したかった。
具体的なコマンドよりも、そもそも何をしているのか、そしてそれは何のために行っているのかを、把握できるようになりたかった。

そもそもサーバーってなんだ

一口にサーバーといっても、多義的。
まずこれを区別していないのが、混乱の元だった。
初学者は「サーバー」と言っている時に具体的に何を指しているのか、意識したほうがいい。

まず最初に存在するのが、ハードウェアとしてのサーバー。
これはただのコンピュータであり、中身が入っていなければただの箱である。
VPSクラウドなどで、本当に物理的にコンピュータが存在するのかなどは、取り敢えず措いておく。
VPSクラウドでも、サーバーというコンピュータ(に相当するもの)が存在するのは同じだから。

我々が使っているコンピュータと一緒で、サーバー(コンピュータ)にもOSが必要である。
サーバーでは、WindowsMacではなく、Linuxが使われていることが多い。
LinuxにはCentOSなど様々な種類がある。
この記事では、サーバーのOSはCentOS7である前提で進めていくが、基本的な考え方は、他のOSでもほとんど変わらないと思う。

OS以外にサーバー(コンピュータ)に必要なものとして、IPアドレスがある。これは、ネットワーク上でこのコンピュータを識別するための仕組み。

VPSサービスなどを契約すると、IPアドレスは最初から割り当てられており、あなたが契約しているサーバー(コンピュータ)のIPアドレスはこれですよとメールなどで送られてくる。
また、OSを簡単にインストールするための仕組みも、VPSサービスなどには用意されていると思う。

しかし、コンピュータを動かすためのOSをインストールし、ネットワーク上で識別するためのIPアドレスを用意しても、それだけでは自分のような初心者ウェブエンジニアが思い浮かべる「サーバー」の動きにはならない。

OSだけでは不十分で、様々なアプリケーションを起動させたり、管理したりする必要がある。
自分が普段使っているパソコンと一緒で、用途に応じてインストールやら設定やらが必要になる。

手元のパソコンでインターネットを利用するためには、ウェブクライアントとしてブラウザを用意しなければならない。
そうすることで、このパソコンはウェブクライアントとして機能するようになる。

そして、ウェブクライアントとHTTP通信を行い、リクエストに応じてレスポンスを返すコンピュータをウェブサーバーと呼ぶ。
手元のパソコンにブラウザを用意するように、サーバー(コンピュータ)にはウェブサーバーソフトウェア(後述)を用意して、そのサーバー(コンピュータ)をウェブサーバーとして利用できるようにする必要があるのだ。
ウェブプログラミングの文脈で単に「サーバー」というときは、「ウェブサーバー」を指していることが多いと思う。

つまり、サーバー(コンピュータ)をウェブサーバーとして利用、運用していくために、サーバー(コンピュータ)の適切な管理が必要になる。
そしてコンピュータを操作するために使うのが、SSHyumである。

参考資料

デーモン

SSHyumの前に、デーモンについて説明しておく。

デーモンとは、UNIX系のOSにおいて、常駐しているソフトウェアのこと。
これが起動しているから常に、必要に応じて処理を行うことが出来る。

ウェブサーバーとHTTP通信できるのも、そのためのデーモンがサーバー(コンピュータ)上で動いているから。
だから、24時間いつでも、HTTPでリクエストを送ればちゃんとレスポンスが返ってくる。

参考資料

SSH

一般的に、サーバー(コンピュータ)として使っているコンピュータは手元にはないことが多いはず。
そのため、離れた場所にあるコンピュータにアクセスする必要がある。
そのための方法が、SSHである。

SSHとは、HTTPと同じ、アプリケーション層のプロトコル
そして、これもHTTPと同じだが、SSH通信を行うためにはそのためのソフトが必要になる。

まず手元のパソコンに、SSHクライアントソフトウェアが入っている必要がある。
Macの場合は最初から入っているため、ターミナルでsshというコマンドを使うことでSSH通信ができる。

そしてサーバー(コンピュータ)にSSHサーバーソフトウェアを入れ、それを起動させれば、そのサーバー(コンピュータ)をSSHサーバーとして使えるようになる。
そうすると、SSHクライアントからのアクセスを受け取ってそれを処理できるようになる。
この状態は、SSHのデーモン(sshd)が動いているとも表現できる。

具体的なソフトウェアとしては、OpenSSHというものを使うことが多い。
クライアントとしてもサーバー(SSHサーバー)としても使うことができ、最初からMacに入っているのもこれ。

Macのターミナルで以下のコマンドを打つと、SSH通信を行える。

$ ssh ユーザー名(後述)@サーバー(コンピュータ)のIP

SSHでログインすれば、サーバー(コンピュータ)にログインした状態になるので、様々な操作を行うことが出来る。

前述のようにサーバー(コンピュータ)のOSはLinuxを使うことが多いが、MacUnix系のOSなので、多くのコマンドは共通している。
そのため、普段ターミナルで使っているlscdなどはそのまま使うことが出来る。

例えば、以下のコマンドで/etc/ssh/sshd_configというファイルを編集できる。

# cd /etc/ssh
# vim sshd_config

このファイルは、sshdの設定ファイル。セキュリティ対策などでSSHの設定を変える際は、このファイルを編集することになる。
ちなみに、編集した設定を有効にするには# systemctl restart sshd.serviceというコマンドでsshdの再起動させる必要がある。

SSH通信を終えるには、exitコマンドでサーバー(コンピュータ)からログアウトする。

参考資料

yum

SSHによってサーバー(コンピュータ)を操作できるようになった。

そこでよく行うものの一つが、yumである。
これは、パッケージ管理システム。
フロントエンドのnpmMacbrewが、役割として近いと思う。

yumを使ってソフトウェア(パッケージ)をインストールしたり、アップデートしたり出来る。

# yum list installedで、既にインストールされているパッケージを確認できる。
# yum install パッケージ名で、パッケージをインストール。
# yum search パッケージ名で、パッケージを検索。

ところで、インストールや検索と言うが、一体どこからインストールしているのだろうか。
どこを対象にして検索をかけているのだろうか。
それは、「リポジトリ」からである。

リポジトリという、パッケージの配布元がある。
そして、リポジトリというのは一つではなく、世の中にたくさん存在するのだが、yumを実行したときに対象となるのは、そのサーバー(コンピュータ)に登録済みかつ有効になっているリポジトリのみである。

登録してあるリポジトリは、# yum repolist allで確認できるし、有効かどうかもこれで確認できる。
ここに登録されており、かつ有効なリポジトリから、インストールしたり、アップデートしたり、検索したりする。

/etc/yum.repos.d/以下にファイルを作ることで、任意のリポジトリを追加することも出来る。
詳しくはこちらの記事を参照。
yum|yum リポジトリの設定と追加

ユーザーとパーミッション

SSH通信によってサーバー(コンピュータ)にアクセスし、yumなどの操作を行っていくわけだが、それは必ず何らかの「ユーザー」によって行われる。 最初にSSHでログインするときは恐らく、rootというユーザーだと思う。

だがroot以外にもユーザーは存在し、# cat /etc/passwdでユーザー一覧を見ることが出来る。

また、自分でユーザーを追加することも出来る。

# adduser ユーザー名 // ユーザーの追加
# passwd ユーザー名 // ユーザーのパスワードを設定

ユーザーが複数存在することは分かったが、では、ユーザーによって何が違うのかというと、そのコンピュータ内で何が出来るのかという権限が異なる。

例えば、ファイルを読み書きするのには、そのファイルに対して権限を持っている必要がある。 # ls -lというコマンドで、そのディレクトリ内のファイルやディレクトリの権限などの情報を見ることが出来る。

これらを変更するには、chmodchownといったコマンドを使う。

参考資料

ファイアウォールとポート

ここからようやく、具体的な設定や操作の話になる。
まずはファイアウォールから。

サーバー(コンピュータ)はネットワークにつながっているため、どうしても外部からの攻撃の危険に晒されることになる。

ファイアウォールは外部からの攻撃を防ぐための仕組みであり、そのための代表的な機能が、パケットフィルタリングである。

サーバー(コンピュータ)とクライアントがデータをやり取りする際、データをパケットという単位に分割して送受信する。
そしてパケットには様々な情報が含まれており、ファイアウォールはこの情報を見て、許可されている通信かどうかを判断し、そうでない通信は拒絶するようにする。
これがパケットフィルタリングである。

よく使われるのが、特定のポートでの通信だけを許可する、という設定である。

ポートとは通信の出入り口のことで、パケットは必ずこのポートを通って、やり取りされる。
ポートは複数存在し、それぞれを識別するために番号が振られている。
これがポート番号。
通信に使うプロトコルにはTCPUDPの2種類があるが、それぞれにポート番号が存在する。

そして、これが重要なのだが、各サービス毎に、使用するポートは決っている。
例えばSSH通信の場合は、デフォルトではTCPの22というポートで通信が行われる。HTTP通信はTCPの80である。

ウェブサーバーとして利用する場合、そのサーバー(コンピュータ)が使用するポートは、かなり限られている。
ファイアウォールのパケットフィルタリングの機能を使い、使用していないポートでの通信は許可しないようにするのが、セキュリティの基本である。
そうすることで、必要な通信以外は発生させないようにして、攻撃に晒されるリスクを減らすことが出来るからだ。

CentOS7でのファイアウォールの設定は、firewalldというツールを使って行う。

参考資料

systemctl

firewalldの操作に先立って、CentOS7の基本的な操作を確認しておく。

ソフトウェアの起動や停止などは、systemctlというコマンドで行う。

上から順に、起動、停止、再起動。

# systemctl start ソフトウェア名
# systemctl stop ソフトウェア名
# systemctl restart ソフトウェア名

ファイアウォールSSHサーバーソフトウェア、ウェブサーバーソフトウェアを停止することはあまりないと思うが、設定を変更した際にそれを反映させるために再起動を行うことは多い。

また、これらのソフトウェアは、自動起動を有効にしておくのが基本。
これを有効にしておくことで、OSが起動した際にそのソフトウェアも自動的に起動してくれる。
この設定を有効にしておかないと、何らかの理由でサーバー(コンピュータ)が再起動した際に、ファイアウォールなどの個別のソフトウェアも手動で起動させないといけなくなってしまう。

自動起動が有効になっているかは、# systemctl list-unit-files -t serviceで確認し、対象のソフトウェアがenabledとなっていれば有効になっている。
だがこれだと大量のソフトウェアが出てきて見づらいので、grepを合わせて使うとよい。

# systemctl list-unit-files -t service | grep firewalld
firewalld.service                             enabled 

無効(disable)になっていた場合、# systemctl enable ソフトウェア名で有効にできる。

firewalld

firewalldを使っていくには、ゾーンという概念とサービスという概念を理解する必要がある。

ゾーンとは、各種設定をひとまとめにした設定集のようなもの。
デフォルトで9つのゾーンが用意されているが、この中から一つを選んで、適用することになる。
そうするとそのゾーンで行っている設定が有効になる。

以下のコマンドで、現在適用されているゾーンを確認できる。

# firewall-cmd --get-active-zones
public
  interfaces: eth0

上記の場合、publicというゾーンが使われていることを意味している。
デフォルトではこの設定になっているはずで、他のゾーンに変更したり、自分でゾーンを作成したりすることも出来るのだが、最初のうちは不要だと思う。
publicをそのまま使いながら、必要に応じてpublicの設定を変えていけばよい。

もう一つ重要なのが、サービスという概念。
サービスを、ゾーンに追加したり削除したりすることで、そのサービスが使っているポートを開けたり閉じたりできる。

例えば、HTTP通信を許可したい場合は、現在有効になっているゾーン、つまりpublicに、httpを追加すればよい。

以下が、そのための具体的な方法。

先程既に出てきたが、firewalldを操作するためのコマンドはfirewall-cmdなので、それを使う。

まず、現在使われているサービスは何なのかを把握する必要がある。

# firewall-cmd --list-all --zone=ゾーン名

いくつか項目が出てくるが、servicesの欄を見て、そこに書かれているものが、そのゾーンで有効になっているサービスである。

services: dhcpv6-client ssh

これを見るとhttpがないので、追加する。

追加のコマンドは# firewall-cmd --zone=ゾーン名 --add-service=サービス名
今回はpublichttpを追加するので# firewall-cmd --zone=public --add-service=httpになる。

削除する場合は--add-serviceではなく--remove-serviceを使う。

# firewall-cmd --list-all --zone=ゾーン名でもう一度確認すると、追加されていることが分かる。

services: dhcpv6-client ssh http

だがこの方法で行った設定は一時的なもので、firewalldが再起動されると元に戻ってしまう。

一時的ではなく恒久的な設定にしたい場合は、--permanentオプションをつける。

# firewall-cmd --zone=ゾーン名 --add-service=サービス名 --permanent

だがこの変更は即座には反映されず# firewall-cmd --reloadを実行しないと反映されない。

こうするとこの設定は恒久的なものになり、再起動しても元に戻ることはない。

恒久的な設定について確認する場合も、--permanentオプションをつければよい。

# firewall-cmd --list-all --zone=ゾーン名 --permanent

設定できるサービスはhttp以外にも存在し、# firewall-cmd --get-servicesで一覧を見ることが出来る。
各サービスの情報を得るのは# firewall-cmd --info-service=サービス名

各サービスの設定ファイルは/usr/lib/firewalld/services/に入っている。
例えば以下は、httpの設定ファイル。使っているポートの情報などが書かれていることが分かる。

# cat /usr/lib/firewalld/services/http.xml
<?xml version="1.0" encoding="utf-8"?>
<service>
  <short>WWW (HTTP)</short>
  <description>HTTP is the protocol used to serve Web pages. If you plan to make your Web server publicly available, enable this option. This option is not required for viewing pages locally or developing Web pages.</description>
  <port protocol="tcp" port="80"/>
</service>

これを編集して# firewall-cmd --reloadを実行すれば、そのサービスに対応するポート番号などを変更できる。
注意点は、これはあくまでもファイアウォールの設定の話であり、それとは別に各ソフトウェア(OpenSSHやnginxなど)側でポート番号の変更を行う必要がある。

参考資料

ウェブサーバーソフトウェア

ファイアウォールの設定も終わったので、次はいよいよ、ウェブサーバーソフトウェア。
これをインストールして起動することで、サーバ(コンピュータ)がウェブサーバーとして機能するようになり、HTTP通信が可能になる。
この場合、サーバ(コンピュータ)は、ウェブサーバーであり、かつSSHサーバーでもある、という状態になる。

ウェブサーバーソフトウェアを起動することでそれがHTTP通信を処理するデーモンとなり、HTTPリクエストを24時間受け付けることが可能になる。
ウェブサーバーとして動作しているデーモンをhttpdと表現することがある。
ただCentOSにおいては、httpdとは、デフォルトのウェブサーバーソフトウェアであるApacheのことを指す。
そのため、単にhttpdといってしまうと、Apacheという具体的なソフトウェアを指しているのか、それともウェブサーバーソフトウェアという総称のことを意味しているのか、分かりにくい。
だから基本的にはhttpdという表現は避けたほうがいいのかもしれない。

Apacheの他に、nginxというウェブサーバーソフトウェアもある。

ここではnginxを使う。バージョンは1.12.2

まずはここまでに書いた内容を使って、yumでnginxをインストールし、起動、そして自動起動を有効にする。
そうすると、HTTP通信が可能になる。
試しにhttp://IPアドレスにアクセスすると、nginxが用意しているデフォルトのコンテンツが表示される。

このコンテンツは、サーバー(コンピュータ)の/usr/share/nginx/htmlに入っている。
つまり、ここのディレクトリの内容が、HTTP通信でルートURLにアクセスしたときに返されている。
このディレクトリを、ドキュメントルートと呼ぶ。

そのためドキュメントルートの内容を差し替えることで、表示されるコンテンツが変えることが出来る。

nginxの設定ファイルは/etc/nginx/nginx.confで、ドキュメントルートもここに書かれている。

また、HTTPリクエストを受け取る度に、そのログが自動的に記録されていく。
ログファイルは/var/log/nginxに入っている。

参考資料

まとめ

DNSの設定など、ここでやってないことも多いが、取り敢えずこれで、スタティックなページをウェブ上に公開することは出来るようになった。

ものすごく大雑把にまとめてしまうと、SSHでサーバー(コンピュータ)にログインし、yumで必要なパッケージ(ソフトウェア)を用意し、ファイアウォールでTCP80のポートを開け、ウェブサーバーソフトウェアを起動してドキュメントルートにコンテンツを置けば、そのコンテンツをウェブで公開することが出来る。