実践Linux
CentOS7        CentOS7 目次へ  TOP(HOME)へ

CentOS7の新機能    2016年6月

systemd

systemdではこれまでのSysVinitやUpstartに代わる新しい起動処理とサービス管理の仕組みが導入された。
最近のサーバーはマルチコアCPU搭載=並列処理があたりまえとなりつつあるが、これまでのSysVinit等の逐次起動の仕組みではまったくこれが生かされていかないといった齟齬が起きてきていた。systemdではこれを抜本から見直し、起動システムの刷新、サービスの管理機能を強化する新しい試みがなされている。

●Unit(ユニット)
systemdの基礎となるのがUnitである。さまざまな処理は、個別のUnitとして定義され、実行される。
従来の起動プロセスではシェルスクリプトによって逐次的に実行されていた処理を、多数のUnitに分解して、並列に実行する。

主なUnitの種類(拡張子で分類される)
service  サービス(デーモン)を起動
target   複数のUnitをグループ化するために使用
mount  ファイルシステムをマウント(/etc/fstabから自動作成)
swap   スワップ領域を有効化(/etc/fstabから自動作成)
device  ディスクデバイスを表す(udevがデバイスを認識すると自動作成)
socket  ソケット


Unitの定義ファイル
Unitの定義ファイルは /usr/lib/systemd/system と /etc/systemd/system に配置される。
前者はシステムのデフォルト設定であり、後者はシステム管理者が追加・修正する場合に使用する。
拡張子を含めたUnit名が、そのまま設定ファイルの名前になる。たとえば、SSHデーモンを起動する設定ファイルは、/usr/lib/systemd/system/sshd.service である。
両方のディレクトリに同じ名称の設定ファイルがある場合は、/etc のほうが優先される。
したがって、デフォルトの設定を変更したい場合は、/usr/libのファイルを/etcにコピーして、これを編集する。もとのデフォルトに戻したい場合は、/etcのファイルを削除すればよい。


Unit間の依存関係、順序関係
Unitには、Unit間の依存関係、順序関係が設定されていて、systemdは各Unitの依存関係を検索して、有効化すべきUnitの一覧を作成する。これに基づいて順番にUnitを起動していく。順序関係を持たないUnitについては、できるだけ並列処理を行う。

Unitの依存関係
@[Unit]セクションの「Wants=」オプション、「Requires=」オプションに指定。
Requiresは、そこのものが起動に失敗していれば、自身も起動できない。
Wantsは、そこのものが起動に失敗していても、自身は起動する。
Aもう一つの方法は、設定ファイルがあるディレクトリに<Unit名>.wantsあるいは<Unit名>.requiresというサブディレクトリを作成し、そこに対象となるUnitへのシンボリックリンクを作成する。

Unitの順序関係
[Unit]セクションの「After=」オプション、「Before=」オプションに指定。

ターゲットUnit
Systemd ではランレベルに似たものとしてターゲットを使っています。ただしその挙動には少し違いがあります。それぞれのターゲットはナンバリングされる代わりに名前がつけられ、ある特定の目的のために作られ、複数のターゲットを同時に有効にできるようになっています。ターゲットによっては、他のターゲットのサービスを全て引継ぎ、そこにサービスを追加するよう実装されています。一般的な SysVinit ランレベルに擬態する systemd ターゲットもあり、親しみのある telinit RUNLEVEL コマンドを使って使用するターゲットを切り替えることが可能です。
systemd(/usr/lib/systemd/systemdが本体)が起動すると、まずdefault.targetというUnitを有効化する。これは、multi-user.targetなど他のUnitへのシンボリックリンクになっていて、その下に連なるtarget群と各targetに依存するUnit群が、まとめて有効化の対象として選択される。
default.targetのリンク先を変更することは、従来の起動プロセスでいえば、ランレベルを変更することに相当する。

現在のターゲットを獲得
$ systemctl list-units --type=target

動的に作成されるUnit
「mount」タイプ、「swap」タイプのUnitはsystemdが/ets/fstabを参照して、対応するUnitを生成する。
動的に生成されたファイルは、/run/systemd/generatorに保存される。

