LINUX.ORG.RU

Помогите раскусить nfs4 и user/group id mapping

 ,


1

1

Тема избитая, но нигде не смог найти решения.

Суть: помогите настроить статическую трансляцию юзеров между NFSv4 сервером и клиентом. Нюанс: доступ к настройкам сервера ограничен, а на клиенте можно делать что угодно; детали - ниже.

Есть NAS; он экспортирует директорию по nfs.
На нем есть юзеры admin (1024), kroz(1027), а также root(0).
Конфигурация в GUI: NFSv4, NFSv4 domain = DDD, Kerberos Settings пусты; пункт «ID mapping» не активен (он в разделе Kerberos). Если надо больше - говорите, есть доступ по ssh.
Так как это NAS, хотелось бы ограничиваться конфигом в GUI если это возможно.

Есть клиент; он монтирует директорию.
На нем есть юзеры kroz (1000), а также root(0).
Вот после монтирования от рута:

192.168.0.205:/volume1/data1 on /mnt/dw type nfs4 (rw,noexec,nosuid,nodev,addr=192.168.0.205,clientaddr=192.168.0.200,_netdev)

Вот что я вижу на сервере через ssh (да и через GUI):

$ ls -la
drwxrwxrwx    6 root     root          4096 Feb 28 16:41 .
drwxr-xr-x   11 root     root          4096 Feb 28 16:32 ..
drwxr-xr-x    2 1000     1000          4096 Feb 28 16:41 1
drwxr-xr-x   24 admin    users         4096 Feb 28 16:29 music
drwxr-xr-x    2 kroz     kroz          4096 Feb 28 16:38 test
drwxr-xr-x    7 admin    users         4096 Dec 31  2013 video
Это образовалось после множества экспериментов.

А вот что я вижу на клиенте:

$ ls -la 
total 20
drwxrwxrwx  6 root root 4096 фев 28 16:41 .
drwxr-xr-x  8 root root  224 дек 13 23:01 ..
drwxr-xr-x  2 root root 4096 фев 28 16:41 1
drwxr-xr-x 24 root root 4096 фев 28 16:29 music
drwxr-xr-x  2 root root 4096 фев 28 16:38 test
drwxr-xr-x  7 root root 4096 дек 31  2013 video
Что за ерунда? Куда подевались все пользователи?

От рута я могу создавать и удалять директории/файлы, но chown не работает.

Вот /etc/idmapd.conf на клиенте:

$ cat idmapd.conf | grep -v "^#"
[General]
Verbosity = 10
Domain=DDD
[Mapping]

Nobody-User = nobody
Nobody-Group = nobody

[Translation]

Method=static
 
[Static]

admin@DDD = kroz

[UMICH_SCHEMA]
Клиент:
$ /etc/init.d/nfsclient start
 * Starting rpcbind ...[ ok ]
 * Starting NFS statd...[ ok ]
 * Setting up RPC pipefs ...[ ok ]
 * Starting idmapd ...
/usr/sbin/rpc.idmapd -vvv
rpc.idmapd: libnfsidmap: using domain: DDD
rpc.idmapd: libnfsidmap: Realms list: 'DDD' 
rpc.idmapd: libnfsidmap: processing 'Method' list
rpc.idmapd: libnfsidmap: loaded plugin /usr/lib/libnfsidmap/static.so for method static
[ ok ]
 * Starting NFS sm-notify ... [ ok ]

$ ps ax | grep idmapd
10967 ?        Ss     0:00 /usr/sbin/rpc.idmapd -vvv
18847 pts/1    S+     0:00 grep --colour=auto idmapd
Как по мне - ни на что не влияет. /etc/init.d/nfsclient запускал, и не запускал - всё равно.

Вот /etc/exports на сервере:

$ cat /etc/exports
/volume1/data1  192.168.0.200(rw,async,no_wdelay,insecure,no_root_squash,insecure_locks,sec=sys,anonuid=1025,anongid=100) 

Вот /etc/idmapd.conf на сервере:

$ cat /etc/idmapd.conf 
[General]
Domain=DDD
[Mapping]
Nobody-User=guest
Nobody-Group=users
[Translation]
Method=nsswitch
GSS-Methods=static,synomap
[Static]
Сервер:
$ ps | grep idmap
25879 root      3084 S    /usr/sbin/idmapd
26575 root      4048 S    grep idmap

Мне нужно на клиенте где-то указать, что kroz на сервере - это kroz на клиенте, или что юзер 1027 на сервере, это 1000 на клиенте (да, я в курсе, что в конфиге про admin - не суть). Это всё, что мне нужно. Желательно безо всяких kerberos и LDAP.

Куда копать? Или приведите свои рабочие конфиги, чтобы сделать по образу и подобию...

Уже столько времени на это убил, не могу допереть где и что должно быть! ЛОР, спасай.

