Linuxの基礎 7日目

# 7日目

## 1 プロセスとジョブ

### 1-1 プロセスの管理
- 実行中のプログラムを**プロセス**という
  - **プロセス**
    - プログラムは通常、ファイルの形でハードディスクをはじめとするストレージに保存される
    - プログラムを実行すると、そのプログラムコードがコンピュータのメモリ上に読み込まれ、CPUによって実行される
    - このメモリ上で実行中のプログラムのことを**プロセス**という
- プロセスには固有のプロセスIDが付与される
  - **プロセスID**
    - プロセスを起動すると、プロセスごとに固有のID番号が割り当てられる
    - これを**プロセスID(PID)**という
    - プロセスIDはプロセスを特定するために利用できる
    - 同じ名前のプログラムが複数実行されていても、それらを識別できるわけである
- **ps**コマンドでプロセス情報を表示できる
  ```
  # プロセス情報を表示する際の書式コマンド
  $ ps [オプション]

  # プロセス情報を表示
  # オプションなしでpsコマンドを実行すると、psコマンドを実行したユーザーがその端末上で起動したプロセスの一覧が表示される
  $ ps
    PID TTY          TIME CMD
    9 pts/0    00:00:00 bash
   32 pts/0    00:00:00 ps

  # 全てのプロセスを表示
  $ ps aux
  USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
  root         1  0.0  0.0   2324  1508 ?        Sl   05:07   0:00 /init
  root         4  0.0  0.0   2324     4 ?        Sl   05:07   0:00 plan9 --control-socket 5 --log-level 4 --server-fd 6 --root         7  0.0  0.0   2332   112 ?        Ss   05:07   0:00 /init
  root         8  0.0  0.0   2348   120 ?        S    05:07   0:00 /init
  general+     9  0.0  0.0   8272  5120 pts/0    Ss   05:07   0:00 -bash
  general+    33  0.0  0.0  10084  3368 pts/0    R+   05:22   0:00 ps aux
  ```
  - psコマンドの主な表示項目
    | 項目 | 説明 |
    | ---- | ---- |
    | PID | プロセスID |
    | TTY | プロセスを実行した端末名 |
    | TIME | プロセス実行時間 |
    | CMD | 実行コマンド |

  - psコマンドの主なオプション
    | オプション | 説明 |
    | ---- | ---- |
    | a | 他のユーザーのプロセスも表示する |
    | u | ユーザー名を表示する |
    | x | 端末から実行されたものではないプロセス(サーバプロセスなど)も表示する |
- **pstree**コマンドでプロセスの親子関係を表示することができる
  - プロセスは、実行中のほかのプロセスから起動される
  - これを**フォーク**といい、起動元のプロセスを**親プロセス**、親プロセスから起動したプロセスを**子プロセス**という
  - プロセスの親子関係は、**pstree**コマンドを使うとよくわかる
    ```
    # プロセスの親子関係を表示するコマンド書式
    pstree [オプション]

    $ pstree
    init(CentOSStre─┬─SessionLeader───Relay(9)───bash───pstree
                ├─SessionLeader───Relay(36)───bash
                ├─init───{init}
                └─{init(CentOSStre}
    ```
  - 主なオプション
    | オプション | 説明 |
    | ---- | ---- |
    | -a | コマンドラインの引数を表示する |
    | -c | 同じ内容のサブツリーをまとめず表示する |
    | -h | カレントプロセスとその先祖のプロセスを強調表示する |
    | -l | 長い行を表示する。デフォルトでは、長い行はディスプレイの幅で切られる |
    | -n | 同じ親を持つプロセスを、名前ではなくPIDでソートする |
    | -p | PIDを表示する |
    | -u | ユーザーIDを表示する |

- **top**コマンドでプロセスの実行状況をモニターできる
  ```
  # プロセスの実行状況を確認するコマンド書式
  top

  # topコマンドの出力例
  $ top
  top - 05:36:30 up 11:14,  0 users,  load average: 0.07, 0.22, 0.16
  Tasks:   9 total,   1 running,   8 sleeping,   0 stopped,   0 zombie
  %Cpu(s):  0.6 us,  0.8 sy,  0.0 ni, 98.3 id,  0.1 wa,  0.0 hi,  0.2 si,  0.0 st
  MiB Mem :  15998.8 total,  10346.5 free,   2617.4 used,   3377.0 buff/cache
  MiB Swap:      0.0 total,      0.0 free,      0.0 used.  13381.3 avail Mem

    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
      1 root      20   0    2324   1508   1404 S   0.0   0.0   0:00.00 init(CentOSStre
      4 root      20   0    2324      4      0 S   0.0   0.0   0:00.00 init
      7 root      20   0    2332    112      0 S   0.0   0.0   0:00.00 SessionLeader
      8 root      20   0    2348    120      0 S   0.0   0.0   0:00.00 Relay(9)
      9 general+  20   0    8272   5120   3608 S   0.0   0.0   0:00.01 bash
    34 root      20   0    2332    112      0 S   0.0   0.0   0:00.00 SessionLeader
    35 root      20   0    2348    120      0 S   0.0   0.0   0:00.00 Relay(36)
    36 general+  20   0    8272   5124   3612 S   0.0   0.0   0:00.00 bash
    61 general+  20   0   10496   3952   3252 R   0.0   0.0   0:00.00 top
  ```
  - topコマンドの主な表示項目
    | 表示項目 | 説明 |
    | ---- | ---- |
    | PID | プロセスID |
    | USER | プロセスを実行しているユーザー |
    | %CPU | CPUを消費している割合 |
    | %MEM | メモリを消費している割合 |
    | COMMAND | 実行されているコマンド |