●systemctl の基本的な使い方
インストールされたユニットを一覧するには、$ systemctl list-unit-files
実行中のユニットを一覧するには、$ systemctl または $ systemctl list-units
失敗したユニットを一覧するには、$ systemctl --failed
特定のタイプに絞り込みたい場合は、 --type=service などと--typeオプションを付ける。
表示が「....」などと省略されるのを避けたい場合は、--fullオプション。

ユニットを使う
systemctl を使うとき、一般的には拡張子 (suffix) を含むユニットファイルの完全な名前を指定する必要があります。例えば、sshd.socket のように。
しかし、以下のような場合には省略形が存在します:
@拡張子が指定されない場合、systemctlは .service とみなします。例えば netcfg と netcfg.service は同じように扱われます。
Aマウントポイントは自動的に対応する .mount ユニットとして扱われます。例えば、/home を指定することは home.mount の指定と同じです。
Bマウントポイントと同じく、デバイスも自動的に対応する .device ユニットとして扱われます。従って、/dev/sda2 の指定は dev-sda2.device と同じです。

開始と停止
いますぐユニットを実行:# systemctl start <unit>
いますぐユニットを停止:# systemctl stop <unit>
ユニットを再始動:# systemctl restart <unit>
ユニットに設定を再読み込みするように通知:# systemctl reload <unit>
ユニットの状態を表示(動いているかどうかなど):$ systemctl status <unit>

有効化(起動時に自動で実行するよう設定)、無効化
起動時に実行されるようにする:# systemctl enable <unit>
システム起動時に実行されないように無効化する:# systemctl disable <unit>
有効化されているかどうか表示:$ systemctl is-enabled <unit>
ユニットに関連するマニュアルページを参照する:$ systemctl help <unit>
systemd をリロードし、新しい、もしくは変化のあったユニットをスキャンする:# systemctl daemon-reload

Unit自動起動の仕組み
/usr/lib/systemd/system/sshd.serviceを見ると、
[Install]セクションにWantedBy=multi-user.targetとある。
# systemctl enable sshd.serviceを実行すると、/etc/systemd/system/multi-user.target.wantsディレクトリの中に/usr/lib/systemd/system/sshd.serviceへのシンボリックリンクが作成され、逆にdisableを実行すると、このシンボリックリンクが削除される。


firewalld(新ファイアウォール)

@動的にファイアウォールのポリシーが変更できる
これまでのiptablesではルールを変更する際、いったん古いルールをすべて一掃して、その後に新しいルールを確立しなおす必要があった。firewalldでは、ルール(ポリシー)をダイナミックに追加、変更できるようになった。
A「ゾーン」と呼ばれる新しい概念の導入
firewalldのゾーンとは、ネットワークで扱うデバイスや通信をユーザーが決めた信頼度に応じて分類したものである。このゾーンごとに異なるファイアウォールのルールセット、つまりポリシーを適用できる。

firewalldは内部的にiptablesを利用しているのですが、firewalldとiptablesを併用することはできません。iptablesを利用する場合はfirewalldを停止しておく必要があり、firewalldを利用する場合はiptablesを停止しておく必要があります。firewalldは、「iptablesサービスの代替」というよりは、iptablesをバックエンドにした、まったく新しいファイアウォール機能を提供するものと考えるとよいでしょう。サーバに搭載されたNICポートごとに仮想的なファイアウォールを設置して、それぞれについて受信を許可するポートを指定します。
より正確に言うと、「ゾーン」が事前に用意されており、各NICポートについて、適用するゾーンを指定します。それぞれのゾーンでは許可するサービス(フィルタリングの設定)を定義していきます。すると、そのゾーンを適用したNICポートに対して、対応するフィルタリング処理が行われるようになります。

