Linuxは、カーネルとそのモジュールがユーザースペースツールに依存してDNS名を解決できるようにする機能を提供します。これは、たとえば、DFSでの参照をサポートするためにCIFSによって使用されます。
私が見ている問題は、カーネルに特定のDNS名を解決させることができず、なぜ失敗するのか理解できないことです。
根本原因を理解するために、次のコマンドを実行して、CIFSとカーネルDNSリゾルバーの両方でデバッグ出力を有効にしました。
echo "1" > /sys/module/dns_resolver/parameters/debug # dns_resolver
echo "7" > /proc/fs/cifs/cifsFYI # CIFS
失敗が発生したときにdmesgに表示されるものは次のとおりです。
fs/cifs/cifs_dfs_ref.c: DFS: ref path: \ESOTEST\dfstest\FS_SERV
fs/cifs/cifs_dfs_ref.c: DFS: node path: \FS\FS_SERV
fs/cifs/cifs_dfs_ref.c: DFS: fl: 2, srv_type: 0
fs/cifs/cifs_dfs_ref.c: DFS: ref_flags: 0, path_consumed: 24
fs/cifs/netmisc.c: address conversion returned 0 for FS
fs/cifs/netmisc.c: address conversion returned 0 for FS
[ls ] ==> dns_query((null),FS,2,(null))
fs/cifs/dns_resolve.c: dns_resolve_server_name_to_ip: unable to resolve: FS
fs/cifs/cifs_dfs_ref.c: cifs_compose_mount_options: Failed to resolve server part of \\FS\FS_SERV to IP:
-22
そして、これは成功した解決の出力です:
fs/cifs/cifs_dfs_ref.c: DFS: node path: \ESOTEST\File-Server
fs/cifs/cifs_dfs_ref.c: DFS: fl: 2, srv_type: 0
fs/cifs/cifs_dfs_ref.c: DFS: ref_flags: 0, path_consumed: 28
fs/cifs/netmisc.c: address conversion returned 0 for ESOTEST
fs/cifs/netmisc.c: address conversion returned 0 for ESOTEST
[ls ] ==> dns_query((null),ESOTEST,7,(null))
[ls ] call request_key(,ESOTEST,)
[ls ] ==> dns_resolver_match(ESOTEST,ESOTEST)
[ls ] <== dns_resolver_match() = 1
[ls ] <== dns_query() = 14
fs/cifs/dns_resolve.c: dns_resolve_server_name_to_ip: resolved: ESOTEST to 192.168.56.102
fs/cifs/cifsfs.c: Devname: \\ESOTEST\File-Server flags: 0
私はDNSサーバーとしてWindowsを使用しており、マシンから「FS」という名前を解決できます。
$ ping FS
PING FS.esodomain.com (192.168.56.104) 56(84) bytes of data.
64 bytes from fs.esodomain.com (192.168.56.104): icmp_seq=1 ttl=128 time=1.37 ms
64 bytes from fs.esodomain.com (192.168.56.104): icmp_seq=2 ttl=128 time=0.630 ms
また、key.dns_resolverを使用して手動でテストを実行しようとしましたが、機能しているようです。
$ key.dns_resolver -vv -D "FS" 'hello'
I: Key description: 'dns_resolver;-1;-1;0;FS'
I: Callout info: 'hello'
D: Get A/AAAA RR for hostname:'FS', options:'hello'
D: Opt hello
D: Resolve 'FS' with 1ff
D: getaddrinfo = 0
D: RR: 0,2,1,6,10,(null)
D: append '192.168.56.104'
I: The key instantiation data is '192.168.56.104'
/etc/request-key.confの内容は次のとおりです。
create dns_resolver * * /sbin/key.dns_resolver %k
create user debug:* negate /bin/keyctl negate %k 30 %S
create user debug:* rejected /bin/keyctl reject %k 30 %c %S
create user debug:* expired /bin/keyctl reject %k 30 %c %S
create user debug:* revoked /bin/keyctl reject %k 30 %c %S
create user debug:loop:* * |/bin/cat
create user debug:* * /usr/share/keyutils/request-key-debug.sh %k %d %c %S
negate * * * /bin/keyctl negate %k 30 %S
私がこれをいじっている理由は、WindowsDFS共有を正常にマウントしようとしているためです。ルートサーバーでホストされているフォルダーをマウントしてアクセスすることはできますが、外部サーバーを参照するサブフォルダーにアクセスしようとすると、次のようになります。
ls: cannot access /mnt/dfstest/FS_SERV/: Invalid argument
私は3.7.10カーネルを使用しています:
Linux gentoo 3.7.10-gentoo-r1 #3 SMP Fri Apr 19 17:32:20 PDT 2013 x86_64 Intel(R) Xeon(R) CPU E5620 @ 2.40GHz GenuineIntel GNU/Linux
ネットワークキャプチャでは、「ESOTEST」のリクエストが表示されているのに、「FS」のDNSリクエストは表示されません。これは、リクエストが行われたことがないことを示しています。
これをトラブルシューティングするために、次のどのステップをお勧めしますか?
これはLinuxカーネルが原因のようです。具体的には、dns_resolverによって。 「FS」は解決しようとさえしていません。
Dns_resolver(net/dns_resolver/dns_query.c)の次の行が、これを引き起こしているようです。
if (namelen < 3)
return -EINVAL;
なぜこのチェックがあるのかわかりません。他のサーバーの名前を「FS」からもっと長いものに変更してみます。このチェックを外してカーネルを再コンパイルしてみます。
更新:はい、それが理由であり、ホスト名の名前をより長い名前に変更した後に機能します
また、 どうやら カーネルのdns_resolverはTTLを尊重しません。 カーネルのDNSキャッシュをクリアするには :
Sudo keyctl clear $((16#$(Sudo cat/proc/keys | grep .dns_resolver | awk '{print $ 1;}')))