- **kill**コマンドでプロセスを終了させることができる
  - プログラムの実行が終了すると、プロセスは消滅する
  - プロセスの中には、各種サーバプロセスやシステムプロセスなど、明確に終了を指示しなければ動作し続けるものもある
  - また、プログラムの不具合が原因で、異常動作を起こして終了しなくなることもある
  - こういった場合は、プロセスに停止信号を送って終了させることになる
  - プロセスをに送る信号のことを**シグナル**という。主なシグナルは次のとおりである
    | シグナルID | シグナル名 | 動作 | 
    | ---- | ---- | ---- |
    | 1 | HUP | 再起動 |
    | 6 | ABRT | 中断 |
    | 9 | KILL | 強制終了 |
    | 15 | TERM | 終了(デフォルト) |
    | 18 | CONT | 再開 |
    | 19 | STOP | 一時停止 |
  - シグナルを送信するには**kill**コマンドを利用する
    ```
    # シグナルを送信する際のコマンド書式
    kill -[シグナルID] プロセスID
    kill -s [シグナル名] プロセスID

    # プロセスIDが28000のプロセスを終了する際には以下のいずれかを実行する

    # プロセスの終了➀
    $ kill 28000

    # プロセスの終了➁
    $ kill -15 28000

    # プロセスの終了➂
    $ kill -s TERM 28000

    # プロセスの強制終了➀
    $ kill -9 28000

    # プロセスの強制終了➁
    $ kill -s KILL 28000
    ```
  - 主なオプション
    | オプション | 説明 |
    | ---- | ---- |
    | -s シグナル名 | 指定したシグナル名を送信する |
    | -シグナルID | 指定したシグナルIDを送信する |
    | -l [] | シグナル名とシグナル番号の対応を表示する |
- **killall**コマンドでプロセスIDではなく、プロセス名を指定してプロセスを終了することができる
  - ただし、同じ名前のプロセスが複数実行されている場合は、それらすべてにシグナルが送られるので注意が必要!!
  ```
  # vimというプロセス名のプロセスを終了
  $ killall -15 kill
  ```

### 1-2 ジョブ管理
- ユーザーから見た処理の単位を**ジョブ**という
  - コンピュータに実行させる作業のまとまりを「**ジョブ**」と呼ぶ。例えば、コマンドラインでは「コマンドを入力してEnterキーを押す」と、1つのジョブが実行される
    - パイプ(|)でいくつかのコマンドをつないで実行する場合でも、それで1つのジョブと考える
  - ジョブには、**フォアグラウンドジョブ**と**バックグラウンドジョブ**がある
    - **フォアグラウンドジョブ**
      - 通常、コマンドライン上でコマンド(ジョブ)を実行すると、それが終了するまでは次のコマンドを入力することができない。
      - これが、**フォアグラウンド**でジョブが実行されている状態
    - **バックグラウンドジョブ**
      - 裏(バックグラウンド)でジョブを実行させることも可能
      - コマンドラインの末尾に「**&**」を付けるとバックグラウンドジョブとして実行される
        ```
        # バックグラウンドで実行
        # lessコマンドをバックグラウンドで実行すると、次のコマンドがすぐに入力できる状態になる
        $ less /etc/services &
        [1] 63
        $ 
        ```
- ジョブには端末ごとにジョブIDが付与される
- **jobs**コマンドでジョブ情報を表示できる
  ```
  # 実行中のジョブを確認するコマンド書式
  jobs

  $ jobs
  [1]+  Stopped                 less /etc/services
  ```
- ジョブをフォアグラウンドで実行させる場合は**fg**(ForeGround)コマンドを使う
  - ジョブIDは「%1」のように、パーセント記号「**%**」に続けて指定する。
  - 「**%**」を付けなければ、プロセスIDが指定されたものとみなされるので、注意が必要!!
  - フォアグラウンドでジョブが実行されている最中に「Ctrl + Z」キーを押すと、そのジョブは一時停止状態になる
  ```
  # ジョブをフォアグラウンドで実行する際のコマンド書式
  fg [%ジョブID]

  # 1番目のジョブをフォアグラウンドで実行
  $ fg %1
  ```

- フォアグラウンドで一時停止中のジョブの実行をバックグラウンドで再開させるには、**bg**(BackGround)コマンドを使う
  ```
  # ジョブをバックグラウンドで実行する際のコマンド書式
  bg [%ジョブID]

  # 1番目のジョブをバックグラウンドで実行
  $ bg %1
  ```

## 2 ネットワークの利用