ゾーン
drop(変更不可)  内向きのパケットはすべてドロップ。外向きのパケットは通過できるが、返信パケットが破棄されるので現実的に使用されることはない。
block(変更不可)   内向きのパケットに対してはICMP Prohibitedメッセージを返し、通過を拒否。内部から開始された通信の返信パケットは通るので、、内部から外部への通信はできる。
public  デフォルトゾーンです。ほかのホストが信頼できない公共のネットワークで用いられるゾーン。内向きパケットは選定されたもののみ許可する。デフォルトで「ssh」と「dhcpv6-client」のみ許可されています。
external  IPマスカレードを有効にして、外部ネットワークに接続する場合に用いられるゾーン。ほかのホストが信頼できないネットワークで用いられる。内向きパケットは選定されたもののみ許可する。デフォルトで「ssh」のみ許可されています。
dmz  非武装ネットワーク(DMZ)で用いられるゾーン。アクセスは可能だが、さらに内側のネットワークへのへのアクセスは制限され、選定されたもののみ許可する。デフォルトで「ssh」のみ許可されています。
work  イントラネットで用いられるゾーン。ほかのホストが概ね信頼できるネットワークで用いる。内向きパケットは選定されたもののみ許可する。デフォルトで「dhcpv6-client」、「ipp-client」、「 ssh」が許可されています。
home  初期設定はworkとほぼ同様のゾーン。デフォルトで「dhcpv6-client」、「ipp-client」、「mdns」、「samba-client」、「ssh」が許可されています。
internal  初期設定はworkとほぼ同様のゾーン。デフォルトで「dhcpv6-client」、「ipp-client」、「mdns」、「samba-client」、「ssh」が許可されています。
trusted(変更不可)  全てのパケットが許可されます。

これらのゾーンの設定は、/usr/lib/firewalld/zonesディレクトリ下の「ゾーン名.xml」ファイルに記述されている。設定を変更する場合は、/etc/firewalld/zonesディレクトリにコピーして編集する。(systemdと同じ。)

さらに、firewalldには多くのサービスが事前に定義されており、これは/usr/lib/firewalld/servicesディレクトリ下の「サービス名.xml」ファイルに記述されている。これも設定を変更する場合は、/etc/firewalld/servicesディレクトリにコピーして編集する。

ゾーン例
public.xml <?xml version="1.0" encoding="utf-8"?>
<zone>
<short>Public</short>
<description>For use in public areas. You do not trust the other computers on networks to not harm your computer. Only selected incoming connections are accepted.</description>
<service name="ssh"/>
<service name="dhcpv6-client"/>
</zone>
external.xml IPマスカレードが有効になっていることがわかる
<?xml version="1.0" encoding="utf-8"?>
<zone>
<short>External</short>
<description>For use on external networks. You do not trust the other computers on networks to not harm your computer. Only selected incoming connections are accepted.</description>
<service name="ssh"/>
<masquerade/>
</zone>
trusted.xml <?xml version="1.0" encoding="utf-8"?>
<zone target="ACCEPT">
<short>Trusted</short>
<description>All network connections are accepted.</description>
</zone>

サービス例
http.xml <?xml version="1.0" encoding="utf-8"?>
<service>
<short>WWW (HTTP)</short>
<description>HTTP is the protocol used to serve Web pages. If you plan to make your Web server publicly available, enable this option. This option is not required for viewing pages locally or developing Web pages.</description>
<port protocol="tcp" port="80"/>
</service>
ftp.xml モジュールが組み込まれていることがわかる
<?xml version="1.0" encoding="utf-8"?>
<service>
<short>FTP</short>
<description>FTP is a protocol used for remote file transfer. If you plan to make your FTP server publicly available, enable this option. You need the vsftpd package installed for this option to be useful.</description>
<port protocol="tcp" port="21"/>
<module name="nf_conntrack_ftp"/>
</service>

GUIによる設定
firewalldにはGUIの設定ツールfirewall-configが用意されていて、アプリケーション→諸ツール→ファイアウォールで起動する。(永続設定でも設定しておくと、再起動したときも有効になる。)

CUIで作業する場合
CUIで作業する場合は、firewall-cmdコマンドを用いる。
●ゾーン情報
デフォルトはpublicゾーンにインターフェイスがアタッチされています。
ゾーン一覧  # firewall-cmd --get-zones
# firewall-cmd --list-all  デフォルトゾーンの設定を表示
# firewall-cmd --zone=public --list-all publicゾーンの設定を見る
--list-allで--permanentを指定すると、永続的な設定が表示され、指定しないと現在有効な設定が表示される。
# firewall-cmd --get-active-zone(--get-active-zones) 現在のゾーンとそれに紐付くインターフェイス
その他のゾーンも含め全てを見たい場合は以下のオプションで閲覧可能です。
# firewall-cmd --list-all-zones  すべてのゾーンについて、対応するNICと利用する機能を表示する

