Administrace uživatelů přes puppet

Z DCEwiki
Skočit na navigaci Skočit na vyhledávání

Každý proces v linuxovém systému někomu patří. Vlastník je identifikován unikátním číslem (UID), ke kterému je přiřazeno jeho unikátní jméno. Toto jméno je však unikátní vždy pouze v rámci systému. Na jiném stroji tak může mít stejné jméno úplně jinou číselnou hodnotu UID, protože ta přiřazuje v okamžiku, kdy je uživatel přidán do systému.

Jen jeden uživatel má vždy stejnou hodnotu UID odpovídající nule - root.

Kromě UID má uživatel přiřazen ještě jeden identifikátor - číselný identifikátor skupiny (GID). Pro skupiny však platí prakticky totéž co bylo zmíněno v předchozím odstavci.

Pokud jde o standalone stroj, není důvod se nad tím pozastavovat, protože systém místo UID a GID vždy zobrazuje odpovídající jména uživatelů a skupin. Ovšem má-li mezi sebou spolupracovat více strojů, mohou rozdílná UID a GID pěkně zamíchat kartami.

Jsou-li tyto stroje spravovány přes Puppet, lze tento problém elegantně řešit pomocí typů user a group.

Poznámka
group { 'git':
	ensure => present,
	gid => 1000,
}
user { 'git':
	ensure => present,
	uid => 1000,
	gid => 'git',
	groups => 'www-data',
	home => '/home/git',
	managehome => true,
	shell => '/bin/bash',
	before => Group['git'],
	password => '$6$MxShiP22$tWawoL7u39iwUi9fEQWe5JDgGW9eBHp2T94QR4dmHCckQpeAxD4SilExyZ2v1jfYa9catLo/ztW8KvnAzTxC./',
}

Puppet by na základě výše uvedeného kódu vytvořil nejprve skupinu git s hodnotou GID 1000 a pak uživatele s názvem git s hodnotou UID 1000 a domovským adresářem /home/git.

Poznámka Skupina, do které má nově založený uživatel patřit musí vždy existovat dřív, než se přidá uživatel. Proto aby agent založil skupinu git dříve než uživatele je u typu user nastaven metaparametr before

Personalizace na základě $hostname

Kdybychom však použili v manifestu kód tak jak je uvedeno výše, dojde k vytvoření skupiny a založení uživatelského účtu na všech strojích. Jak tedy pořešit situaci, kdy spravujeme více strojů ale uživatel by měl mít aktivní účet pouze na jednom z nich?

V takovém případě lze použít stavovou podmínku na základě hostname klientského nodu:

Poznámka
group { 'git':
	ensure => present,
	gid => 1000,
}
case $hostname {
	'git': {
		user { 'git':
		ensure => present,
		uid => 1000,
		gid => 'git',
		groups => 'www-data',
		home => '/home/git',
		managehome => true,
		shell => '/bin/bash',
		before => Group['git'],
		password => '$6$MxShiP22$tWawoL7u39iwUi9fEQWe5JDgGW9eBHp2T94QR4dmHCckQpeAxD4SilExyZ2v1jfYa9catLo/ztW8KvnAzTxC./',
		}
	}
	default: {
		user { 'git':
		ensure => present,
		uid => 1000,
		gid => 'git',
		before => Group['git'],
		shell => false,
		}
	}
}

Agent při zpracování tohoto kódu manifestu sice na všech na strojích založí skupinu git a uživatele git, ale pouze na stroji s hostname git by měl tento uživatel vytvořen domovský adresář a povoleno přihlášení přes heslo.

Na ostatních strojích by pokus o přihlášení tohoto uživatele selhal, protože nemá povolen shell.

Poznámka Je žádoucí založit skupinu i uživatele git i přesto, že na daném stroji nebude nikdy aktivní. A to z toho důvodu, že obsazením GID a UID do budoucna zabráníte, aby tato identifikační čísla dostal nějaký jiný uživatel či skupina založená při instalaci nového software.

To by totiž mohlo do budoucna komplikovat situaci při přesunu domovských adresářů na jiný stroj.

Uživatelská funkce personality

Výš uvedené příklady zatím pracovaly pouze s variantou, že chceme uživatele a skupiny zakládat. Ale co když je chceme také prostřednictvím puppetu odstraňovat?

V takovém případě už je výhodnější použít vlastní funkci. Protože při odebírání skupin je třeba použít místo parametru before require. Skupinu do které patří nějaký uživatel totiž nelze odstranit a tento metaparametr zajistí, aby se o to agent nepokoušel dřív, dokud z ní nejsou odstraněni všichni uživatelé.


Poznámka
define personality(
	$ensure = 'present',
	$gid = '',
	$ggid = '',
	$groups = [],
	$uid = '',
	$comment = '',
	$managehome = false,
	$home = '',
	$shell = '/bin/sh',
	$system = true,
	) {
	if $gid { "$name":
		group { "$name":
			ensure => $ensure,
			gid => $gid,
			allowdupe => false,
			system => $system
		}
		if $uid {
			if $ensure == 'absent' {
				user { "$name":
					ensure => $ensure,
					before => Group["$name"]
				}
			}
			else {
				user { "$name":
					ensure => $ensure,
					uid => $uid,
					gid => $name,
					system => $system,
					comment => $comment,
					managehome => $managehome,
					home => "$home",
					shell => "$shell",
					require => Group[$name]
				}
			}
		}
	}
	else { 
		user { "$name":
			ensure => $ensure,
			uid => $uid,
			gid => $ggid,
			ggroups => $groups,
			system => $system,
			comment => $comment,
			managehome => $managehome,
			home => "$home",
			shell => "$shell",
			require => Group[$ggid]
		}
	}
}

personality { 'nogroup':
	gid => 65534,
}

personality { 'nobody':
	ensure => 'absent',
	uid => 65534,
	ggid => nogroup,
	comment => 'nobody',
	home => '/nonexistent',
	shell => '/bin/sh'
}

personality { 'gnats':
	ensure => 'absent',
	gid => 41,
	uid => 41,
	comment => 'Gnats Bug-Reporting System (admin)',
	home => '/var/lib/gnats',
	shell => '/bin/sh'
}

personality { 'ssh':
	gid => 101,
}

personality { 'sshd':
	uid => 101,
	ggid => nogroup,
	home => '/var/run/sshd',
	shell => '/usr/sbin/nologin'
}

personality { 'git':
	ensure => 'present',
	gid => 1000,
	uid => 1000,
	comment => 'Gitolite user',
	system => false,
	managehome => true,
	home => '/home/git',
	shell => '/bin/sh'
}

Zjištění UID a GID uživatele

Poznámka
user@stroj~$ id want
uid=1001(want) gid=1001(want) skupiny=1001(want),4(adm),50(staff)


Zjištění názvu skupiny podle GID

Poznámka
user@stroj~$ getent passwd 33
www-data:x:33:33:www-data:/var/www:/bin/sh