hana_shinのLinux技術ブログ

Linuxの技術情報を掲載しています。特にネットワークをメインに掲載していきます。

conntrackコマンドの使い方

1 conntrackコマンドとは?

OS(netfilter)が維持するコネクショントラッキング情報を取得するためのコマンドです。トラッキングとは、送信パケットに対する応答パケットを関連付けることです。関連付けすることで、ユーザが応答パケットの受信を許可するフィルタリング設定が不要になります。conntrackコマンドは、以下の図のようにNETLINKインタフェースを使用してトラッキング情報を取得します。

     CentOS7
+---------------------+                                         -*-
|    firewall-cmd     |                                          |
+---------------------+                                          |
                                                               ユーザ空間
+---------------------+        +---------------------+           |
|  iptables command   |        |  conntrack command  |           |
+---------------------+        +---------------------+          -*-
          ↑                             ↑
======= AF_INET =======        ===== AF_NETLINK =====
          ↓                             ↓
+-----------------------------------------------------------+   -*-
|                                                           |    |
|                    OS(netfilter)                          |  カーネル空間
|                                                           |    |
+-----------------------------------------------------------+   -*-

2 検証環境

CentOS版数は以下のとおりです。

[root@server ~]# cat /etc/centos-release
CentOS Linux release 7.9.2009 (Core)

カーネル版数は以下のとおりです。

[root@server ~]# uname -r
3.10.0-1160.el7.x86_64

3 インストール方法

conntrack-toolsパッケージをインストールします。

[root@server ~]# yum -y install conntrack-tools

版数を確認します。

[root@server ~]# conntrack --version
conntrack v1.4.4 (conntrack-tools)

firewalldサービスの状態がactiveであることを確認します

[root@server ~]# systemctl is-active firewalld.service
active

4 オプション一覧

オプションは以下のとおりです。

[root@server ~]# conntrack --help
Command line interface for the connection tracking system. Version 1.4.4
Usage: conntrack [commands] [options]

Commands:
  -L [table] [options]          List conntrack or expectation table
  -G [table] parameters         Get conntrack or expectation
  -D [table] parameters         Delete conntrack or expectation
  -I [table] parameters         Create a conntrack or expectation
  -U [table] parameters         Update a conntrack
  -E [table] [options]          Show events
  -F [table]                    Flush table
  -C [table]                    Show counter
  -S                            Show statistics

Tables: conntrack, expect, dying, unconfirmed

Conntrack parameters and options:
  -n, --src-nat ip                      source NAT ip
  -g, --dst-nat ip                      destination NAT ip
  -j, --any-nat ip                      source or destination NAT ip
  -m, --mark mark                       Set mark
  -c, --secmark secmark                 Set selinux secmark
  -e, --event-mask eventmask            Event mask, eg. NEW,DESTROY
  -z, --zero                            Zero counters while listing
  -o, --output type[,...]               Output format, eg. xml
  -l, --label label[,...]               conntrack labels

Expectation parameters and options:
  --tuple-src ip        Source address in expect tuple
  --tuple-dst ip        Destination address in expect tuple

Updating parameters and options:
  --label-add label     Add label
  --label-del label     Delete label

Common parameters and options:
  -s, --src, --orig-src ip              Source address from original direction
  -d, --dst, --orig-dst ip              Destination address from original direction
  -r, --reply-src ip            Source addres from reply direction
  -q, --reply-dst ip            Destination address from reply direction
  -p, --protonum proto          Layer 4 Protocol, eg. 'tcp'
  -f, --family proto            Layer 3 Protocol, eg. 'ipv6'
  -t, --timeout timeout         Set timeout
  -u, --status status           Set status, eg. ASSURED
  -w, --zone value              Set conntrack zone
  --orig-zone value             Set zone for original direction
  --reply-zone value            Set zone for reply direction
  -b, --buffer-size             Netlink socket buffer size
  --mask-src ip                 Source mask address
  --mask-dst ip                 Destination mask address

5 リアルタイムに表示する方法(-E)

-Eはトラッキング情報をリアルタイムに表示するオプションです。

-Eを指定してconntrackコマンドを実行します。

[root@server ~]# conntrack -E

もう1つターミナルをオープンして、digコマンドを実行します。なお、digコマンドのインストール方法、使い方は、digコマンドの使い方 - hana_shinのLinux技術ブログを参照してください。

[root@server ~]# dig ntp.nict.jp +short

digコマンドによるDNS名前解決はUDPを使います。したがって、UDPパケットのトラッキング情報が出力されることが確認できます。また、2行目でDNSサーバからのDNS応答を受信していないので、[UNREPLIED]と表示されています。3行目はDNS応答を受信したので、[UNREPLIED]の表示が消えて、 [UPDATE] と状態が更新されていることがわかります。

[root@server ~]# conntrack -E
    [NEW] udp      17 30 src=::1 dst=::1 sport=60242 dport=60242 [UNREPLIED] src=::1 dst=::1 sport=60242 dport=60242
    [NEW] udp      17 30 src=192.168.122.216 dst=192.168.122.1 sport=46630 dport=53 [UNREPLIED] src=192.168.122.1 dst=192.168.122.216 sport=53 dport=46630
 [UPDATE] udp      17 30 src=192.168.122.216 dst=192.168.122.1 sport=46630 dport=53 src=192.168.122.1 dst=192.168.122.216 sport=53 dport=46630

次は、デフォルトGWに対してpingを実行してみます。

-Eを指定してconntrackコマンドを実行します。

[root@server ~]# conntrack -E

デフォルトGWに対してpingを1回実行してみます。なお、pingコマンドの使い方は、pingコマンドの使い方 - hana_shinのLinux技術ブログを参照してください。

[root@server ~]# ping -c 1 192.168.122.1

conntrackコマンドの実行結果を確認します。1行目はping要求に対して応答を受信していないので、 [UNREPLIED] と表示されていることがわかります。2行目は、ping応答を受信したので[UNREPLIED] の表示が消えて、 [UPDATE] と状態が更新されたことがわかります。

[root@server ~]# conntrack -E
    [NEW] icmp     1 30 src=192.168.122.216 dst=192.168.122.1 type=8 code=0 id=1365 [UNREPLIED] src=192.168.122.1 dst=192.168.122.216 type=0 code=0 id=1365
 [UPDATE] icmp     1 30 src=192.168.122.216 dst=192.168.122.1 type=8 code=0 id=1365 src=192.168.122.1 dst=192.168.122.216 type=0 code=0 id=1365

6 特定のプロトコルのトラッキング情報を表示する方法(-p)

6.1 TCPのトラッキング情報を表示する方法(-p tcp)

-pはプロトコルを指定するオプションです。指定できるオプションはtcp,udp,icmpです。

-pにtcpを指定して、TCPのトラッキング情報だけを表示してみます。

[root@server ~]# conntrack -E -p tcp

もう1つターミナルを開きます。そして、www.google.comに対してcurlコマンドを実行します。

[root@server ~]# curl -I https://www.google.com/

conntrackコマンドの実行結果を確認します。TCPコネクションの確立から解放までの様子を確認することができます。

[root@server ~]# conntrack -E -p tcp
    [NEW] tcp      6 301 ESTABLISHED src=192.168.122.1 dst=192.168.122.216 sport=57780 dport=22 [UNREPLIED] src=192.168.122.216 dst=192.168.122.1 sport=22 dport=57780
 [UPDATE] tcp      6 300 src=192.168.122.1 dst=192.168.122.216 sport=57780 dport=22 src=192.168.122.216 dst=192.168.122.1 sport=22 dport=57780
 [UPDATE] tcp      6 432000 src=192.168.122.1 dst=192.168.122.216 sport=57780 dport=22 src=192.168.122.216 dst=192.168.122.1 sport=22 dport=57780 [ASSURED]
    [NEW] tcp      6 120 SYN_SENT src=192.168.122.216 dst=172.217.31.132 sport=59538 dport=443 [UNREPLIED] src=172.217.31.132 dst=192.168.122.216 sport=443 dport=59538
 [UPDATE] tcp      6 60 SYN_RECV src=192.168.122.216 dst=172.217.31.132 sport=59538 dport=443 src=172.217.31.132 dst=192.168.122.216 sport=443 dport=59538
 [UPDATE] tcp      6 432000 ESTABLISHED src=192.168.122.216 dst=172.217.31.132 sport=59538 dport=443 src=172.217.31.132 dst=192.168.122.216 sport=443 dport=59538 [ASSURED]
 [UPDATE] tcp      6 120 FIN_WAIT src=192.168.122.216 dst=172.217.31.132 sport=59538 dport=443 src=172.217.31.132 dst=192.168.122.216 sport=443 dport=59538 [ASSURED]
 [UPDATE] tcp      6 30 LAST_ACK src=192.168.122.216 dst=172.217.31.132 sport=59538 dport=443 src=172.217.31.132 dst=192.168.122.216 sport=443 dport=59538 [ASSURED]
 [UPDATE] tcp      6 120 TIME_WAIT src=192.168.122.216 dst=172.217.31.132 sport=59538 dport=443 src=172.217.31.132 dst=192.168.122.216 sport=443 dport=59538 [ASSURED]

6.2 TCPの状態で絞り込む方法(--state)

netfilterが管理するTCPの状態を以下に示します。なおnetfilterが管理する状態とTCPプロトコルが管理する状態に関係はありません。

man conntrackより抜粋
--state [NONE | SYN_SENT | SYN_RECV | ESTABLISHED | FIN_WAIT | CLOSE_WAIT | LAST_ACK | TIME_WAIT | CLOSE | LISTEN]

SYN_SENTの状態のトラッキング情報だけを表示してみます。

[root@server ~]# conntrack -E -p tcp --state SYN_SENT

www.google.comに対してcurlコマンドを実行します。

[root@server ~]# curl -I https://www.google.com/

conntrackコマンドの実行結果を確認します。SYN_SENT状態のトラッキング情報だけが表示されることがわかります。

[root@server ~]# conntrack -E -p tcp --state SYN_SENT
    [NEW] tcp      6 120 SYN_SENT src=192.168.122.216 dst=172.217.161.36 sport=60562 dport=443 [UNREPLIED] src=172.217.161.36 dst=192.168.122.216 sport=443 dport=60562

6.3 UDPのトラッキング情報を表示する方法(-p udp)

-pにUDPを指定して、UDPのトラッキング情報だけを表示してみます。

[root@server ~]# conntrack -E -p udp

もう1つターミナルをオープンして、digコマンドを実行します。

[root@server ~]# dig ntp.nict.jp +short

conntrackコマンドの実行結果を確認します。1行目はDNSサーバからのDNS応答を受信していないので、[UNREPLIED]と表示されています。2行目はDNS応答を受信したので、[UNREPLIED] の表示が消えて、[UPDATE] と状態が更新されていることがわかります。そして、3行目は、30秒経過してトラッキング情報が管理テーブルから削除されたので、[DESTROY] と状態が更新されていることがわかります。

[root@server ~]# conntrack -E -p udp
    [NEW] udp      17 30 src=192.168.122.216 dst=192.168.122.1 sport=60377 dport=53 [UNREPLIED] src=192.168.122.1 dst=192.168.122.216 sport=53 dport=60377
 [UPDATE] udp      17 30 src=192.168.122.216 dst=192.168.122.1 sport=60377 dport=53 src=192.168.122.1 dst=192.168.122.216 sport=53 dport=60377
[DESTROY] udp      17 src=192.168.122.216 dst=192.168.122.1 sport=60377 dport=53 src=192.168.122.1 dst=192.168.122.216 sport=53 dport=60377

6.4 ICMPのトラッキング情報を表示する方法(-p icmp)

-pにicmpを指定して、ICMPのトラッキング情報だけを表示してみます。

[root@server ~]# conntrack -E -p icmp

デフォルトGWに対してpingを1回実行してみます。

[root@server ~]# ping -c 1 192.168.122.1

conntrackコマンドの実行結果を確認します。1行目はping要求に対する応答を受信していないので、 [UNREPLIED] と表示されていることがわかります。2行目は、ping応答を受信したので[UNREPLIED] が消えて、 [UPDATE] と状態が更新されたことがわかります。3行目は、30秒経過してトラッキング情報が管理テーブルから削除されたので、[DESTROY] と状態が更新されていることがわかります。

[root@server ~]# conntrack -E -p icmp
    [NEW] icmp     1 30 src=192.168.122.216 dst=192.168.122.1 type=8 code=0 id=1407 [UNREPLIED] src=192.168.122.1 dst=192.168.122.216 type=0 code=0 id=1407
 [UPDATE] icmp     1 30 src=192.168.122.216 dst=192.168.122.1 type=8 code=0 id=1407 src=192.168.122.1 dst=192.168.122.216 type=0 code=0 id=1407
[DESTROY] icmp     1 src=192.168.122.216 dst=192.168.122.1 type=8 code=0 id=1407 src=192.168.122.1 dst=192.168.122.216 type=0 code=0 id=1407

7 IPアドレスで絞り込む方法(-s)

-sは送信元IPアドレスを指定するオプションです。なお、192.168.122.216はサーバ(server)のIPアドレスです。

[root@server ~]# conntrack -E -s 192.168.122.216

もう1つターミナルをオープンして、digコマンドを実行します。

[root@server ~]# dig ntp.nict.jp +short

conntrackコマンドの実行結果を確認します。送信元IPアドレスが192.168.122.216のトラッキング情報だけが表示されていることがわかります。

[root@server ~]# conntrack -E -s 192.168.122.216
    [NEW] udp      17 30 src=192.168.122.216 dst=144.76.138.23 sport=36239 dport=123 [UNREPLIED] src=144.76.138.23 dst=192.168.122.216 sport=123 dport=36239
 [UPDATE] udp      17 29 src=192.168.122.216 dst=144.76.138.23 sport=36239 dport=123 src=144.76.138.23 dst=192.168.122.216 sport=123 dport=36239
    [NEW] udp      17 30 src=192.168.122.216 dst=192.168.122.1 sport=35798 dport=53 [UNREPLIED] src=192.168.122.1 dst=192.168.122.216 sport=53 dport=35798
 [UPDATE] udp      17 30 src=192.168.122.216 dst=192.168.122.1 sport=35798 dport=53 src=192.168.122.1 dst=192.168.122.216 sport=53 dport=35798

8 宛先ポート番号で絞り込む方法(--dport)

--dport に53番ポートを指定して、宛先ポート番号がUDPの53番のトラッキング情報だけを表示してみます。なお、UDPの53番ポートはNTPに割り当てられているポート番号です。

