Linux各種SW機能まとめ

Linux機能で少しニッチだが役に立つことをまとめる。

#NFS(Network File System)
一言で言うと、Linuxのファイル共有機能。
NFS v4からstatd,lockd,rpcbind,mountdなど機能が全て統合されて、2049固定ポートで
NFSサービスを待ち受けられるようになっている。

```ruby:NFSv2,v3,rpcbind無効化
#/etc/sysconfig/nfsの以下編集。
#NFSv4から不要になったportmapperとmountdだが、
#v2,v3が有効化されていると以下で明示的に無効化しないと
#rpcbindが無効化された状態だとNFS自体の起動に失敗する。
#またnfsv4のUDPを-Uで無効化。

---
RPCNFSDARGS="-N 2 -N 3 -U"
---
RPCMOUNTDOPTS="-N 2 -N 3"
---

# rpcbind無効化
systemctl mask rpcbind
```
参考：http://man7.org/linux/man-pages/man7/nfs.systemd.7.html

```ruby:NFSパラメータ選定(サーバ側)
#/etc/exportsに以下設定してマウントを許可(例)
[マウントポイント] [アクセス許可するIP](パラメータ)
```
※パラメータ各書
[rw]
NFS ボリュームに対して、書き込みと読み出しリクエストの両方を許可
[ro] 
NFS ボリュームに対して、読み出しリクエストのみ許可 
[async]
遅延書き込み有効化。このオプションを指定するとパフォーマンスは向上するがサーバ側でsyncする前にクラッシュするとデータが失われる
[sync]
遅延書き込み無効。サーバ側でsyncしてから次の書き込みリクエストに応じるのでパフォーマンスは多少犠牲にするがデータロストの可能性が少ない
[all_squash]
全ユーザがnobodyユーザにマッピングされる
[no_all_squash]
全ユーザ共にそのユーザID自体の権限でアクセスできる
[root_squash]
rootユーザがnobodyユーザにマッピングされる
[no_root_squash]
rootユーザがroot自身の権限でアクセスして操作できる
[secure]
1024未満のポートからのアクセスしか受け付けなくなる
[insecure]
1024以上のポートからのアクセスも受け付ける
[no_wdelay]
このオプションは同時に  async が設定されていると効果を持たない。 NFS サーバは、書き込み要求を受けたとき、 関連した別の書き込み要求が実行中である  (または近々到着する)と予想した場合、  その要求のディスクへの反映を少し遅らせる。 これにより一度の操作で複数の書き込み要求が ディスクに反映されるので、性能が向上する。 NFSサーバが受け取るデータの書き込み要求が、 主として関連性のない小さなものの場合には、この動作は実際には性能を低下させてしまうので、 no_wdelay を指定して無効にできる。デフォルトの動作を wdelay オプションで明示的に指定することもできる。
[no_subtree_check]
ファイルシステムのサブディレクトリがエクスポートされているが、 ファイルシステム全体がエクスポートされていない場合、 NFS リクエストがくると、サーバは対応するファイルシステムにアクセスされたファイルがあるかをチェックするだけでなく、 エクスポートされたツリーのなかにあるかもチェックしなければならない。このチェックは subtree_check とよばれる。サーバはクライアントに渡す 「ファイルハンドル」に、ファイルの場所に関する情報を入れなければならない。こうすると、クライアントがファイルをオープンしている間に、アクセスしているファイルの名前が変更されると問題が起こる。基本的に更新の多いディレクトリのエクスポートの場合は無効にすべきである。
[fsid=0]
fsid=0 でエクスポートされたエクスポートポイントは、 クライアント側のルート(/)がマウントされているように見える。

```ruby:NFSパフォーマンス関連
#デフォルトで8個起動する[nfsd]。
#/etc/sysconfig/nfs のRPCNFSDCOUNTで変更します。
#/proc/net/rpc/nfsd を見て、th行の値を見て過不足を判断します。

th 128 1196 48 11 677 54 66 31 288 27 26 118
    th (threads): <threads> <fullcnt> <10%-20%> <20%-30%> ... <90%-100%> <100%>

```