cast Pinkbyte, teisatsu, ESTAF

★★★★★

Последнее исправление: Kroz (всего исправлений: 3)

rpc.idmapd на клиенте запущен?

Далее:

admin@192.168.0.205 = kroz

Что это за ересь? Смотрим ман:

#someuser@REALM = localuser

Читаем откуда берется REALM(обычно из DNS-а, ключ Domain в NFS)

Я вообще не заморачивался, у меня и клиент и сервера имеют закомментированный Domain и правильно настроенный DNS. В твоём случае, пусть будет DDD, тогда:

admin@DDD = kroz
Pinkbyte ★★★★★
()
Ответ на: комментарий от Pinkbyte

rpc.idmapd на клиенте запущен?

$ /etc/init.d/nfsclient start
 * Starting rpcbind ...[ ok ]
 * Starting NFS statd...[ ok ]
 * Setting up RPC pipefs ...[ ok ]
 * Starting idmapd ...
/usr/sbin/rpc.idmapd -vvv
rpc.idmapd: libnfsidmap: using domain: DDD
rpc.idmapd: libnfsidmap: Realms list: 'DDD' 
rpc.idmapd: libnfsidmap: processing 'Method' list
rpc.idmapd: libnfsidmap: loaded plugin /usr/lib/libnfsidmap/static.so for method static
[ ok ]
 * Starting NFS sm-notify ... [ ok ]

$ ps ax | grep idmapd
10967 ?        Ss     0:00 /usr/sbin/rpc.idmapd -vvv
18847 pts/1    S+     0:00 grep --colour=auto idmapd

Сразу скажу, что /etc/init.d/rpc.idmapd немного модифицирован. Во-первых, он выводит команду с аргументами (что видно выше). Во-вторых, я заглянул в исходники - rpc.idmapd всегда возвращает 1; т. о. текущая реализация rpc.idmapd всегда завершается неудачей. Поэтому перед eend $? "make sure DNOTIFY support is enabled ..." добавил true. То, что rpc.idmapd на самом деле запускается успешно, видно из вывода команды выше. Да и порты 111, 55352, 60176 пооткрывались (не знаю зачем столько).

Да: ничего не поменялось, вывод ls на подмонтированной шаре тот же.

Еще доп. инфа: Вот /etc/exports на сервере:

$ cat /etc/exports
/volume1/data1  192.168.0.200(rw,async,no_wdelay,insecure,no_root_squash,insecure_locks,sec=sys,anonuid=1025,anongid=100) 

Вот /etc/idmapd.conf на сервере:

$ cat /etc/idmapd.conf 
[General]
Domain=DDD
[Mapping]
Nobody-User=guest
Nobody-Group=users
[Translation]
Method=nsswitch
GSS-Methods=static,synomap
[Static]

Kroz ★★★★★
() автор топика
Последнее исправление: Kroz (всего исправлений: 1)
Ответ на: комментарий от Pinkbyte

Покажи содержимое /proc/keys

На клиенте:

$ cat /proc/keys
12bec7cb I--Q--- 1 perm 1f3f0000 0 65534 keyring _uid_ses.0: 1/4
1db1522b I------ 1 perm 1f030000 0 0 keyring .dns_resolver: empty
2a4ed08f I------ 1 perm 1f030000 0 0 keyring .id_resolver: empty
2edb83c1 I--Q--- 2 perm 1f3f0000 0 65534 keyring _uid.0: empty
397977bf I------ 1 perm 1f030000 0 0 keyring .cifs_idmap: empty
На сервере:
$ cat /proc/keys
08295069 I----- 1 perm 1f030000 0 0 keyring .dns_resolver: empty

Kroz ★★★★★
() автор топика
Ответ на: комментарий от Pinkbyte

Самое забавное, что атрибуты частично работают: там где сервер кажет owner=1000, клиентский kroz (uid=1000) может создавать, удалять и т. п. chown - нет; ls с клиента показывает root. Бред.

Kroz ★★★★★
() автор топика

Так, ведем блог.

При команде ls на клиенте для конверсии имен используется библиотека libnfsidmap. По команде nfsidmap -c она читает /etc/idmapd.conf и подгружает ссотв. плагины.

Если мы сделаем Method = static, то без kerberos это впринципе не работает. Механизм такой: для каждого имени, которое пришло от nfs сервера, вызывается макрос RUN_TRANSLATIONS. Этот макрос проходится по всем плагинам и запускает конвертацию юзеров. Если запускать нечего (например, плагинов нет), по пользователю автоматом в соответствие ставится 0, то есть root.

А теперь внимание: вот конфигурация плагина static:

struct trans_func static_trans = {
	.name			= "static",
	.init			= NULL,
	.name_to_uid		= NULL,
	.name_to_gid		= NULL,
	.uid_to_name		= NULL,
	.gid_to_name		= NULL,
	.princ_to_ids		= static_gss_princ_to_ids,
	.gss_princ_to_grouplist	= static_gss_princ_to_grouplist,
};