[root@server ~]# conntrack -E -p udp --dport 53

もう1つターミナルをオープンして、digコマンドを実行します

[root@server ~]# dig ntp.nict.jp +short

conntrackコマンドの実行結果を確認します。1行目でDNSサーバからのDNS応答を受信していないので、[UNREPLIED]と表示されています。2行目はDNS応答を受信したので、 [UPDATE] と状態が更新されていることがわかります。

[root@server ~]# conntrack -E -p udp --dport 53
    [NEW] udp      17 30 src=192.168.122.216 dst=192.168.122.1 sport=57591 dport=53 [UNREPLIED] src=192.168.122.1 dst=192.168.122.216 sport=53 dport=57591
 [UPDATE] udp      17 30 src=192.168.122.216 dst=192.168.122.1 sport=57591 dport=53 src=192.168.122.1 dst=192.168.122.216 sport=53 dport=57591

9 時間を表示する方法(-o timestamp)

ICMPのトラッキング情報に時刻情報を付加してみます。

[root@server ~]# conntrack -E -p icmp -o timestamp

もう1つターミナルを開きます。そして、デフォルトGWに対してpingコマンドを実行します。

[root@server ~]# ping -c 1 192.168.122.1

conntrackコマンドの実行結果を確認します。NEWからDESTROYになる時間は約30秒であることがわかります。

[root@server ~]# conntrack -E -p icmp -o timestamp
[1655385091.917279]         [NEW] icmp     1 30 src=192.168.122.216 dst=192.168.122.1 type=8 code=0 id=1494 [UNREPLIED] src=192.168.122.1 dst=192.168.122.216 type=0 code=0 id=1494
[1655385091.917808]      [UPDATE] icmp     1 30 src=192.168.122.216 dst=192.168.122.1 type=8 code=0 id=1494 src=192.168.122.1 dst=192.168.122.216 type=0 code=0 id=1494
[1655385121.917959]     [DESTROY] icmp     1 src=192.168.122.216 dst=192.168.122.1 type=8 code=0 id=1494 src=192.168.122.1 dst=192.168.122.216 type=0 code=0 id=1494

10 特定状態のトラッキング情報を表示する方法(-e)

10.1 NEW状態のトラッキング情報を表示する方法

状態がNEWのトラッキング情報だけを表示してみます。NEWは、管理管理テーブルにトラッキング情報が初めて登録されたときの状態です。

[root@server ~]# conntrack -E -p icmp -e NEW

pingコマンドを3回実行します。

[root@server ~]# ping -c 1 192.168.122.1
[root@server ~]# ping -c 1 192.168.122.1
[root@server ~]# ping -c 1 192.168.122.1

conntrackコマンドの実行結果を確認します。NEWの状態のトラッキング情報だけが表示されていることがわかります。

[root@server ~]# conntrack -E -p icmp -e NEW
    [NEW] icmp     1 10 src=192.168.122.216 dst=192.168.122.1 type=8 code=0 id=1460 [UNREPLIED] src=192.168.122.1 dst=192.168.122.216 type=0 code=0 id=1460
    [NEW] icmp     1 10 src=192.168.122.216 dst=192.168.122.1 type=8 code=0 id=1461 [UNREPLIED] src=192.168.122.1 dst=192.168.122.216 type=0 code=0 id=1461
    [NEW] icmp     1 10 src=192.168.122.216 dst=192.168.122.1 type=8 code=0 id=1462 [UNREPLIED] src=192.168.122.1 dst=192.168.122.216 type=0 code=0 id=1462

10.2 UPDATES状態のトラッキング情報を表示する方法

状態がUPDATESのトラッキング情報だけを表示してみます。UPDATESは、管理管理テーブルのトラッキング情報が更新されたときの状態です。たとえば、送信パケットに対する応答パケットを受信すると状態がUPDATESになります。

[root@server ~]# conntrack -E -p icmp -e UPDATES

pingコマンドを3回実行します。

[root@server ~]# ping -c 1 192.168.122.1
[root@server ~]# ping -c 1 192.168.122.1
[root@server ~]# ping -c 1 192.168.122.1

conntrackコマンドの実行結果を確認します。UPDATESの状態のトラッキング情報だけが表示されていることがわかります。

[root@server ~]# conntrack -E -p icmp -e UPDATES
 [UPDATE] icmp     1 10 src=192.168.122.216 dst=192.168.122.1 type=8 code=0 id=1467 src=192.168.122.1 dst=192.168.122.216 type=0 code=0 id=1467
 [UPDATE] icmp     1 10 src=192.168.122.216 dst=192.168.122.1 type=8 code=0 id=1468 src=192.168.122.1 dst=192.168.122.216 type=0 code=0 id=1468
 [UPDATE] icmp     1 10 src=192.168.122.216 dst=192.168.122.1 type=8 code=0 id=1469 src=192.168.122.1 dst=192.168.122.216 type=0 code=0 id=1469

10.3 DESTROY状態のトラッキング情報を表示する方法

状態がDESTROYのトラッキング情報だけを表示してみます。DESTROYは、管理テーブルからトラッキング情報が消去された状態です

[root@server ~]# conntrack -E -p icmp -e DESTROY

pingコマンドを1回実行します。

[root@server ~]# ping -c 1 192.168.122.1

conntrackコマンドの実行結果を確認します。DESTROYの状態のトラッキング情報だけが表示されていることがわかります。

[root@server ~]# conntrack -E -p icmp -e DESTROY
[DESTROY] icmp     1 src=192.168.122.216 dst=192.168.122.1 type=8 code=0 id=1471 src=192.168.122.1 dst=192.168.122.216 type=0 code=0 id=1471

11 管理テーブルのトラッキング情報を表示する方法(-L)

ラッキング情報はnetfilterの管理テーブルに保存されています。ここでは、管理テーブルに保存されているトラッキング情報を表示してみます。以下の実行例では、トラッキング情報が2つ表示されていることがわかります。

[root@server ~]# conntrack -L
udp      17 28 src=192.168.122.216 dst=192.168.122.1 sport=50202 dport=53 src=192.168.122.1 dst=192.168.122.216 sport=53 dport=50202 mark=0 secctx=system_u:object_r:unlabeled_t:s0 use=1
tcp      6 431999 ESTABLISHED src=192.168.122.216 dst=192.168.122.1 sport=22 dport=55496 src=192.168.122.1 dst=192.168.122.216 sport=55496 dport=22 [ASSURED] mark=0 secctx=system_u:object_r:unlabeled_t:s0 use=1
conntrack v1.4.4 (conntrack-tools): 2 flow entries have been shown.

12 トラッキング情報を消去する方法

12.1 全てのトラッキング情報を消去する方法(-F)

-Fは管理テーブルのトラッキング情報を全て消去するオプションです。
現在、管理テーブルに3つのトラッキング情報が登録されていることがわかります。

[root@server ~]# conntrack -L
tcp      6 431999 ESTABLISHED src=192.168.122.216 dst=192.168.122.1 sport=22 dport=55496 src=192.168.122.1 dst=192.168.122.216 sport=55496 dport=22 [ASSURED] mark=0 secctx=system_u:object_r:unlabeled_t:s0 use=1
icmp     1 26 src=192.168.122.216 dst=192.168.122.1 type=8 code=0 id=1197 src=192.168.122.1 dst=192.168.122.216 type=0 code=0 id=1197 mark=0 secctx=system_u:object_r:unlabeled_t:s0 use=1
udp      17 28 src=192.168.122.216 dst=192.168.122.1 sport=36503 dport=53 src=192.168.122.1 dst=192.168.122.216 sport=53 dport=36503 mark=0 secctx=system_u:object_r:unlabeled_t:s0 use=1
conntrack v1.4.4 (conntrack-tools): 3 flow entries have been shown.

ラッキング情報を全て削除します。

[root@server ~]# conntrack -F
conntrack v1.4.4 (conntrack-tools): connection tracking table has been emptied.

ラッキング情報が1つだけであることがわかります。これは、デスクトップからのssh接続のトラッキング情報なので、削除することができません。

[root@server ~]# conntrack -L
tcp      6 431999 ESTABLISHED src=192.168.122.216 dst=192.168.122.1 sport=22 dport=55496 src=192.168.122.1 dst=192.168.122.216 sport=55496 dport=22 [ASSURED] mark=0 secctx=system_u:object_r:unlabeled_t:s0 use=1
conntrack v1.4.4 (conntrack-tools): 1 flow entries have been shown.

12.2 特定のトラッキング情報を消去する方法(-D)

-Dは特定のラッキング情報を消去するオプションです。

[root@server ~]# conntrack -L
tcp      6 431999 ESTABLISHED src=192.168.122.216 dst=192.168.122.1 sport=22 dport=55496 src=192.168.122.1 dst=192.168.122.216 sport=55496 dport=22 [ASSURED] mark=0 secctx=system_u:object_r:unlabeled_t:s0 use=1
icmp     1 26 src=192.168.122.216 dst=192.168.122.1 type=8 code=0 id=1289 src=192.168.122.1 dst=192.168.122.216 type=0 code=0 id=1289 mark=0 secctx=system_u:object_r:unlabeled_t:s0 use=1
udp      17 24 src=192.168.122.216 dst=192.168.122.1 sport=36529 dport=53 src=192.168.122.1 dst=192.168.122.216 sport=53 dport=36529 mark=0 secctx=system_u:object_r:unlabeled_t:s0 use=1
conntrack v1.4.4 (conntrack-tools): 3 flow entries have been shown.

ICMPのトラッキング情報だけを消去します。

[root@server ~]# conntrack -D -p icmp
icmp     1 15 src=192.168.122.216 dst=192.168.122.1 type=8 code=0 id=1289 src=192.168.122.1 dst=192.168.122.216 type=0 code=0 id=1289 mark=0 secctx=system_u:object_r:unlabeled_t:s0 use=1
conntrack v1.4.4 (conntrack-tools): 1 flow entries have been deleted.

conntrackコマンドの実行結果を確認します。ICMPのトラッキング情報だけが消去されたことがわかります。

[root@server ~]# conntrack -L
tcp      6 431999 ESTABLISHED src=192.168.122.216 dst=192.168.122.1 sport=22 dport=55496 src=192.168.122.1 dst=192.168.122.216 sport=55496 dport=22 [ASSURED] mark=0 secctx=system_u:object_r:unlabeled_t:s0 use=1
udp      17 11 src=192.168.122.216 dst=192.168.122.1 sport=36529 dport=53 src=192.168.122.1 dst=192.168.122.216 sport=53 dport=36529 mark=0 secctx=system_u:object_r:unlabeled_t:s0 use=1
conntrack v1.4.4 (conntrack-tools): 2 flow entries have been shown.

13 管理テーブルのトラッキング数を変更する方法(nf_conntrack_max)

13.1変更前

コネクショントラッキング数を確認します。管理テーブルには最大65536個のコネクショントラッキング情報を保存できることがわかります。

[root@server ~]# cat /proc/sys/net/netfilter/nf_conntrack_max
65536

13.2 変更後

コネクショントラッキング数を3個に制限します。

root@server ~]# echo 3 > /proc/sys/net/netfilter/nf_conntrack_max

コネクショントラッキング数を確認します。

[root@server ~]# cat /proc/sys/net/netfilter/nf_conntrack_max
3
[root@server ~]# conntrack -L
tcp      6 431999 ESTABLISHED src=192.168.122.216 dst=192.168.122.1 sport=22 dport=55496 src=192.168.122.1 dst=192.168.122.216 sport=55496 dport=22 [ASSURED] mark=0 secctx=system_u:object_r:unlabeled_t:s0 use=1
icmp     1 25 src=192.168.122.216 dst=192.168.122.1 type=8 code=0 id=1378 src=192.168.122.1 dst=192.168.122.216 type=0 code=0 id=1378 mark=0 secctx=system_u:object_r:unlabeled_t:s0 use=1
icmp     1 26 src=192.168.122.216 dst=192.168.122.1 type=8 code=0 id=1379 src=192.168.122.1 dst=192.168.122.216 type=0 code=0 id=1379 mark=0 secctx=system_u:object_r:unlabeled_t:s0 use=1
conntrack v1.4.4 (conntrack-tools): 3 flow entries have been shown.

14 トラッキング情報のタイムアウト時間を変更する方法

nf_conntrack_icmp_timeoutは、ICMPトラッキング情報のタイムアウト時間を指定するパラメータです。タイムアウトすると、管理テーブルからトラッキング情報が削除されます。

ICMPトラッキング情報のタイムアウト時間を確認します。タイムアウト時間が30秒であることがわかります。

[root@server ~]# cat /proc/sys/net/netfilter/nf_conntrack_icmp_timeout
30

タイムアウト時間を10秒に変更します。

[root@server ~]# echo 10 > /proc/sys/net/netfilter/nf_conntrack_icmp_timeout

変更したタイムアウト時間を確認します。タイムアウト時間が10秒に変更されたことがわかります。

[root@server ~]# cat /proc/sys/net/netfilter/nf_conntrack_icmp_timeout
10

pingを実行します。

[root@server ~]# date;ping -c 1 192.168.122.1
2022年  6月 16日 木曜日 21:35:23 JST
PING 192.168.122.1 (192.168.122.1) 56(84) bytes of data.
64 bytes from 192.168.122.1: icmp_seq=1 ttl=64 time=0.384 ms

--- 192.168.122.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.384/0.384/0.384/0.000 ms

ICMPのトラッキング情報を確認します。まだ10秒たっていないので、管理テーブルにICMPのトラッキング情報が残っていることがわかります。

[root@server ~]# date;conntrack -L -p icmp
2022年  6月 16日 木曜日 21:35:24 JST
icmp     1 8 src=192.168.122.216 dst=192.168.122.1 type=8 code=0 id=1437 src=192.168.122.1 dst=192.168.122.216 type=0 code=0 id=1437 mark=0 secctx=system_u:object_r:unlabeled_t:s0 use=1
conntrack v1.4.4 (conntrack-tools): 1 flow entries have been shown.

ICMPのトラッキング情報を確認します。まだ10秒たっていないので、管理テーブルにICMPのトラッキング情報が残っていることがわかります。

[root@server ~]# date;conntrack -L -p icmp
2022年  6月 16日 木曜日 21:35:29 JST
icmp     1 3 src=192.168.122.216 dst=192.168.122.1 type=8 code=0 id=1437 src=192.168.122.1 dst=192.168.122.216 type=0 code=0 id=1437 mark=0 secctx=system_u:object_r:unlabeled_t:s0 use=1
conntrack v1.4.4 (conntrack-tools): 1 flow entries have been shown.

