Windows 10でNFSクライアントを有効にするとSambaの応答が悪くなる謎

【環境】
クライアント:Windows 10 1803
サーバ:CentOS 6/7 の標準リポジトリのSambaで構築した共有フォルダ


コンパネからWindowsの機能として、NFSクライアントを有効にしたところ、Sambaの共有フォルダの応答が悪くなった。

ちょっとテストでWindowsクライアントが必要になり、Windowsの機能から有効にした時に気が付いた。


症状としては・・・

  • NFSクライアントを有効にしただけ(マウントしていない状態)で発生する。
  • ファイルをクライアント→Sambaの共有フォルダへコピーすると、99%のところで停止し、Windowsエクスプローラーが応答しなくなる。
  • 共有フォルダ上のファイルを右クリックしてプロパティを出そうとすると、出ない。Windowsエクスプローラーが応答しなくなる。
  • Samba側のログにエラーなどは出ていない

なお、

  • 同じクライアント~サーバ間で、FTP/SFTPでやり取りする分には、問題ない。
  • WindowsNFSクライアントを無効にしてWindowsを再起動すると、問題は起こらなくなる。

なので、WindowsNFSクライアントが原因と思っているけど、調査に難航しそう。

相性の問題?

freshclam コマンドが「Can't create new socket」を出す

環境

CentOS 6.x/7.x
clamav-0.99.4-1.el6.x86_64 ~ clamav-0.100.0-1.el6.x86_64
clamav-0.99.4-1.el7.x86_64 ~ clamav-0.100.0-2.el7.x86_64

2018年の5月下旬頃からか、以下のエラーが出るようになった。

/etc/cron.daily/freshclam:

ERROR: Can't create new socket: Address family not supported by protocol

cronで定期実行されているclamavシグネチャの更新時に、何やらエラーが出ているようだった。

エラーメッセージを見る限り、IPv4/IPv6関係か(?)と思い、
/etc/freshclam.conf の設定を見ると、

 DatabaseMirror

の設定値はIPv4のものだけになっていて、IPv6向けの設定はコメントされている。
OS側のネットワーク設定でも、IPv6を無効化しているので、問題ないように思えた。

ClamAVのMailing List Archiveにも、同様の問題が投稿されていて、以下が最後に確認したものだった。
https://lists.gt.net/clamav/users/73099

リプライが途中で終わっていた。

暫くして、ClamAVのMailing List Archive を見たら、
https://lists.gt.net/clamav/users/73229

The error you're referring to has been fixed in 0.100.1. Unfortunately,
unless you enable ipv6 for your computer/network, you'll have to live
with the error until you're able to upgrade to 0.100.1.

とあった。

このバージョンがyumリポジトリに来るのを待っていたら、7/25 にyum updateしたところ更新された。

更新後のバージョンは、以下の通り。

clamav-0.100.1-1.el6.x86_64
clamav-0.100.1-1.el7.x86_64

このバージョンに更新後、freshclam で同様のエラーが出なくなった。

OpenLDAP の同期(レプリケーション)で refreshOnly を指定するとエラーになる

OpenLDAP の同期(レプリケーション)で refreshOnly を指定するとエラーになる

環境(プロバイダ、コンシューマ同じ)

$ cat /etc/redhat-release
CentOS Linux release 7.5.1804 (Core)

$ rpm -qa | grep -i openldap
openldap-servers-2.4.44-15.el7_5.x86_64
openldap-2.4.44-15.el7_5.x86_64
openldap-clients-2.4.44-15.el7_5.x86_64


設定(プロバイダ)

overlay                   syncprov
syncprov-sessionlog       100
index entryCSN,entryUUID  eq


設定(コンシューマ)

syncrepl
 rid=11
 type=refreshOnly
 interval=00:00:05:00
 provider=ldap://192.168.1.11
 bindmethod=simple
 binddn="cn=Manager,dc=master,dc=ldap,dc=local"
 credentials=******
 searchbase="dc=master,dc=ldap,dc=local"
 filter=(objectClass=*)
 scope=sub

※設定は、プロバイダ/コンシューマどちらも、Configuration Backend を使わず従来のテキスト形式で設定している。


ログを確認するため、SLAPD_OPTIONS に "-s 16640" を追加してサービスを起動。

syslogに出力されたログを確認すると、次のようなエラーが出て、同期しない。

slapd[1661]: slapd starting
slapd[1661]: do_syncrep2: rid=011 LDAP_RES_SEARCH_RESULT
slapd[1661]: do_syncrep2: rid=011 cookie=rid=011,csn=20180701054359Z#000000#00#000000
slapd[1661]: slap_queue_csn: queueing 0x7fa68010a010 20180701054359.000000Z#000000#000#000000
slapd[1661]: slap_graduate_commit_csn: removing 0x7fa68010a010 20180701054359.000000Z#000000#000#000000
slapd[1661]: syncrepl_updateCookie: rid=011 be_modify failed (32)