### 2-1 ネットワークの基礎を理解しよう
- コンピュータ同士が理解できる約束事(ルール)を守ってメッセージをやり取りする方法を**プロトコル**という
  - 最も一般的なプロトコルは、インターネットの基盤となっている**TCP/IP**である
    - **TCP/IP**
      - これは、1つのプロトコルではなく、TCP及びIPという2つのプロトコルと、関連する多数のプロトコルを含めたプロトコル群を表す
  - プロトコルには以下のものがある
    - **TCP**
      - Transmission Control Protocolの略である
      - ネットワーク通信において信頼性を確保するためのプロトコルである
      - TCP/IPではデータを細切れに分割し、通信を行う。この分割されたデータを**パケット**という
      - パケットが届いたかどうかを確保し、届いていなければパケットを再送するなど、さまざまな方法で信頼性の向上を図る
    - **IP**
      - Internet Protocolの略である
      - IPはネットワーク上のIPアドレスを規定し、パケットが伝送されるネットワーク経路を担当する
      - TCP/IPではコンピュータやネットワーク機器にIPアドレスを割り当てる
      - IPには、IPアドレスが32ビット(IPv4)と、128ビットの(IPv6)がある
      - IPv4のIPアドレスはすでにほぼ枯渇してしまい、2019年には余剰分をやり繰りしている状況である
      - そのため、今後はIPv4と並んでIPv6が普及していくと考えられる
    - **UDP**
      - User Datagram Protocolの略である
      - TCPがパケットの到達を確認しながら通信するのに対し、UDPはそのような確認を行わない
      - そのため通信の信頼性は劣るが、その分スピーディな伝送が期待される
    - **ICMP**
      - Internet Control Message Protocolの略である
      - 通信で発生したエラーを伝えるメッセージや、通信の制御に関するメッセージなどを伝送するプロトコルである

- IPアドレス(IPv4)の32ビットはネットワーク部とホスト部から構成される。境界はサブネットマスクで求められる
  - **IPv4でのIPアドレス**
    - TCP/IPネットワークに接続した機器に割り当てられ、送信元や送信先の住所となるアドレスである
    - IPv4でのIPアドレスは32ビットの長さで表される
    - 2進数で表すと次のようになる
      ```
      2進数
      11000000101010000000000000000011

      上記の2進数を8ビットずつに区切り、「.」でつないだ10進数で表すのが一般的である
      192.168.0.3(11000000.10101000.00000000.00000011)
      ```
    - **ネットワーク部**
      - 日本住所でいう町名部分に相当するもの
        ```
        (東京都新宿区)〇〇町
        ```
    - **ホスト部**
      - 日本住所でいう番地部分に相当するもの
        ```
        3番5号
        ```
    - **サブネットマスク**
      - IPアドレス(IPv4)のうち「**ネットワーク部(ネットワークアドレス)**」と「**ホスト部(ホストアドレス)**」を識別するための数値
      - このサブネットマスクを使ってネットワーク部とホスト部を求めることが可能
        ```
        IPアドレス：     110000001010100000000000|00000011
        サブネットマスク：111111111111111111111111|00000000
        ```
      - サブネットマスクの「1」で表されている部分がネットワーク部、「0」の部分がホスト部である。つまり、次のように**ネットワーク部**と**ホスト部**が表される
        ```
        ネットワーク部：110000001010100000000000 = 192.168.0
        ホスト部：00000011 = 3
        ```
        - 上記のネットワーク部とホスト部を見ると、「**192.168.0**という町内の**3**番地」のような意味になる
    - **ネットワークセグメント**
      - ネットワーク部が同じであるIPアドレスは1つのネットワークに属している
      - このネットワークの範囲を**ネットワークセグメント**という
      - **同じネットワークに属しているコンピュータ同士は、直接通信を行うことが可能**
      - 逆に、**別のネットワークに属しているコンピュータとは、中継機器であるルーター(router)を介さなければ通信ができない**
- **ネットワークアドレス**と**ブロードキャストアドレス**はコンピュータに割り当てるIPアドレスとしては利用できない
  - 0からでする255まで、全部で256個のIPアドレスがあるが、これらのIPアドレスすべてがコンピュータなどに割り当て可能なわけではない
  - アドレス範囲のうち、先頭のIPアドレスと末尾のIPアドレスは特別な用途に使われる
    - ネットワークアドレス
      - 先頭のIPアドレスを**ネットワークアドレス**といい、ネットワーク自信を表すのに使う
        ```
        192.168.0.0(11000000.10101000.00000000.00000000)
        ```
      - 末尾のIPアドレスを**ブロードキャストアドレス**といい、同じネットワークに属するすべてのIPアドレスに同報で送信するために使われる
        ```
        192.168.0.255(11000000.10101000.00000000.11111111)
        ```

- IPアドレスには**クラス**という概念がある
  - **クラス**
    - クラスは、ネットワーク部とホスト部をあらかじめ、決められたビット数で分割する方法で、クラスごとにサブネットマスクの長さが決まっている
    - クラスにはクラスAからクラスEまでありますが、通常はクラスA~Cが利用されている
      | クラス | IPアドレスの範囲 | サブネットマスク | 
      | ---- | ---- | ---- |
      | A | 0.0.0.0 ~ 127.255.255.255 | 255.0.0.0 |
      | B | 128.0.0.0 ~ 191.255.255.255 | 255.255.0.0 |
      | C | 192.0.0.0 ~ 223.255.255.255 | 255.255.255.0 |
    - 1つのネットワークにいくつのIPアドレスがふくまれてるかということは、サブネットマスクのホスト部のビット数を見ればわかる
      | クラス | 使用可能なIPアドレスの個数 | 規模 | 
      | ---- | ---- | ---- |
      | A | 2^24 = 1677万個 | 大規模() |
      | B | 2^16 = 65536個 | 中規模 |
      | C | 2^8 = 256個 | 小規模 |
      - しかし、このクラスでは、300個のIPアドレスが必要な場合は、クラスBを選択することしかできず無駄に使用可能なIPアドレスを取得してしまうので、現在は**CIDR(サイダー)**というクラスにとらわれない仕組みでIPアドレスを扱える
        - **CIDR(サイダー)**
          - クラスにとらわれず、サブネットマスクを任意のビット数で扱うことが可能
          - たとえば、ネットワーク部を28ビット、ホスト部を4ビットとすると、そのネットワークは2^4=16個のIPアドレスが含まれ、クラスCよりも小さなネットワークになる
          - 1ビット単位で区切れるようになるのが、**CIDR(サイダー)**であり、IPアドレスを効率的に扱える