ICMPのトラッキング情報を確認します。タイムアウトしたので、管理テーブルからICMPのトラッキング情報が消去されたことがわかります。

[root@server ~]# date;conntrack -L -p icmp
2022年  6月 16日 木曜日 21:35:34 JST
conntrack v1.4.4 (conntrack-tools): 0 flow entries have been shown.

Z 参考情報

私が業務や記事執筆で参考にした書籍を以下のページに記載します。
Linux技術のスキルアップをしよう! - hana_shinのLinux技術ブログ

virshコマンドの使い方

1 virshコマンドとは?

仮想マシンとハイパーバイザを管理するコマンドです。

2 検証環境

KVMホストのCentOS版数は以下のとおりです。

[root@kvm ~]# cat /etc/redhat-release
CentOS Linux release 7.6.1810 (Core)

カーネル版数は以下のとおりです。

[root@kvm ~]# uname -r
3.10.0-957.el7.x86_64

NetworkManagerサービスの状態を確認します。activeであることを確認します。

[root@kvm ~]# systemctl is-active NetworkManager
active

3 オプション一覧

virshコマンドのオプションは非常に多いので、ここでは、ネットワークに関する設定をおもに試したいと思います。なお、オプションは、virsh helpを実行すると表示されます。

[root@kvm ~]# virsh help
グループ別コマンド:

 Domain Management (ヘルプのキーワード 'domain'):
    attach-device                  XML ファイルによるデバイスの接続
    attach-disk                    ディスクデバイスの接続
    attach-interface               ネットワークインターフェースの接続

さらに、オプションの詳細を表示するには、以下のように実行します。

[root@kvm ~]# virsh help net-autostart
  名前
    net-autostart - ネットワークの自動起動

  形式
    net-autostart <network> [--disable]

  詳細
    システム起動時にネットワークを自動的に起動するよう設定します。

  オプション
    [--network] <string>  ネットワークの名前または UUID
    --disable        自動起動の設定解除

4 仮想マシンの各種情報を表示する方法

4.1 仮想マシン一覧を表示する方法(list)

listは実行中の仮想マシンを表示するオプションです。

[root@kvm ~]# virsh list
 Id    名前                         状態
----------------------------------------------------
 1     server                         実行中

--allオプションを付けると、シャットオフの仮想マシンも表示します。 serverが実行中で、routerがシャットオフであることがわかります。

[root@kvm ~]# virsh list --all
 Id    名前                         状態
----------------------------------------------------
 1     server                         実行中
 -     router                         シャットオフ

4.2 設定ファイルの出力方法(dumpxml)

dumpxmlは、仮想マシンの設定ファイルを出力するオプションです。

[root@kvm ~]# virsh dumpxml server
<domain type='kvm' id='1'>
  <name>server</name>
-snip-

4.3 IDの表示方法(domid)

domidは、仮想マシンのIDを表示するオプションです。

[root@kvm ~]# virsh domid server
1

4.4 情報の表示方法(dominfo)

dominfoは、仮想マシンの名前やPCU数等の情報を表示するオプションです。

[root@kvm ~]# virsh dominfo server
Id:             1
名前:         server
UUID:           66d60e60-2221-49d1-9939-d9a82b848a4e
OS タイプ:   hvm
状態:         実行中
CPU:            4
CPU 時間:     66.9s
最大メモリー: 4194304 KiB
使用メモリー: 4194304 KiB
永続:         はい (yes)
自動起動:   無効にする
管理済み保存: いいえ (no)
セキュリティモデル: selinux
セキュリティ DOI: 0
セキュリティラベル: system_u:system_r:svirt_t:s0:c351,c394 (enforcing)

4.5 状態の表示方法(domstate)

domstateは、仮想マシンの状態を表示するオプションです。

serverは実行中であることがわかります。

[root@kvm ~]# virsh domstate server
実行中

routerはシャットダウン中であることがわかります。

[root@kvm ~]# virsh domstate router
シャットオフ

4.6 UUIDの表示方法(domuuid)

domuuidは、UUIDの表示すりオプションです。

[root@kvm ~]# virsh domuuid server
66d60e60-2221-49d1-9939-d9a82b848a4e

4.7 名前の表示方法(domname)

domnameは、IDに対する仮想マシン名を表示するオプションです。

[root@kvm ~]# virsh domname 1
server

5 仮想マシンの起動、停止方法

5.1 起動方法(start)

仮想マシン一覧を確認します。serverが実行中、routerがシャットオフの状態であることがわかります。

[root@kvm ~]# virsh list --all
 Id    名前                         状態
----------------------------------------------------
 1     server                         実行中
 -     router                         シャットオフ

routerを起動します。

[root@kvm ~]# virsh start router
ドメイン router が起動されました

仮想マシン一覧を確認します。routerが実行中になったことがわかります。

[root@kvm ~]# virsh list --all
 Id    名前                         状態
----------------------------------------------------
 1     server                         実行中
 2     router                         実行中

5.2 停止方法(shutdown)

routerを停止してみます。

[root@kvm ~]# virsh shutdown router
ドメイン router はシャットダウン中です

仮想マシン一覧を確認します。routerがシャットオフになったことがわかります。

[root@kvm ~]# virsh list --all
 Id    名前                         状態
----------------------------------------------------
 1     server                         実行中
 -     router                         シャットオフ

6 仮想マシンの一時停止、再開方法

6.1 一時停止(suspend)

仮想マシン一覧を確認します。serverが実行中であることがわかります。

[root@kvm ~]# virsh list
 Id    名前                         状態
----------------------------------------------------
 1     server                         実行中

serverを一時停止にします。

[root@kvm ~]# virsh suspend server
ドメイン server は一時停止されました

仮想マシン一覧を確認します。serverが停止中であることがわかります。

[root@kvm ~]# virsh list
 Id    名前                         状態
----------------------------------------------------
 1     server                         一時停止中

6.2 再開(resume)

serverを再開します。

[root@kvm ~]# virsh resume server
ドメイン server が再開されました

仮想マシン一覧を確認します。serverが実行中になったことがわかります。

[root@kvm ~]# virsh list
 Id    名前                         状態
----------------------------------------------------
 1     server                         実行中

7 仮想マシン名の変更方法

仮想マシンの名前(ドメイン名)を変更してみます。名前を変更するには、仮想マシンをシャットオフにして行う必要があります。

[root@kvm ~]# virsh list --all
 Id    名前                         状態
----------------------------------------------------
 1     server                         実行中
 -     router                         シャットオフ

routerの名前をbridgeに変更してみます。

[root@kvm ~]# virsh domrename router bridge
Domain successfully renamed

仮想マシン一覧を確認します。routerがbridgeに変更されたことがわかります。

[root@kvm ~]# virsh list --all
 Id    名前                         状態
----------------------------------------------------
 1     server                         実行中
 -     bridge                         シャットオフ

8 仮想マシンのインタフェース情報の参照、変更方法

8.1 仮想マシンIPアドレスを表示する方法(domifaddr)

serverのvnet0に設定されているIPアドレスを表示してみます。

[root@kvm ~]# virsh domifaddr server
 名前     MAC アドレス     Protocol     Address
-------------------------------------------------------------------------------
 vnet0      52:54:00:98:4d:5d    ipv4         192.168.122.55/24

8.2 インタフェース名等の取得方法(domiflist)

仮想マシンのインタフェースを確認してみます。実行中でもシャットオフ中の仮想マシンに対しても実行することができます。

[root@kvm ~]# virsh domiflist server
インターフェース 種類     ソース  モデル   MAC
-------------------------------------------------------
vnet0      network    default    virtio      52:54:00:98:4d:5d

8.3 統計情報の取得方法(domifstat)

domifstatは、統計情報を表示するオプションです。

[root@kvm ~]# virsh domifstat server --interface vnet0
vnet0 rx_bytes 99883
vnet0 rx_packets 1746
vnet0 rx_errs 0
vnet0 rx_drop 0
vnet0 tx_bytes 21596
vnet0 tx_packets 276
vnet0 tx_errs 0
vnet0 tx_drop 0

vnet0の状態を確認します。アップしていることがわかります。

[root@kvm ~]# virsh domif-getlink server --interface vnet0
vnet0 up

vnet0の状態を確認します。リンクアップしていることがわかります。

[root@kvm ~]# virsh domif-getlink server --interface vnet0
vnet0 up

serverのインタフェース(vnet0)をDOWNします。

[root@kvm ~]# virsh domif-setlink server vnet0 down
デバイスが正常に更新されました

インタフェースの状態を確認します。リンクダウンしていることがわかります。

[root@kvm ~]# virsh domif-getlink server --interface vnet0
vnet0 down

9 仮想マシンのインタフェース追加、削除方法

ここでは、仮想マシンにインタフェースの追加、削除の方法だけ説明します。追加したインタフェースにIPアドレスを設定し、仮想マシン同士で通信をするための環境作成手順は、仮想マシンにNICを追加する方法 - hana_shinのLinux技術ブログを参照してください。

9.1 事前準備

KVMホストに仮想ブリッジ(br1)を作成します。ifnameにはデバイス名、con-nameにはプロファイル名を指定します。プロファイルとは設定ファイルのことです。デバイスに設定したIPアドレスやデフォルトルータのIPアドレス等を定義したもので、/etc/sysconfig/network-scripts配下にいいいい作成されます。

[root@kvm ~]# nmcli connection add type bridge ifname br1 con-name br1-profile
接続 'br1-profile' (3bbbaf0a-9b0d-4b4c-9762-f1db0be5575b) が正常に追加されました。

バイスの状態を確認します。仮想ブリッジが追加されたことがわかります。ただし、この時点では、仮想ブリッジは、まだシステムに接続されていません。

[root@kvm ~]# nmcli device |grep br1
br1         bridge    接続中 (IP 設定を取得中)  br1-profile

作成した仮想ブリッジに、管理用のIPアドレスを設定します。

[root@kvm ~]# nmcli connection modify br1-profile ipv4.method manual ipv4.addresses "10.0.0.1/24"

仮想ブリッジをシステムに接続します。

[root@kvm ~]# nmcli device connect br1
デバイス 'br1' が '3bbbaf0a-9b0d-4b4c-9762-f1db0be5575b' で正常にアクティベートされました。

バイスの状態を確認します。仮想ブリッジがシステムに接続されたことがわかります。

[root@kvm ~]# nmcli device |grep br1
br1         bridge    接続済み  br1-profile

9.2 追加方法(attach-interface)

実行中の仮想マシンを確認します。これらの仮想マシンにインタフェースを追加していきます。

[root@kvm ~]# virsh list
 Id    名前                         状態
----------------------------------------------------
 1     server                         実行中
 2     router                         実行中

サーバにはインタフェースを2つ追加してみます。

[root@kvm ~]# virsh attach-interface --type bridge --source br1 --model e1000 server
インターフェースが正常に接続できました
[root@kvm ~]# virsh attach-interface --type bridge --source br1 --model e1000 server
インターフェースが正常に接続できました

サーバのインタフェースを確認します。vnet2とvnet3の2つのインタフェースが追加されたことがわかります。

[root@kvm ~]# virsh domiflist server
インターフェース 種類     ソース  モデル   MAC
-------------------------------------------------------
vnet0      network    default    virtio      52:54:00:98:4d:5d
vnet2      bridge     br1        e1000       52:54:00:4e:da:11
vnet3      bridge     br1        e1000       52:54:00:8c:68:92

次にルータにインタフェースを追加してみます。

[root@kvm ~]# virsh attach-interface --type bridge --source br1 --model e1000 router
インターフェースが正常に接続できました

ルータのインタフェースを確認します。vnet4が追加されたことがわかります。

[root@kvm ~]# virsh domiflist router
インターフェース 種類     ソース  モデル   MAC
-------------------------------------------------------
vnet1      network    default    virtio      52:54:00:09:62:b0
vnet4      bridge     br1        e1000       52:54:00:5a:d8:d1

brctlコマンドを使っても、仮想ブリッジに追加されたインタフェースを確認することができます。

[root@kvm ~]# brctl show br1
bridge name     bridge id               STP enabled     interfaces
br1             8000.fe54004eda11       no              vnet2
                                                        vnet3
                                                        vnet4

9.3 削除方法(detach-interface)

ルータのインタフェースを確認します。ルータからvnet4を削除します。

[root@kvm ~]# virsh domiflist router
インターフェース 種類     ソース  モデル   MAC
-------------------------------------------------------
vnet1      network    default    virtio      52:54:00:09:62:b0
vnet4      bridge     br1        e1000       52:54:00:5a:d8:d1

vnet4を削除します。

[root@kvm ~]# virsh detach-interface --type bridge --mac 52:54:00:5a:d8:d1 router
インターフェースが正常に切断されました

ルータのインタフェースを確認します。vnet4が削除されたことがわかります。

[root@kvm ~]# virsh domiflist router
インターフェース 種類     ソース  モデル   MAC
-------------------------------------------------------
vnet1      network    default    virtio      52:54:00:09:62:b0

同様に、ホストのvnet2とvnet4を削除します。

[root@kvm ~]#  virsh detach-interface --type bridge --mac 52:54:00:4e:da:11 server
インターフェースが正常に切断されました
[root@kvm ~]#  virsh detach-interface --type bridge --mac 52:54:00:8c:68:92 server
インターフェースが正常に切断されました

ブリッジのインタフェースを確認します。サーバ、ルータに接続していたインタフェースが削除されていることがわかります。

[root@kvm ~]# brctl show br1
bridge name     bridge id               STP enabled     interfaces
br1             8000.000000000000       no

Z 参考情報

私が業務や記事執筆で参考にした書籍を以下のページに記載します。
Linux技術のスキルアップをしよう! - hana_shinのLinux技術ブログ

cpulimitコマンドの使い方

1 cpulimitコマンドとは?

NICE値やスケジューリングポリシーを変更せず、プロセスのCPU使用率を制限することができるコマンドです。以下にGitHub - opsengine/cpulimit: CPU usage limiter for Linuxからの抜粋を示します。

Cpulimit is a tool which limits the CPU usage of a process (expressed in percentage, not in CPU time). 
It is useful to control batch jobs, when you don't want them to eat too many CPU cycles. 
The goal is prevent a process from running for more than a specified time ratio. 
It does not change the nice value or other scheduling priority settings, but the real CPU usage. 
Also, it is able to adapt itself to the overall system load, dynamically and quickly. 
The control of the used CPU amount is done sending SIGSTOP and SIGCONT POSIX signals to processes. 
All the children processes and threads of the specified process will share the same percentage of CPU.

