README.TEMPLATING revision 43240
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
15143240Sdillon				DELETION OF FILES
15243240Sdillon
15343240Sdillon    Any file found on the template destination that does not exist in the
15443240Sdillon    source and is not listed as an exception by the source should be deleted.
15543240Sdillon    However, deletion can be dangerous and cpdup will ask for confirmation
15643240Sdillon    by default.  Once you know you aren't going to blow things up, you can
15743240Sdillon    turn this feature off and update your systems automatically from cron.
15843240Sdillon
15943240Sdillon    By formalizing the delete operation, you can be 100% sure that it is
16043240Sdillon    possible to recreate / and /usr on any machine with only the original
16143240Sdillon    template and a backup of the ( relatively few ) explicitly-excepted 
16243240Sdillon    files.  The most common mistake a sysop makes is to make a change to a 
16343240Sdillon    file in / or /usr on a target machine instead of the template machine.
16443240Sdillon    If the target machine is updated once a night from cron, the sysop
16543240Sdillon    quickly learns not to do this ( because his changes get overwritten
16643240Sdillon    overnight ).  With a manual update, these sorts of mistakes can propogate
16743240Sdillon    for weeks or months before they are caught.
16843240Sdillon
16943240Sdillon			    TEMPLATE COPYING AND SAFETY
17043240Sdillon			       THE CPDUP PROGRAM
17143240Sdillon
17243240Sdillon    The 'cpdup' program is a program which efficiently duplicates a directory
17343240Sdillon    tree.  The program copies source to destination, duplicating devices, 
17443240Sdillon    softlinks, hardlinks, files, modification times, uid, gid, flags, perms,
17543240Sdillon    and so forth.  The program incorporates several major features:
17643240Sdillon
17743240Sdillon	*   The program refuses, absolutely, to cross partition boundries.
17843240Sdillon	    i.e. if you were copying the template /usr from an NFS mount to
17943240Sdillon	    your /usr, and you had a mount point called /usr/home, the
18043240Sdillon	    template copying program would *NOT* descend into /usr/home on
18143240Sdillon	    the destination.
18243240Sdillon
18343240Sdillon	    This is a safety.
18443240Sdillon
18543240Sdillon	*   The program accesses a file called .cpignore in each directory
18643240Sdillon	    it descending into on the source to obtain a list of exceptions
18743240Sdillon	    for that directory -- that is, files not to copy or mess with.
18843240Sdillon
18943240Sdillon	    This is a templating function.
19043240Sdillon
19143240Sdillon	*   The program refuses to delete a directory on the destination
19243240Sdillon	    being replaced by a softlink or file on the source.
19343240Sdillon
19443240Sdillon	    This is a safety mechanism
19543240Sdillon
19643240Sdillon	*   The program is capable of maintaing MD5 check cache files and
19743240Sdillon	    doing an MD5 check between source and destination during the
19843240Sdillon	    scan.
19943240Sdillon
20043240Sdillon	*   The program is capable of deleting files/directories on the
20143240Sdillon	    destination that do not exist on the source, but asks for
20243240Sdillon	    confirmation by default.
20343240Sdillon
20443240Sdillon	    This is a templating and a safety mechanism.
20543240Sdillon
20643240Sdillon	*   The program uses a copy-to-tmp-and-rename methodology allowing
20743240Sdillon	    it to be used to update live filesystems.
20843240Sdillon
20943240Sdillon	    This is a templating mechanism.
21043240Sdillon
21143240Sdillon	*   The program, by default, tries to determine if a copy is required
21243240Sdillon	    by checking modify times, file size, perms, and other stat
21343240Sdillon	    elements.  If the elements match, it does not bother to copy
21443240Sdillon	    ( unless an MD5 check is being made, in which case it must read
21543240Sdillon	    the destination file ).
21643240Sdillon
21743240Sdillon    You typically run cpdup on the target machine.  The target machine
21843240Sdillon    temporarily mounts the template machine's / and /usr via NFS, read-only,
21943240Sdillon    and runs cpdup to update / and /usr.  If you use this methodology note
22043240Sdillon    that THERE ARE SECURITY CONSIDERATIONS!  See 'SECURITY CONSIDERATIONS WITH
22143240Sdillon    NFS' below.  
22243240Sdillon
22343240Sdillon    Whatever script you use that does the NFS mounts should ensure that the
22443240Sdillon    mount succeeded before continuing with the cpdup.
22543240Sdillon
22643240Sdillon    You should create .cpignore files in the appropriate directories on the 
22743240Sdillon    template machine's / and /usr partitions so as not to overwrite active
22843240Sdillon    files on the target.  The most critical .cpignore files should be
22943240Sdillon    protected with 'chflags schg .cpignore'.  Specifically, the ones in /
23043240Sdillon    and /etc, but possibly others as well.  For example, the .cpignore
23143240Sdillon    hierarchy for protect /root is:
23243240Sdillon
23343240Sdillon	# /root/.cpignore contains
23443240Sdillon	.history
23543240Sdillon
23643240Sdillon	# /root/.ssh/.cpignore contains
23743240Sdillon	random_seed
23843240Sdillon	known_hosts
23943240Sdillon	authorized_keys
24043240Sdillon	identity
24143240Sdillon	identity.pub
24243240Sdillon
24343240Sdillon    WHEN INITIALLY CONVERTING A TARGET MACHINE TO USE TEMPLATING, ALWAYS
24443240Sdillon    MAKE A FULL BACKUP OF THE TARGET MACHINE FIRST!  You may accidently delete
24543240Sdillon    files on the target during the conversion due to forgetting to enter
24643240Sdillon    items into appropriate .cpignore files on the source.
24743240Sdillon
24843240Sdillon	SECURITY CONSIDERATIONS WITH NFS ROOT EXPORT FROM TEMPLATE MACHINE
24943240Sdillon	SECURITY CONSIDERATIONS WITH NFS USR EXPORT FROM TEMPLATE MACHINE
25043240Sdillon
25143240Sdillon    There are some serious security considerations that must be taken into
25243240Sdillon    account when exporting / and /usr on the template machine.
25343240Sdillon
25443240Sdillon	* only export read-only 
25543240Sdillon
25643240Sdillon	* the password file ( aka vipw ) may not contain any crypted passwords
25743240Sdillon	  at all.  You MUST use ssh or kerberos to access the template machine.
25843240Sdillon
25943240Sdillon	  You can get away with giving only root a crypted password, but only
26043240Sdillon	  if you disallow network root logins and only allow direct root
26143240Sdillon	  logins on the  console.
26243240Sdillon
26343240Sdillon	* The machine's private ssh_host_key usually resides in /usr/local/etc.
26443240Sdillon	  You must move this key to /var/db.  You can softlink link so no
26543240Sdillon	  modification of sshd_config is required.
26643240Sdillon
26743240Sdillon	* The machine's private ~root/.ssh/identity file is also exposed by
26843240Sdillon	  the NFS export, you should move this file to /var/db as well and
26943240Sdillon	  put a softlink in ~root/.ssh.
27043240Sdillon
27143240Sdillon	* DON'T EXPORT /var !  Either that, or don't put the private keys
27243240Sdillon	  in /var/db ... put them somewhere else.
27343240Sdillon
27443240Sdillon	* You may want to redirect the location of the random_seed file, which
27543240Sdillon	  can be done by editing ~root/.ssh/sshd_config and
27643240Sdillon	  /usr/local/etc/sshd_config so it is not exposed either.
27743240Sdillon
27843240Sdillon					-Matt
27943240Sdillon					Matthew Dillon
28043240Sdillon					dillon@backplane.com
28143240Sdillon
282