Conditional evaluation question.

Stewart Walters stw at bgc.com.au
Sat Apr 10 02:38:31 UTC 2010


Hi Glenn,

Thanks for the tip on only needing one option space defined - that 
actually makes sense, not sure why I didn't think of that when I was 
writing it!

The only other issue I have with this config now, is that I can't use 
the allow and deny statements within a scope for the group.

For example consider:

--- snip ---
subnet 192.168.1.0 netmask 255.255.255.0 {
   option routers 192.168.1.1;
   option subnet-mask 255.255.255.0;
   option broadcast-address 192.168.1.255;
   pool {
      deny members of "ProductionSunray" # This works, because it's a class.
      deny members of "TestingSunray" # This fails, because it's a group.
      range 192.168.1.30 192.168.1.153;
   }
   pool {
      allow members of "ProductionSunray" # This works, because it's a 
class.
      allow members of "TestingSunray" # This fails, because it's a group.
      range 192.168.1.154 192.168.1.254;
   }
}
subnet 192.168.2.0 netmask 255.255.255.0 {
   option routers 192.168.2.1;
   option subnet-mask 255.255.255.0;
   option broadcast-address 192.168.2.255;
   pool {
      deny members of "ProductionSunray" # This works, because it's a class.
      deny members of "TestingSunray" # This fails, because it's a group.
      range 192.168.2.30 192.168.2.153;
   }
   pool {
      allow members of "ProductionSunray" # This works, because it's a 
class.
      allow members of "TestingSunray" # This fails, because it's a group.
      range 192.168.2.154 192.168.2.254;
   }
}
--- snip ---

Do you know if there is any effective way to say "members of XX group 
are to be now cconsidered members of YY class"? I could then use allow 
and deny statements on the YY class.

Or do you think that's not possible?

Kind Regards,

Stewart