- **プライベートアドレス**は自由に使ってよいIPアドレスである
  - プライベートアドレスはLAN(Local Area Network)内で、自由に利用できるIPアドレスの範囲が定められている
  - プライベートアドレスの範囲は次のとおりである
    | プライベートアドレスの範囲 |
    | ---- |
    | 10.0.0.0 ~ 10.255.255.255 |
    | 172.16.0.0 ~ 172.31.255.255 |
    | 192.168.0.0 ~ 192.168.255.255 |
  - **LAN(Local Area Network)**
    - 企業内や家庭内など、1つの建物(あるいわせいぜい1つの施設)の中でのネットワークを表す
    - インターネットにはルーターを介して接続する
  - **WAN(Wide Area Network)**
    - LAN同士をつなぐ広域のネットワークのこと
- **グローバルアドレス**は重複しないようISP(インターネットサービスプロバイダー)などを通してユーザーに割り当てられるIPアドレスである
  - **グローバルアドレス**はICANN(Internet Corporation for Assigned Names and Numbers)という非営利団体が管理している
  - また、個人が決して勝手に利用してはいけないIPアドレスである
- **ポート番号**でアプリケーションを識別する
  - IPアドレスは、TCP/IPネットワーク上のコンピュータ(ホスト)の識別に使われるが、1台のコンピュータ上では、Webブラウザとメールクライアントなど、複数のネットワークアプリケーションをやり取りする際に、送信元や送信先のアプリケーションを識別するために、**ポート番号**が使われる
  - IPアドレスがマンションの住所を表すものだとすれば、ポート番号は部屋番号を会わらすものだといえる
  - 同時に複数のアプリケーションを利用していても、それぞれの通信を正しく処理することができる
  - ポート番号の範囲は0番から65535番までである
  - 代表的なネットワークサービスで使われるポート番号は標準化されており、これを**ウェルノウンポート(well-known port)**といい、0番から1023番までが予約されている
  - 主なポート番号は次のとおりである
    | ポート番号 | 説明 |
    | ---- | ---- |
    | 20 | FTPのデータ転送 |
    | 21 | FTPの制御情報 |
    | 22 | SSH(Secure-Shell)接続 |
    | 23 | Telnet情報 |
    | 25 | 電子メール送信(SMTP) |
    | 53 | DNS |
    | 80 | Web(HTTP) |
    | 110 | 電子メール受信(POP3) |
    | 443 | Web(HTTPS) |

### 2-2 ネットワークの設定と管理
- **/etc/hostname**ファイルにはホスト名を設定する
  - ホスト名はLinuxマシンを付ける名前である
  - Linuxのプロンプト上でユーザー名@**ホスト名**を表示する
  ```
  # 現在設定されている、ホスト名を表示する(自身のLinux環境ホスト名を表示する)
  $ cat /etc/hostname
  centos7
  ```
  - ホスト名を確認するには、**hostname**コマンドを実行する
    ```
    # ホスト名を確認する際のコマンド書式
    hostname

    $ hostname
    centos7
    ```
  - **/etc/hostname**をvi等で変更した場合は、システムを再起動する必要があるので注意が必要!!
- **/etc/hosts**ファイルにはIPアドレスとホスト名の対応を記述する
  - このhostsふぁいるで設定しておくと、IPアドレスを指定する代わりにホスト名をコマンドの引数や設定ファイルの値として指定できるようになる
  - また、IPアドレスの代わりにホスト名で表示されるようにもなる
    ```
    # /etc/hostsファイルの設定例
    $ cat /etc/hosts
    127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
    ::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
    ```
    - 上記の例では、127.0.1.1のIPアドレスに自身の「ホスト名」もしくは、「ホスト名.」というホスト名を対応付けている
    - 1行目と2行目のホスト名は削除しないよう、注意が必要!!
      - 自身のローカルIPで紐づいているので、ホストを削除してしまうとローカルシステム側のLinuxOSが正常に動作しなくなる場合がある
- **/etc/resolv.conf**ファイルには、利用するDNSサーバやドメイン名を指定する
  - **DNS(Domain Name System)サーバ**
    - ホスト名とIPアドレスの相互変換を処理するサーバである
    - Webブラウザでホスト名を使ってアドレスを指定したり、ドメイン名を使ったメールアドレスでやり取りしたりできるのは、DNSサーバがそれらのホスト名とIPアドレスを変換している
    - **/etc/resolv.conf**ファイルでは、「nameserver」に続けて、参照先DNSサーバのIPアドレスを指定する
      ```
      # /etc/resolv.confファイルの設定例
      $ cat /etc/resolv.conf
      # Generated by NetworkManager
      search elecom
      nameserver 192.168.2.1
      ```
      - 上記の例では、192.168.2.1のDNSサーバを利用するよう設定している
