[lxc-devel] {Disarmed} Re: [PATCH] Enhancements to the centos template

Michael H. Warfield mhw at WittsEnd.com
Fri Mar 14 17:00:12 UTC 2014


On Fri, 2014-03-14 at 23:05 +0800, Mingjiang Shi wrote:
> Hi Michael,
> Thanks a lot for your good comments.  I will create a new patch to
> address your comments which only includes the items #1 and #2, and
> leave the static ip patch for now. 


>         I have no heartburn over making that optional but the other
>         password
>         parameters are being done with tuning knobs.  I think I would
>         prefer to
>         add a tuning knob for that.


> Would you please elaborate on this comments?  Are you suggesting allow
> user to pass the password as a command line parameter? 

No no no, not at all.

Right now, the password tuning knobs in the CentOS template are defined
starting around line 32 of lxc-centos starting here...

--
# Some combinations of the tunning knobs below do not exactly make sense.
# but that's ok.
-

[Great...  Another bloody typo in my comments (tunning).  I'll fix that
later.  I'm constantly doing that.]

The current set are:

root_password
root_display_password
root_store_password
root_prompt_password

They are each picked up by a unusual looking assignment statement (the
convention of which dates back to the earliest days of the Bourne
Shell /bin/sh):

-- 
# These are conditional assignments...  The can be overridden from the
# preexisting environment variables...
#
# Make sure this is in single quotes to defer expansion to later!
# :{root_password='Root-${name}-${RANDOM}'}
: ${root_password='Root-${name}-XXXXXX'}

# Now, it doesn't make much sense to display, store, and force change
# together.  But, we gotta test, right???
: ${root_display_password='no'}
: ${root_store_password='yes'}
# Prompting for something interactive has potential for mayhem
# with users running under the API...  Don't default to "yes"
: ${root_prompt_password='no'}
-- 

Now, something like ": foo" wouldn't appear to do anything ( : is an
shell alias for the "true" command ) but it does in this case.  The
expansion of something like ${root_prompt_password='no'} will perform
the assignment inside the brace if the variable is not defined and then
will expand the variable.  We don't care about the expansion part, all
we care about is the conditional assignment.  Means you can do this:

export root_password='Who-${name}-XXXXXX' ${root_display_password='yes'} lxc-create -t centos -n CentOS

The exported variables will override the defaults in the script.  You
can use that in higher level scripts to adjust policy.

In this case, I would add an environment variable root_password_expired
default "yes" much the same way.  Then you could just to a whole series
of creates in your shell script like this...

export root_password_expired=no
export root_store_password=no
export root_password=${new_pass}
lxc-create -t centos -n centos-111
lxc-create -t centos -n centos-112
lxc-create -t centos -n centos-113

The script takes the password expired toggle from the environment.

> I found that the centos template could get the password from an
> environment variable named "root_password", so I use it in this way:
> root_password="my root password" lxc-create -t centos -n my_container
> -E
> where -E is the newly added switch to not expire the root password.

Yeah, you're using one of the tuning knobs, root_password, which can be
a template for password patterns as well.

In your case, if you are doing this, I would strongly recommend setting
"root_store_password=no" as well.  Otherwise, your (expected to be
temporary) is stored in /var/lib/lxc/${Container}/tmp_root_pass which is
something you probably don't want.

I'm glad to see someone is actually using that facility.

> Thanks again!