#リモートファイル同期(rsync/lsync)
Linux機能によるファイル同期機能。
rsync単体だけだと随時的な同期機能に最適。常時同期したい場合はlsyncを利用する。
デフォルトだと暗号化されないので、リモート通信の場合SSHを介するようにすることで通信の暗号化を行う。
ソースディレクトリ内のファイルの中身が変更されたり、ファイルが追加されたり、ファイルが削除されたりすると、全く同じ状態になるようにターゲットディレクトリを同期してくれる。ディレクトリやシンボリックリンクも対象。

rsyncをデーモンモードで起動することも可能だが、SSHで十分だと思われる。
(暗号化のオーバーヘッドはかかるが)

```ruby:rsync同期(随時利用)
1)ローカル同期
rsync -av --delete {sourcedir} {targetdit}

2)リモート同期(SSHで同期)
rsync -av -e 'ssh -p 22'--delete {sourcedir} {user}@{targethost}:{targetdit}
```

| オプション | 別名 | 意味 |
|:--|:--|
| -a | -rlptgoD と同じ |
| -r | 指定ディレクトリ配下をすべて対象とする |
| -l | シンボリックリンクをそのままシンボリックリンクとしてコピー |
| -p | パーミッションをそのままコピー |
| -t | タイムスタンプをそのままコピー |
| -g | グループをそのままコピー |
| -o | ファイル所有者をそのままコピー (root のみ有効) |
| -D | --devices --specials と同じ |

```ruby:lsync同期(常時利用)
ソース側でlsyncdサービスを起動すればOK。
設定ファイルの内容は以下。settingsで全体的な設定をして、syncで個別の監視内容や更新時の処理を記述する。syncは複数記述することができる。内部的にrsyncで同期する。
---[/etc/lsyncd.cong]------------------------
settings {
    logfile    = "/var/log/lsyncd/lsyncd.log",
    pidfile = "/var/pid/lsyncd",
    statusFile = "/var/log/lsyncd/lsyncd.status", #最新の処理結果が書かれる
    maxProcesses = 2,                             #同時にsyncを走らせる数
    insist       = 1,                             #起動時に接続に失敗しても再接続を試み続ける
}
sync {
    default.rsync,
    source = "/var/www/html/",               #監視対象のディレクトリ。rsyncのSRCに相当
    target = "example.com:/var/www/html/",   #同期先のホスト名＋ディレクトリ。rsyncのDESTに相当
    rsync  = {
        archive = true,                      #アーカイブモード=rsyncの-a
        links   = true,                      #シンボリックリンクをシンボリックリンクとしてrsync
        update  = true,                      #ターゲット側でより新しいファイルは同期しない。
        verbose = false,                     #詳細モード
        exclude = { "*.bak", "*.backup" },   #除外対象定義
        rsh     = "/usr/bin/ssh -p 22",      #接続時に使うsshコマンド。ポートや鍵のファイルはここで指定できる

    }
}
---------------------------------------------

```

#iSCSI
iSCSI は、データストレージ装置に対するネットワークデータ転送を基にしたインターネットプロトコル。IP ネットワークに SCSI コマンドを送ると、iSCSI は、ローカルエリアネットワーク (LAN)、広域ネットワーク (WAN)、またはインターネット経由でデータを転送できる。 iSCSI を使うと、ストレージサーバーのスペースがクライアントのオペレーションシステムによりローカルディスクとして処理されます。実際は、ディスクに転送されるすべてのデータはネットワーク経由でストレージサーバーに転送される。

iscsiを提供するサーバ側（ストレージデバイスを提供する側）をiSCSIターゲット、
iscsiを利用するクライアント側をiSCSIイニシエータと一般的には呼ぶ。