- **ip**コマンドでネットワークインターフェースの情報やルーティングテーブルを確認できる
  - **ネットワークインターフェース**
    - ホストとネットワークとの窓口となるもの
    - LANケーブルや無線を介してネットワークにつながる。
    - ネットワークインターフェースには「**enpOs3**」、「**eth0**」といった名前が付いている
  - **ip**コマンド
    - ネットワークインターフェースや後述のルーティングテーブルを管理するのに役立つコマンドである
    - **ip address show**コマンドを実行すると、ネットワークインターフェースの情報が確認できる
      ```
      # ネットワークインターフェースの情報を確認するコマンド書式
      ip address show [ネットワークインターフェース名]

      # ip address showコマンドでネットワークインターフェースの情報を確認
      $ ip address show
      1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
          link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
          inet 127.0.0.1/8 scope host lo
            valid_lft forever preferred_lft forever
          inet6 ::1/128 scope host
            valid_lft forever preferred_lft forever
      2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
          link/ether 08:00:27:41:d0:01 brd ff:ff:ff:ff:ff:ff
          inet 10.0.2.15/24 brd 10.0.2.255 scope global noprefixroute dynamic enp0s3
            valid_lft 86215sec preferred_lft 86215sec
          inet6 fe80::3313:fcd6:3ae3:b264/64 scope link noprefixroute
            valid_lft forever preferred_lft forever
      ```
      - **lo**はホスト自身を示す**ローカルループバックインターフェース**である
        - ローカルループバックインターフェースとは、どのようなホストであっても自分自身を表す特殊なインターフェースである
        - 動作テストやシステム内部の処理で使われる
        - どのホストでも、「**127.0.0.1**」はそのホスト自身を指す
      - **enp0s3(または、eth0)**は外部と接続されているインターフェースである
        - IPv4アドレス「**10.0.2.15**」とIPv6アドレス「**fe80::3313:fcd6:3ae3:b264**」が割り当てられている
    - 古いシステムでは、ipコマンドの代わりに**ifconfig**コマンドが使われていることがある
      ```
      # ネットワークインターフェースの情報を確認するコマンド書式
      ifconfig [ネットワークインターフェース名]

      $ ifconfig enp0s3
      enp0s3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.0.2.15  netmask 255.255.255.0  broadcast 10.0.2.255
        inet6 fe80::3313:fcd6:3ae3:b264  prefixlen 64  scopeid 0x20<link>
        ether 08:00:27:41:d0:01  txqueuelen 1000  (Ethernet)
        RX packets 435  bytes 43152 (42.1 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 314  bytes 35913 (35.0 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
      ```
    - ipコマンドやifconfigコマンドを使ってネットワークインターフェースの設定を変更することも可能である
      - 設定を変更する際には以下のURLを参考にして、ネットワークインターフェースの設定を変更する
        - https://qiita.com/_dakc_/items/4eefa443306860bdcfde
- **ss**コマンドで、開いているポートを確認できる
  - Webサーバーは起動すると80番(または、443番)ポートを監視し接続を待ち受けまたは、SMTPサーバー(メールサーバー)は25番ポートを監視し接続を待ち受ける
  - サーバーがポートからのデータを待ち受けている状態を「ポートが開いている」という
  - どのポートが開いているのかを調べれば、そのホストで稼働しているサーバーが判明する
  - 開いているポートを確認するには、**ss**コマンドを使う
    ```
    # ポートの状態を確認する際のコマンド書式
    ss [オプション]

    # ssコマンドでポートの状態を確認
    $ ss
    Netid  State      Recv-Q Send-Q              Local Address:Port                               Peer Address:Port
    u_str  ESTAB      0      0                               * 23677                                         * 23676
    u_str  ESTAB      0      0                               * 23638                                         * 23639
    u_str  ESTAB      0      0                               * 23676                                         * 23677
    u_str  ESTAB      0      0                               * 23646                                         * 23645
    u_str  ESTAB      0      0                               * 23679                                         * 23680
    u_str  ESTAB      0      0                               * 23645                                         * 23646
    u_str  ESTAB      0      0                               * 23643                                         * 23642
    u_str  ESTAB      0      0                               * 23778                                         * 23779
    u_str  ESTAB      0      0      /run/systemd/journal/stdout 22967                                         * 22966
    ```
    - ssコマンドの主なオプション
      | オプション | 説明 |
      | ---- | ---- |
      | -a | すべてのソケット(接続)情報を表示 |
      | -l | サーバーが開いているポートを表示 |
      | -t | TCPポートのみを表示 |
  - 古いシステムでは、ssコマンドの代わりに**netstat**コマンドが使われていることがある。オプションは、ssコマンドの場合と同じ
    ```
    # ポートの状態を確認する際のコマンド書式
    netstat [オプション]

    # netstatコマンドでポートの状態を確認
    $ netstal -atl
    Active Internet connections (servers and established)
    Proto Recv-Q Send-Q Local Address           Foreign Address         State
    tcp        0      0 0.0.0.0:ssh             0.0.0.0:*               LISTEN
    tcp        0      0 localhost:smtp          0.0.0.0:*               LISTEN
    tcp        0      0 centos7:ssh             gateway:62994           ESTABLISHED
    tcp6       0      0 [::]:ssh                [::]:*                  LISTEN
    tcp6       0      0 localhost:smtp          [::]:*                  LISTEN
    ```
  - ssコマンドやnetstatコマンドでは、ポートの情報以外にも、さまざまなネットワーク情報を確認できる
    - ネットワーク情報を確認する際は、以下のURLのオプションを参考にして、確認する
      - https://atmarkit.itmedia.co.jp/ait/articles/1710/06/news014.html