Regards.
Mike
> 
> On Fri, Mar 14, 2014 at 8:11 AM, Michael H. Warfield
> <mhw at wittsend.com> wrote:
>         Ok...  Back from the -users list, now I'll get into some
>         details...
>         
>         On Thu, 2014-03-13 at 23:49 +0800, Mingjiang Shi wrote:
>         > Hi All,
>         > This patch introduces the following enhancements to the
>         centos
>         > templates.
>         > 1. Added option to not expire the root password
>         
>         
>         I have no heartburn over making that optional but the other
>         password
>         parameters are being done with tuning knobs.  I think I would
>         prefer to
>         add a tuning knob for that.
>         
>         I should mentioned that I, personally, actually never use
>         those
>         generated passwords anyways and generally immediately follow
>         the
>         lxc-create command with a command like this:
>         
>         chroot /var/lib/lxc/${Container}/rootfs passwd
>         
>         That resets the password to one I'm providing without even
>         using the
>         generated one and it resets the expired bit, so you're done
>         anyways.  We
>         really can't "prompt for" the password in the template because
>         of issues
>         regarding interactive prompts in API functions, from what I
>         understand.
>         
>         > 2. Added option to copy the host ssh public key to the
>         container so
>         > that one can ssh to the my containers without using password
>         
>         
>         Ubuntu and Gentoo seem to already do this in a different way
>         using a
>         different parameter than what you're suggesting...
>         
>         They:
>         -S auth_key
>         Copies specified auth_key to root users authorized_keys file.
>         
>         You:
>         -s
>         Copies the user's authorized_keys file to root in the
>         container.
>         
>         I'm not sure I would implement that feature your way at all.
>          It has
>         some problems.  That template can only be run under "uid
>         0" (root).
>         Older versions of sudo would leave HOME set to the calling
>         user, causing
>         it to act one way, newer version set it to /root resulting in
>         another
>         behavior.  That sort of potential ambiguity is not a good
>         practice.
>         
>         I'm also not sure copying the two public id files is the right
>         another
>         either.  It may be for you, it certainly wouldn't be for me.
>          My hosts
>         don't have the individual id files on them (and certainly no
>         private
>         keys) and only have the authoritized_keys file (which a number
>         of public
>         id keys).  I have no need for the private keys on those hosts,
>         since
>         they're only connected to from a secure remote workstation and
>         I use key
>         agent forwarding for subsequent connections between remote
>         systems.
>         
>         My choice there would be the method in the Ubuntu template
>         (the Gentoo
>         template has a typo in it that likely renders that feature
>         non-operable
>         in a non-obvious way {hangs on line 620}).
>         
>         > 3. Added option to set static IP to the container. Used when
>         run
>         > services which needs static ip address, such as hadoop.
>         
>         
>         Ok...  Here I have some heartburn.  Not from adding the IP,
>         but the way
>         it's done.  Two other templates, lxc-altlinux and
>         lxc-openmadrivia, are
>         already doing this but using different parameters.
>         
>         Your option:
>         
>         --ip)           use_static_ip=yes; ip=$2;
>         
>         Their options:
>         
>         -4|--ipv4)      ipv4=$2;
>         -6|--ipv6)      ipv6=$2;
>         
>         I realize that you may not care about IPv6, but I certainly
>         do.
>         
>         Even in the IPv4 case, you've assumed a /24.  That may be
>         often true but
>         it certainly is not universally true and you don't provide a
>         way to
>         specify that either by included CIDR or by netmask.
>         
>         You specify the /24 CIDR into the config but then don't
>         specify the
>         netmask in the ifcfg files.  That would not end well on my
>         network,
>         which is an old "class B" subneted in may variable ways (to
>         say nothing
>         of the 10./8 or 172.16/12 or others below 128./8).  If someone
>         happen to
>         be using the 10. net on their private bridge and you give one
>         machine a
>         10.1.1.1, the system is going to try and configure itself to
>         MailScanner has detected a possible fraud attempt from
>         "10.1.1.1" claiming to be MailScanner warning: numerical links
>         are often malicious: 10.1.1.1/8,
>         with a broadcast of 10.255.255.255.  172.17.1.1 would end up
>         being
>         MailScanner has detected a possible fraud attempt from
>         "172.17.1.1" claiming to be MailScanner warning: numerical
>         links are often malicious: 172.17.1.1/16 with a broadcast of
>         172.17.255.255.  Not the intended
>         result at all.
>         
>         You're not sanity checking those IP addresses to insure they
>         are valid
>         addresses or usable addresses.  Yeah, it'll cause the
>         container's
>         networking to blow up down the road but it would be nice to
>         catch the
>         easy typos before getting that far.  Sanity checking addresses
>         like that
>         is a non-trivial task, though, I will admit.
>         
>         I also have some heartburn here as to multiple interfaces.
>          You may have
>         only one in each container, I happen to have at least two in
>         each.  It's
>         not clear how that structures out when you're merely cat'ing
>         the
>         "lxc.network.ipv4 =" line to the end of the config file.  It
>         would be
>         after the definition of veth1 (the second interface).  I think
>         it will
>         only apply to veth0, since these are not tightly associated,
>         but I'll
>         have to tinker with it a bit.  I generally find that just
>         setting up the
>         ifcfg-eth* files are sufficient.
>         
>         I think we could have a whole long discussion over assignment
>         of static
>         IPv4 and IPv6 addresses much along the lines that took place a
>         couple of
>         months ago with regards to assigning persistent mac addresses
>         to
>         containers.  I also need to have a closer look at how those
>         other two
>         templates are handling netmasks and netblocks and multiple
>         interfaces.
>         
>         > Let me know if you have any questions. Thanks!
>         
>         
>         Other problems I have with your attached patch...
>         
>         It makes other changes to the template that are not
>         documented,
>         reasoned, or commented on.
>         
>         You've added packages to the package list, and I wouldn't
>         normally
>         disagree with them (I add most of them myself) but we've been
>         trying to
>         keep the minimal config as minimal as possible.  Yeah, I would
>         place
>         "sudo" on the list of "should be there" but "wget"?  Yeah, I
>         like wget
>         but I have no heartburn with curl and if we all added our
>         fav's to the
>         default for everybody, I'm not sure we'd be happy with the
>         result.
>         There's been some discussion over "additional packages" (like
>         Oracle
>         does) but not much.
>         
>         You've "flipped case" on some variables for no apparent
>         reason.  I know
>         that's a gimish gamash of upper and lower case variable names
>         and (even
>         though I'm not the original author - 4th down on the list in
>         fact) but,
>         if you start making arbitrary changes in style, outside of
>         what's been
>         established, it creates unnecessary patching in git and the
>         potential
>         for "patch wars".  Such changes are also potential for trouble
>         if you
>         "miss something" and "something unintended occurs".  I
>         inherited the
>         gimish gamash and have made no effort to "clean it up", I
>         admit.
>         
>         If you change something, even if you think it's trivial or
>         just cleaning
>         something up, you should comment on it either in the code or
>         in the
>         patch header comments or both.
>         
>         You've got some good ideas but this needs more discussion in
>         the realm
>         of all the templates and some of the details may work fine on
>         your
>         network but you break on mine and others.  Options should
>         "work in
>         general" as much as possible and not be for specific setups.
>         
>         > Tests have been run:
>         > 1. Created a container without using the newly added
>         options, the
>         > current behaviors are preserved, i.e. root password need to
>         be changed
>         > at first log, dynamic ip address and no public key is
>         copied.
>         > 2. Tested the new behaviors are working by creating a
>         container using
>         > the newly added options.
>         
>         > Signed-off-by: Mingjiang Shi <mrjewes at gmail dot com>
>         
>         
>         At minimum for the networking issues and parameter usage that
>         is
>         inconsistent with the other existing templates, this isn't
>         ready yet.
>         
>         Nacked-by: Michael H. Warfield <mhw at WittsEnd.com>
>         
>         > ---
>         > diff --git a/templates/lxc-centos.in
>         b/templates/lxc-centos.in
>         > index 55e0531..3c0e9e6 100644
>         > --- a/templates/lxc-centos.in
>         > +++ b/templates/lxc-centos.in
>         > @@ -229,31 +229,57 @@ configure_centos()
>         >               cd ${rootfs_path}/etc/rc.d/rc6.d
>         >               ln -s ../init.d/lxc-halt S00lxc-reboot
>         >          )
>         >      fi
>         >
>         > +    if [ $use_static_ip == "yes" ];then
>         > +    # configure the network using static ip
>         > +    cat <<EOF >
>         > ${rootfs_path}/etc/sysconfig/network-scripts/ifcfg-eth0
>         > +DEVICE=eth0
>         > +BOOTPROTO=none
>         > +ONBOOT=yes
>         > +HOSTNAME=${utsname}
>         > +NM_CONTROLLED=no
>         > +TYPE=Ethernet
>         > +MTU=${MTU}
>         > +EOF
>         > +    # set static route, add the default gateway
>         > +    cat <<EOF > ${rootfs_path}/etc/sysconfig/static-routes
>         > +any net default gw ${gw}
>         > +EOF
>         > +
>         > +    # set minimal hosts, don't resolve the hostname to
>         127.0.0.1
>         > +    # resolve it to the static ip
>         > +    cat <<EOF > $rootfs_path/etc/hosts
>         > +127.0.0.1 localhost
>         > +$ip ${utsname} $name
>         > +EOF
>         > +
>         > +    else
>         >      # configure the network using the dhcp
>         >      cat <<EOF >
>         > ${rootfs_path}/etc/sysconfig/network-scripts/ifcfg-eth0
>         >  DEVICE=eth0
>         >  BOOTPROTO=dhcp
>         >  ONBOOT=yes
>         > -HOSTNAME=${UTSNAME}
>         > +HOSTNAME=${utsname}
>         >  NM_CONTROLLED=no
>         >  TYPE=Ethernet
>         >  MTU=${MTU}
>         >  EOF
>         >
>         > +    # set minimal hosts
>         > +    cat <<EOF > $rootfs_path/etc/hosts
>         > +127.0.0.1 localhost $name
>         > +EOF
>         > +    fi
>         > +
>         >      # set the hostname
>         >      cat <<EOF > ${rootfs_path}/etc/sysconfig/network
>         >  NETWORKING=yes
>         > -HOSTNAME=${UTSNAME}
>         > +HOSTNAME=${utsname}
>         >  EOF
>         >
>         > -    # set minimal hosts
>         > -    cat <<EOF > $rootfs_path/etc/hosts
>         > -127.0.0.1 localhost $name
>         > -EOF
>         >
>         >      # set minimal fstab
>         >      cat <<EOF > $rootfs_path/etc/fstab
>         >  /dev/root               /                       rootfs
>         defaults
>         >      0 0
>         >  none                    /dev/shm                tmpfs
>         >  nosuid,nodev    0 0
>         > @@ -337,12 +363,15 @@ EOF
>         >          echo ${root_password} >
>         ${config_path}/tmp_root_pass
>         >          echo "Storing root password in
>         > '${config_path}/tmp_root_pass'"
>         >      fi
>         >
>         >      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
>         > +
>         > +    if [ $expire_root_passwd == "yes" ];then
>         > +        # Set this password as expired to force the user to
>         change
>         > it!
>         > +        chroot $rootfs_path passwd -e root
>         > +    fi
>         >
>         >      # This will need to be enhanced for CentOS 7 when
>         systemd
>         >      # comes into play...   /\/\|=mhw=|\/\/
>         >
>         >      return 0
>         > @@ -370,11 +399,11 @@ download_centos()
>         >      fi
>         >
>         >      # download a mini centos into a cache
>         >      echo "Downloading centos minimal ..."
>         >      YUM="yum --installroot $INSTALL_ROOT -y --nogpgcheck"
>         > -    PKG_LIST="yum initscripts passwd rsyslog vim-minimal
>         > openssh-server openssh-clients dhclient chkconfig rootfiles
>         > policycoreutils"
>         > +    PKG_LIST="yum initscripts passwd rsyslog vim
>         openssh-server
>         > openssh-clients dhclient chkconfig rootfiles policycoreutils
>         wget tar
>         > sudo zip unzip which"
>         >
>         >      # use temporary repository definition
>         >      REPO_FILE=
>         $INSTALL_ROOT/etc/yum.repos.d/lxc-centos-temp.repo
>         >      mkdir -p $(dirname $REPO_FILE)
>         >      if [ -n "$repo" ]; then
>         > @@ -559,10 +588,15 @@ lxc.rootfs = $rootfs_path
>         >              fi
>         >          fi
>         >      done < $config_path/config.def
>         >
>         >      rm -f $config_path/config.def
>         > +
>         > +    # append the container ip address
>         > +    if [ $use_static_ip == "yes" ];then
>         > +      echo "lxc.network.ipv4 = ${ip}/24" >>
>         $config_path/config
>         > +    fi
>         >
>         >      if [ -e "@LXCTEMPLATECONFIG@/centos.common.conf" ];
>         then
>         >          echo "
>         >  # Include common configuration
>         >  lxc.include = @LXCTEMPLATECONFIG@/centos.common.conf
>         > @@ -635,46 +669,87 @@ Optional args:
>         >    -p,--path         path to where the container rootfs will
>         be
>         > created, defaults to /var/lib/lxc/name.
>         >    -c,--clean        clean the cache
>         >    -R,--release      Centos release for the new container.
>         if the host
>         > is Centos, then it will defaultto the host's release.
>         >       --fqdn         fully qualified domain name (FQDN) for
>         DNS and
>         > system naming
>         >       --repo         repository to use (url)
>         > +     --ip           specify a static ip, must use with --gw
>         option
>         > +     --gw           specify the default gateway, required
>         if --ip
>         > option is used.
>         > +  -E,               don't set the root password expired
>         > +  -s,               Copy the current ssh public key to the
>         authorized
>         > host list of the container
>         >    -a,--arch         Define what arch the container will be
>         > [i686,x86_64]
>         >    -h,--help         print this help
>         >  EOF
>         >      return 0
>         >  }
>         >
>         > -options=$(getopt -o a:hp:n:cR: -l
>         > help,path:,rootfs:,name:,clean,release:,repo:,arch:,fqdn: --
>         "$@")
>         > +copy_ssh_key_to_container()
>         > +{
>         > +    # create the .ssh folder and set permission
>         > +    container_ssh_dir=${rootfs_path}/root/.ssh
>         > +    if [ ! -d $container_ssh_dir ];then
>         > +        mkdir -p $container_ssh_dir
>         > +        chmod 700 $container_ssh_dir
>         > +    fi
>         > +
>         > +    # copy the id_rsa.pub to authorized_keys if exists
>         > +    my_ssh_id=$HOME/.ssh/id_rsa.pub
>         > +    if [ -f $my_ssh_id ];then
>         > +        cat $my_ssh_id >>
>         $container_ssh_dir/authorized_keys
>         > +    fi
>         > +
>         > +    # copy the id_dsa.pub to authorized_keys if exists
>         > +    my_ssh_id=$HOME/.ssh/id_dsa.pub
>         > +    if [ -f $my_ssh_id ];then
>         > +        cat $my_ssh_id >>
>         $container_ssh_dir/authorized_keys
>         > +    fi
>         > +}
>         > +
>         > +options=$(getopt -o a:hp:n:cR:Es -l
>         >
>         help,path:,rootfs:,name:,clean,release:,repo:,arch:,fqdn:,ip:,gw: --
>         > "$@")
>         >  if [ $? -ne 0 ]; then
>         >      usage $(basename $0)
>         >      exit 1
>         >  fi
>         >
>         >  arch=$(arch)
>         > +use_static_ip=no
>         > +ip=
>         > +gw=
>         > +expire_root_passwd=yes
>         > +copy_ssh_id=no
>         >  eval set -- "$options"
>         >  while true
>         >  do
>         >      case "$1" in
>         >          -h|--help)      usage $0 && exit 0;;
>         >          -p|--path)      path=$2; shift 2;;
>         >          --rootfs)       rootfs=$2; shift 2;;
>         >          -n|--name)      name=$2; shift 2;;
>         >          -c|--clean)     clean=$2; shift 2;;
>         >          -R|--release)   release=$2; shift 2;;
>         > - --repo) repo="$2"; shift 2;;
>         > +    --repo) repo="$2"; shift 2;;
>         >          -a|--arch)      newarch=$2; shift 2;;
>         >          --fqdn)         utsname=$2; shift 2;;
>         > +        --ip)           use_static_ip=yes; ip=$2; shift 2;;
>         > +        --gw)           gw=$2; shift 2;;
>         > +        -E)             expire_root_passwd=no; shift 1;;
>         > +        -s)             copy_ssh_id=yes; shift 1;;
>         >          --)             shift 1; break ;;
>         >          *)              break ;;
>         >      esac
>         >  done
>         >
>         >  if [ ! -z "$clean" -a -z "$path" ]; then
>         >      clean || exit 1
>         >      exit 0
>         >  fi
>         >
>         > +if [ ! -z "$ip" -a -z "$gw" ];then
>         > +    echo "Missing the default gateway, use --gw option to
>         specify the
>         > default gateway"
>         > +    usage $0
>         > +    exit 1
>         > +fi
>         > +
>         >  basearch=${arch}
>         >  # Map a few architectures to their generic CentOS
>         repository archs.
>         >  # The two ARM archs are a bit of a guesstimate for the v5
>         and v6
>         >  # archs.  V6 should have hardware floating point (Rasberry
>         Pi).
>         >  # The "arm" arch is safer (no hardware floating point).  So
>         > @@ -846,10 +921,15 @@ if [ $? -ne 0 ]; then
>         >      exit 1
>         >  fi
>         >
>         >  configure_centos_init
>         >
>         > +# copy the ssh public key to authorized keys in the
>         container
>         > +if [ $copy_ssh_id == "yes" ];then
>         > +    copy_ssh_key_to_container
>         > +fi
>         > +
>         >  if [ ! -z $clean ]; then
>         >      clean || exit 1
>         >      exit 0
>         >  fi
>         >  echo "
>         > @@ -879,15 +959,17 @@ then
>         >
>         >          chroot ${rootfs_path} passwd
>         >  "
>         >      chroot ${rootfs_path} passwd
>         >  else
>         > -    echo "
>         > -The root password is set up as "expired" and will require
>         it to be
>         > changed
>         > -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
>         > -"
>         > +    if [ $expire_root_passwd == "yes" ];then
>         > +    echo "
>         > + The root password is set up as "expired" and will require
>         it to be
>         > changed
>         > + 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
>         > + "
>         > +    fi
>         >  fi
>         > ---
>         >
>         >
>         > --
>         > Thanks
>         > -Mingjiang
>         >
>         
>         > --
>         > This message has been scanned for viruses and
>         > dangerous content by MailScanner, and is
>         > believed to be clean.
>         > _______________________________________________
>         > 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!
>         
>         
>         _______________________________________________
>         lxc-devel mailing list
>         lxc-devel at lists.linuxcontainers.org
>         http://lists.linuxcontainers.org/listinfo/lxc-devel
>         
> 
> 
> 
> 
> -- 
> Thanks
> -Mingjiang
> 
> -- 
> This message has been scanned for viruses and 
> dangerous content by MailScanner, and is 
> believed to be clean. 
> _______________________________________________
> 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: 482 bytes
Desc: This is a digitally signed message part
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20140314/cb738add/attachment-0001.pgp>


More information about the lxc-devel mailing list