```ruby:iscsiターゲット側の設定
#(1) iSCSIターゲット構成ツールのインストール
yum install -y targetcli

#(2) targetサービスの自動起動設定&起動
systemctl enable target.service && systemctl start target.service
※特にプロセスは無い。
[root@iscsi ~]# systemctl status target
● target.service - Restore LIO kernel target configuration
   Loaded: loaded (/usr/lib/systemd/system/target.service; enabled; vendor preset: disabled)
   Active: active (exited) since Mon 2019-03-25 05:29:43 UTC; 11min ago
 Main PID: 2626 (code=exited, status=0/SUCCESS)
   CGroup: /system.slice/target.service

Mar 25 05:29:42 iscsi systemd[1]: Starting Restore LIO kernel target configuration...
Mar 25 05:29:43 iscsi systemd[1]: Started Restore LIO kernel target configuration.


#3)targetcliにて構成を行っていく。初期状態は以下のようにまっさら。
###############
targetcli ls /
o- / ......................................................................................................................... [...]
  o- backstores .............................................................................................................. [...]
  | o- block .................................................................................................. [Storage Objects: 0]
  | o- fileio ................................................................................................. [Storage Objects: 0]
  | o- pscsi .................................................................................................. [Storage Objects: 0]
  | o- ramdisk ................................................................................................ [Storage Objects: 0]
  o- iscsi ............................................................................................................ [Targets: 0]
  o- loopback ......................................................................................................... [Targets: 0]
###############

#4)Backstoreの作成
#ストレージオブジェクトを作成して、バックストアが使用するリソースを定義します。 

・FILEIO (Linux ファイルと関連付けられたストレージ)
#要するに、ファイルをストレージオブジェクトと仮想的に定義して他サーバにIPプロトコル経由で
提供する方式。

targetcli /backstores/fileio create file1 /tmp/disk1.img 200M write_back=false
Created fileio file1 with size 209715200

・BLOCK (Linux BLOCK デバイス)
ブロックドライバーは、/sys/block に指定されているブロックデバイスを定義して提供できるように
する方式。最もパフォーマンスが高い。
targetcli /backstores/block create name=block_backend dev=/dev/sdb

#5)Targetの作成
iSCSI Targetリソースを作成。特に引数指定していない場合はデフォルトのターゲット名で作成される。
targetcli /iscsi create iqn.2019-02.com.example:myhost01

#6)backstoreとiSCSI targetの紐付け
targetcli /iscsi/iqn.2019-02.com.example:myhost01/tpg1/luns create /backstores/block/block_backend

#7)ACLの設定
iSCSIイニシエータ側の以下で確認できる定義を混ぜ込む。
例)cat /etc/iscsi/initiatorname.iscsi 
XXXXX

targetcli /iscsi/iqn.2019-02.com.example:myhost01/tpg1/acls create XXXXX

#8)設定の保存
targetcli saveconfig

Tips:設定の初期化
targetcli clearconfig confirm=True
```
###参考
https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/7/html/storage_administration_guide/ch24


```ruby:iscsiイニシエータ側の設定
#(1) iSCSIイニシエータ構成ツールのインストール
yum install iscsi-initiator-utils

#2)イニシエータ側のIQN確認。必要あればカスタマイズ。
cat /etc/iscsi/initiatorname.iscsi

#3)アクセス可能なターゲット検索。
iscsiadm -m discovery -t st -p <target-ip-address> 
例)
[root@rac1 ~]# iscsiadm -m discovery -t st -p 10.128.0.3
10.128.0.3:3260,1 iqn.2019-02.com.example:myhost01

#4) #3で判明したターゲットのIQNに対してログインする。
iscsiadm -m node -T iqn.2019-02.com.example:myhost01 -l 
例)
[root@rac1 ~]# iscsiadm -m node -T iqn.2019-02.com.example:myhost01 -l 
Logging in to [iface: default, target: iqn.2019-02.com.example:myhost01, portal: 10.128.0.3,3260] (multiple)
Login to [iface: default, target: iqn.2019-02.com.example:myhost01, portal: 10.128.0.3,3260] successful.

#5)以下sdbとしてiSCSI接続のデバイスが追加された。
[root@rac1 ~]# lsblk -S
NAME HCTL       TYPE VENDOR   MODEL             REV TRAN
sda  0:0:1:0    disk Google   PersistentDisk   1    
sdb  2:0:0:0    disk LIO-ORG  block_backend    4.0  iscsi
```
###参考
https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/7/html/storage_administration_guide/osm-create-iscsi-initiator