以降、記載する詳細なコマンドにおいてゾーンを省略して記載した場合、デフォルトゾーンのpublicが適用されます。
また、firewall-cmdコマンド等でのゾーン内容の変更は、/etc/firewalld/zones/ゾーン名.xmlに記述されていく。(デフォルトの設定/usr/lib/firewalld/zones/ゾーン名.xmlコピーして上書きしたもの。/etcが優先される。)
同様に、servicesを変更する場合も、/usr/lib/firewalld/servicesのものを/etc/firewalld/servicesにコピーして編集する。

●デフォルトゾーンの変更
デフォルトゾーンの確認 # firewall-cmd --get-default-zone
デフォルトゾーンの変更 # firewall-cmd --set-default-zone=external

●インターフェイスの変更
# firewall-cmd --zone=trusted --change-interface=eno1  ゾーンのインターフェイスを付け替える
# firewall-cmd --zone=public --add-interface=eno2 publicゾーンにインターフェイスeno2を追加
# firewall-cmd --zone=public --remove-interface=eno2 publicゾーンからインターフェイスeno2を削除
確認  # firewall-cmd --get-active-zone
インターフェイスに恒久的にゾーンを設定するには、
/etc/sysconfig/network-scripts/ifcfg-****を編集、ZONE=trusted等を追加する。

●サービスの追加・削除
ゾーンごとに許可されているサービスが異なります。大体の場合、デフォルトのままだと必要なサービスが追加されていないことは多いと思いますのでコマンドでサービスを追加する必要があります。下記がサービスの追加・削除などを行うコマンドです。下記ではいずれもゾーンを指定しておりますが、デフォルトゾーンの場合は省略可能です。
定義されているサービス一覧 # firewall-cmd --get-services
サービスの表示
# firewall-cmd --list-services  デフォルトゾーンで公開されているサービス
# firewall-cmd --list-services --zone=public  publicのサービス
--zone=を指定しない場合、デフォルトゾーンとなります。
--permanentを指定すると、永続的な設定が表示され、指定しないと現在有効な設定が表示されます。
サービスの追加・削除
# firewall-cmd --add-service=http --zone=public  サービスを追加する
# firewall-cmd --add-service=http --zone=public --permanent  恒久的にサービスを追加する
# firewall-cmd --remove-service=dhcpv6-client --zone=public  サービスを削除する
# firewall-cmd --remove-service=dhcpv6-client --zone=public --permanent  恒久的にサービスを削除する
【注意】
--zone=を指定しない場合、デフォルトゾーンとなります。
--permanentを指定しない場合、設定は一時的に行われるだけで、再起動すると設定は失われます。また、指定した場合には、すぐには設定が反映されないので、次のようにしてfirewalldに設定を再読み込みさせる必要があります。
# firewall-cmd --reload

●ポートの公開設定
上でサービスが登録・定義されていない場合は、ポート番号とプロトコル(TCP/UDP)を指定して、ポートを公開する設定を行う必要があります。
公開状態の表示
# firewall-cmd --list-ports  デフォルトゾーンで公開されているポート
# firewall-cmd --list-ports --zone=public  publicで公開されているポート
--zone=を指定しない場合、デフォルトゾーンとなります。
--permanentを指定すると、永続的な設定が表示され、指定しないと現在有効な設定が表示されます。
追加・削除
# firewall-cmd --permanent --add-port=5900-5903/TCP; firewall-cmd --reload
# firewall-cmd --permanent --add-port=POP3/TCP; firewall-cmd --reload
# firewall-cmd --permanent --remove-port=5900-5903; firewall-cmd --reload  削除する
--zone=を指定しない場合、デフォルトゾーンとなります。
--permanentを指定しない場合、設定は一時的に行われるだけで、再起動すると設定は失われます。また、指定した場合には、すぐには設定が反映されないので、# firewall-cmd --reloadを実行してfirewalldに設定を再読み込みさせる必要があります。

