[lxc-devel] [PATCH] [Cancel] CentOS and Fedora Templates: Harden root passwords and add static MAC network addresses.

Michael H. Warfield mhw at WittsEnd.com
Mon Jan 13 16:44:33 UTC 2014


On Mon, 2014-01-13 at 09:26 -0600, Serge Hallyn wrote: 
> Quoting Michael H. Warfield (mhw at WittsEnd.com):
> > This patch hasn't made it into the repo yet and there's been a lot of
> > other changes.  I'm canceling this one and will reissue after rebasing
> > to include some changes after some discussion with Serge and others.
> > Please drop this patch.

> Ah.  Now I see.  I must have missed *this* patch which the other
> patch depended on.

> Please do check for the hunk(s) which *were* applied and make sure
> they are ok :)

I checked and I think I've got everything straight now and I've reissued
a patch to cover all the missed changes plus the additional password
logic.

> > Regards,
> > Mike


Regards,
Mike

> > On Thu, 2013-12-26 at 18:08 -0500, Michael H. Warfield wrote: 
> > > CentOS and Fedora Templates: Harden root passwords and add static MAC network addresses.
> > > 
> > > 1) Add logic to root password setting.  Root password is now set to
> > > 	"Root-${name}-${RANDOM} to defeat common brute force scans.
> > > 2) Enhance exit messages to explain root password and password changing.
> > > 3) Add random generated hwaddr (MAC) entires for any network interfaces
> > > 	in default config copied to container.
> > > 4) Add shell variable expansion of default config.
> > > 5) Cross patch templates to bring them more into coherence with each other.
> > > 
> > > Signed-off-by: Michael H. Warfield <mhw at WittsEnd.com>
> > > ---
> > >  templates/lxc-centos.in | 114 +++++++++++++++++++++++++++++++++++++-----------
> > >  templates/lxc-fedora.in |  99 +++++++++++++++++++++++++++++++++++++----
> > >  2 files changed, 180 insertions(+), 33 deletions(-)
> > > 
> > > diff --git a/templates/lxc-centos.in b/templates/lxc-centos.in
> > > index 7d47715..5bb5349 100644
> > > --- a/templates/lxc-centos.in
> > > +++ b/templates/lxc-centos.in
> > > @@ -33,6 +33,7 @@ default_path=@LXCPATH@
> > >  # We really need something better here!
> > >  root_password=root
> > >  
> > > +# These are only going into comments in the resulting config...
> > >  lxc_network_type=veth
> > >  lxc_network_link=lxcbr0
> > >  
> > > @@ -256,8 +257,10 @@ EOF
> > >      mknod -m 600 ${dev_path}/initctl p
> > >      mknod -m 666 ${dev_path}/ptmx c 5 2
> > >  
> > > -    echo "setting root passwd to $root_password"
> > > +    echo "Setting root passwd to '$root_password'"
> > >      echo "root:$root_password" | chroot $rootfs_path chpasswd
> > > +    # Also set this password as expired to force the user to change it!
> > > +    chroot $rootfs_path passwd -e root
> > >  
> > >      # This will need to be enhanced for CentOS 7 when systemd
> > >      # comes into play...   /\/\|=mhw=|\/\/
> > > @@ -374,6 +377,7 @@ copy_centos()
> > >      # i prefer rsync (no reason really)
> > >      mkdir -p $rootfs_path
> > >      rsync -a $cache/rootfs/ $rootfs_path/
> > > +    echo
> > >      return 0
> > >  }
> > >  
> > > @@ -428,28 +432,71 @@ install_centos()
> > >      return $?
> > >  }
> > >  
> > > -copy_configuration()
> > > +create_hwaddr()
> > >  {
> > > +    echo $(dd if=/dev/urandom bs=8 count=1 2>/dev/null | md5sum
> > > +        | sed -e 's/\(..\)\(..\)\(..\)\(..\)\(..\).*/fe:\1:\2:\3:\4:\5/')
> > > +}
> > >  
> > > +copy_configuration()
> > > +{
> > >      mkdir -p $config_path
> > > +
> > > +    grep -q "^lxc.rootfs" $config_path/config 2>/dev/null || echo "
> > > +lxc.rootfs = $rootfs_path
> > > +" >> $config_path/config
> > > +
> > > +    # The following code is to create static MAC addresses for each
> > > +    # interface in the container.  This code will work for multiple
> > > +    # interfaces in the default config.
> > > +    mv $config_path/config $config_path/config.def
> > > +    while read LINE
> > > +    do
> > > +        # This should catch variable expansions from the default config...
> > > +        if expr "${LINE}" : '.*\$' > /dev/null 2>&1
> > > +        then
> > > +		LINE=$(eval "echo \"${LINE}\"")
> > > +        fi
> > > +
> > > +        # There is a tab and a space in the regex bracket below!
> > > +        # Seems that \s doesn't work in brackets.
> > > +        KEY=$(expr $LINE : '\s*\([^	 ]*\)\s*=')
> > > +
> > > +        if [[ "${KEY}" != "lxc.network.hwaddr" ]]
> > > +        then
> > > +            echo ${LINE} >> $config_path/config
> > > +
> > > +            if [[ "${KEY}" == "lxc.network.link" ]]
> > > +            then
> > > +                echo "lxc.network.hwaddr = $(create_hwaddr)" >> $config_path/config
> > > +            fi
> > > +        fi
> > > +    done < $config_path/config.def
> > > +
> > > +    rm -f $config_path/config.def
> > > +
> > >      cat <<EOF >> $config_path/config
> > >  lxc.utsname = $utsname
> > >  lxc.tty = 4
> > >  lxc.pts = 1024
> > > -lxc.rootfs = $rootfs_path
> > > -lxc.mount  = $config_path/fstab
> > > +lxc.mount = $config_path/fstab
> > >  lxc.cap.drop = sys_module mac_admin mac_override sys_time
> > >  
> > >  lxc.autodev = $auto_dev
> > >  
> > > +# When using LXC with apparmor, uncomment the next line to run unconfined:
> > > +#lxc.aa_profile = unconfined
> > > +
> > >  # example simple networking setup, uncomment to enable
> > >  #lxc.network.type = $lxc_network_type
> > >  #lxc.network.flags = up
> > >  #lxc.network.link = $lxc_network_link
> > >  #lxc.network.name = eth0
> > > -# additional example for veth network type, static MAC address,
> > > -# and persistent veth device name on host side
> > > +# Additional example for veth network type
> > > +#    static MAC address,
> > >  #lxc.network.hwaddr = 00:16:3e:77:52:20
> > > +#    persistent veth device name on host side
> > > +#        Note: This may potentially collide with other containers of same name!
> > >  #lxc.network.veth.pair = v-$name-e0
> > >  
> > >  #cgroups
> > > @@ -460,8 +507,6 @@ lxc.cgroup.devices.allow = c 1:5 rwm
> > >  # consoles
> > >  lxc.cgroup.devices.allow = c 5:1 rwm
> > >  lxc.cgroup.devices.allow = c 5:0 rwm
> > > -lxc.cgroup.devices.allow = c 4:0 rwm
> > > -lxc.cgroup.devices.allow = c 4:1 rwm
> > >  # /dev/{,u}random
> > >  lxc.cgroup.devices.allow = c 1:9 rwm
> > >  lxc.cgroup.devices.allow = c 1:8 rwm
> > > @@ -473,13 +518,12 @@ EOF
> > >  
> > >      cat <<EOF > $config_path/fstab
> > >  proc            proc         proc    nodev,noexec,nosuid 0 0
> > > -devpts          dev/pts      devpts defaults 0 0
> > >  sysfs           sys          sysfs defaults  0 0
> > >  EOF
> > >  
> > >      if [ $? -ne 0 ]; then
> > > -    echo "Failed to add configuration"
> > > -    return 1
> > > +        echo "Failed to add configuration"
> > > +        return 1
> > >      fi
> > >  
> > >      return 0
> > > @@ -489,22 +533,21 @@ clean()
> > >  {
> > >  
> > >      if [ ! -e $cache ]; then
> > > -    exit 0
> > > +        exit 0
> > >      fi
> > >  
> > >      # lock, so we won't purge while someone is creating a repository
> > >      (
> > > -    flock -x 200
> > > -    if [ $? != 0 ]; then
> > > -        echo "Cache repository is busy."
> > > -        exit 1
> > > -    fi
> > > -
> > > -    echo -n "Purging the download cache for centos-$release..."
> > > -    rm --preserve-root --one-file-system -rf $cache && echo "Done." || exit 1
> > > -    exit 0
> > > +        flock -x 200
> > > +        if [ $? != 0 ]; then
> > > +            echo "Cache repository is busy."
> > > +            exit 1
> > > +        fi
> > >  
> > > -    ) 200>/var/lock/subsys/lxc-centos
> > > +        echo -n "Purging the download cache for centos-$release..."
> > > +        rm --preserve-root --one-file-system -rf $cache && echo "Done." || exit 1
> > > +        exit 0
> > > +    ) 200>@LOCALSTATEDIR@/lock/subsys/lxc-centos
> > >  }
> > >  
> > >  usage()
> > > @@ -554,6 +597,12 @@ if [ ! -z "$clean" -a -z "$path" ]; then
> > >      exit 0
> > >  fi
> > >  
> > > +# Let's do something better for the initial root password.
> > > +# It's not perfect but it will defeat common scanning brute force
> > > +# attacks in the case where ssh is exposed.  It will also be set to
> > > +# expired, forcing the user to change it at first login.
> > > +root_password=Root-${name}-${RANDOM}
> > > +
> > >  if [ -z "${utsname}" ]; then
> > >      utsname=${name}
> > >  fi
> > > @@ -572,7 +621,7 @@ fi
> > >  #    utsname and hostname = Container_Name.Domain_Name
> > >  
> > >  if [ $(expr "$utsname" : '.*\..*\.') = 0 ]; then
> > > -    if [ -n "$(dnsdomainname)" ]; then
> > > +    if [[ "$(dnsdomainname)" != "" && "$(dnsdomainname)" != "localdomain" ]]; then
> > >          utsname=${utsname}.$(dnsdomainname)
> > >      fi
> > >  fi
> > > @@ -666,5 +715,20 @@ if [ ! -z $clean ]; then
> > >      clean || exit 1
> > >      exit 0
> > >  fi
> > > -echo "container rootfs and config created, default root password is '$root_password'"
> > > -echo "edit the config file to check/enable networking setup"
> > > +echo "
> > > +Container rootfs and config have been created.
> > > +Edit the config file to check/enable networking setup.
> > > +"
> > > +
> > > +echo "The temporary password for root is: '$root_password'
> > > +
> > > +You may want to note that password down before starting the container.
> > > +
> > > +The password set up as "expired" and will require it to be changed it at
> > > +first login, which you should do as soon as possible.  If you lose the
> > > +root password or wish to change it without starting the container, you
> > > +can change it from the host by running the following command (which will
> > > +also reset the expired flag):
> > > +
> > > +        chroot ${rootfs_path} passwd
> > > +"
> > > diff --git a/templates/lxc-fedora.in b/templates/lxc-fedora.in
> > > index 5f66ff1..b0c214a 100644
> > > --- a/templates/lxc-fedora.in
> > > +++ b/templates/lxc-fedora.in
> > > @@ -33,6 +33,10 @@ default_path=@LXCPATH@
> > >  # We really need something better here!
> > >  root_password=root
> > >  
> > > +# These are only going into comments in the resulting config...
> > > +lxc_network_type=veth
> > > +lxc_network_link=lxcbr0
> > > +
> > >  # is this fedora?
> > >  # Alow for weird remixes like the Raspberry Pi
> > >  #
> > > @@ -194,8 +198,10 @@ EOF
> > >      mknod -m 600 ${dev_path}/initctl p
> > >      mknod -m 666 ${dev_path}/ptmx c 5 2
> > >  
> > > -    echo "setting root passwd to $root_password"
> > > +    echo "Setting root passwd to '$root_password'"
> > >      echo "root:$root_password" | chroot $rootfs_path chpasswd
> > > +    # Also set this password as expired to force the user to change it!
> > > +    chroot $rootfs_path passwd -e root
> > >  
> > >      # specifying this in the initial packages doesn't always work.
> > >      # Even though it should have...
> > > @@ -243,7 +249,7 @@ configure_fedora_init()
> > >  
> > >  configure_fedora_systemd()
> > >  {
> > > -    unlink ${rootfs_path}/etc/systemd/system/default.target
> > > +    rm -f ${rootfs_path}/etc/systemd/system/default.target
> > >      touch ${rootfs_path}/etc/fstab
> > >      chroot ${rootfs_path} ln -s /dev/null /etc/systemd/system/udev.service
> > >      chroot ${rootfs_path} ln -s /lib/systemd/system/multi-user.target /etc/systemd/system/default.target
> > > @@ -837,6 +843,7 @@ copy_fedora()
> > >      # i prefer rsync (no reason really)
> > >      mkdir -p $rootfs_path
> > >      rsync -Ha $cache/rootfs/ $rootfs_path/
> > > +    echo
> > >      return 0
> > >  }
> > >  
> > > @@ -891,11 +898,53 @@ install_fedora()
> > >      return $?
> > >  }
> > >  
> > > -copy_configuration()
> > > +# Generate a random hardware (MAC) address composed of FE followed by
> > > +# 5 random bytes...
> > > +create_hwaddr()
> > >  {
> > > +    echo $(dd if=/dev/urandom bs=8 count=1 2>/dev/null | md5sum |
> > > +        sed -e 's/\(..\)\(..\)\(..\)\(..\)\(..\).*/fe:\1:\2:\3:\4:\5/')
> > > +}
> > >  
> > > +copy_configuration()
> > > +{
> > >      mkdir -p $config_path
> > > -    grep -q "^lxc.rootfs" $config_path/config 2>/dev/null || echo "lxc.rootfs = $rootfs_path" >> $config_path/config
> > > +
> > > +    grep -q "^lxc.rootfs" $config_path/config 2>/dev/null || echo "
> > > +lxc.rootfs = $rootfs_path
> > > +" >> $config_path/config
> > > +
> > > +    # The following code is to create static MAC addresses for each
> > > +    # interface in the container.  This code will work for multiple
> > > +    # interfaces in the default config.  It will also strip any
> > > +    # hwaddr stanzas out of the default config since we can not share
> > > +    # MAC addresses between containers.
> > > +    mv $config_path/config $config_path/config.def
> > > +    while read LINE
> > > +    do
> > > +        # This should catch variable expansions from the default config...
> > > +        if expr "${LINE}" : '.*\$' > /dev/null 2>&1
> > > +        then
> > > +		LINE=$(eval "echo \"${LINE}\"")
> > > +        fi
> > > +
> > > +        # There is a tab and a space in the regex bracket below!
> > > +        # Seems that \s doesn't work in brackets.
> > > +        KEY=$(expr "${LINE}" : '\s*\([^	 ]*\)\s*=')
> > > +
> > > +        if [[ "${KEY}" != "lxc.network.hwaddr" ]]
> > > +        then
> > > +            echo "${LINE}" >> $config_path/config
> > > +
> > > +            if [[ "${KEY}" == "lxc.network.link" ]]
> > > +            then
> > > +                echo "lxc.network.hwaddr = $(create_hwaddr)" >> $config_path/config
> > > +            fi
> > > +        fi
> > > +    done < $config_path/config.def
> > > +
> > > +    rm -f $config_path/config.def
> > > +
> > >      cat <<EOF >> $config_path/config
> > >  lxc.utsname = $utsname
> > >  lxc.tty = 4
> > > @@ -908,6 +957,18 @@ lxc.autodev = $auto_dev
> > >  # When using LXC with apparmor, uncomment the next line to run unconfined:
> > >  #lxc.aa_profile = unconfined
> > >  
> > > +# example simple networking setup, uncomment to enable
> > > +#lxc.network.type = $lxc_network_type
> > > +#lxc.network.flags = up
> > > +#lxc.network.link = $lxc_network_link
> > > +#lxc.network.name = eth0
> > > +# Additional example for veth network type
> > > +#    static MAC address,
> > > +#lxc.network.hwaddr = 00:16:3e:77:52:20
> > > +#    persistent veth device name on host side
> > > +#        Note: This may potentially collide with other containers of same name!
> > > +#lxc.network.veth.pair = v-$name-e0
> > > +
> > >  #cgroups
> > >  lxc.cgroup.devices.deny = a
> > >  # /dev/null and zero
> > > @@ -929,6 +990,7 @@ EOF
> > >  proc            proc         proc    nodev,noexec,nosuid 0 0
> > >  sysfs           sys          sysfs defaults  0 0
> > >  EOF
> > > +
> > >      if [ $? -ne 0 ]; then
> > >          echo "Failed to add configuration"
> > >          return 1
> > > @@ -1006,6 +1068,12 @@ if [ ! -z "$clean" -a -z "$path" ]; then
> > >      exit 0
> > >  fi
> > >  
> > > +# Let's do something better for the initial root password.
> > > +# It's not perfect but it will defeat common scanning brute force
> > > +# attacks in the case where ssh is exposed.  It will also be set to
> > > +# expired, forcing the user to change it at first login.
> > > +root_password=Root-${name}-${RANDOM}
> > > +
> > >  if [ -z "${utsname}" ]; then
> > >      utsname=${name}
> > >  fi
> > > @@ -1024,7 +1092,7 @@ fi
> > >  #    utsname and hostname = Container_Name.Domain_Name
> > >  
> > >  if [ $(expr "$utsname" : '.*\..*\.') = 0 ]; then
> > > -    if [ -n "$(dnsdomainname)" ]; then
> > > +    if [[ "$(dnsdomainname)" != "" && "$(dnsdomainname)" != "localdomain" ]]; then
> > >          utsname=${utsname}.$(dnsdomainname)
> > >      fi
> > >  fi
> > > @@ -1128,12 +1196,14 @@ if [ ! -z $clean ]; then
> > >      clean || exit 1
> > >      exit 0
> > >  fi
> > > -echo "container rootfs and config created"
> > > +echo "
> > > +Container rootfs and config have been created.
> > > +Edit the config file to check/enable networking setup.
> > > +"
> > >  
> > >  if [[ -d ${cache_base}/bootstrap ]]
> > >  then
> > > -    echo "
> > > -You have successfully built a Fedora container and cache.  This cache may
> > > +    echo "You have successfully built a Fedora container and cache.  This cache may
> > >  be used to create future containers of various revisions.  The directory
> > >  ${cache_base}/bootstrap contains a bootstrap
> > >  which may no longer needed and can be removed.
> > > @@ -1147,3 +1217,16 @@ This is only used in the creation of the bootstrap run-time-environment
> > >  and may be removed.
> > >  "
> > >  fi
> > > +
> > > +echo "The temporary password for root is: '$root_password'
> > > +
> > > +You may want to note that password down before starting the container.
> > > +
> > > +The password set up as "expired" and will require it to be changed it at
> > > +first login, which you should do as soon as possible.  If you lose the
> > > +root password or wish to change it without starting the container, you
> > > +can change it from the host by running the following command (which will
> > > +also reset the expired flag):
> > > +
> > > +        chroot ${rootfs_path} passwd
> > > +"
> > > -- 
> > > 1.8.3.1
> > > 
> > > 
> > 
> > -- 
> > Michael H. Warfield (AI4NB) | (770) 978-7061 |  mhw at WittsEnd.com
> >    /\/\|=mhw=|\/\/          | (678) 463-0932 |  http://www.wittsend.com/mhw/
> >    NIC whois: MHW9          | An optimist believes we live in the best of all
> >  PGP Key: 0x674627FF        | possible worlds.  A pessimist is sure of it!
> > 
> 
> 
> 
> > _______________________________________________
> > lxc-devel mailing list
> > lxc-devel at lists.linuxcontainers.org
> > http://lists.linuxcontainers.org/listinfo/lxc-devel
> 
> _______________________________________________
> lxc-devel mailing list
> lxc-devel at lists.linuxcontainers.org
> http://lists.linuxcontainers.org/listinfo/lxc-devel
> 

-- 
Michael H. Warfield (AI4NB) | (770) 978-7061 |  mhw at WittsEnd.com
   /\/\|=mhw=|\/\/          | (678) 463-0932 |  http://www.wittsend.com/mhw/
   NIC whois: MHW9          | An optimist believes we live in the best of all
 PGP Key: 0x674627FF        | possible worlds.  A pessimist is sure of it!

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 465 bytes
Desc: This is a digitally signed message part
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20140113/9ba5bbef/attachment.pgp>


More information about the lxc-devel mailing list