iSCSI時のデバイス名のずれをudevで固定する方法
https://access.redhat.com/solutions/1135513


#Firewalld(RHEL7/CentOS7)

firewalld は、D-Bus インターフェースを使用して、動的にカスタマイズできるホストベースのファイアウォールを提供するファイアウォールサービスデーモン。ルールが変更するたびに、ファイアウォールデーモンを再起動する必要なくルールの作成、変更、および削除を動的に削除可能。
firewalld は、ゾーン および サービス の概念を使用し、トラフィック管理を簡素化する。ゾーンは、事前定義したルールセットです。ネットワークインターフェースおよびソースはゾーンに割り当てることができる。

CentOS7ではファイアウォールの設定が「iptables」から「firewalld」に変更となった。
いずれもLinuxOS自体のパケットフィルタリング機能であることに変わりはないが、CentOS7からはこちらが推奨(理由は簡素化されているから？)。今まで通り「iptables」の設定を有効にすることも可能。「iptables」を使用する際は「firewalld」を無効にしなければならない。

事前に以下9つのゾーンが定義されている。デフォルトゾーンはpublic。
インターフェース接続が NetworkManager に追加されると、デフォルトゾーンに割り当てられる。
blockとdropの違いは、dropはネットワークリクエストに反応無し、blockは拒否メッセージを返す点。

・block
IPv4 の場合は icmp-host-prohibited メッセージ、そして IPv6 の場合は icmp6-adm-prohibited メッセージで、すべての着信ネットワーク接続が拒否されます。システム内で開始したネットワーク接続のみが可能です。
・dmz
公開アクセスが可能ではあるものの、内部ネットワークへのアクセスには制限がある非武装地帯にあるコンピューター用。選択した着信接続のみが許可されます。
・drop
着信ネットワークパケットは、通知なしで遮断されます。発信ネットワーク接続だけが可能です。
・external
マスカレードを特別にルーター用に有効にした外部ネットワーク上での使用向けです。自分のコンピューターを保護するため、ネットワーク上の他のコンピューターを信頼しません。選択された着信接続のみが許可されます。
・home
そのネットワークでその他のコンピューターをほぼ信頼できる自宅での使用。選択した着信接続のみが許可されます。
・internal
そのネットワークでその他のコンピューターをほぼ信頼できる内部ネットワークでの使用。選択した着信接続のみが許可されます。
・public
そのネットワークでその他のコンピューターを信頼できないパブリックエリアでの使用。選択した着信接続のみが許可されます。
・trusted
すべてのネットワーク接続が許可されます。
・work
そのネットワークで、その他のコンピューターをほぼ信頼できる職場での使用。選択した着信接続のみが許可されます。

引用：https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/7/html/security_guide/sec-using_firewalls


