README.TEMPLATING revision 43808
143240Sdillon
243240Sdillon		      TEMPLATING machine configurations
343240Sdillon
443240Sdillon			    Matthew Dillon
543240Sdillon			    dillon@backplane.com
643240Sdillon
743240Sdillon    This document describes a general mechanism by which you can template
843240Sdillon    / and /usr.  That is, to keep a 'master template' of / and /usr on a
943240Sdillon    separate machine which is then used to update the rest of your machines.
1043240Sdillon
1143240Sdillon    Generally speaking, you can't simply mirror /.  You might be able to 
1243240Sdillon    get away with mirroring /usr.  There are two main problems involved with
1343240Sdillon    templating:
1443240Sdillon
1543240Sdillon    (1) Avoiding overwriting run-time generated files
1643240Sdillon
1743240Sdillon	By default, the system maintains a number of files in the root 
1843240Sdillon	partition.  For example, sendmail will dbm /etc/aliases into
1943240Sdillon	/etc/aliases.db.  vipw or chpass or other password related routines
2043240Sdillon	will regenerate the password dbm's /etc/spwd.db, /etc/pwd.db, and
2143240Sdillon	passwd.  /etc/namedb/s might contain generated secondaries.  And
2243240Sdillon	so forth.
2343240Sdillon
2443240Sdillon	The templating mechanism must avoid copying over such files.
2543240Sdillon
2643240Sdillon    (2) Customizing machines.
2743240Sdillon
2843240Sdillon	Customizing machines is actually considerably simpler.  You create
2943240Sdillon	a configuration hierarchy and convert the configuration files that
3043240Sdillon	have to be customized into softlinks that run through a special
3143240Sdillon	softlink in the configuration directory.  This will work for every
3243240Sdillon	configuration file except possibly /etc/master.passwd
3343240Sdillon
3443240Sdillon	For example, /etc/resolv.conf would be turned into a softlink to
3543240Sdillon	/conf/ME/resolv.conf, and /conf/ME itself would be a softlink to
3643240Sdillon	/conf/<HOSTNAME>.  The actual resolv.conf configuration file
3743240Sdillon	would reside in /conf/<HOSTNAME>.
3843240Sdillon
3943240Sdillon	If you have a lot of hosts, some configuration files may be commonly
4043240Sdillon	classified.  For example, all your shell machines might have the 
4143240Sdillon	same /etc/resolv.conf.  The solution is to make
4243240Sdillon	/conf/<HOSTNAME>/resolv.conf a softlink to a common directory, say
4343240Sdillon	/conf/HT.SHELL/resolv.conf.  It may sound a little messy, but this
4443240Sdillon	sort of categorization actually makes the sysadmins job much, much
4543240Sdillon	easier.
4643240Sdillon
4743240Sdillon	The /conf/ directory hierarchy is stored on the template and
4843240Sdillon	distributed to all the machines along with the rest of the root
4943240Sdillon	partition.
5043240Sdillon
5143240Sdillon	This type of customization is taken from my direct experience 
5243240Sdillon	instituting such a system at BEST.  At the time, BEST had over 45 
5343240Sdillon	machines managed from a single template.
5443240Sdillon
5543240Sdillon		RUN-TIME GENERATED OR MODIFIED FILES IN / or /USR
5643240Sdillon
5743240Sdillon	/etc/aliases.db
5843240Sdillon	/etc/master.passwd
5943240Sdillon	/etc/spwd.db
6043240Sdillon	/etc/pwd.db
6143240Sdillon	/etc/passwd
6243240Sdillon	/etc/namedb/s
6343240Sdillon	/root/.history
6443240Sdillon	/root/.ssh/identity
6543240Sdillon	/root/.ssh/identity.pub
6643240Sdillon	/root/.ssh/random_seed
6743240Sdillon	/root/.ssh/known_hosts
6843240Sdillon	/conf/ME
6943240Sdillon	/kernel*	( note 2 )
7043240Sdillon	/dev	( note 3 )
7143240Sdillon	/var	( note 4 )
7243240Sdillon	/home	( note 4 )
7343240Sdillon	/lost+found
7443240Sdillon
7543240Sdillon	/usr/lost+found
7643240Sdillon	/usr/home	( note 4 )
7743240Sdillon	/usr/crash	( note 5 )
7843240Sdillon	/usr/obj	( note 5 )
7943240Sdillon	/usr/ports	( note 5 )
8043240Sdillon	/usr/src	( note 5 )
8143240Sdillon	/usr/local/crack ( note 5 )
8243240Sdillon	/usr/X11R6/lib/X11/xdm/xdm-errors ( note 6 )
8343240Sdillon	/usr/X11R6/lib/X11/xdm/xdm-pid 	  ( note 6 )
8443240Sdillon	/usr/local/etc/ssh_host_key	  ( note 6 )
8543240Sdillon	/usr/local/etc/ssh_host_key.pub	  ( note 6 )
8643240Sdillon	/usr/local/etc/ssh_random_seed	  ( note 6 )
8743240Sdillon
8843240Sdillon	/conf/ME	( note 7 )
8943240Sdillon
9043240Sdillon	note 2:	You typically want to update kernels manually and *NOT* 
9143240Sdillon		template them as a safety measure.  This also allows you to run
9243240Sdillon		different kernels on different machines or.
9343240Sdillon
9443240Sdillon	note 3: /dev must be updated manually.  Some devices, such as tty's and
9543240Sdillon		pty's, use the access and/or modify time and/or user/group
9643240Sdillon		operationally and regenerating the devices on the fly would be
9743240Sdillon		bad.
9843240Sdillon
9943240Sdillon	note 4:	/var and /home are usually separately mounted partitions and
10043240Sdillon		thus would not fall under the template, but as a safety measure
10143240Sdillon		the template copier refuse to copy directories named 'home'.
10243240Sdillon
10343240Sdillon	note 5: These are directories that are as often created directly on
10443240Sdillon		/usr as they are separately-mounted partitions.  You typically
10543240Sdillon		do not want to template such directories.
10643240Sdillon
10743240Sdillon	note 6: Note that you can solve the problem of xdm and sshd creating
10843240Sdillon		files in /usr.  With xdm, edit /usr/X11R6/lib/xdm/xdm-config
10943240Sdillon		and change the errorLogFile and pidFile config lines.
11043240Sdillon
11143240Sdillon		With sshd, add 'HostKey' and 'RandomSeed' directives to specify
11243240Sdillon		/var/db for the location of the host key and run-time sshd
11343240Sdillon		random seed:
11443240Sdillon
11543240Sdillon		HostKey /var/db/ssh_host_key
11643240Sdillon		RandomSeed /var/db/ssh_random_seed
11743240Sdillon
11843240Sdillon	note 7: In this example, /conf/ME is the machine customizer and must
11943240Sdillon		be pointed to the /conf/<full-host-name>/ directory, which is
12043240Sdillon		different for each machine.  Thus, the /conf/ME softlink 
12143240Sdillon		should never be overwritten by the templating copy.
12243240Sdillon
12343240Sdillon
12443240Sdillon		TYPICAL CUSTOMIZED CONFIGRATION SOFTLINKS
12543240Sdillon
12643240Sdillon    The following files typically need to be turned into softlinks 
12743240Sdillon    to /conf/ME/<filename>:
12843240Sdillon
12943240Sdillon	/etc/ccd.conf		-> /conf/ME/ccd.conf
13043240Sdillon	/etc/ipfw.conf		...
13143240Sdillon	/etc/fstab
13243240Sdillon	/etc/motd
13343240Sdillon	/etc/resolv.conf
13443240Sdillon	/etc/aliases
13543240Sdillon	/etc/sendmail.cw
13643240Sdillon	/etc/organization
13743240Sdillon	/etc/named.conf
13843240Sdillon	/etc/rc.conf.local
13943240Sdillon	/etc/printcap
14043240Sdillon	/etc/inetd.conf
14143240Sdillon	/etc/login.conf
14243240Sdillon	/etc/gettytab
14343240Sdillon	/etc/ntp.conf
14443240Sdillon	/etc/exports
14543240Sdillon	/root/.k5login		-> /conf/ME/root/.k5login
14643240Sdillon
14743240Sdillon    And, of course, /conf/ME is usually a softlink to the appropriate 
14843240Sdillon    /conf/<full-host-name>/.  Depending on your system configuration, 
14943240Sdillon    there may be other files not listed above that you have to worry about.
15043240Sdillon
15143808Sdillon    In many cases, /conf/ME/filename is itself a softlink to 
15243808Sdillon    "../HT.xxxx/filename", where HT.xxxx is something like HT.STD ... this
15343808Sdillon    added complexity actually makes it easier to manage multiple
15443808Sdillon    classifications of machines.
15543808Sdillon
15643240Sdillon				DELETION OF FILES
15743240Sdillon
15843240Sdillon    Any file found on the template destination that does not exist in the
15943240Sdillon    source and is not listed as an exception by the source should be deleted.
16043240Sdillon    However, deletion can be dangerous and cpdup will ask for confirmation
16143240Sdillon    by default.  Once you know you aren't going to blow things up, you can
16243240Sdillon    turn this feature off and update your systems automatically from cron.
16343240Sdillon
16443240Sdillon    By formalizing the delete operation, you can be 100% sure that it is
16543240Sdillon    possible to recreate / and /usr on any machine with only the original
16643240Sdillon    template and a backup of the ( relatively few ) explicitly-excepted 
16743240Sdillon    files.  The most common mistake a sysop makes is to make a change to a 
16843240Sdillon    file in / or /usr on a target machine instead of the template machine.
16943240Sdillon    If the target machine is updated once a night from cron, the sysop
17043240Sdillon    quickly learns not to do this ( because his changes get overwritten
17143240Sdillon    overnight ).  With a manual update, these sorts of mistakes can propogate
17243240Sdillon    for weeks or months before they are caught.
17343240Sdillon
17443240Sdillon			    TEMPLATE COPYING AND SAFETY
17543240Sdillon			       THE CPDUP PROGRAM
17643240Sdillon
17743240Sdillon    The 'cpdup' program is a program which efficiently duplicates a directory
17843240Sdillon    tree.  The program copies source to destination, duplicating devices, 
17943240Sdillon    softlinks, hardlinks, files, modification times, uid, gid, flags, perms,
18043240Sdillon    and so forth.  The program incorporates several major features:
18143240Sdillon
18243240Sdillon	*   The program refuses, absolutely, to cross partition boundries.
18343240Sdillon	    i.e. if you were copying the template /usr from an NFS mount to
18443240Sdillon	    your /usr, and you had a mount point called /usr/home, the
18543240Sdillon	    template copying program would *NOT* descend into /usr/home on
18643240Sdillon	    the destination.
18743240Sdillon
18843240Sdillon	    This is a safety.
18943240Sdillon
19043240Sdillon	*   The program accesses a file called .cpignore in each directory
19143240Sdillon	    it descending into on the source to obtain a list of exceptions
19243240Sdillon	    for that directory -- that is, files not to copy or mess with.
19343240Sdillon
19443240Sdillon	    This is a templating function.
19543240Sdillon
19643240Sdillon	*   The program refuses to delete a directory on the destination
19743240Sdillon	    being replaced by a softlink or file on the source.
19843240Sdillon
19943240Sdillon	    This is a safety mechanism
20043240Sdillon
20143240Sdillon	*   The program is capable of maintaing MD5 check cache files and
20243240Sdillon	    doing an MD5 check between source and destination during the
20343240Sdillon	    scan.
20443240Sdillon
20543240Sdillon	*   The program is capable of deleting files/directories on the
20643240Sdillon	    destination that do not exist on the source, but asks for
20743240Sdillon	    confirmation by default.
20843240Sdillon
20943240Sdillon	    This is a templating and a safety mechanism.
21043240Sdillon
21143240Sdillon	*   The program uses a copy-to-tmp-and-rename methodology allowing
21243240Sdillon	    it to be used to update live filesystems.
21343240Sdillon
21443240Sdillon	    This is a templating mechanism.
21543240Sdillon
21643240Sdillon	*   The program, by default, tries to determine if a copy is required
21743240Sdillon	    by checking modify times, file size, perms, and other stat
21843240Sdillon	    elements.  If the elements match, it does not bother to copy
21943240Sdillon	    ( unless an MD5 check is being made, in which case it must read
22043240Sdillon	    the destination file ).
22143240Sdillon
22243240Sdillon    You typically run cpdup on the target machine.  The target machine
22343240Sdillon    temporarily mounts the template machine's / and /usr via NFS, read-only,
22443240Sdillon    and runs cpdup to update / and /usr.  If you use this methodology note
22543240Sdillon    that THERE ARE SECURITY CONSIDERATIONS!  See 'SECURITY CONSIDERATIONS WITH
22643240Sdillon    NFS' below.  
22743240Sdillon
22843240Sdillon    Whatever script you use that does the NFS mounts should ensure that the
22943240Sdillon    mount succeeded before continuing with the cpdup.
23043240Sdillon
23143240Sdillon    You should create .cpignore files in the appropriate directories on the 
23243240Sdillon    template machine's / and /usr partitions so as not to overwrite active
23343240Sdillon    files on the target.  The most critical .cpignore files should be
23443240Sdillon    protected with 'chflags schg .cpignore'.  Specifically, the ones in /
23543240Sdillon    and /etc, but possibly others as well.  For example, the .cpignore
23643240Sdillon    hierarchy for protect /root is:
23743240Sdillon
23843240Sdillon	# /root/.cpignore contains
23943240Sdillon	.history
24043240Sdillon
24143240Sdillon	# /root/.ssh/.cpignore contains
24243240Sdillon	random_seed
24343240Sdillon	known_hosts
24443240Sdillon	authorized_keys
24543240Sdillon	identity
24643240Sdillon	identity.pub
24743240Sdillon
24843240Sdillon    WHEN INITIALLY CONVERTING A TARGET MACHINE TO USE TEMPLATING, ALWAYS
24943240Sdillon    MAKE A FULL BACKUP OF THE TARGET MACHINE FIRST!  You may accidently delete
25043240Sdillon    files on the target during the conversion due to forgetting to enter
25143240Sdillon    items into appropriate .cpignore files on the source.
25243240Sdillon
25343240Sdillon	SECURITY CONSIDERATIONS WITH NFS ROOT EXPORT FROM TEMPLATE MACHINE
25443240Sdillon	SECURITY CONSIDERATIONS WITH NFS USR EXPORT FROM TEMPLATE MACHINE
25543240Sdillon
25643240Sdillon    There are some serious security considerations that must be taken into
25743240Sdillon    account when exporting / and /usr on the template machine.
25843240Sdillon
25943240Sdillon	* only export read-only 
26043240Sdillon
26143240Sdillon	* the password file ( aka vipw ) may not contain any crypted passwords
26243240Sdillon	  at all.  You MUST use ssh or kerberos to access the template machine.
26343240Sdillon
26443240Sdillon	  You can get away with giving only root a crypted password, but only
26543240Sdillon	  if you disallow network root logins and only allow direct root
26643240Sdillon	  logins on the  console.
26743240Sdillon
26843240Sdillon	* The machine's private ssh_host_key usually resides in /usr/local/etc.
26943240Sdillon	  You must move this key to /var/db.  You can softlink link so no
27043240Sdillon	  modification of sshd_config is required.
27143240Sdillon
27243240Sdillon	* The machine's private ~root/.ssh/identity file is also exposed by
27343240Sdillon	  the NFS export, you should move this file to /var/db as well and
27443240Sdillon	  put a softlink in ~root/.ssh.
27543240Sdillon
27643240Sdillon	* DON'T EXPORT /var !  Either that, or don't put the private keys
27743240Sdillon	  in /var/db ... put them somewhere else.
27843240Sdillon
27943240Sdillon	* You may want to redirect the location of the random_seed file, which
28043240Sdillon	  can be done by editing ~root/.ssh/sshd_config and
28143240Sdillon	  /usr/local/etc/sshd_config so it is not exposed either.
28243240Sdillon
28343240Sdillon					-Matt
28443240Sdillon					Matthew Dillon
28543240Sdillon					dillon@backplane.com
28643240Sdillon
287