- **route**コマンドで、ルーティングテーブル(ルーティング情報)を確認できる
  - コンピュータやルーターは、ネットワークで繋がっているすべてのホストの場所を知っているわけではない
  - 通信先のホストへ正しくデータを届けるため、データの通過する経路(ルート)を制御する処理が行われる
  - これを**ルーティング**といい、ルーティング情報は**ルーティングテーブル**に格納される
  - **route**コマンドを実行すると、ルーティングテーブルが表示される
    ```
    # ルーティングテーブルを確認する際のコマンド書式
    route

    # routeコマンドでルーティングテーブルを表示
    $ route
    Kernel IP routing table
    Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
    default         gateway         0.0.0.0         UG    100    0        0 enp0s3
    10.0.2.0        0.0.0.0         255.255.255.0   U     100    0        0 enp0s3
    ```
    - defaultの**gameway**に注目すると、これは**デフォルトゲートウェイ**である
      - **デフォルトゲートウェイ**
        - 別のネットワークへデータを送る際に利用するルーターのことである
        - LANから外のネットワークへ出ていくパケットは、このルーターへ送られる
        - もし、デフォルトゲートウェイが見つからないと、LAN外にあるコンピュータとは通信ができなくなる
  - **ip**コマンドを利用してもルーティングテーブルを表示することが可能
    ```
    # ipコマンドでルーティングテーブルを表示
    $ ip route show
    default via 10.0.2.2 dev enp0s3 proto dhcp metric 100
    10.0.2.0/24 dev enp0s3 proto kernel scope link src 10.0.2.15 metric 100
    ```

### 2-3 ネットワークを利用するコマンド
- **hosts**コマンドでホスト名とIPアドレスを相互に変換できる
  - **host**コマンドを使うと、DNSサーバーに問い合わせを行い、指定したホスト名に対応するIPアドレスを確認できる
  - IPアドレスを指定しない場合は、対応するホスト名を表示する
    ```
    # ホスト名とIPアドレスを相互に変換する際のコマンド書式
    host [ホスト名 または IPアドレス]

    # book.impress.co.jpのIPアドレスを調べる
    $ host book.impress.co.jp
    book.impress.co.jp has address 203.183.234.8

    # 逆にIPアドレスを指定すると、対応するホスト名が表示される
    # ホスト名を調べる
    $ host 203.183.234.8
    8.234.183.203.in-addr.arpa is an alias for 8.0/25.234.183.203.in-addr.arpa.
    8.0/25.234.183.203.in-addr.arpa domain name pointer book.impress.co.jp.
    ```
  - hostコマンドが問い合わせを行うDNSサーバーは、**/etc/resolv.conf**で確認できる
- **ssh**コマンドでリモートホストに安全にログインできる
  - **SSH(Secure SHell)**は、ネットワークを経由したほかのホストとの通信を安全に行うプロトコルである
  - **ssh**コマンドを使うと、SSHプロトコルを使ってリモートホストに接続し、暗号化された安全な通信を行うことができる
  - 接続先のホストではSSHサーバーが動作しており、そのホストにログインするためのアカウントを持っている必要があるが、多くのディストリビューションではSSHサーバーがデフォルトで動作している
    ```
    # SSH接続をする際のコマンド書式
    ssh [ユーザー名@接続先ホスト名 または IPアドレス]

    # ssh接続をする際のIPアドレスを表示する
    # 仮想マシンに割り当てられたIPアドレスをsshコマンドに指定する
    # IPアドレスは、前述の「ip address show」コマンドや、「ifconfig」コマンドで調べられる
    $ ip address show enp0s3
    2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 08:00:27:41:d0:01 brd ff:ff:ff:ff:ff:ff
    inet 10.0.2.15/24 brd 10.0.2.255 scope global noprefixroute dynamic enp0s3
       valid_lft 86125sec preferred_lft 86125sec
    inet6 fe80::3313:fcd6:3ae3:b264/64 scope link noprefixroute
       valid_lft forever preferred_lft forever

    # sshでの初回接続例
    # 次の例では、10.0.2.15のホストに、penguinというユーザーで接続している
    # 初回接続時のみ、接続確認メッセージが表示されるので、「yes」と入力する
    $ ssh penguin@10.0.2.15
    The authenticity of host '10.0.2.15 (10.0.2.15)' can't be established.
    ECDSA key fingerprint is SHA256:DJ2GxOY5citiZByV8s9ztmw2c1fX5jCfAwbUd+3J2k0.
    ECDSA key fingerprint is MD5:34:cc:76:82:a7:df:1a:21:97:0d:13:46:0d:b2:1d:3b.
    Are you sure you want to continue connecting (yes/no)? yes
    Warning: Permanently added '10.0.2.15' (ECDSA) to the list of known hosts.
    penguin@10.0.2.15's password:
    Last login: Fri Aug 18 02:51:34 2023 from gateway
    [penguin@centos7 ~]$

    # 2回目以降のssh接続例
    $ ssh penguin@10.0.2.15
    penguin@10.0.2.15's password:
    Last login: Fri Aug 18 02:53:20 2023 from centos7
    [penguin@centos7 ~]$
    ```
  - **exit**コマンドを実行すると、ログアウトしてSSH接続を終了する
    ```
    # ssh接続を終了する際の、コマンド書式
    exit

    # ssh接続を終了する
    $ exit
    logout
    Connection to 10.0.2.15 closed.
    ```
  - SSH接続は暗号化されているため、通信を盗聴されていても安全に通信可能
  - また、**公開鍵認証**という、パスワードを使わずに認証を行う仕組みも備えている
    - 公開鍵認証ではパスワードの代わりに、**公開鍵**と**秘密鍵**という2つの鍵ペアを使って認証する
      - **公開鍵**
        - 接続元から接続先に接続する際に、公開される鍵情報
        - 接続元の秘密鍵がないと接続されない
      - **秘密鍵**
        - 接続元から接続先に接続する際に、秘密(非公開)にされる鍵情報
        - この鍵を別のユーザーに知られると誰でも接続が可能になるので、秘密鍵の管理には十分注意が必要になる
        - 秘密鍵の情報は膨大な文字列(パスワード)数になっているので、たとえ総当たり攻撃を行われても、秘密鍵の解析が不可能
    - 公開鍵認証でログインする環境を整えておけば、たとえパスワードが盗まれたとしても、第三者がログインすることはできない
  - SSHはリモートログインだけでなく、安全なファイル転送(ネットワークを介したファイルコピー)などにも使うことができる