```ruby:firewalld基本コマンド(凡例)
#--permanent設定後の永続反映のためにこれ。
firewall-cmd --reload

#ZONE（NewZone）の作成
firewall-cmd --permanent --new-zone=NewZone
 
#ZONE（NewZone）の削除
firewall-cmd --permanent --delete-zone=NewZone

#ZONEの確認
firewall-cmd --get-active-zones
     
#ZONEの確認（詳細）
firewall-cmd --list-all-zones
     
#ZONEの確認（ZONE指定）
#--zoneがなければデフォルトZONEになる
firewall-cmd --list-all --zone=NewZone
 
#アクティブZONEの確認
firewall-cmd --get-active-zones
 
#デフォルトZONE（NewZone）の確認
firewall-cmd --get-default-zone
 
#デフォルトZONE（NewZone）の変更
firewall-cmd --set-default-zone=drop

##サービス登録されている場合こちらで可能。
#登録されているサービス一覧
firewall-cmd --get-services
     
#サービスの登録
firewall-cmd --permanent --zone=NewZone --add-service=http
     
#サービスの削除
firewall-cmd --permanent --zone=NewZone --remove-service=http

##サービス登録されていない場合こちらで直ポーと指定
#53/TCP(DNS)ポートの登録
firewall-cmd --permanent --zone=NewZone --add-port=53/tcp
     
#53/UDP(DNS)ポートの登録
firewall-cmd --permanent --zone=NewZone --add-port=53/udp
     
#53/TCP(DNS)ポートの削除
firewall-cmd --permanent --zone=NewZone --remove-port=53/tcp
     
#53/UDP(DNS)ポートの削除
firewall-cmd --permanent --zone=NewZone --remove-port=53/udp

##IPアドレスで接続元制限したい場合はこちら。
#IPアドレスの登録
firewall-cmd --permanent --zone=NewZone --add-source=192.168.1.101/32
     
#マスクで範囲指定可能
firewall-cmd --permanent --zone=NewZone --add-source=192.168.1.1/24
 
#IPアドレスの削除
firewall-cmd --permanent --zone=NewZone --remove-source=192.168.1.101/32
firewall-cmd --permanent --zone=NewZone --remove-source=192.168.1.1/24

#NICへのZONE割当
nmcli connection modify [対象NIC] connection.zone [対象ゾーン]
nmcli connection up [対象NIC]

#NICに割り当てられているゾーン確認
firewall-cmd --get-zone-of-interface=eth0

```
注意：上記はあくまでOR条件、例えばsourceとportを同一ゾーンに設定したからといって、
ANDで適用される訳ではなくORで適用される。ので複数条件の組合せを使いたい場合は下記のリッチ言語

```ruby:firewalld応用コマンド
#リッチ言語コマンドを使い,特定の接続元からの特定のポートへのアクセスという複数要素組み合わせの制御も可能。
①rule family=(ipv4/ipv6)
②	[ source address =(souce address)[/mask] [invert="true"] ]
②	[ destination address =(souce address)[/mask] [invert="true"] ]
③	[ service name=(service) ]
③	[ port port=(portid) protocol=(protocol) ]
③	[ forward-port port=(portid) protocol=(protocol) to-port=(portid) to-addr=(address) ]
④	[ log [ prefix=(prefix) ] [ level=(loglevel) ] [ limit value=(rate)/(duration) ]
⑤	[ masquerade ]
⑥	[ accept|reject|drop ]

#特定IPからのSSH接続のみ許可。
firewall-cmd --permanent --zone=NewZone --add-rich-rule="rule family="ipv4" source address="192.168.1.101/32" port protocol="tcp" port="22" accept"

#特定IPからの接続のみ全許可。
firewall-cmd --permanent --zone=NewZone --add-rich-rule="rule family="ipv4" source address="192.168.1.101/32" accept"

#リッチルールの削除
firewall-cmd --permanent --zone=NewZone --remove-rich-rule="Rule名"

```

firewalldの動作確認用にtcpdumpを使ったので使い方メモを実施する。

```ruby:firewalldの動作確認用
#特定のネットワークを指定してキャプチャ
tcpdump net 192.168.100.0/24

#特定のホストを指定してキャプチャ
tcpdump host 192.168.100.12

#特定のNICを指定してキャプチャ
tcpdump -i enp0s3

#特定のポートを指定してキャプチャ
tcpdump port 80

#特定のプロトコルを指定してキャプチャ
tcpdump icmp
tcpdump tcp
tcpdump udp
tcpdump arp

#and条件,or条件
tcpdump net 192.168.100.0/24 and host 192.168.100.12
tcpdump net 192.168.100.0/24 or host 192.168.100.12

##　送信元アドレスを指定する
tcpdump src 192.168.100.2

##　送信先アドレスを指定する
tcpdump dst 192.168.100.2

#キャプチャするバイト指定(-s0は無制限)、また名前解決なし(-n)、またアスキーでキャプチャしたデータ表示(-A)
tcpdump -s0 -n -A net 192.168.100.0/24
Tips:-nnとすることで自サーバ以外のポートも数字表記で出力可能。

```