Glenn Satchell wrote:
> Hi Stewart,
>
> Nicely documented solution - very handy for the archives and google!
>
> One point I would make is that you only need to define one option 
> space. You can fill in different values in the class and the group and 
> the appropriate values will be used by the client...
>
> regards,
> -glenn
>
> On 04/08/10 16:46, Stewart Walters wrote:
>> Hi Glenn,
>>
>> Sorry, I re-read your reply and ultimately found the answer. You said,
>> as does the man page, host definitions get processed before classes.
>>
>> If anyone else in future wants to know how to get this to work
>> (particularly Sunray users attempting the same thing) - this is
>> essentially how to structure dhcpd.conf to manage multiple Sunray
>> environments:
>>
>> --- snip ---
>> authoritative;
>>
>> options.... # fill out all global options here
>>
>> #----------
>> # Sunray DHCP Vendor Encapsulated Options Definitions
>> #----------
>> # Setup the vendor encapulated options specific to Sun Ray DTUs. Run
>> 'man 5 dhcp-options' and search for 'VENDOR ENCAPSULATED OPTIONS' for
>> more information.
>>
>> # Production Environment
>> option space SunRay-ProdEnv; # 'SunRay-ProdEnv' is an arbitary value,
>> but needs to be used consistently for all the 'options' that apply to
>> this space.
>> option SunRay-ProdEnv.altauth code 35 = array of ip-address; # Optional
>> List of Sun Ray server IP addresses
>> option SunRay-ProdEnv.authsrvr code 21 = ip-address; # Mandatory Single
>> Sun Ray server IP address
>> option SunRay-ProdEnv.authport code 22 = unsigned integer 16; # Optional
>> Sun Ray server port
>> option SunRay-ProdEnv.barrierlevel code 36 = unsigned integer 32; #
>> Mandatory Firmware Download: barrier level
>> option SunRay-ProdEnv.fwsrvr code 31 = ip-address; # Optional Firmware
>> tftp server IP address
>> option SunRay-ProdEnv.intf code 29 = text; # Optional Sun Ray server
>> interface name
>> option SunRay-ProdEnv.loghost code 24 = ip-address; # Optional Syslog
>> server IP address
>> option SunRay-ProdEnv.logkern code 25 = unsigned integer 8; # Optional
>> Log level for kernel
>> option SunRay-ProdEnv.lognet code 26 = unsigned integer 8; # Optional
>> Log level for network
>> option SunRay-ProdEnv.logusb code 27 = unsigned integer 8; # Optional
>> Log level for USB
>> option SunRay-ProdEnv.logvid code 28 = unsigned integer 8; # Optional
>> Log level for video
>> option SunRay-ProdEnv.logappl code 28 = unsigned integer 8; # Optional
>> Sun Ray server interface namea (== logvid??)
>> option SunRay-ProdEnv.newtbw code 30 = unsigned integer 32; # Optional
>> Bandwidth cap
>> option SunRay-ProdEnv.newtpispindx code 32 = unsigned integer 32; #
>> Optional Obsolete. Do not use.
>> option SunRay-ProdEnv.newtflags code 34 = unsigned integer 32; #
>> Optional Obsolete. Do not use.
>> option SunRay-ProdEnv.newtver code 23 = text; # Optional Desired
>> firmware version
>>
>> # Test Environment
>> option space SunRay-TestEnv; # 'SunRay-TestEnv' is an arbitary value,
>> but needs to be used consistently for all the 'options' that apply to
>> this space.
>> option SunRay-TestEnv.altauth code 35 = array of ip-address; # Optional
>> List of Sun Ray server IP addresses
>> option SunRay-TestEnv.authsrvr code 21 = ip-address; # Mandatory Single
>> Sun Ray server IP address
>> option SunRay-TestEnv.authport code 22 = unsigned integer 16; # Optional
>> Sun Ray server port
>> option SunRay-TestEnv.barrierlevel code 36 = unsigned integer 32; #
>> Mandatory Firmware Download: barrier level
>> option SunRay-TestEnv.fwsrvr code 31 = ip-address; # Optional Firmware
>> tftp server IP address
>> option SunRay-TestEnv.intf code 29 = text; # Optional Sun Ray server
>> interface name
>> option SunRay-TestEnv.loghost code 24 = ip-address; # Optional Syslog
>> server IP address
>> option SunRay-TestEnv.logkern code 25 = unsigned integer 8; # Optional
>> Log level for kernel
>> option SunRay-TestEnv.lognet code 26 = unsigned integer 8; # Optional
>> Log level for network
>> option SunRay-TestEnv.logusb code 27 = unsigned integer 8; # Optional
>> Log level for USB
>> option SunRay-TestEnv.logvid code 28 = unsigned integer 8; # Optional
>> Log level for video
>> option SunRay-TestEnv.logappl code 28 = unsigned integer 8; # Optional
>> Sun Ray server interface namea (== logvid??)
>> option SunRay-TestEnv.newtbw code 30 = unsigned integer 32; # Optional
>> Bandwidth cap
>> option SunRay-TestEnv.newtpispindx code 32 = unsigned integer 32; #
>> Optional Obsolete. Do not use.
>> option SunRay-TestEnv.newtflags code 34 = unsigned integer 32; #
>> Optional Obsolete. Do not use.
>> option SunRay-TestEnv.newtver code 23 = text; # Optional Desired
>> firmware version
>>
>> #----------
>> # Define Production & Testing Sunray Environments Section
>> #----------
>> # dhcpd checks host statements before checking class statements.
>> #
>> # An excert from that section:
>> #
>> # When a client is to be booted, its boot parameters are determined by
>> consulting that client's host declaration (if any), and then 
>> consulting any
>> # class declarations matching the client, followed by the pool, subnet
>> and shared-network declarations for the IP address assigned to the 
>> client.
>> # Each of these declarations itself appears within a lexical scope, and
>> all declarations at less specific lexical scopes are also consulted for
>> # client option declarations. Scopes are never considered twice, and if
>> parameters are declared in more than one scope, the parameter 
>> declared in
>> # the most specific scope is the one that is used.
>> #
>> # Run 'man 5 dhcpd.conf' and read the 'DESCRIPTION' section for more
>> infomation.
>>
>> # Production Sunray Class
>> class "ProductionSunray" {
>> match if vendor-class-identifier = "SUNW.NewT.SUNW";
>> option dhcp-parameter-request-list 1,2,3,23,43,51,54,49,62;
>> vendor-option-space SunRay-ProdEnv;
>> option SunRay-ProdEnv.altauth prodsunray2.example.com,
>> prodsunray3.example.com, prodsunray4.example.com;
>> option SunRay-ProdEnv.authsrvr prodsunray1.example.com;
>> option SunRay-ProdEnv.fwsrvr prodsunray1.example.com;
>> option SunRay-ProdEnv.loghost prodsunray1.example.com;
>> }
>>
>> # Testing Suray Group
>> group "TestingSunray" {
>> option dhcp-parameter-request-list 1,2,3,23,43,51,54,49,62;
>> vendor-option-space SunRay-TestEnv;
>> option SunRay-TestEnv.altauth testsunray1.example.com;
>> option SunRay-TestEnv.authsrvr testsunray1.example.com;
>> option SunRay-TestEnv.fwsrvr testsunray1.example.com;
>> option SunRay-TestEnv.loghost testsunray1.example.com;
>>
>> # Training Room Sunrays
>> host sunray01 { hardware ethernet xx:xx:xx:xx:xx:xx; } # Asset Number
>> XXXXX; Owned by Joe Bloggs
>> host sunray02 { hardware ethernet yy:yy:yy:yy:yy:yy; } # Asset Number
>> XXXXX; Owned by Jane Bloggs
>> host sunray03 { hardware ethernet zz:zz:zz:zz:zz:zz; } # Asset Number
>> XXXXX; Owned by Fred Bloggs
>> host sunray04 { hardware ethernet aa:aa:aa:aa:aa:aa; } # Asset Number
>> XXXXX; Owned by Peter Bloggs
>> host sunray05 { hardware ethernet bb:bb:bb:bb:bb:bb; } # Asset Number
>> XXXXX; Owned by Madonna Bloggs
>> host sunray06 { hardware ethernet cc:cc:cc:cc:cc:cc; } # Asset Number
>> XXXXX; Owned by Bloggy Bloggs
>> }
>>
>> subnet 192.168.1.0 netmask 255.255.255.0 {
>> option routers 192.168.1.1;
>> option subnet-mask 255.255.255.0;
>> option broadcast-address 192.168.1.255;
>> pool {
>> range 192.168.1.30 192.168.1.254;
>> }
>> }
>> --- snip ---
>>
>> Regards,
>>
>> Stewart
>>
>>
>>
>>
>> Stewart Walters wrote:
>>> Hi Glenn, Mailinglist,
>>>
>>> Thanks for the reply.
>>>
>>> Do you know at all if it's possible to do multiple match statements?
>>>
>>> e.g.
>>>
>>> class "TestingSunray" {
>>> match vendor-class-identifier = "SUNW.NewT.SUNW" and hardware;
>>> option space...
>>> option...
>>> }
>>>
>>> Or even like this?
>>>
>>> class "ProductionSunray {
>>> if not match class "TestingSunray" and match vendor-class-identifier =
>>> "SUNW.NewT.SUNW";
>>> option space...
>>> option...
>>> }
>>>
>>> I'm just spitballing ideas here, not really sure if dhcpd is capable
>>> in this regard.
>>>
>>> Regards,
>>>
>>> Stewart
>>>
>>>
>>>
>>> Glenn Satchell wrote:
>>>> On 04/07/10 19:00, Stewart Walters wrote:
>>>>> Hi,
>>>>>
>>>>> I'm trying to work out what's the best way to configure dhcpd using
>>>>> some
>>>>> form of evaluation to send different vendor encapsulated options 
>>>>> to our
>>>>> Sunray thin clients.
>>>>>
>>>>> We currently have a server which provides a Production Sunray desktop
>>>>> environment to our userbase.
>>>>>
>>>>> If it helps - here is an example of how to set up dhcpd for passing a
>>>>> single Sunray environment to 100% of Sunray clients
>>>>> (http://blogs.sun.com/lewiz/entry/configuring_sun_ray_dhcp)
>>>>>
>>>>> As shown in that example, 100% of Sunray clients can be evaluated via
>>>>> the vendor-class-identifier = "SUNW.NewT.SUNW"; statement.
>>>>
>>>> I did something similar many years ago with ISC dhcpd on Solaris.
>>>>
>>>>> But I want to create a Test Sunray desktop evironment and move 10% of
>>>>> our users (determined by MAC address) to a different Testing
>>>>> environment. If the conditional evaluation doesn't qualify in the
>>>>> 10%, I
>>>>> want the remaining 90% of our Sunray clients to receive the 
>>>>> Production
>>>>> environment options.
>>>>>
>>>>> I've been reading through dhcp-options(5), dhcpd.conf(5) and
>>>>> dhcp-eval(5), as well as several online posts relating to this.
>>>>>
>>>>> But I'm a little perplexed about what the best approach for this
>>>>> kind of
>>>>> setup would be.
>>>>>
>>>>> Would it be better to go, for example:
>>>>>
>>>>> --- snip ---
>>>>> class "TestingSunray" {
>>>>> match <some match criteria here>
>>>>> <insert Testing vendor encapsulated options here>
>>>>> }
>>>>>
>>>>> subclass "TestingSunray" 1:xx:xx:xx:xx:xx:xx;
>>>>> subclass "TestingSunray" 1:yy:yy:yy:yy:yy:yy;
>>>>> subclass "TestingSunray" 1:zz:zz:zz:zz:zz:zz;
>>>>
>>>> The syntax for whatever is in the match line of the class is what
>>>> goes in the match portion of the subclass. So in the class if you 
>>>> said:
>>>>
>>>> class "TestingSunray" {
>>>> match hardware;
>>>> option space ...
>>>> option ...
>>>> }
>>>>
>>>> Then in the subclass you use the hardware address. This needs a
>>>> leading 1 which represents ethernet.
>>>>
>>>> subclass "TestingSunray" 1:xx:xx:xx:xx:xx:xx;
>>>>
>>>> The sub-class uses a fast hashing algorithm to determine membership,
>>>> so it's efficient even where there are lots of clients. See
>>>> dhcpd.conf SUBCLASSES section.
>>>>
>>>>> class "ProductionSunray" {
>>>>> match if vendor-class-identifier = "SUNW.NewT.SUNW";
>>>>> <insert Production vendor encapsulated options here>
>>>>> }
>>>>
>>>> If you are going to be filling in the option space in different
>>>> places, then you should put the option space definitions in the
>>>> global scope, and assign the values in the classes or groups.
>>>>
>>>>> --- snip ---
>>>>>
>>>>> Does dhcpd even process class matching in the order in which it's
>>>>> listed
>>>>> in dhcpd.conf? Am I guaranteed in that configuration that a Test 
>>>>> Sunray
>>>>> wont be classified as Production just because the Testing class is
>>>>> defined first?
>>>>
>>>> What happens here is that some clients will be in *both* classes.
>>>> It's not about only matching the first class you come across.
>>>> Unfortunately things are not clear about which class definition is
>>>> the most specific, ie which one "wins" when both define the same
>>>> options. If this point can be clearly defined then the subclass
>>>> solution is the definite winner.
>>>>
>>>> Now for some other ways to clearly use the most specific group.
>>>> Consider this paragraph from the dhcpd.conf man page, which specifies
>>>> the scoping order:
>>>>
>>>> When a client is to be booted, its boot parameters are
>>>> determined by consulting that client's host declaration (if
>>>> any), and then consulting any class declarations matching
>>>> the client, followed by the pool, subnet and shared-network
>>>> declarations for the IP address assigned to the client.
>>>> Each of these declarations itself appears within a lexical
>>>> scope, and all declarations at less specific lexical scopes
>>>> are also consulted for client option declarations. Scopes
>>>> are never considered twice, and if parameters are declared
>>>> in more than one scope, the parameter declared in the most
>>>> specific scope is the one that is used.
>>>>
>>>> We could use a group and host statements to make sure we are more
>>>> specific than a class. For example this group, and the
>>>> ProductionSunrays class above. You only need to put in the options
>>>> that are different for testing, as these clients are still members of
>>>> ProductionSunrays and will pick up other options from there.
>>>>
>>>> # testing sunrays
>>>> group {
>>>> option ...
>>>> host "host1" { hardware ethernet xx:xx:xx:xx:xx:xx; }
>>>> host "host2" { hardware ethernet xx:xx:xx:xx:xx:xx; }
>>>> }
>>>>
>>>>> Or is it better to do this?
>>>>>
>>>>> --- snip ---
>>>>> class "Sunray" {
>>>>> match if substring(hardware,1,3)=xx:xx:xx:xx:xx:xx or
>>>>> elsif substring(hardware,1,3)=yy:yy:yy:yy:yy:yy or
>>>>> elsif substring(hardware,1,3)=zz:zz:zz:zz:zz:zz;
>>>>> <insert Testing vendor encapsulated options here>
>>>>> else
>>>>> match if option vendor-class-identifier = "SUNW.NewT.SUNW";
>>>>> <insert Production vendor encapsulated options here>
>>>>> }
>>>>> --- snip ---
>>>>> (I probably made a bunch of minor syntax errors above, but I can work
>>>>> those out later)
>>>>
>>>> That doesn't scale very well and the logic is not quite right.
>>>>
>>>> class "Sunray" {
>>>> match if option vendor-class-identifier = "SUNW.NewT.SUNW";
>>>> # default options for all
>>>> option ...
>>>>
>>>> # option for testing sunrays
>>>> if hardware = xx:xx:xx:xx:xx:xx
>>>> or substring(hardware,1,3) = yy:yy:yy
>>>> or ... {
>>>> option ...
>>>> }
>>>> }
>>>>
>>>>> Or should I be doing some complicated if and else statements as
>>>>> shown in
>>>>> the example at
>>>>> http://www.linuxforums.org/forum/servers/69851-dhcpd-conf-multiple-subnet-single-physical-network-configuration.html 
>>>>>
>>>>>
>>>>
>>>> Having just looked at that page I would *not* recommend using those
>>>> methods at all. That guy is deliberately trying to make things as
>>>> difficult and complicated as possible. Difficult and complicated
>>>> means hard to understand, hard to get working and hard to fix if
>>>> things aren't quite right.
>>>>
>>>>> As you can see, I'm not exactly sure to which way might be best 
>>>>> for me.
>>>>> Let me say thanks in advance for any assistance you can provide on 
>>>>> the
>>>>> matter.
>>>>
>>>> Ah, it is a very interesting question, but the solution comes down to
>>>> being able to define the subset of clients that are going to get
>>>> different options. That's all.
>>>>
> _______________________________________________
> dhcp-users mailing list
> dhcp-users at lists.isc.org
> https://lists.isc.org/mailman/listinfo/dhcp-users


-- 
Stewart Walters
IT Systems Manager
BGC Australia Pty Ltd
Phone:   08 9334 4646
Fax:     08 9334 4660
Mobile:  0429 100 465
Email:   stw at bgc.com.au




More information about the dhcp-users mailing list