2 検証環境

CentOS版数は以下のとおりです。

[root@server ~]# cat /etc/centos-release
CentOS Linux release 7.9.2009 (Core)

カーネル版数は以下のとおりです。

[root@server ~]# uname -r
3.10.0-1160.el7.x86_64

3 インストール方法

cpulimitパッケージは、epelリポジトリにあるので、まず、epel-releaseパッケージをインストールします。

[root@server ~]# yum -y install epel-release

次に、cpulimitパッケージをインストールします。

[root@server ~]# yum -y install cpulimit

4 オプション一覧

オプションは以下のとおりです。

[root@server ~]# cpulimit -h
Usage: cpulimit [OPTIONS...] TARGET
   OPTIONS
      -l, --limit=N          percentage of cpu allowed from 0 to 400 (required)
      -v, --verbose          show control statistics
      -z, --lazy             exit if there is no target process, or if it dies
      -i, --include-children limit also the children processes
      -h, --help             display this help and exit
   TARGET must be exactly one of these:
      -p, --pid=N            pid of the process (implies -z)
      -e, --exe=FILE         name of the executable program file or path name
      COMMAND [ARGS]         run this command and limit it (implies -z)

Report bugs to <marlonx80@hotmail.com>.

5 CPU使用率の制限方法

stress-ngコマンドを使って、CPU使用率が10%のプロセスを1つ生成します。
なお、stress-ngコマンドのインストール方法、使い方は、stress-ngコマンドの使い方 - hana_shinのLinux技術ブログを参照してください。

[root@server ~]# stress-ng -k -c 1 -l 10 -q &
[1] 1527

プロセスの状態を確認します。親プロセス(PID1527)はwaitシステムコールを実行して、子プロセス(PID1528)の終了を待っています。そのため、CPU使用率が0%であることがわかります。なお、do_wait関数は、waitシステムコールの延長で呼び出すカーネル関数です。一方、子プロセスはCPU使用率が約12%であることがわかります。なお、psコマンドの使い方は、psコマンドの使い方 - hana_shinのLinux技術ブログを参照してください。

[root@server ~]# ps -C stress-ng -o comm,pid,ppid,%cpu,wchan
COMMAND           PID  PPID %CPU WCHAN
stress-ng        1527  1114  0.0 do_wait
stress-ng        1528  1527 11.7 -

cpulimitコマンドを使って、子プロセスのCPU使用率を5%に制限してみます。

[root@server ~]# cpulimit -p 1528 -l 5
Process 1528 found

もう1つターミナルを開いて、CPU使用率を確認します。指定したCPU使用率にすぐになるのではなく、徐々に指定したCPU使用率に下がっていくのがわかります。

[root@server ~]# ps -C stress-ng -o comm,pid,ppid,%cpu
COMMAND           PID  PPID %CPU
stress-ng        1527  1114  0.0
stress-ng        1528  1527  8.6

CPU使用率を確認します。私の環境では、10分程度経過したあと、子プロセスのCPU使用率が約5%になりました。

[root@server ~]# ps -C stress-ng -o comm,pid,ppid,%cpu
COMMAND           PID  PPID %CPU
stress-ng        1527  1114  0.0
stress-ng        1528  1527  4.9

Z 参考情報

私が業務や記事執筆で参考にした書籍を以下のページに記載します。
Linux技術のスキルアップをしよう! - hana_shinのLinux技術ブログ

MariaDBの使い方

1 MariaDBとは?

MySQLの派生として開発されている、オープンソース関係データベース管理システム (RDBMS) です。

2 環境

CentOS版数は以下のとおりです。

[root@server ~]# cat /etc/centos-release
CentOS Linux release 7.9.2009 (Core)

カーネル版数は以下のとおりです。

[root@server ~]# uname -r
3.10.0-1160.el7.x86_64

3 パッケージのインストール

下記公式ページの説明にしたがって、パッケージをインストールします。
https://mariadb.com/kb/en/yum/

下記コマンドを実行してyum レポジトリを設定します。

[root@server ~]# curl -sS https://downloads.mariadb.com/MariaDB/mariadb_repo_setup | sudo bash
# [info] Checking for script prerequisites.
# [warning] Found existing file at /etc/yum.repos.d/mariadb.repo. Moving to /etc/yum.repos.d/mariadb.repo.old_1
# [info] MariaDB Server version 10.7 is valid
# [info] Repository file successfully written to /etc/yum.repos.d/mariadb.repo
# [info] Adding trusted package signing keys...
/etc/pki/rpm-gpg ~
~
# [info] Successfully added trusted package signing keys
# [info] Cleaning package cache...
読み込んだプラグイン:fastestmirror
リポジトリーを清掃しています: base epel extras mariadb-main mariadb-maxscale mariadb-tools updates
Other repos take up 531 M of disk space (use --verbose for details)

追加されたリポジトリを確認します。mariadb-main,mariadb-maxscale,mariadb-toolsの3つのリポジトリが追加されたことがわかります。

[root@server ~]# cat /etc/yum.repos.d/mariadb.repo

[mariadb-main]
name = MariaDB Server
baseurl = https://dlm.mariadb.com/repo/mariadb-server/10.7/yum/rhel/7/x86_64
gpgkey = file:///etc/pki/rpm-gpg/MariaDB-Server-GPG-KEY
gpgcheck = 1
enabled = 1

[mariadb-maxscale]
# To use the latest stable release of MaxScale, use "latest" as the version
# To use the latest beta (or stable if no current beta) release of MaxScale, use "beta" as the version
name = MariaDB MaxScale
baseurl = https://dlm.mariadb.com/repo/maxscale/latest/yum/rhel/7/x86_64
gpgkey = file:///etc/pki/rpm-gpg/MariaDB-MaxScale-GPG-KEY
gpgcheck = 1
enabled = 1

[mariadb-tools]
name = MariaDB Tools
baseurl = https://downloads.mariadb.com/Tools/rhel/7/x86_64
gpgkey = file:///etc/pki/rpm-gpg/MariaDB-Enterprise-GPG-KEY
gpgcheck = 1
enabled = 1
[root@server ~]#

リポジトリを追加したので、MariaDB-serverパッケージをインストールします。

[root@server ~]# yum -y install MariaDB-server

MariaDBの版数を確認します。

[root@server ~]# mariadb -V
mariadb  Ver 15.1 Distrib 10.7.4-MariaDB, for Linux (x86_64) using readline 5.1

4 mariadbサービスの起動方法

mariadbサービスを起動します。

[root@server ~]# systemctl start mariadb.service

mariadbサービスの状態を確認します。activeであることがわかります。

[root@server ~]# systemctl status mariadb.service
● mariadb.service - MariaDB 10.7.4 database server
   Loaded: loaded (/usr/lib/systemd/system/mariadb.service; disabled; vendor preset: disabled)
  Drop-In: /etc/systemd/system/mariadb.service.d
           mqmigrated-from-my.cnf-settings.conf
   Active: active (running) since 金 2022-06-10 20:03:01 JST; 52s ago
     Docs: man:mariadbd(8)
           https://mariadb.com/kb/en/library/systemd/
  Process: 1532 ExecStartPost=/bin/sh -c systemctl unset-environment _WSREP_START_POSITION (code=exited, status=0/SUCCESS)
  Process: 1504 ExecStartPre=/bin/sh -c [ ! -e /usr/bin/galera_recovery ] && VAR= ||   VAR=`cd /usr/bin/..; /usr/bin/galera_recovery`; [ $? -eq 0 ]   && systemctl set-environment _WSREP_START_POSITION=$VAR || exit 1 (code=exited, status=0/SUCCESS)
  Process: 1501 ExecStartPre=/bin/sh -c systemctl unset-environment _WSREP_START_POSITION (code=exited, status=0/SUCCESS)
 Main PID: 1515 (mariadbd)
   Status: "Taking your SQL requests now..."
   CGroup: /system.slice/mariadb.service
           mq1515 /usr/sbin/mariadbd

 6月 10 20:03:01 server mariadbd[1515]: 2022-06-10 20:03:01 0 [Note] InnoDB: File './ibtmp1' size is now 12 MB.
 6月 10 20:03:01 server mariadbd[1515]: 2022-06-10 20:03:01 0 [Note] InnoDB: 10.7.4 started; log sequence number 42219; transaction id 14
 6月 10 20:03:01 server mariadbd[1515]: 2022-06-10 20:03:01 0 [Note] InnoDB: Loading buffer pool(s) from /var/lib/mysql/ib_buffer_pool
 6月 10 20:03:01 server mariadbd[1515]: 2022-06-10 20:03:01 0 [Note] Plugin 'FEEDBACK' is disabled.
 6月 10 20:03:01 server mariadbd[1515]: 2022-06-10 20:03:01 0 [Note] InnoDB: Buffer pool(s) load completed at 220610 20:03:01
 6月 10 20:03:01 server mariadbd[1515]: 2022-06-10 20:03:01 0 [Note] Server socket created on IP: '0.0.0.0'.
 6月 10 20:03:01 server mariadbd[1515]: 2022-06-10 20:03:01 0 [Note] Server socket created on IP: '::'.
 6月 10 20:03:01 server mariadbd[1515]: 2022-06-10 20:03:01 0 [Note] /usr/sbin/mariadbd: ready for connections.
 6月 10 20:03:01 server mariadbd[1515]: Version: '10.7.4-MariaDB'  socket: '/var/lib/mysql/mysql.sock'  port: 3306  MariaDB Server
 6月 10 20:03:01 server systemd[1]: Started MariaDB 10.7.4 database server.

5 事前準備

5.1 文字コード設定

/etc/my.cnf.d/server.cnfにcharacter-set-server=utf8を追加します。

[root@server ~]# diff -Nur /etc/my.cnf.d/server.cnf.org /etc/my.cnf.d/server.cnf
--- /etc/my.cnf.d/server.cnf.org        2022-06-10 21:52:08.090551505 +0900
+++ /etc/my.cnf.d/server.cnf    2022-06-10 21:52:24.831679371 +0900
@@ -38,6 +38,7 @@
 # If you use the same .cnf file for MySQL and MariaDB,
 # you can put MariaDB-only options here
 [mariadb]
+character-set-server=utf8

 # This group is only read by MariaDB-10.7 servers.
 # If you use the same .cnf file for MariaDB of different versions,

5.2 管理者の登録

mariadb管理者のパスワードを設定します。ここでは、管理者パスワードとしてadminを設定します。

[root@server ~]# mysqladmin -u root password 'admin'

6 データベースの作成、削除方法

mysqlモニタを起動します。パスワードは、先ほど設定したadminを入力します。

[root@server ~]# mysql -u root -p
Enter password:
-snip-

6.1 データベースの作成方法

デフォルトの状態を確認します。デフォルトでは、下記5つのデータベースが登録されていることがわかります。

MariaDB [(none)]> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| test               |
+--------------------+
5 rows in set (0.001 sec)

testdbという名前のデータベースを作成します。

MariaDB [(none)]> create database testdb;
Query OK, 1 row affected (0.001 sec)

作成したデータベースを確認します。testdbが作成されたことがわかります。

MariaDB [(none)]> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| test               |
| testdb             |
+--------------------+
6 rows in set (0.001 sec)

6.2 データベースの削除方法

testdbを削除します。

MariaDB [(none)]> drop database testdb;
Query OK, 0 rows affected (0.046 sec)

データベースを確認します。testdbが削除されたことがわかります。

MariaDB [(none)]> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| test               |
+--------------------+
5 rows in set (0.001 sec)

7 テーブルに対する操作

testdbデータベースにcustomerテーブルを作成してみます。
まず、testdbという名前のデータベースを作成します。

MariaDB [(none)]> create database testdb;
Query OK, 1 row affected (0.001 sec)

使用するデータベースをtestdbに切り替えます。

MariaDB [(none)]> use testdb
Database changed

statusコマンドを使って、現在使用しているデータベースを確認します。Current databaseがtestdbになっていることがわかります。また、MariaDBのプロンプトがnoneからtestdbに変更されたことからも、
データベースがtestdbに変更されたことがわかります。

MariaDB [testdb]> status;
--------------
mysql  Ver 15.1 Distrib 10.7.4-MariaDB, for Linux (x86_64) using readline 5.1

Connection id:          4
Current database:       testdb
Current user:           root@localhost
SSL:                    Not in use
Current pager:          stdout
Using outfile:          ''
Using delimiter:        ;
Server:                 MariaDB
Server version:         10.7.4-MariaDB MariaDB Server
Protocol version:       10
Connection:             Localhost via UNIX socket
Server characterset:    utf8mb3
Db     characterset:    latin1
Client characterset:    utf8mb3
Conn.  characterset:    utf8mb3
UNIX socket:            /var/lib/mysql/mysql.sock
Uptime:                 2 min 20 sec

Threads: 1  Questions: 22  Slow queries: 0  Opens: 17  Open tables: 10  Queries per second avg: 0.157
--------------

7.1 テーブルの作成方法(create)

testdbデータベースにcustomerテーブルを作成します。customerテーブルは、名前(name)と年齢(age)のカラムを指定して作成します。

MariaDB [testdb]> create table customer (name varchar(32), age tinyint unsigned);
Query OK, 0 rows affected (0.066 sec)

テーブルを確認します。customerという名前のテーブルが作成されたことがわかります。

MariaDB [testdb]> show tables;
+------------------+
| Tables_in_testdb |
+------------------+
| customer         |
+------------------+
1 row in set (0.000 sec)

7.2 カラム情報を取得する方法

customerテーブルのカラム情報を取得します。名前(name)と年齢(age)のカラムを確認することができます。

MariaDB [testdb]> show columns from customer;
+-------+---------------------+------+-----+---------+-------+
| Field | Type                | Null | Key | Default | Extra |
+-------+---------------------+------+-----+---------+-------+
| name  | varchar(32)         | YES  |     | NULL    |       |
| age   | tinyint(3) unsigned | YES  |     | NULL    |       |
+-------+---------------------+------+-----+---------+-------+
2 rows in set (0.002 sec)

7.3 テーブルの削除方法(drop)

testdbデータベースからcustomerテーブルを削除します。

MariaDB [testdb]> drop table customer;
Query OK, 0 rows affected (0.034 sec)

