Puppet - File Server


Puppet follows the concept of client and server where one machine in a setup works as the server machine with Puppet server software running on it and the remaining works as the client with Puppet agent software running on it. This feature of the file server helps in copying the files around multiple machines. This feature of file serving function in Puppet comes as a part of central Puppet daemon. Puppetmasterd and the client function plays a key role in sourcing file attributes as the file object.

class { 'java':  
   package               => 'jdk-8u25-linux-x64',  
   java_alternative      => 'jdk1.8.0_25',  
   java_alternative_path => '/usr/java/jdk1.8.0_25/jre/bin/java'  

As in the above code snippet, Puppet’s file serving functions abstracts the local filesystem topology by supporting the file service module. We will specify the file serving module in the following manner.


File Format

In Puppet directory structure, by default the file server configuration is located under /etc/puppet/fileserver.config directory, if the user wishes to change this default configuration file path, it can be done using the new config flag to puppetmasterd. The configuration file resembles INI files but is not exactly the same.

path /path/to/files 
allow *.domain.com 
deny *.wireless.domain.com 

As shown in the above code snippet, all the three options are represented in the configuration file. The module name somewhat goes in the brackets. The path is the only required option. Default security option is to deny all the access, so if no allow lines are specified, the module which will be configured will be available to anyone.

The path can contain any or all of the %d, %h and %H which are dynamically replaced by its domain name, its host name, and fully qualified host name. All are taken from the client’s SSL certificate (so be careful if one has a mismatch in hostname and certificate name). This is useful is creating modules where the files of each client are kept completely separately. Example, for private host keys.

path /data/private/%h 
allow * 

In the above code snippet, the code is trying to search for file /private/file.txt from the client client1.vipin.com. It will look for it in /data/private/client1/file.txt, while the same request for client2.vipin.com will try to retrieve the file /data/private/client2/file.txt on the file server.


Puppet supports the two basic concepts of securing file on the Puppet file server. This is achieved by allowing access to specific files and denying access to the ones which are not required. By default, Puppet does not allow access to any of the files. It needs to be defined explicitly. The format which can be used in the files to allow or deny access is by using IP address, name, or global allow.

If the client is not connected to the Puppet file server directly, for example using a reverse proxy and Mongrel, then the file server will see all the connections as coming from the proxy server and not the Puppet client. In the above cases, restricting the host name on the base of hostname is the best practice.

One key point to be noted while defining the file structure is, all the deny statements are parsed before the allow statement. Hence, if any deny statement matches a host, then that host will be denied and if no allow statement is written in the upcoming files, then the host will be denied. This feature helps in setting priority of any particular site.

Host Name

In any file server configuration, file hostname can be specified in two ways either by using a complete hostname or specifying an entire domain name using the * wildcard as shown in the following example.

path /usr 
allow brcleprod001.brcl.com 
allow *.brcl.com 
deny brcleprod002.brcl.com

IP Address

In any file server configuration, the file address can be specified as similar to the host names, using either complete IP address or wildcard address. One can also use CIDR system notation.

path /usr 
allow 172.223.30.* 

Global Allow

Global allow is used when the user wants that everyone can access a particular module. To do this, a single wildcard helps in letting everyone access the module.

path /export 
allow *