以下、試したこと。

  • コンシューマから、ldapsearchコマンドでは、データを検索できる。

 →FWの設定やLDAPのアクセス権は大丈夫そう。

  • このコンシューマから、同じ設定のまま、CentOS 5.x で構築した同じ設定のプロバイダに接続すると、データは同期する。

 →コンシューマの設定に問題は無さそう?

  • プロバイダ側に問題があるのかと思い、プロバイダ側のモジュール不足の懸念を払拭するため、全てのモジュールをロード

 →変化はない。

  • コンシューマ側にて、type を refreshOnly → refreshAndPersist へ変更

 →エラー無く同期できる。

  • syncrepl_updateCookie をキーワードにして検索

 →類似例は出て来ない。(2018/7/15時点)


とりあえずの結論としては、おそらくプロバイダ/コンシューマが、いずれも openldap-2.4.x の場合だけに発生する問題と思われる。

設定が悪いのか、真っ当な対応が分からないので、同期モードを refreshAndPersist で運用できるなら、refreshAndPersist で運用すれば回避はできる。

引き続き調査して、何か分かったら追記するつもり。

yum で古いパッケージをインストールする方法

何らかの理由で、古いパッケージをインストールしたい時のためのメモ。

yum で利用可能な古いパッケージを探すには、--showduplicates オプションを付加して検索する。

利用可能なパッケージは、RHELCentOSでは、動作が異なるらしい。
 RHEL :過去のバージョン全てを利用可能(たぶん、全てと思われる)
 CentOS:過去のバージョンの一部


RHEL 6.10の例

$ yum search --showduplicates nmap
・・・略
2:nmap-5.21-3.el6.x86_64 : Network exploration tool and security scanner
2:nmap-5.21-4.el6.x86_64 : Network exploration tool and security scanner
2:nmap-5.51-2.el6.x86_64 : Network exploration tool and security scanner
2:nmap-5.51-3.el6.x86_64 : Network exploration tool and security scanner
2:nmap-5.51-4.el6.x86_64 : Network exploration tool and security scanner
2:nmap-5.51-6.el6.x86_64 : Network exploration tool and security scanner
2:nmap-5.51-6.el6.x86_64 : Network exploration tool and security scanner


CentOS 6.10の例

$ yum search --showduplicates nmap
・・・略
2:nmap-frontend-5.51-6.el6.noarch : The GTK+ front end for nmap
2:nmap-5.51-6.el6.x86_64 : Network exploration tool and security scanner
2:nmap-5.51-6.el6.x86_64 : Network exploration tool and security scanner


CentOSの場合、パッケージによって利用可能なバージョンの数が異なる模様。

$ yum search --showduplicates firefox
・・・略
firefox-52.8.0-1.el6.centos.i686 : Mozilla Firefox Web browser
firefox-52.8.0-1.el6.centos.x86_64 : Mozilla Firefox Web browser
firefox-60.1.0-5.el6.centos.i686 : Mozilla Firefox Web browser
firefox-60.1.0-5.el6.centos.x86_64 : Mozilla Firefox Web browser
firefox-60.1.0-6.el6.centos.i686 : Mozilla Firefox Web browser
firefox-60.1.0-6.el6.centos.x86_64 : Mozilla Firefox Web browser
firefox-60.1.0-6.el6.centos.x86_64 : Mozilla Firefox Web browser


インストールの際は、パッケージ名のみでなく、バージョンまで含めて指定するとインストールできる。

# yum install firefox-52.8.0-1.el6.centos.x86_64

tcpdump でNSDのクエリログを取る

【環境】
CentOS 7.5
nsd-4.1.20-1.el7.x86_64


NSDDNSサーバ)だと、標準の機能ではクエリログを取得できない。
nsd-4.1.20 の時点では)

権威サーバでクエリログが必要なニーズが無いのかもしれないが、どれだけのクエリがあるのか調べたかったので、ログを取る方法を考えた。

で、思い付いたのが tcpdump でログを取ること。

#!/bin/bash

NIC="ens160"
DST_IP="192.168.1.20"
DST_PORT="53"
LOG_FILE="/var/log/nsd-query/query.log"
ROTATE_SIZE=10485760
REMOVE_RANGE=129600

# check log rotate
if [ ${ROTATE_SIZE} -lt $(ls -l ${LOG_FILE} | awk '{print $5}') ] ; then
  pkill -9 tcpdump
  mv ${LOG_FILE} ${LOG_FILE}"-"$(date "+%Y%m%d-%H%M%S")
fi

# remove old files
find $(dirname ${LOG_FILE}) -type f -name $(basename ${LOG_FILE})"*" -mmin +${REMOVE_RANGE} -delete

# start logger
if [ $(ps aux | grep tcpdump | grep -v 'grep' -c) -lt 1 ] ; then
  /usr/sbin/tcpdump -p -l -nn -tttt -i ${NIC} dst host ${DST_IP} and dst port ${DST_PORT} >> ${LOG_FILE} &
fi

このスクリプトは、以下のような動作を行う。

  • キャプチャするNIC、そのNICのIP、ポート番号を指定
  • クエリログの出力先を指定
  • クエリログをローテーションするファイルサイズ(バイト)の閾値を指定
  • 古いクエリログファイルを削除するための閾値(秒)を指定
  • クエリログのファイルのサイズが設定値を超えた場合、tcpdump プロセスをkill してログファイルをリネームしてmv
  • 指定秒より古いクエリログファイルがあれば削除
  • ps コマンドでtcpdump プロセスが見つからない場合だけ(重複起動をチェック)、ログ取得のためのtcpdump を実行