customerテーブルが削除されたことがわかります。

MariaDB [testdb]> show tables;
Empty set (0.000 sec)

7.4 テーブルの名前を変更する方法(alter)

customerという名前のテーブルをcustomer_newに変更します。

MariaDB [testdb]> alter table customer rename customer_new;
Query OK, 0 rows affected (0.020 sec)

テーブルの名前を確認します。テーブルの名前が、customer_newに変更されたことがわかります。

MariaDB [testdb]> show tables;
+------------------+
| Tables_in_testdb |
+------------------+
| customer_new     |
+------------------+
1 row in set (0.001 sec)

テーブルの名前をcustomerに戻します。

MariaDB [testdb]> alter table customer_new rename customer;
Query OK, 0 rows affected (0.018 sec)

7.5 データを登録する方法(insert)

customerテーブルに名前(suzuki-san)と年齢(40)を登録します。

MariaDB [testdb]> insert into customer values("suzuki-san",40);
Query OK, 1 row affected (0.004 sec)

テーブルを確認します。customerテーブルに名前(name)と年齢(age)が登録されたことがわかります。

MariaDB [testdb]> select name,age from customer;
+------------+------+
| name       | age  |
+------------+------+
| suzuki-san |   40 |
+------------+------+
1 row in set (0.000 sec)

7.6 データを更新する方法(update)

suzuki-sanの年齢を40歳から30歳に変更してみます。

MariaDB [testdb]> update customer set age=30 where age=40;
Query OK, 1 row affected (0.003 sec)
Rows matched: 1  Changed: 1  Warnings: 0

データを確認します。suzuki-sanの年齢が40歳から30歳に変更されたことがわかります。

MariaDB [testdb]> select name,age from customer;
+------------+------+
| name       | age  |
+------------+------+
| suzuki-san |   30 |
+------------+------+
1 row in set (0.000 sec)

7.7 データを削除する方法(delete,where)

MariaDB [testdb]> delete from customer where name='suzuki-san';
Query OK, 1 row affected (0.004 sec)
MariaDB [testdb]> select name,age from customer;
Empty set (0.000 sec)

7.8 データを一括削除する方法(delete)

testdbに登録されているデータを確認します。

MariaDB [testdb]> select name,age from customer;
+------------+------+
| name       | age  |
+------------+------+
| suzuki-san |   40 |
| kato-san   |   45 |
+------------+------+
2 rows in set (0.000 sec)

テーブルからデータを一括削除します。

MariaDB [testdb]> delete from customer;
Query OK, 2 rows affected (0.003 sec)

テーブルを確認します。データが削除されたことがわかります。

MariaDB [testdb]> select name,age from customer;
Empty set (0.000 sec)

7.9 カラムの追加方法(alter table add)

既存のカラム(name,age)に対して、住所(addres)のカラムを追加してみます。

MariaDB [testdb]> select name,age from customer;
+------------+------+
| name       | age  |
+------------+------+
| suzuki-san |   40 |
| kato-san   |   45 |
+------------+------+
2 rows in set (0.000 sec)

customerテーブルに住所(addres)カラムを追加してみます。

MariaDB [testdb]> alter table customer add address varchar(32);
Query OK, 0 rows affected (0.067 sec)
Records: 0  Duplicates: 0  Warnings: 0

customerテーブルを確認します。住所(address)カラムが追加されたことがわかります。

MariaDB [testdb]> show columns from customer;
+---------+---------------------+------+-----+---------+-------+
| Field   | Type                | Null | Key | Default | Extra |
+---------+---------------------+------+-----+---------+-------+
| name    | varchar(32)         | YES  |     | NULL    |       |
| age     | tinyint(3) unsigned | YES  |     | NULL    |       |
| address | varchar(32)         | YES  |     | NULL    |       |
+---------+---------------------+------+-----+---------+-------+
3 rows in set (0.001 sec)

7.10 カラムの削除方法(alter table drop)

customerテーブルのカラムを確認します。name,age,addressの3つのカラムが存在することがわかります。

MariaDB [testdb]> select name,age,address from customer;
+------------+------+---------+
| name       | age  | address |
+------------+------+---------+
| suzuki-san |   40 | NULL    |
| kato-san   |   45 | NULL    |
+------------+------+---------+
2 rows in set (0.000 sec)

customerテーブルからaddressカラムを削除します。

MariaDB [testdb]> alter table customer drop column address;
Query OK, 0 rows affected (0.036 sec)
Records: 0  Duplicates: 0  Warnings: 0

customerテーブルのカラムを確認します。addressカラムが削除されたことがわかります。

MariaDB [testdb]> show columns from customer;
+-------+---------------------+------+-----+---------+-------+
| Field | Type                | Null | Key | Default | Extra |
+-------+---------------------+------+-----+---------+-------+
| name  | varchar(32)         | YES  |     | NULL    |       |
| age   | tinyint(3) unsigned | YES  |     | NULL    |       |
+-------+---------------------+------+-----+---------+-------+
2 rows in set (0.002 sec)

8 条件に一致するレコードを表示する方法

8.1 事前準備

testdbデータベース内にテーブルが存在しないことを確認します。

MariaDB [testdb]> show tables;
Empty set (0.000 sec)

testdbデータベース内にテスト用のcustomerテーブルを作成します。

MariaDB [testdb]> create table customer (name varchar(32), age tinyint unsigned, address varchar(32));

作成したcustomerテーブルにデータを登録します。

MariaDB [testdb]> insert into customer values("suzuki-san", 40, "tokyo");
MariaDB [testdb]> insert into customer values("kato-san", 30, "osaka");
MariaDB [testdb]> insert into customer values("tanaka-san", 20, "aichi");
MariaDB [testdb]> insert into customer values("ito-san", 10, "tokyo");

作成したテーブルを確認します。

MariaDB [testdb]> select * from customer;
+------------+------+---------+
| name       | age  | address |
+------------+------+---------+
| suzuki-san |   40 | tokyo   |
| kato-san   |   30 | osaka   |
| tanaka-san |   20 | aichi   |
| ito-san    |   10 | tokyo   |
+------------+------+---------+
4 rows in set (0.000 sec)

8.2 特定の条件に一致するレコードの取り出し方法(where)

customerテーブルから年齢が30歳のレコードを取り出します。年齢が30歳の人はkato-sanであることがわかります。

MariaDB [testdb]> select * from customer where age=30;
+----------+------+---------+
| name     | age  | address |
+----------+------+---------+
| kato-san |   30 | osaka   |
+----------+------+---------+
1 row in set (0.001 sec)

次は、年齢が30歳以上のレコードを取り出します

MariaDB [testdb]> select * from customer where age>=30;
+------------+------+---------+
| name       | age  | address |
+------------+------+---------+
| suzuki-san |   40 | tokyo   |
| kato-san   |   30 | osaka   |
+------------+------+---------+
2 rows in set (0.001 sec)

次は、住所がtokyoのレコードを取り出します。tokyoの人はsuzuki-sanとito-sanであることがわかります。

MariaDB [testdb]> select * from customer where address='tokyo';
+------------+------+---------+
| name       | age  | address |
+------------+------+---------+
| suzuki-san |   40 | tokyo   |
| ito-san    |   10 | tokyo   |
+------------+------+---------+
2 rows in set (0.001 sec)

最後に、住所がtokyoに一致しないレコードを取り出してみます。tokyo以外の人はkato-sanとtanaka-sanであることがわかります。

MariaDB [testdb]> select * from customer where not address='tokyo';
+------------+------+---------+
| name       | age  | address |
+------------+------+---------+
| kato-san   |   30 | osaka   |
| tanaka-san |   20 | aichi   |
+------------+------+---------+
2 rows in set (0.000 sec)

9 データベースを利用するユーザの登録、削除方法

セキュリティの観点から管理者権限でデータベースを利用するべきではありません。ここでは、データベースを利用するユーザの登録、削除を行います。

9.1 ユーザの登録方法

管理者権限でモニタにログインします。

[root@server ~]# mysql -u root -p
Enter password:
-snip-

localhostからのみデータベースに利用可能なユーザ(apache)を登録します。apacheのパスワードは11111に設定します。

MariaDB [(none)]> create user apache@localhost identified by '11111';
Query OK, 0 rows affected (0.009 sec)

登録されているユーザを確認します。apacheが登録されたことがわかります。

MariaDB [(none)]> select host,user from mysql.user;
+-----------+-------------+
| Host      | User        |
+-----------+-------------+
| localhost |             |
| localhost | apache      |
| localhost | mariadb.sys |
| localhost | mysql       |
| localhost | root        |
| server    |             |
+-----------+-------------+
6 rows in set (0.005 sec)

9.2 ユーザの削除方法

登録したユーザ(apache)を削除してみます。

MariaDB [(none)]> drop user apache@localhost;
Query OK, 0 rows affected (0.004 sec)

ユーザを確認してみます。apacheが削除されたことがわかります。

MariaDB	[(none)]>	select	host,user	from	mysql.user;
+-----------+-------------+
|	Host	|	User	|
+-----------+-------------+
|	localhost	|	|
|	localhost	|	mariadb.sys	|
|	localhost	|	mysql	|
|	localhost	|	root	|
|	server	|	|
+-----------+-------------+
5	rows	in	set	(0.001	sec)

10 ユーザ権限の設定、削除する方法

10.1 権限の種類

ユーザ権限には、次のようなものがあります。一部を抜粋

権限 内容
ALL 全ての権限を表す。管理者のみがもつことが望ましい
CREATE CREATEコマンドを発行する権限
ALTER ALTERコマンドを発行する権限
DELETE DELETEコマンドを発行する権限
INSERT INSERTコマンドを発行する権限
SELECT SELECTコマンドを発行する権限
UPDATE UPDATEコマンドを発行する権限

10.2 事前準備

管理者権限でモニタを起動します。

[root@server ~]# mysql -u root -p
Enter password:
-snip-

使用するデータベースをtestdbに切り替えます。

MariaDB [(none)]> use testdb;

2つのテーブル(customer1,customer2)を作成します。

MariaDB [testdb]> create table customer1 (name varchar(32), age tinyint unsigned);
MariaDB [testdb]> create table customer2 (name varchar(32), age tinyint unsigned);

作成したテーブルを確認します。

MariaDB [testdb]> show tables;
+------------------+
| Tables_in_testdb |
+------------------+
| customer1        |
| customer2        |
+------------------+
2 rows in set (0.000 sec)

localhost内からのみ接続可能なユーザ(apache)を作成します。ユーザのパスワードは11111を設定します。

MariaDB [testdb]> create user apache@localhost identified by '11111';
Query OK, 0 rows affected (0.004 sec)

10.3 権限を付与する方法(grant)

apacheユーザにselectコマンド実行の権限を付与します。

MariaDB [testdb]> grant select on customer1 to apache@localhost identified by '11111';
Query OK, 0 rows affected (0.006 sec)

apacheユーザに与えられている権限を確認します。

MariaDB [testdb]> show grants for apache@localhost;
+---------------------------------------------------------------------------------------------------------------+
| Grants for apache@localhost                                                                                   |
+---------------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO `apache`@`localhost` IDENTIFIED BY PASSWORD '*58D24DFDC5B5D55D6F6A25496AB51B74AA0FF7C9' |
| GRANT SELECT ON `testdb`.`customer1` TO `apache`@`localhost`                                                  |
+---------------------------------------------------------------------------------------------------------------+
2 rows in set (0.000 sec)

apacheユーザでモニタを起動します。パスワードは11111を入力します。

[root@server ~]# mysql -u apache -p
Enter password:
-snip-

使用するデータベースをtestdbに切り替えます。

MariaDB [(none)]> use testdb;

customer1テーブルにselectコマンドを実行すると、正常終了することがわかります。

MariaDB [testdb]> select * from customer1;
Empty set (0.000 sec)

customer2テーブルにselectコマンドを実行すると、異常終了することがわかります。

MariaDB [testdb]> select * from customer2;
ERROR 1142 (42000): SELECT command denied to user 'apache'@'localhost' for table 'customer2'

10.4 権限を削除する方法(revoke)

管理者権限でモニタを起動します。

[root@server ~]# mysql -u root -p
Enter password:
-snip-

使用するデータベースをtestdbに切り替えます。

MariaDB [(none)]> use testdb;

apacheユーザのSELECTコマンド使用の権限を削除します。

MariaDB [testdb]> revoke select on customer1 from apache@localhost;
Query OK, 0 rows affected (0.003 sec)
MariaDB [testdb]> show grants for apache@localhost;
+---------------------------------------------------------------------------------------------------------------+
| Grants for apache@localhost                                                                                   |
+---------------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO `apache`@`localhost` IDENTIFIED BY PASSWORD '*58D24DFDC5B5D55D6F6A25496AB51B74AA0FF7C9' |
+---------------------------------------------------------------------------------------------------------------+
1 row in set (0.000 sec)

11 AUTO_INCREMENTの使い方

AUTO_INCREMENTとは,それを指定したカラムに対してMySQLが自動的に一意のシーケンス番号を生成する機能です。

まず、shopというテーブルを作成します。

MariaDB [testdb]> create table shop(id int unsigned auto_increment not null, pref varchar(32), name varchar(32), address varchar(256), primary key(id));
Query OK, 0 rows affected (0.036 sec)

作成したテーブルを確認します。

MariaDB [testdb]> show columns from shop;
+---------+------------------+------+-----+---------+----------------+
| Field   | Type             | Null | Key | Default | Extra          |
+---------+------------------+------+-----+---------+----------------+
| id      | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| pref    | varchar(32)      | YES  |     | NULL    |                |
| name    | varchar(32)      | YES  |     | NULL    |                |
| address | varchar(256)     | YES  |     | NULL    |                |
+---------+------------------+------+-----+---------+----------------+
4 rows in set (0.002 sec)

作成したテーブルにデータを設定します。このとき、auto_incrementを設定するカラムには、nullを設定します。