●ポートフォワーディングの設定
ただし、ポートフォワーディングの設定ができるのはIPv4のみ。
ポートフォワーディングの表示
# firewall-cmd --permanent --list-forward-ports  デフォルトゾーン
# firewall-cmd --permanent --list-forward-ports --zone=public  publicゾーン
--zone=を指定しない場合、デフォルトゾーンとなります。
--permanentを指定すると、永続的な設定が表示され、指定しないと現在有効な設定が表示されます。
ポートフォワーディングの設定
# firewall-cmd --permanent --add-forward-port="port=10022:proto=tcp:toaddr=192.168.7.2:toport=22"
# firewall-cmd --reload
# firewall-cmd --permanent --remove-forward-port="port=10022:proto=tcp:toaddr=192.168.7.2:toport=22" # firewall-cmd --reload
--zone=を指定しない場合、デフォルトゾーンとなります。
--permanentを指定しない場合、設定は一時的に行われるだけで、再起動すると設定は失われます。また、指定した場合には、すぐには設定が反映されないので、# firewall-cmd --reloadを実行してfirewalldに設定を再読み込みさせる必要があります。

●許可・拒否するICMPパケットのタイプの指定
また、サービスのみならず許可・拒否するICMPパケットのタイプを指定することもできます。こちらも同様にゾーンを指定しておりますが、デフォルトゾーンの場合は省略可能です。
ICMPタイプの一覧表示 # firewall-cmd --get-icmptypes
禁止されているICMPタイプを表示 # firewall-cmd --list-icmp-blocks --zone=public
禁止されているICMPタイプに追加 # firewall-cmd --add-icmp-block=echo-request --zone=public
恒久的に禁止されているICMPタイプに追加 # firewall-cmd --add-icmp-block=echo-request --zone=public --permanent
禁止されるICMPタイプから削除 # firewall-cmd --remove-icmp-block=echo-request
恒久的に禁止されるICMPタイプから削除 # firewall-cmd --remove-icmp-block=echo-request --permanent
--zone=や--permanentについてはこれまでと同様です。

●リッチルール(複雑なルール)の設定
以下、--zone=や--permanentについてはこれまでと同様です。
リッチルールの表示
# firewall-cmd --list-rich-rules
リッチルールの設定
# firewall-cmd --add-rich-rule=ルールを記述
# firewall-cmd --remove-rich-rule=ルール  削除

ルールの書式
rule family=<ipv4|ipv6>  必須
[ source address=<ソースアドレス>[/mask] [invert="true"] ]   invert="true"を指定すると、指定したホスト以外の意味になる
[ destination address=<ソースアドレス>[/mask] [invert="true"] ]
[ service name=<サービス> ]
[ port port=<ポート番号> protocol=<プロトコル> ]   サービス名がない場合はポートで指定
[ forward-port port=<ポート番号> protocol=<プロトコル> to-port=<ポート番号> to-addr=<アドレス> ]
[ icmp-block name=<icmpタイプ> ]
[ masquerade ]
[ log [ prefix=<プレフィックス> ] [level=<ログレベル> ] [ limit value=<レート>/<デュレイション> ] ]
[ audit ]
[ accept|reject|drop]

logのprefixはログの頭につける文字列、levelはemerg,alert,crit,error,warning,notce,info,debugなどのログレベル、limitはログに記録できる最大数を数/期間で指定。accept|reject|dropのrejectは拒否してicmpメッセージを返します。dropは単純に破棄。


# firewall-cmd --permanent --add-rich-rule='rule family=ipv4 source address="192.168.3.207" service name=vnc-server accept'
# firewall-cmd --reload
# firewall-cmd --permanent --add-rich-rule='rule family=ipv4 source address="192.168.3.0/24" port port=pop3 protocol=tcp accept'
# firewall-cmd --reload

●ダイレクトルールの設定
これまでは主に、INPUT、FORWARDチェインへの設定を扱ってきたが、外部へのデータ送信を規制する場合にはOUTPUTチェインへの設定が必要になる。このようなとき利用するのがダイレクトルール。旧来のiptablesと同様の書式を使って設定ができる。

以下、--permanentについてはこれまでと同様です。ただ、--zone=の指定はない。
ダイレクトルールの表示
# firewall-cmd --direct --get-all-rules