- **ping**コマンドでホストの死活監視ができる
  - 死活監視
    - コンピュータが動作しているか、エラーを起こしてダウンしているかをコンピュータの動作状況を監視すること
  - **ping**コマンドは、指定したホスト(IPアドレス)に向けてICMPパケットを送信する
    - ICMP(Internet Control Message Protocol)
      - インターネット制御メッセージプロトコルのこと
      - ネットワーク上のデバイス間のデータ通信の問題を送信するためのプロトコルである
      - この定義におけるICMPは主に、データが目的の宛先(ホストまたは、IPアドレス)にタイムリーに到達しているかどうかを判断するために使われる
  - もしホストが動作していれば反応が返ってくるため、そのホストが動作している(およびネットワークがつながっている)ことが確認できる
  ```
  # ホストの動作状況を確認する際のコマンド書式
  ping [接続先ホスト名 または IPアドレス]

  # pingコマンドの実行例➀
  # 10.0.2.15のホストに対してICMPパケットを送信し、その状況を出力する
  # Ctrl + Cキーを押すまでICMPパケットは送信される
  $ ping 10.0.2.15
  PING 10.0.2.15 (10.0.2.15) 56(84) bytes of data.
  64 bytes from 10.0.2.15: icmp_seq=1 ttl=64 time=0.015 ms
  64 bytes from 10.0.2.15: icmp_seq=2 ttl=64 time=0.019 ms
  64 bytes from 10.0.2.15: icmp_seq=3 ttl=64 time=0.021 ms
  64 bytes from 10.0.2.15: icmp_seq=4 ttl=64 time=0.020 ms
  64 bytes from 10.0.2.15: icmp_seq=5 ttl=64 time=0.020 ms
  64 bytes from 10.0.2.15: icmp_seq=6 ttl=64 time=0.019 ms
  64 bytes from 10.0.2.15: icmp_seq=7 ttl=64 time=0.020 ms
  64 bytes from 10.0.2.15: icmp_seq=8 ttl=64 time=0.018 ms
  64 bytes from 10.0.2.15: icmp_seq=9 ttl=64 time=0.018 ms
  64 bytes from 10.0.2.15: icmp_seq=10 ttl=64 time=0.019 ms
  ^C
  --- 10.0.2.15 ping statistics ---
  10 packets transmitted, 10 received, 0% packet loss, time 8999ms
  rtt min/avg/max/mdev = 0.015/0.018/0.021/0.006 ms

  # pingコマンドの実行例➁
  # ネットワーク障害や接続先ホストのダウンが発生している場合は、次のように反応が返ってこなくなる
  $ ping 10.0.2.13
  PING 10.0.2.13 (10.0.2.13) 56(84) bytes of data.
  ^C
  --- 10.0.2.13 ping statistics ---
  2 packets transmitted, 0 received, 100% packet loss, time 999ms
  ```
  - ルーターによってはICMPパケットを制御していたり、ホストのネットワーク設定をICMPパケットの反応を返さないようにしていることもある
    - 反応が返ってこないからといって必ずしもホストがダウンしているとは限らないので注意が必要!!
  - IPv6のネットワーク環境では、pingコマンドの代わりに**ping6**コマンドを使う

## 3 システムの管理

### 3-1 ログとログファイル
- コンピュータ上で動作するシステムやプログラムの活動状況の記録を**ログ**という
  - ログの多くは**ログファイル**に書き込まれ蓄積される
  - 何か問題が発生した場合、ログファイルを確認すれば問題の原因を見つけられる可能性がある