MariaDB [testdb]> insert into shop values(null,"東京","洋包丁","東京都新宿区高田馬場3丁目1");
MariaDB [testdb]> insert into shop values(null,"東京","リンガーハット","東京都町田市木曽東3-8-24");
MariaDB [testdb]> insert into shop values(null,"神奈川","たまい本店","神奈川県川崎市高津区溝口1丁目
MariaDB [testdb]> insert into shop values(null,"香川","郷家","香川県高松市瓦町2丁目10-12");

登録したデータを確認します。idの部分に1,2,3,4が設定されていることがわかります。

MariaDB [testdb]> select * from shop;
+----+-----------+-----------------------+--------------------------------------------------+
| id | pref      | name                  | address                                          |
+----+-----------+-----------------------+--------------------------------------------------+
|  1 | 東京      | 洋包丁                | 東京都新宿区高田馬場3丁目1                       |
|  2 | 東京      | リンガーハット        | 東京都町田市木曽東3-8-24                         |
|  3 | 神奈川    | たまい本店            | 神奈川県川崎市高津区溝口1丁目11-22               |
|  4 | 香川      | 郷家                  | 香川県高松市瓦町2丁目10-12                       |
+----+-----------+-----------------------+--------------------------------------------------+
4 rows in set (0.000 sec)

Z 参考情報

私が業務や記事執筆で参考にした書籍を以下のページに記載します。
Linux技術のスキルアップをしよう! - hana_shinのLinux技術ブログ

ファイルシステムコマンドの使い方

1 はじめに

ext4,xfsファイルシステムで使用するコマンドの概要についてまとめました。お手軽に試すため、ループバックデバイスを使って、コマンドの使い方を確認してみます。

2 環境

CentOS版数は以下のとおりです。

[root@server ~]# cat /etc/centos-release
CentOS Linux release 7.9.2009 (Core)

カーネル版数は以下のとおりです。

[root@server ~]# uname -r
3.10.0-1160.el7.x86_64

3 コマンド一覧

xt4,xfsファイルシステムで使用するコマンドを以下に示します。

ファイルシステムに対する操作 ext4 xfs
ファイルシステムの作成 mke2fs,mkfs -t ext4 mkfs.xfs
ファイルシステムのパラメータ表示 dumpe2fs xfs_info
ファイルシステムのパラメータ変更 tune2fs xfs_admin
ファイルシステムのラベル表示,変更 e2label xfs_admin
ファイルシステムのエラーチェック,修復 fsck.ext4,e2fsck xfs_repair,fsck.xfs
ファイルシステムデバッグ debugfs xfs_db
ファイルシステムへのアクセス禁止,解除 fsfreeze xfs_freeze,fsfreeze
ファイルシステムデフラグ e4defrag xfs_fsr
ファイル断片化の確認 filefrag xfs_bmap

4 ext4ファイルシステム

4.1 事前準備(デバイスの作成)

ループバックデバイスで使用するファイル(100M)を作成します。なお、ファイルの作り方は、ファイルの作り方 - hana_shinのLinux技術ブログを参照してください。

[root@server ~]# fallocate -l 100M disk.img

作成したファイルを確認します。

[root@server ~]# ls -l disk.img
-rw-r--r--. 1 root root 104857600  6月  7 19:25 disk.img

作成したファイルをループバックデバイスとして登録します。なお、losetupコマンドの使い方は、losetupコマンドの使い方 - hana_shinのLinux技術ブログを参照してください。

[root@server ~]# losetup -f /root/disk.img

登録したループバックデバイスを確認します。

[root@server ~]# losetup -l
NAME       SIZELIMIT OFFSET AUTOCLEAR RO BACK-FILE
/dev/loop0         0      0         0  0 /root/disk.img

4.2 ファイルシステム作成(mke2fs)

ループバックデバイス(/dev/loop0)にext4ファイルシステムを作成します。

[root@server ~]# mke2fs -t ext4 /dev/loop0
mke2fs 1.42.9 (28-Dec-2013)
Discarding device blocks: done
Filesystem label=
OS type: Linux
Block size=1024 (log=0)
Fragment size=1024 (log=0)
Stride=0 blocks, Stripe width=0 blocks
25688 inodes, 102400 blocks
5120 blocks (5.00%) reserved for the super user
First data block=1
Maximum filesystem blocks=33685504
13 block groups
8192 blocks per group, 8192 fragments per group
1976 inodes per group
Superblock backups stored on blocks:
        8193, 24577, 40961, 57345, 73729

Allocating group tables: done
Writing inode tables: done
Creating journal (4096 blocks): done
Writing superblocks and filesystem accounting information: done

ループバックデバイスに作成したファイルシステムを確認します。ext4ファイルシステムが作成されたことがわかります。

[root@server ~]# lsblk -fip /dev/loop0
NAME       FSTYPE LABEL UUID                                 MOUNTPOINT
/dev/loop0 ext4         fb485f39-6486-41f6-801a-f1a00fff3f06

作成したループバックデバイスを/mntにマウントします。

[root@server ~]# mount -o loop /dev/loop0 /mnt

ファイルシステムを確認します。ループバックデバイスが/mntにマウントされていることがわかります。

[root@server ~]# df -hT -t ext4
ファイルシス   タイプ サイズ  使用  残り 使用% マウント位置
/dev/loop1     ext4      93M  1.6M   85M    2% /mnt

4.3 パラメータ表示/変更(dumpe2fs/tune2fs)

ファイルシステムのチェック回数を変更してみます。マウント回数が、チェック回数を超えると、次回ブート時にファイルシステムfsckを行います。

ファイルシステム作成直後は、チェック回数が-1になっています。

[root@server ~]# dumpe2fs -h /dev/loop0 |grep "Maximum mount count"
dumpe2fs 1.42.9 (28-Dec-2013)
Maximum mount count:      -1

チェック回数を5に設定してみます。

[root@server ~]# tune2fs -c 5 /dev/loop0
tune2fs 1.42.9 (28-Dec-2013)
Setting maximal mount count to 5

チェック回数が5に設定されたことがわかります。

[root@server ~]# dumpe2fs -h /dev/loop0 |grep "Maximum mount count"
dumpe2fs 1.42.9 (28-Dec-2013)
Maximum mount count:      5

4.4 ラベルの表示/設定(e2label)

ファイルシステムのラベルを変更してみます。初期状態を確認します。ラベルが何も設定されていないことがわかります。

[root@server ~]# e2label /dev/loop0

ラベルを確認します。TESTという名前のラベルが設定されたことがわかります。

[root@server ~]# e2label /dev/loop0 TEST

ラベルを確認します。TESTという名前のラベルが設定されたことがわかります。

[root@server ~]# e2label /dev/loop0
TEST

他のコマンドでも、ラベルの確認ができます
dumpe2fsコマンドで確認してみます。

[root@server ~]# dumpe2fs -h /dev/loop0 |grep "Filesystem volume name"
dumpe2fs 1.42.9 (28-Dec-2013)
Filesystem volume name:   TEST

lsblkコマンドで確認してみます。lsblkコマンドの使い方は、lsblkコマンドの使い方 - hana_shinのLinux技術ブログを参照してください。

[root@server ~]# lsblk -fip /dev/loop0
NAME       FSTYPE LABEL UUID                                 MOUNTPOINT
/dev/loop0 ext4   TEST  fb485f39-6486-41f6-801a-f1a00fff3f06

blkidコマンドで確認してみます。

[root@server ~]# blkid /dev/loop0
/dev/loop0: LABEL="TEST" UUID="fb485f39-6486-41f6-801a-f1a00fff3f06" TYPE="ext4"

4.5 エラーチェック(fsck.ext4)

[root@server ~]# fsck.ext4 /dev/loop0
e2fsck 1.42.9 (28-Dec-2013)
TEST: recovering journal
TEST: clean, 11/25688 files, 8896/102400 blocks (check in 4 mounts)

4.6 デバッグ(debugfs)

debugfsコマンドを実行します。

[root@server ~]# debugfs /dev/loop0
debugfs 1.42.9 (28-Dec-2013)
debugfs:

コマンドプロンプトに対してhelpと入力すると、オプションが表示されます。

[root@server ~]# debugfs /dev/loop0
debugfs 1.42.9 (28-Dec-2013)
debugfs:  help
Available debugfs requests:

show_debugfs_params, params
                         Show debugfs parameters
open_filesys, open       Open a filesystem
close_filesys, close     Close the filesystem
-snip-

4.7 アクセス禁止/解除(fsfreeze)

/mntへのアクセス禁止/解除を試してみます。

[root@server ~]# df -hT -t ext4
ファイルシス   タイプ サイズ  使用  残り 使用% マウント位置
/dev/loop1     ext4      93M  1.6M   85M    2% /mnt

/mntへのアクセスを禁止にします。

[root@server ~]# fsfreeze -f /mnt

アクセス禁止にしたファイルシステムにファイルを作成します。アクセス禁止になっているため、touchコマンドが復帰しません。

[root@server ~]# touch /mnt/test.txt

もう1つターミナルを開きます。新しく開いたターミナルで/mntへのアクセス禁止を解除します。

[root@server ~]# fsfreeze -u /mnt

アクセス禁止を解除するとtouchコマンドが復帰します。

[root@server ~]# touch /mnt/test.txt
[root@server ~]#

touchコマンドが復帰したら、作成したファイルを確認します。

[root@server ~]# ls /mnt/test.txt
/mnt/test.txt

4.8 断片化の状況確認/デフラグ(e4defrag)

[root@server ~]# fallocate -l 80M /mnt/test.dat
[root@server ~]# e4defrag -c /mnt
<Fragmented files>                             now/best       size/ext
1. /mnt/test.dat                                 8/1          10240 KB

 Total/best extents                             8/1
 Average size per extent                        10240 KB
 Fragmentation score                            0
 [0-30 no problem: 31-55 a little bit fragmented: 56- needs defrag]
 This directory (/mnt) does not need defragmentation.
 Done.

デフラグを実行してみます。デフラグをするには、オプションなしでe4defragコマンドを実行します。

[root@server ~]# e4defrag /mnt
ext4 defragmentation for directory(/mnt)

        Success:                        [ 0/4 ]
        Failure:                        [ 4/4 ]

4.9 ファイル断片化の確認(filefrag)

ファイルの各部分がファイルシステム内のどのブロックにマッピングされているかがわかります

[root@server ~]# filefrag -v /mnt/test.dat
Filesystem type is: ef53
File size of /mnt/test.dat is 83886080 (81920 blocks of 1024 bytes)
 ext:     logical_offset:        physical_offset: length:   expected: flags:
   0:        0..   14335:      10241..     24576:  14336:             unwritten
   1:    14336..   28671:      26625..     40960:  14336:      24577: unwritten
   2:    28672..   34815:      43009..     49152:   6144:      40961: unwritten
   3:    34816..   38911:      53249..     57344:   4096:      49153: unwritten
   4:    38912..   53247:      59393..     73728:  14336:      57345: unwritten
   5:    53248..   77823:      75777..    100352:  24576:      73729: unwritten
   6:    77824..   79871:       6145..      8192:   2048:     100353: unwritten
   7:    79872..   81919:       3511..      5558:   2048:       8193: unwritten,eof
/mnt/test.dat: 8 extents found

4.10 あと始末

テストに使用したファイルシステムのアンマウントします。

[root@server ~]# umount /mnt

削除するループバックデバイスを確認します。

[root@server ~]# losetup -l
NAME       SIZELIMIT OFFSET AUTOCLEAR RO BACK-FILE
/dev/loop0         0      0         0  0 /root/disk.img

ループバックデバイスの削除をします。

[root@server ~]# losetup -d /dev/loop0

ループバックデバイスを確認します。作成したループバックデバイスが削除されたことがわかります。

[root@server ~]# losetup -l

作成したファイルを削除します。

[root@server ~]# rm disk.img
rm: 通常ファイル `disk.img' を削除しますか? y

5 xfsファイルシステム

5.1 事前準備(デバイスの作成)

ループバックデバイスで使用するファイル(100M)を作成します。。

[root@server ~]# fallocate -l 100M disk.img

作成したファイルをループバックデバイスとして登録します。

[root@server ~]# losetup -f /root/disk.img

登録したループバックデバイスを確認します。

[root@server ~]# losetup -l
NAME       SIZELIMIT OFFSET AUTOCLEAR RO BACK-FILE
/dev/loop0         0      0         0  0 /root/disk.img

5.2 ファイルシステム作成(mkfs.xfs)

ループバックデバイス(/dev/loop0)にxfsファイルシステムを作成します。

[root@server ~]# mkfs.xfs /dev/loop0
Discarding blocks...Done.
meta-data=/dev/loop0             isize=512    agcount=4, agsize=6400 blks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=1        finobt=0, sparse=0
data     =                       bsize=4096   blocks=25600, imaxpct=25
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0 ftype=1
log      =internal log           bsize=4096   blocks=855, version=2
         =                       sectsz=512   sunit=0 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0

ループバックデバイスに作成したファイルシステムを確認します。xfsファイルシステムが作成されたことがわかります。

[root@server ~]# lsblk -fip /dev/loop0
NAME       FSTYPE LABEL UUID                                 MOUNTPOINT
/dev/loop0 xfs          6326cb24-3ff0-4f48-bcdd-ba45faca27ae

作成したループバックデバイスを/mntにマウントします。

[root@server ~]# mount -o loop /dev/loop0 /mnt

ファイルシステムを確認します。ループバックデバイスが/mntにマウントされていることがわかります。

[root@server ~]#  df -hT -t xfs
ファイルシス   タイプ サイズ  使用  残り 使用% マウント位置
/dev/vda3      xfs      4.8G  2.8G  2.0G   60% /
/dev/vda1      xfs      125M  116M  8.8M   94% /boot
/dev/loop1     xfs       97M  5.3M   92M    6% /mnt

5.3 パラメータの表示(xfs_info)

[root@server ~]# xfs_info /mnt/
meta-data=/dev/loop1             isize=512    agcount=4, agsize=6400 blks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=1        finobt=0 spinodes=0
data     =                       bsize=4096   blocks=25600, imaxpct=25
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0 ftype=1
log      =internal               bsize=4096   blocks=855, version=2
         =                       sectsz=512   sunit=0 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0

5.4 パラメータの変更(xfs_admin)

ファイルシステムのラベルを変更してみます。初期状態を確認します。ラベルが何も設定されていないことがわかります。

[root@server ~]# xfs_admin -l /dev/loop0
label = ""

TESTという名前のラベルを設定します。

[root@server ~]# xfs_admin -L TEST /dev/loop0
writing all SBs
new label = "TEST"

ラベルを確認します。TESTという名前のラベルが設定されたことがわかります。

[root@server ~]# xfs_admin -L TEST /dev/loop0
writing all SBs
new label = "TEST"

5.5 エラーチェック(xfs_repair)

ファイルシステムが壊れていないかどうかをチェックします。
壊れていた場合、ファイルシステムの修復を行います。
ファイルシステムをアンマウントした状態で実行します。

[root@server ~]# umount /mnt
[root@server ~]# xfs_repair /dev/loop0
Phase 1 - find and verify superblock...
Phase 2 - using internal log
        - zero log...
        - scan filesystem freespace and inode maps...
        - found root inode chunk
Phase 3 - for each AG...
        - scan and clear agi unlinked lists...
        - process known inodes and perform inode discovery...
        - agno = 0
        - agno = 1
        - agno = 2
        - agno = 3
        - process newly discovered inodes...
Phase 4 - check for duplicate blocks...
        - setting up duplicate extent list...
        - check for inodes claiming duplicate blocks...
        - agno = 0
        - agno = 2
        - agno = 3
        - agno = 1
Phase 5 - rebuild AG headers and trees...
        - reset superblock...
Phase 6 - check inode connectivity...
        - resetting contents of realtime bitmap and summary inodes
        - traversing filesystem ...
        - traversal finished ...
        - moving disconnected inodes to lost+found ...
Phase 7 - verify and correct link counts...
done

5.6 デバッグ(debugfs)

[root@server ~]# xfs_db /dev/loop0
xfs_db>

コマンドプロンプトに対してhelpと入力すると、オプションが表示されます。

[root@server ~]# xfs_db /dev/loop0
xfs_db> help
ablock filoff -- set address to file offset (attr fork)
addr [field-expression] -- set current address
agf [agno] -- set address to agf header
-snip-

5.7 ファイルシステムデフラグ(xfs_fsr)

[root@server ~]# df -hT -t xfs /mnt
ファイルシス   タイプ サイズ  使用  残り 使用% マウント位置
/dev/loop1     xfs       97M  5.3M   92M    6% /mnt
[root@server ~]# fallocate -l 80M /mnt/test.dat
[root@server ~]# xfs_fsr -v /mnt
/mnt start inode=0
ino=67
insufficient freespace for: ino=67: size=83886080: ignoring

5.8 ファイル断片化の確認(xfs_bmap)

テスト用ファイルを作成するファイルシステムを確認します。

/mntにテスト用ファイル(80M)を作成します。

[root@server ~]# fallocate -l 80M /mnt/test.dat

ファイルの断片化を確認します。ファイルの各部分がファイルシステム内のどのブロックにマッピングされているかがわかります。ファイルが4つのエクステントに分割されていることがわかります。

[root@server ~]# xfs_bmap -v /mnt/test.dat
/mnt/test.dat:
 EXT: FILE-OFFSET       BLOCK-RANGE      AG AG-OFFSET        TOTAL
   0: [0..51063]:       128..51191        0 (128..51191)     51064
   1: [51064..102191]:  51264..102391     1 (64..51191)      51128
   2: [102192..146479]: 109304..153591    2 (6904..51191)    44288
   3: [146480..163839]: 153664..171023    3 (64..17423)      17360

フラグメントの状況は、xfs_dbコマンドを使っても確認できます。

[root@server ~]#  xfs_db -r /dev/loop0
xfs_db> frag
actual 4, ideal 1, fragmentation factor 75.00%
Note, this number is largely meaningless.
Files on this filesystem average 4.00 extents per file
xfs_db>

5.9 あと始末

テストに使用したファイルシステムのアンマウントします。

[root@server ~]# umount /mnt

削除するループバックデバイスを確認します。

[root@server ~]# losetup -l
NAME       SIZELIMIT OFFSET AUTOCLEAR RO BACK-FILE
/dev/loop0         0      0         0  0 /root/disk.img

ループバックデバイスの削除をします。

[root@server ~]# losetup -d /dev/loop0

ループバックデバイスを確認します。作成したループバックデバイスが削除されたことがわかります。

[root@server ~]# losetup -l
[root@server ~]#

作成したファイルを削除します。

[root@server ~]#  rm disk.img
rm: 通常ファイル `disk.img' を削除しますか? y

Z 参考情報

私が業務や記事執筆で参考にした書籍を以下のページに記載します。
Linux技術のスキルアップをしよう! - hana_shinのLinux技術ブログ

仮想マシンにNICを追加する方法

1 はじめに

KVMホストに仮想ブリッジ(br1)を作成し、仮想マシンを仮想ブリッジに接続してみます。
以下が初期状態となります。

+---- client ----+                                +---- server ----+
|                |                                |                |
|                |                                |                |
|                |                                |                |
|                |                                |                |
|                |                                |                |
+---- [eth0]-----+                                +---- [eth0] ----+
        | .181                                            | .216
        |                                                 |
        |                 192.168.122.0/24                |
        |                                                 |
+--- [vnet0] ----------------- virbr0 ----------------- [vnet1] ---+
|                                                                  |
|                                                                  |
+------------------------------------------------------------------+

最終的に以下の環境を作成します。図中の[]内はデバイス名(インタフェース名)を表します。

                             10.0.0.0/8

+---- client ----+           +-- br1 --+          +---- server ----+
|                |           |         |          |                |
|                | .20       |         |      .10 |                |
|              [eth1] --- [vnet2]   [vnet3] --- [eth1]             |
|                |           |         |          |                |
|                |           |         |          |                |
+---- [eth0]-----+           +---------+          +---- [eth0] ----+
        | .181                                            | .216
        |                                                 |
        |                 192.168.122.0/24                |
        |                                                 |
+--- [vnet0] ----------------- virbr0 ----------------- [vnet1] ---+
|                                                                  |
|                                                                  |
+------------------------------------------------------------------+

2 環境

サーバ、クライアントのCentOS版数は以下のとおりです。

[root@server ~]# cat /etc/centos-release
CentOS Linux release 7.9.2009 (Core)

KVMホストのCentOS版数は以下のとおりです。

[root@kvm ~]# cat /etc/centos-release
CentOS Linux release 7.6.1810 (Core)

virshコマンドの版数は以下のとおりです。

[root@kvm ~]# virsh -v
4.5.0

3 環境作成手順

3.1 仮想ブリッジの作成

KVMホストに仮想ブリッジ(br1)を作成します。ifnameにはデバイス名、con-nameにはプロファイル名を指定します。

[root@kvm ~]# nmcli connection add type bridge ifname br1 con-name br1-profile
接続 'br1-profile' (79447e2f-1041-4f65-a8df-2883f368cf1d) が正常に追加されました。

バイスの状態を確認します。仮想ブリッジが追加されたことがわかります。ただし、この時点では、仮想ブリッジは、まだシステムに接続されていません。

[root@kvm ~]# nmcli device |grep br1
br1         bridge    切断済み  --

仮想ブリッジを作成したらプロファイルを確認してみます。/etc/sysconfig/network-scripts配下にプロファイルが作成されることがわかります。

[root@kvm ~]# cat /etc/sysconfig/network-scripts/ifcfg-br1-profile
STP=yes
BRIDGING_OPTS=priority=32768
TYPE=Bridge
-snip-

作成した仮想ブリッジに、管理用のIPアドレスを設定します。

[root@kvm ~]# nmcli connection modify br1-profile ipv4.method manual ipv4.addresses "10.0.0.1/24"

仮想ブリッジをシステムに接続します。

[root@kvm ~]# nmcli device connect br1
デバイス 'br1' が 'dff11b62-2c59-4a13-96e3-246406c0cf3d' で正常にアクティベートされました。

バイスの状態を確認します。仮想ブリッジがシステムに接続されたことがわかります。

[root@kvm ~]# nmcli device |grep br1
br1         bridge    接続済み  br1-profile

3.2 サーバにNICを追加

サーバ、クライアントにデバイス(NIC)を追加します。デバイスの追加は、サーバ、クライアントが実行中のときに行います。

[root@kvm ~]# virsh list
 Id    名前                         状態
----------------------------------------------------
 3     server                         実行中
 4     client                         実行中

仮想ブリッジと接続するデバイスをサーバに追加します。

[root@kvm ~]# virsh attach-interface --type bridge --source br1 --model virtio server
インターフェースが正常に接続できました

サーバと接続するためのデバイス(vnet2)が、仮想ブリッジに追加されたことがわかります。

[root@kvm ~]# virsh domiflist server
インターフェース 種類     ソース  モデル   MAC
-------------------------------------------------------
vnet0      network    default    virtio      52:54:00:6f:b0:ca
vnet2      bridge     br1        virtio      52:54:00:11:22:e8

brctlコマンドを使っても、仮想ブリッジに追加されたデバイス(vnet2)を確認することが確認できます。

[root@kvm ~]# brctl show br1
bridge name     bridge id               STP enabled     interfaces
br1             8000.fe5400639565       yes             vnet2

サーバでデバイスを確認します。デバイス(eth1)が追加されたことがわかります。

[root@server ~]# ip l show dev eth1
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
    link/ether 52:54:00:0b:52:e7 brd ff:ff:ff:ff:ff:ff

バイスの状態を確認します。

[root@server ~]# nmcli device
DEVICE  TYPE      STATE     CONNECTION
eth0    ethernet  接続済み  eth0
eth1    ethernet  切断済み  --
lo      loopback  管理無し  --

eth1という名前の接続プロファイルを作成します。

[root@server ~]# nmcli connection add type ethernet ifname eth1 con-name eth1
接続 'eth1' (a1f1d160-4dfc-4f89-8ac4-ede9bec33f23) が正常に追加されました

eth1にIPアドレス(10.0.0.10)を設定します

[root@server ~]# nmcli connection modify eth1 ipv4.method manual ipv4.addresses 10.0.0.10/24

バイス(eth1)をシステムに接続します。

[root@server ~]# nmcli device connect eth1
デバイス 'eth1' が '1868a469-132a-43f8-833d-71dad0621094' で正常にアクティベートされました。

バイスの状態を確認します。デバイス(eth1)がシステムに接続されたことがわかります。

[root@server ~]# nmcli device
DEVICE  TYPE      STATE     CONNECTION
eth0    ethernet  接続済み  eth0
eth1    ethernet  接続済み  eth1
lo      loopback  管理無し  --

バイス(eth1)に設定したIPアドレスを確認します。IPアドレスは10.0.0.10であることがわかります。

[root@server ~]# ip a show dev eth1
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 52:54:00:0b:52:e7 brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.10/24 brd 10.0.0.255 scope global noprefixroute eth1
       valid_lft forever preferred_lft forever
    inet6 fe80::18b7:805:de79:7f0b/64 scope link noprefixroute
       valid_lft forever preferred_lft forever

3.3 クライアントにNICを追加

仮想ブリッジと接続するNICをクライアントに追加します。

[root@kvm ~]# virsh attach-interface --type bridge --source br1 --model virtio client
インターフェースが正常に接続できました

クライアントと接続するデバイス(vnet3)が、仮想ブリッジに追加されたことがわかります。

[root@kvm ~]# virsh domiflist client
インターフェース 種類     ソース  モデル   MAC
-------------------------------------------------------
vnet0      network    default    virtio      52:54:00:d0:e3:a7
vnet3      bridge     br1        virtio      52:54:00:a8:67:25

brctlコマンドを使っても、仮想ブリッジに追加されたデバイス(vnet3)を確認することが確認できます。

[root@kvm ~]# brctl show br1
bridge name     bridge id               STP enabled     interfaces
br1             8000.fe5400639565       yes             vnet2
                                                        vnet3

クライアントでデバイスを確認します。デバイス(eth1)が追加されたことがわかります。

[root@client ~]# ip l show eth1
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
    link/ether 52:54:00:a8:67:25 brd ff:ff:ff:ff:ff:ff

バイスの状態を確認します。

[root@client ~]# nmcli device
DEVICE  TYPE      STATE                     CONNECTION
eth0    ethernet  接続済み                  eth0
eth1    ethernet  接続中 (IP 設定を取得中)  有線接続 1
lo      loopback  管理無し                  --

eth1という名前の接続プロファイルを作成します。

[root@client ~]# nmcli connection add type ethernet ifname eth1 con-name eth1
接続 'eth1' (f419b1c4-6a66-4f6b-9c9a-7dadac903da4) が正常に追加されました。

eth1にIPアドレス(10.0.0.20)を設定します

[root@client ~]# nmcli connection modify eth1 ipv4.method manual ipv4.addresses 10.0.0.20/24

バイス(eth1)をシステムに接続します。

[root@client ~]# nmcli device connect eth1
デバイス 'eth1' が 'dd6bcfd0-9484-44f7-8cb6-30004084a3f5' で正常にアクティベートされました。

バイスの状態を確認します。デバイス(eth1)がシステムに接続されたことがわかります。

[root@client ~]# nmcli device
DEVICE  TYPE      STATE     CONNECTION
eth0    ethernet  接続済み  eth0
eth1    ethernet  接続済み  eth1
lo      loopback  管理無し  --

バイス(eth1)に設定したIPアドレスを確認します。IPアドレスは10.0.0.20であることがわかります。

[root@client ~]# ip a show dev eth1
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 52:54:00:a8:67:25 brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.20/24 brd 10.0.0.255 scope global noprefixroute eth1
       valid_lft forever preferred_lft forever
    inet6 fe80::bc91:fe92:5463:fff3/64 scope link noprefixroute
       valid_lft forever preferred_lft forever

4 動作確認

4.1 デバイスの確認

作成した仮想ブリッジを確認します。

[root@kvm ~]# nmcli device show br1
GENERAL.DEVICE:                         br1
GENERAL.TYPE:                           bridge
GENERAL.HWADDR:                         FE:54:00:63:95:65
GENERAL.MTU:                            1500
GENERAL.STATE:                          100 (接続済み)
GENERAL.CONNECTION:                     br1-profile
GENERAL.CON-PATH:                       /org/freedesktop/NetworkManager/ActiveConnection/8
IP4.ADDRESS[1]:                         10.0.0.1/24
IP4.GATEWAY:                            --
IP4.ROUTE[1]:                           dst = 10.0.0.0/24, nh = 0.0.0.0, mt = 425
IP6.ADDRESS[1]:                         fe80::f494:3a19:12c3:ef51/64
IP6.GATEWAY:                            --
IP6.ROUTE[1]:                           dst = fe80::/64, nh = ::, mt = 425
IP6.ROUTE[2]:                           dst = ff00::/8, nh = ::, mt = 256, table=255

4.2 pingによる確認

クライアントでpingコマンドを実行します。宛先はサーバのeth1を指定します。なお、pingコマンドの使い方は、pingコマンドの使い方 - hana_shinのLinux技術ブログを参照してください。

[root@client ~]# ping -I eth1 -c 1 10.0.0.10
PING 10.0.0.10 (10.0.0.10) from 10.0.0.20 eth1: 56(84) bytes of data.
64 bytes from 10.0.0.10: icmp_seq=1 ttl=64 time=1.22 ms

--- 10.0.0.10 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 1.223/1.223/1.223/0.000 ms

4.3 tsharkによる確認

tsharkを使って、仮想ブリッジのvnet2を通過するICMP echo request/replyパケットを確認します。確認をするため、KVMホストでtsharkコマンドを実行します。なお、tsharkコマンドの使い方は、tsharkコマンドの使い方 - hana_shinのLinux技術ブログを参照してください。

[root@kvm ~]# tshark -i vnet2 -Y 'icmp.type==0 or icmp.type==8'
Running as user "root" and group "root". This could be dangerous.
Capturing on 'vnet2'

クライアントでpingを1回実行してみます。宛先はサーバのeth1のIPアドレスを指定します。

[root@client ~]# ping -I eth1 -c 1 10.0.0.10

tsharkの実行結果を確認します。vnet2をICMP echo request/replyパケットが通過していることがわかります。

[root@kvm ~]# tshark -i vnet2 -Y 'icmp.type==0 or icmp.type==8'
Running as user "root" and group "root". This could be dangerous.
Capturing on 'vnet2'
  1 0.000000000    10.0.0.20 -> 10.0.0.10    ICMP 98 Echo (ping) request  id=0x067b, seq=1/256, ttl=64
  2 0.000980030    10.0.0.10 -> 10.0.0.20    ICMP 98 Echo (ping) reply    id=0x067b, seq=1/256, ttl=64 (request in 1)

5 環境削除手順

5.1 サーバのNIC削除

バイス(eth1)の接続を切断します。

[root@server ~]# nmcli device disconnect eth1

バイス(eth1)のプロファイルを削除します。プロファイルを削除すると、/etc/sysconfig/network-scripts配下から、当該プロファイルが削除されます。

[root@server ~]# nmcli connection delete eth1

仮想ブリッジのデバイスを確認します。仮想ブリッジは、サーバとvnet2で接続していることがわかります。

[root@kvm ~]# virsh domiflist server
インターフェース 種類     ソース  モデル   MAC
-------------------------------------------------------
vnet1      network    default    virtio      52:54:00:6f:b0:ca
vnet2      bridge     br1        virtio      52:54:00:0b:52:e7

サーバと仮想ブリッジの接続を切断します。

[root@kvm ~]# virsh detach-interface --domain server --type bridge --mac 52:54:00:0b:52:e7
インターフェースが正常に切断されました
[root@kvm ~]# virsh domiflist server
インターフェース 種類     ソース  モデル   MAC
-------------------------------------------------------
vnet1      network    default    virtio      52:54:00:6f:b0:ca

5.2 クライアントのNIC削除

バイス(eth1)の接続を切断します。

[root@client ~]# nmcli device disconnect eth1

バイス(eth1)のプロファイルを削除します。

[root@client ~]# nmcli connection delete eth1

仮想ブリッジのデバイスを確認します。仮想ブリッジは、クライアントとvnet3で接続していることがわかります。

[root@kvm ~]# virsh domiflist client
インターフェース 種類     ソース  モデル   MAC
-------------------------------------------------------
vnet0      network    default    virtio      52:54:00:d0:e3:a7
vnet3      bridge     br1        virtio      52:54:00:a8:67:25

クライアントと仮想ブリッジの接続を切断します。

[root@kvm ~]# virsh detach-interface --domain client --type bridge --mac 52:54:00:a8:67:25 
インターフェースが正常に切断されました
[root@kvm ~]# virsh domiflist client
インターフェース 種類     ソース  モデル   MAC
-------------------------------------------------------
vnet0      network    default    virtio      52:54:00:d0:e3:a7

5.3 仮想ブリッジの削除

削除する仮想ブリッジを確認します。

[root@kvm ~]# nmcli device |grep br1
br1         bridge    接続済み  br1-profile

仮想ブリッジをシステムから切断します。

[root@kvm ~]# nmcli device disconnect br1
デバイス 'br1' が正常に切断されました。

仮想ブリッジを削除します。

[root@kvm ~]# nmcli device delete br1
デバイス 'br1' が正常に削除されました。

仮想ブリッジを確認します。仮想ブリッジが削除されたことがわかります。

[root@kvm ~]# nmcli device |grep br1
[root@kvm ~]#

Z 参考情報

私が業務や記事執筆で参考にした書籍を以下のページに記載します。
Linux技術のスキルアップをしよう! - hana_shinのLinux技術ブログ

ACL(アクセス制御リスト)の使い方

1 ACL(アクセス制御リスト)とは?

Linuxのファイルやディレクトリに対するアクセス制御方式には、以下の方式があります。任意アクセス制御方式では、ファイルやディレクトリの所有者自身が、それらに対するアクセス権を設定します。

方式 実装
任意アクセス制御(DAC) パーミッション(rwx)、ACL(アクセス制御リスト)
強制アクセス制御(MAC): SELinux,AppArmor,Smack

本記事では、ACLで使うgetfacl,setfaclコマンドの使い方を説明します。ACLは、パーミッションによるアクセス方式に比べ、粒度の細かいアクセス制御ができます。

コマンド名 概要
setfacl ファイルやディレクトリにACLを設定します
getfacl ファイルやディレクトリに設定されたACLを取得します

2 検証環境

CentOS版数は以下のとおりです。

[root@server ~]# cat /etc/redhat-release
CentOS Linux release 7.9.2009 (Core)

カーネル版数は以下のとおりです。

[root@server ~]# uname -r
3.10.0-1160.el7.x86_64

3 インストール方法

aclパッケージをインストールします。

[root@server ~]# yum -y install acl

getfaclコマンドの版数を確認します。

[root@server ~]# getfacl -v
getfacl 2.2.51

setfaclコマンドの版数を確認します。

[root@server ~]# setfacl -v
setfacl 2.2.51

4 ユーザのACL設定、削除方法

4.1 事前準備

テスト用ユーザ(usere1)を作成します。なお、ユーザの作成、削除方法は、useradd/groupaddコマンドの使い方 - hana_shinのLinux技術ブログを参照してください。

[root@server ~]# useradd user1

テスト用ユーザ(user2)を作成します。

[root@server ~]# useradd user2

テスト用ファイルを作成します。

[root@server ~]# touch /tmp/test.txt

test.txtのACLを確認します。ACLはまだ設定されていないことがわかります。

[root@server ~]# getfacl /tmp/test.txt
getfacl: Removing leading '/' from absolute path names
# file: tmp/test.txt
# owner: root
# group: root
user::rw-
group::r--
other::r--

テスト用ファイルの所有者、グループを確認します。ともにrootであることがわかります。

[root@server ~]# ls -l /tmp/test.txt
-rw-r--r--. 1 root root 0  5月 31 19:50 /tmp/test.txt

4.2 設定方法(-m)

test.txtに対してuser1のみ、リード/ライトができるようにACLを設定します。

[root@server ~]# setfacl -m u:user1:rw /tmp/test.txt

test.txtに対してuser2のみ、リードができるようにACLを設定します。

[root@server ~]# setfacl -m u:user2:r /tmp/test.txt

test.txtのACLを確認します。test.txtに対して、各ユーザは次のことができることがわかります。
・user1はリード/ライト
・user2はリードのみ

[root@server ~]# getfacl /tmp/test.txt
getfacl: Removing leading '/' from absolute path names
# file: tmp/test.txt
# owner: root
# group: root
user::rw-
user:user1:rw-
user:user2:r--
group::r--
mask::rw-
other::r--

なお、ACLを設定すると、パーミッションの右端に+が表示されることがわかります。

[root@server ~]# ls -l /tmp/test.txt
-rw-rw-r--+ 1 root root 0  5月 31 19:50 /tmp/test.txt

4.3 削除方法(-x)

test.txtからuser1のACLを削除します。

[root@server ~]# setfacl -x u:user1 /tmp/test.txt

test.txtのACLを確認します。test.txtからuser1のACLが削除されたことがわかります。

[root@server ~]# getfacl /tmp/test.txt
getfacl: Removing leading '/' from absolute path names
# file: tmp/test.txt
# owner: root
# group: root
user::rw-
user:user2:r--
group::r--
mask::r--
other::r--

test.txtからuser2のACLを削除します。

[root@server ~]# setfacl -x u:user2 /tmp/test.txt

test.txtのACLを確認します。test.txtからuser2のACLが削除されたことがわかります。

[root@server ~]# getfacl /tmp/test.txt
getfacl: Removing leading '/' from absolute path names
# file: tmp/test.txt
# owner: root
# group: root
user::rw-
group::r--
mask::r--
other::r--

5 グループのACL設定、削除方法

グループに対して、ACLの設定、削除をおこなってみます。

5.1 事前準備

テスト用のファイルを作成します。

[root@server ~]# touch /tmp/test.txt

テスト用のグループ(staff)を作成します。

[root@server ~]# groupadd staff

作成したグループを確認します。

[root@server ~]# getent group|grep staff
staff:x:1001:

5.2 設定方法(-m)

test.txtに対して、staffグループはリード/ライトできるようにACLを設定してみます。

[root@server ~]# setfacl -m g:staff:rw /tmp/test.txt

ACLを確認します。staffグループは、test.txtに対してリード/ライトができることがわかります。

[root@server ~]# getfacl /tmp/test.txt
getfacl: Removing leading '/' from absolute path names
# file: tmp/test.txt
# owner: root
# group: root
user::rw-
group::r--
group:staff:rw-
mask::rw-
other::r--

5.3 削除方法(-x)

[root@server ~]# setfacl -x g:staff /tmp/test.txt

ACLを確認します。

[root@server ~]# getfacl /tmp/test.txt
getfacl: Removing leading '/' from absolute path names
# file: tmp/test.txt
# owner: root
# group: root
user::rw-
group::r--
mask::r--
other::r--

6 ACLを一括削除する方法(-b)

test.txtに設定されているACLを確認します。user1,user2のACLが設定されていることがわかります。

[root@server ~]# getfacl /tmp/test.txt
getfacl: Removing leading '/' from absolute path names
# file: tmp/test.txt
# owner: root
# group: root
user::rw-
user:user1:rw-
user:user2:r--
group::r--
mask::rw-
other::r--

ACLを一括削除します。

[root@server ~]# setfacl -b /tmp/test.txt

test.txtのACLを確認します。user1,user2のACLが削除されたことがわかります。

[root@server ~]# getfacl /tmp/test.txt
getfacl: Removing leading '/' from absolute path names
# file: tmp/test.txt
# owner: root
# group: root
user::rw-
group::r--
other::r--

7 再帰的に表示する方法(-R)

ファイルやディレクトリのACL再帰的に表示してみます。まず、テスト用に使うディレクトリを作成します。

[root@server ~]# mkdir -p dir1/dir2

dir1,dir2のACLを確認します。dir1,dir2のACLが表示されていることがわかります。

[root@server ~]# getfacl -R dir1/
# file: dir1/
# owner: root
# group: root
user::rwx
group::r-x
other::r-x

# file: dir1//dir2
# owner: root
# group: root
user::rwx
group::r-x
other::r-x

8 ファイルを使ってACLを設定する方法(-M)

ACLを定義したファイルを作成します。

[root@server ~]# vi acl.txt
[root@server ~]# cat acl.txt
user:user1:rw
user:user2:rwx

file.txtのACLを確認します。ACLは、まだ設定されていないことがわかります。

[root@server ~]# getfacl /tmp/test.txt
getfacl: Removing leading '/' from absolute path names
# file: tmp/test.txt
# owner: root
# group: root
user::rw-
group::r--
other::r--

test.txtにACLを設定します。

[root@server ~]# setfacl -M acl.txt /tmp/test.txt

file.txtに設定されているACLを確認します。user1とuser2のACLが設定されたことがわかります。

[root@server ~]# getfacl /tmp/test.txt
getfacl: Removing leading '/' from absolute path names
# file: tmp/test.txt
# owner: root
# group: root
user::rw-
user:user1:rw-
user:user2:rwx
group::r--
mask::rwx
other::r--

9 デフォルトACLを設定、削除する方法

dir1に対し、user1がリード/ライトができるようにデフォルトACLを設定します。

[root@server ~]# setfacl -m d:u:user1:rw dir1/

dir1に設定したデフォルトACLを確認します。デフォルトACLが設定されたことがわかります。

[root@server ~]# getfacl dir1/
# file: dir1/
# owner: root
# group: root
user::rwx
group::r-x
other::r-x
default:user::rwx
default:user:user1:rw-
default:group::r-x
default:mask::rwx
default:other::r-x

ディレクトリ(dir1)に設定されたデフォルトACLを削除します。

[root@server ~]# setfacl -k dir1

dir1に設定したデフォルトACLを確認します。

[root@server ~]# getfacl dir1/
# file: dir1/
# owner: root
# group: root
user::rwx
group::r-x
other::r-x

10 実験

test.txtに対して、user1はリード/ライト、user2はリードができるようにACLを設定してみます。

[root@server ~]# setfacl -m u:user1:rw /tmp/test.txt
[root@server ~]# setfacl -m u:user2:r /tmp/test.txt

user1のfile.txtに対するリード/ライトを確認します。file.txtに対して、リード/ライトができることがわかります。

[root@server ~]# su - user1
最終ログイン: 2022/05/28 (土) 20:45:07 JST日時 pts/1

テスト用ファイルに書き込みをします。user1はファイルへの書き込みが許可されているので、エラーは発生しません。

[user1@server ~]$ echo "12345" > /tmp/test.txt

テスト用ファイルから読み込みをします。user1はファイルからの読み込みが許可されているので、エラーは発生しません。

[user1@server ~]$ cat /tmp/test.txt
12345

user1からrootに切り替えます。

[user1@server ~]$ exit
logout

次に、user2に切り替えます。

[root@server ~]# su - user2

テスト用ファイルに書き込みをします。user2はファイルへの書き込みが禁止されているので、書き込みができません。

[user2@server ~]$ echo "12345" > /tmp/test.txt
-bash: /tmp/test.txt: Permission denied

テスト用ファイルから読み込みをします。user2はファイルからの読み込みが許可されているので、ファイルの中身を読み込むことができます。

[user2@server ~]$ cat /tmp/test.txt
12345

Z 参考情報

私が業務や記事執筆で参考にした書籍を以下のページに記載します。
Linux技術のスキルアップをしよう! - hana_shinのLinux技術ブログ