ダイレクトルールの書式
# firewall-cmd [--permanent] --direct --add-rule ipv4 <テーブル> <チェイン> <優先順位> <引数>
 テーブル filter、nat、mangle
 チェイン INPUT、OUTPUT、FORWARD、PREROUTING、POSTROUTING
 引数部分
  stateモジュール
   -m state --state NEW
   INVALID  既存のコネクションとは関係のないパケット
   NEW    新しいコネクションの接続に関するパケット
   ESTABLISHD  接続済みのコネクションのパケット
   RELATED  接続済みのコネクションに関連して発生した新たなコネクションのパケット
  オプション
   -s <address>
   -d <address>
   --sport <port>
   --dport <port>
   -i <interface>
   -o <interface>
   -j <target>
   -m <module>
 プロトコル tcp、udp、icpm(ipv6のときはicmpv6)、all
 ターゲット ACCEPT、DROP、RETURN、REJECT、REDIRECT、SNAT、DNAT、MASQUERADE、LOG

ダイレクトルールの設定例  詳しくはこちらを参照
# firewall-cmd --permanent --direct --add-rule ipv4 filter OUTPUT 3 -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
# firewall-cmd --reload

削除
# firewall-cmd --permanent --direct --remove-rule ipv4 filter OUTPUT 3 -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
# firewall-cmd --reload



●サービスやICMPタイプはデフォルトで定義されているものが多数あるのですが、独自に追加したい場合は以下のディレクトリにファイルを追加することになります。デフォルトで用意されているものは全て以下のディレクトリに保存されています。
サービス一覧 # ls /usr/lib/firewalld/services/
ICMPタイプ一覧 # ls /usr/lib/firewalld/icmptypes/

●iptablesで設定内容を確認
# iptables -L -n --line-number



TOP(HOME)へ

目 次

特別企画
Raspberry Piで遊ぶ

HOME(全体のシステム構成&目次)

CentOS7
CentOS7のインストール〜ネットワークの設定ほか
CentOS7の新機能(systemdとfirewalld)
ダイレクトルールを使ったfirewallの強化
DNS(BIND)サーバー
Webサーバー
  Webでファイルの受け渡し
  アクセス解析ツールAwstats
  Wordpressでブログ構築
FTPサーバー
FTPS(FTP over SSL/TLS)
Mail(Dovecot&Postfix)サーバー
Sambaサーバー
MariaDB(MySQL)サーバー
DHCPサーバー
SSHサーバー
VNCサーバー
ドメインの追加

CentOS5〜6
ネットワーク&ファイアウォール(iptables)
DNS(BIND)サーバー
DHCPサーバー
メールサーバー(基本)
メールサーバー/実際の運用
Webサーバー
  WebDAVによるファイル共有
  Webでファイルのやり取り
  アクセス解析ツールawstats
  namazuで全文検索
  WordPressブログサイト構築
  EC-CUBEショッピングサイト構築
FTPサーバー
ファイルサーバー・Samba
データベースpostgreSQL
  ExcelからpostgreSQLを操作
データベースMySQL
SSHサーバー
VNC
SSL/TLSを利用した暗号化通信
openVPN
ストリーミングサーバー
    C++ RTMP Server
    Helix server Basic
ドメインの追加
Xen・仮想化
特定ディレクトリに容量制限

SELinux
SELinux基本設定
新しいタイプとポリシー・モジュールを作成してみる
マクロを利用したteファイルの記述
新しいドメインを導入してみる

coLinux
Fedora11で試す

Cプログラミング目次
X11プログラム
サイエンス・プログラム

計測・プログラム
秋月電子のデーターロガーpico ADC-16
「今すぐ使えるパソコン計測USBマイコン基板」に付属のTRZ1102
センサーの使用例

Glade2/GTK+を使ってみる
テキスト・ビューで簡易エディター
ドローイングエリアで自動描画
放物線運動(pango、cairoも試してみる)
これらを、GTK+のみで書き出す

フォントについて
ネットワーク・プログラミング
postgreSQL接続
CGI
ファイル操作

●その他
印刷機関連開発 刷版絵柄面積率測定
数独をExcelで解く