- ログファイルには、収集されたログが記録されている
  - Linuxには、ログを集約して管理する**syslog**という仕組みがある
  - CentOSでは、**rsylog**というシステムプログラムによってログが収集され、ログファイルに保存される
  - 主なログファイル
    | ファイル名 | 説明 |
    | ---- | ---- |
    | /var/log/messages | 主要なログファイル |
    | /var/log/syslog | 主要なログファイル(Ubuntu、Debian/GNU Linux) |
    | /var/log/maillog | メール送受信のログファイル |
    | /var/log/secure | 認証関連のログファイル |
  - ログファイルは**/var/log**ディレクトリ以下に保存される
    - 多くのログファイルはテキストファイルなので、lessコマンドを使って閲覧したり、grepコマンドで特定のキーワードを検索することが可能
    ```
    # /var/log/messagesの例
    $ less /var/log/messages
    Aug 14 11:27:01 centos7 systemd: Removed slice User Slice of root.
    Aug 17 07:19:27 centos7 kernel: Initializing cgroup subsys cpuset
    Aug 17 07:19:27 centos7 kernel: Initializing cgroup subsys cpu
    Aug 17 07:19:27 centos7 kernel: Initializing cgroup subsys cpuacct
    Aug 17 07:19:27 centos7 kernel: Linux version 3.10.0-957.12.1.el7.x86_64 (mockbuild@kbuilder.bsys.centos.org) (gcc version 4.8.5 20150623 (Red Hat 4.8.5-36) (GCC) ) #1 SMP Mon Apr 29 14:59:59 UTC 2019
    Aug 17 07:19:27 centos7 kernel: Command line: BOOT_IMAGE=/vmlinuz-3.10.0-957.12.1.el7.x86_64 root=UUID=37abee08-086b-46bf-a636-b4b6f26d7380 ro rhgb quiet LANG=ja_JP.UTF-8
    Aug 17 07:19:27 centos7 kernel: e820: BIOS-provided physical RAM map:
    Aug 17 07:19:27 centos7 kernel: BIOS-e820: [mem 0x0000000000000000-0x000000000009fbff] usable
    Aug 17 07:19:27 centos7 kernel: BIOS-e820: [mem 0x000000000009fc00-0x000000000009ffff] reserved
    Aug 17 07:19:27 centos7 kernel: BIOS-e820: [mem 0x00000000000f0000-0x00000000000fffff] reserved
    Aug 17 07:19:27 centos7 kernel: BIOS-e820: [mem 0x0000000000100000-0x000000003ffeffff] usable
    Aug 17 07:19:27 centos7 kernel: BIOS-e820: [mem 0x000000003fff0000-0x000000003fffffff] ACPI data
    Aug 17 07:19:27 centos7 kernel: BIOS-e820: [mem 0x00000000fec00000-0x00000000fec00fff] reserved
    Aug 17 07:19:27 centos7 kernel: BIOS-e820: [mem 0x00000000fee00000-0x00000000fee00fff] reserved
    Aug 17 07:19:27 centos7 kernel: BIOS-e820: [mem 0x00000000fffc0000-0x00000000ffffffff] reserved
    Aug 17 07:19:27 centos7 kernel: NX (Execute Disable) protection: active
    Aug 17 07:19:27 centos7 kernel: SMBIOS 2.5 present.
    Aug 17 07:19:27 centos7 kernel: DMI: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006
    (以下省略)
    ```
    - また、一般ユーザーでは閲覧できないログファイルもあるので、その場合はroot(管理者)ユーザーに切り替えて閲覧する

### 3-2 システムの状態を確認するコマンド
- **dmesg**コマンドで、システム起動時のメッセージを確認する
  ```
  [    0.000000] Initializing cgroup subsys cpuset
  [    0.000000] Initializing cgroup subsys cpu
  [    0.000000] Initializing cgroup subsys cpuacct
  [    0.000000] Linux version 3.10.0-957.12.1.el7.x86_64 (mockbuild@kbuilder.bsys.centos.org) (gcc version 4.8.5 20150623 (Red Hat 4.8.5-36) (GCC) ) #1 SMP Mon Apr 29 14:59:59 UTC 2019
  [    0.000000] Command line: BOOT_IMAGE=/vmlinuz-3.10.0-957.12.1.el7.x86_64 root=UUID=37abee08-086b-46bf-a636-b4b6f26d7380 ro rhgb quiet LANG=ja_JP.UTF-8
  [    0.000000] e820: BIOS-provided physical RAM map:
  [    0.000000] BIOS-e820: [mem 0x0000000000000000-0x000000000009fbff] usable
  [    0.000000] BIOS-e820: [mem 0x000000000009fc00-0x000000000009ffff] reserved
  [    0.000000] BIOS-e820: [mem 0x00000000000f0000-0x00000000000fffff] reserved
  [    0.000000] BIOS-e820: [mem 0x0000000000100000-0x000000003ffeffff] usable
  [    0.000000] BIOS-e820: [mem 0x000000003fff0000-0x000000003fffffff] ACPI data
  (以下省略)
  ```
- **last**コマンドで、最近ログインしたユーザーを確認する
  - reboot行は、システムの再起動に関する記録である
  ```
  penguin  pts/2        centos7          Fri Aug 18 02:58 - 03:01  (00:03)
  penguin  pts/1        centos7          Fri Aug 18 02:53   still logged in
  penguin  pts/0        gateway          Fri Aug 18 02:51   still logged in
  reboot   system boot  3.10.0-957.12.1. Fri Aug 18 02:50 - 05:34  (02:44)
  penguin  pts/0        gateway          Thu Aug 17 07:34 - crash  (19:16)
  reboot   system boot  3.10.0-957.12.1. Thu Aug 17 07:33 - 05:34  (22:00)
  penguin  tty1                          Thu Aug 17 07:19 - crash  (00:14)
  reboot   system boot  3.10.0-957.12.1. Thu Aug 17 07:19 - 05:34  (22:14)
  penguin  pts/0        gateway          Mon Aug 14 09:08 - 10:12  (01:03)
  reboot   system boot  3.10.0-957.12.1. Mon Aug 14 09:07 - 05:34 (3+20:26)
  (以下省略)
  ```
- **who**コマンドで、ログイン中のユーザーを確認する
  ```
  penguin  pts/0        Aug 18 02:51 (gateway)
  penguin  pts/1        Aug 18 02:53 (centos7)
  ```
- **w**コマンドで、ログイン中のユーザーと実行中のコマンド、システム情報を確認する
  ```
   05:36:11 up  2:45,  2 users,  load average: 0.00, 0.02, 0.05
  USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
  penguin  pts/0    gateway          02:51    3.00s  0.01s  0.01s ssh penguin@10.
  penguin  pts/1    centos7          02:53    3.00s  0.02s  0.04s sshd: penguin [
  ```