То есть он даже не предполагает конвертацию юзеров (static_gss_princ_to_ids и static_gss_princ_to_grouplist, как я понял, работают с kerberos). Иными словами, если у нас Method = static, то всегда owners будут root.

И еще, похоже, что static_gss_princ_to_ids и static_gss_princ_to_grouplist таки не используют функционал kerberos. Но здесь я не уверен, продолжаю копать.

P. S. !@#$@#$!@#%$!@# разработчики!!!
P. P. S. И всё-таки хорошо. что Линукс - open source.

Kroz ★★★★★
() автор топика

Продолжаем разговор.

Method=nsswitch работает нормально: берет имя пользователя, находит ему локальный id и выдает. Но: он обязательно требует формат как «user@domain». И здесь все хорошо за исключением: если на NAS нет пользователя с uid, с которым создан файл.

Например, на NAS есть файл с owner=1000. На NAS нет пользователя с uid=1000. Тогда сервер на NAS берет имя Nobody-User из /etc/idmapd.conf. Но: домен он не добавляет!

На клиенте nsswitch не находит в имени символа '@' и мапит это на nobody. Именно nobody, а не пользователя указанного в как Nobody-User на клиентском /etc/idmapd.conf. Если в Nobody-User указать имя пользователя с доменом, idmapd этот файл не распарсит и вообще не запустится.

Выводы:
- Использовать nsswitch
- Nobody-User и Nobody-Group на клиенте ни на что не влияют
- На сервере есть баг, который состоит в не-добавлении доменного имени к Nobody-User (к остальным добавляет). Значит очень важно, чтобы на сервер были все пользователи, которые указаны как owners к файлам/каталогам.

Как по мне механизм странный. С багом или без, получается нельзя создать универсальный NFS сервер, который бы принимал любые файлы вне зависимости от owner:group. Иными словами, маппинг в NFSv4 обязателен.

Kroz ★★★★★
() автор топика

Короче, проблема решена на 2/3

На клиенте:

$ cat /etc/idmapd.conf
[General]

Verbosity = 10
Domain =  CCC

[Mapping]

[Translation]

Method = nsswitch

[Static]

[UMICH_SCHEMA]

$ cat /etc/fstab |grep nfs4
192.168.0.205:/volume1/data1    /mnt/dw nfs4    nfsvers=4,rw,users,noauto,_netdev,sec=sys  0 0
Никаких запусков дополнительных демонов (типа rpc.imapd) на клиенте не нужно.

На сервере (генерится автоматически софтом NAS'а):

$ cat /etc/exports 

/volume1/data1  192.168.0.100(rw,async,no_wdelay,insecure,no_root_squash,insecure_locks,sec=sys,anonuid=1025,anongid=100)

$ cat /etc/idmapd.conf
[General]
Domain=CCC
[Mapping]
Nobody-User=nobody
Nobody-Group=nobody

[Translation]
Method=nsswitch
GSS-Methods=static,synomap
[Static]

Требования:
- на сервере и клиенте должны быть одинаковые Domain (которые в idmapd.conf)
- на сервере и клиенте должны быть одинаковые пользователи и группы с точки зрения имен (а не ID)

Результат: если подмонтировать под рутом, то можно создавать, удалять файлы, изменять owner:group и т. п. Но никто кроме рута этого делать не может.

Kroz ★★★★★
() автор топика

Вот здесь четко описывается поведение: https://bugs.launchpad.net/ubuntu/ source/nfs-utils/ bug/966734

Да, трансляция имен работает и в одну, и в другую сторону. Проблема в том, что не все операции используют этот механизм. В частности touch напрямую записывает uid юзера, а не его имя.

Из-под рута другой юзер не может делать ничего. Если подмонтировать под этим юзером, то он может создавать файлы/каталоги в корне; но uid у этих каталогов/файлов будет такой как клиентский. То есть, если на клиенте uid=1000, но на сервере создастся файл с uid=1000; при ls сервер такого пользователя не найдет и передаст nobody. Создавал под kroz, получил под nobody.

Kroz ★★★★★
() автор топика

Откатился на NFSv3. Работает как песня. (P. S. Вот тут нужно запускать /etc/init.d/nfsclient)

Совет на будущее: если вы не хотите или у вас нет возможности
- иметь одинаковые uid и gui на NFSv4 сервер и клиентах, или
- городить kerberos/LDAP
не используйте NFSv4. Используйте NFSv3.

Это результат убитых 3 дней беспросветного гугуления, экспериментов, детального изучения исходников и патчинга libnfsidmap.

Kroz ★★★★★
() автор топика
Последнее исправление: Kroz (всего исправлений: 3)
14 августа 2015 г.
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.