これを cron などで定期時刻すれば、重複実行を避けつつクエリログを取得し、ログファイルのローテーションを行う。
テキストファイルなので、cat(圧縮したものはzcat)で開き、適当な条件で grep する。


ログファイルのローテーションと言えば、logrotate が手軽だが、tcpdump をローテーションしようとすると、anacron がゾンビのように残ってしまい、うまくローテーションされなかった。

tcpdump にも、出力ファイルをローテーションするオプション(-G)があるが、tcpdump -w で生データを書き出す場合、-r オプションでしか読めず、gzip圧縮して出力場合は直接読み込めない。

圧縮して出力すると、いったん非圧縮ファイルへ書きだす必要があり、圧縮するのを止めようか迷ったが、容量圧迫のプレッシャーに勝てず断念。

また、tcpdump のローテーションでは、古いファイルを削除する仕組みが無い。

これらをうまく解決できず、シェルスクリプト側で無理やりローテーションするようにした。

NSD で複数のスレーブにゾーン転送する場合の記述例

【環境】
CentOS 7.5
nsd-4.1.20-1.el7.x86_64


マスタとして動作しているNSDにて、複数のスレーブ(NSDでもBINDでも)へゾーン転送したい場合の記述例。

ドキュメントに説明が書いてあるが、具体的な記述例がない。

ゾーン オプション

ゾーン毎に一つのzone:節で指定されるオプションが必要です。複数のサーバー
を加えるためにはアクセス制御リストの要素を複数回与えます。これらの要素は
明示的に追加される必要があります。

スレーブが複数ある場合には、設定をその分だけ列挙する。

例)

zone:
        name: "aaa.bbb.domain"
        zonefile: "aaa.bbb.domain.zone"
        provide-xfr: 192.168.1.6 NOKEY
        provide-xfr: 192.168.1.7 NOKEY
        notify: 192.168.1.6 NOKEY
        notify: 192.168.1.7 NOKEY
        notify-retry: 5
provide-xfr: 192.168.1.6 192.168.1.7 NOKEY
 あるいは
provide-xfr: 192.168.1.6, 192.168.1.7 NOKEY

のような書式ではエラーになる。
1つのIPについて1行記載し、スレーブが複数台の場合は繰り返す。

なお、ゾーン転送のログは、verbosity:1 にしないと確認できない。
(デフォルトは、verbosity:0 になっていて、ログに出ない)

参考;
nsd.conf(5) – 日本Unboundユーザー会

Postfix でメールの宛先をもとにフィルタする方法

テスト環境にて、誤ってメールを送信してしまう場合に備え、予め設定した宛先以外にはPostfixがメールを送信しないようにする方法。
但し、テスト環境におけるメールの送信は、他ホストのSMTPを利用せず、自身で動作しているPostfixから送信する前提。

【環境】
CentOS 6/postfix-2.6.6-8.el6.x86_64
CentOS 7/postfix-2.10.1-6.el7.x86_64


/etc/postfix/main.cf にて、ヘッダーのチェックを有効化する。

#header_checks = regexp:/etc/postfix/header_checks
 ↓
header_checks = regexp:/etc/postfix/header_checks


/etc/postfix/header_checks を開いて、正規表現でルールを記載する。

例)全て拒否

/^To: .*/ REJECT


$ mail root のようなローカル配送も失敗する。
 →エラーログ:reject: header To: root from local;
但し、その後、失敗した旨を通知するメールはroot宛等に送信される。


例)OK にマッチしたアドレスなら送信、マッチしない場合は全て拒否

/^To: hoge@myhostname.domain/ OK
/^To: .*/ REJECT


例)特定アドレスと特定ドメインへは送信を許可、マッチしなければ全て拒否

/^To: hoge@myhostname.domain/ OK
/^To: .*@test.domain/ OK
/^To: .*/ REJECT


サービス再起動

CentOS 6
# /etc/init.d/postfix restart

CentOS 7
# systemctl restart postfix


メールを送信して、許可されていない宛先だった場合には、メールログに送信を拒否した旨が記録される。

reject: header To: 

追記(2018/2/20)

/^To: hoge/ OK

のように指定した OK は、DUNNO の別名。
これは後方互換性のため残されている設定値。
他の設定値は、man や以下の日本語ドキュメントを参照。

参考;
Postfix manual - header_checks(5)


注意しなければいけないのが、DUNNO/OK の動作。
DUNNO/OK は、「このテーブルに検索キーが見つからなかったように見せ、次の入力行を検査する」との事。

つまり、このアクションが行われた後、そこで以降のルールをチェックしない訳ではない。

ハマりやすいのは、以下のような定義をした場合。

/@test.domain/ OK
/./ REJECT

To か From かヘッダを記載していないので、たとえ To が OK にマッチしても、From など他のヘッダに対しても検査が行われるので、それが最後のREJECTに引っかかりREJECTされてしまう。