Tuesday, March 27, 2012

Chroot dns/named/bind in Solaris 10 zone

My latest project was to create a chroot bind environment inside a solaris 10 zone. The goal is to make it as secure as possible since it will be on an outside facing network. Here's the guide.



-->
To configure a Secure dns instance in a Solaris 10 non-global zone using zfs, roles, and chroot:

  1. Create the zone and filesystem for the dns chroot structure
* This assumes that you have a zfs root or at least a zfs pool to build your zone on
    1. zfs create rpool/Root/S10x_u9/zone1
    2. chmod 700 /zone1
    3. zonecfg -z zone1
zonecfg:zone1> create
zonecfg:zone1> set zonepath=/zone1
zonecfg:zone1> set autoboot=true
zonecfg:zone1> add net
zonecfg:zone1:net> set physical=net0
* giving the zone a physical interface instead of an ip makes enables an exclusive ip zone. This gives the benefit of having a physically separated interface that can be on a network not connected to the global zone.
zonecfg:zone1:net> end
zonecfg:zone1> set ip-type=exclusive
zonecfg:zone1> verify
zonecfg:zone1> commit
zonecfg:zone1> exit
*you can now run a # zoneadm list -civ to see the zone as configured
    1. zoneadm -z zone1 install
    2. zoneadm -z zone1 boot
    3. zlogin -C -e “#.” zone1
*Login on the console for the zone to se the original parameters, just like an initial install of Solaris. (~.) is the escape sequence although this functionality is lacking. That's why I add the -e “#.” to the zlogin command. This way I wont get kicked out of the entire session. It may be necessary to log back into the global zone and kill the zlogin -C process.
  1. Create the role and modify the dns services to run as a role and in a chroot environment
* These commands are ran in the zone unless otherwise noted
    1. roleadd -d /local/dns -s /bin/false named
* make the role, give it a home dir of the chroot filesystem and set the shell to /bin/false
    1. groupadd dnsgroup
    2. rolemod -g dnsgroup named
    3. chown -R named:dnsgroup /local/dns
    4. cd /var/svc/manifest/network/dns
    5. cp server.xml chroot-server.xml
    6. vi chroot-server.xml
*Make the following changes
      1. go down to last dependency statement and copy 7 line (7yy)
      2. go just above the <exec_method> statement and paste your seven line (p)
      3. change the dependency statement as follows
<dependency
name='config'
grouping='optional_all'
restart_on='error'
type='path'>
</dependency>
* modify this line if your named.conf is not going to be under an etc directory in your chroot structure
      1. change the instance name statement to reflect the name of your new server chroot-server
* the line looks like this
<instance name='chroot-server' enabled='false' >
      1. go down to the method credential statement and change the user and group to our role and group
<method_credential
user='named'
group='dnsgroup'
* leave the rest of the statement alone
      1. change the propval method for chroot_dir
<propval name='chroot_dir' type='astring' value='/local/dns' />
    1. validate the configured
svccfg validate chroot-server.xml
*if there are any errors go back and fix whichever line it is complaining about
    1. import the service
        1. svccfg
        2. svc:> import /var/svc/manifest/network/dns/chroot-server.xml
        3. svc:> exit
  1. Configure your dns files within the chroot directory structure
* Typically you will want to put your dns files in standard as possible locations inside your chroot directory structure of /local/dns. For instance usual directories will be etc, var, and db. Another directory we will need to create under /local/dns is dev. This will hold our character devices used by dns.
    1. mkdir /local/dns/etc
    2. mkdir /local/dns/var
    3. mkdir /local/dns/db
    4. mkdir /local/dns/dev
*The devices necessary for named will need to added to this dev directory. Because this is in a zone this will have be done from the global zone.
    1. ls -laL /dev/poll
    2. ls -laL /dev/random
    3. ls -laL /dev/urandom
*Be sure to not the major and minor number and the type of device for each of these files.
For instance ls -laL /dev/poll produces
crw-rw-rw 1 root sys 135, 0 /dev/poll
The “c” means a character device and the first number (135) is the major and the second (0) is the minor
    1. Add the devices to the zone
*Done from the global zone
      1. mknod /zone1/root/local/dns/dev/poll c 135 0
      2. mknod /zone1/root/local/dns/dev/random c 149 0
      3. mknod /zone1/root/local/dns/dev/urandom c 149 1
    1. Make the named user and dnsgroup owner of the devices
      1. chown -R named:dnsgroup /local/dns/dev
    2. Configure your dns files however you see fit. The only things to keep in mind is that all files needed to run dns including logs and pid files will need to exist with your /local/dns chroot directory structure. Also the named.conf needs to exist in the location you specified while creating the chroot-server.xml service.
    3. Modify the named.conf file to point to files within the directory structure.
*All paths in the named.conf should be relative to the chroot starting point. For instance the directory option should read /db, not /local/dns/db. Here are the changes I make in named.conf.
      1. Directory “/db”;
      2. key-directory “/etc/”;
      3. pid-file “/etc/named.pid”;
*The main point is that any file or path specified in the named.conf needs to be relative the the chroot starting point of /local/dns so if you keep key files in /local/dns/key/zone1.key the entry in the named.conf should only point to /key/zone1.key
  1. Enable the dns service
    1. svcadm enable svc:/network/dns/server:chroot-server
*ps -ef | grep named
the named process should be running with a “-t” option and the path to the chroot directory structure. If not look in /var/adm/messages for any errors (usually due to permissions of the devices or non-chroot based file paths in the named.conf



References:

No comments:

Post a Comment