We already downloaded and installed func on our clients using kickstart. We can now install fun on server0 and push the configuration with puppet.
[root@server0 ~]# yum install func Setting up Install Process Parsing package install arguments Resolving Dependencies --> Running transaction check ---> Package func.noarch 0:0.24-1.el5 set to be updated --> Processing Dependency: certmaster >= 0.24 for package: func --> Processing Dependency: python-simplejson for package: func --> Processing Dependency: pyOpenSSL for package: func --> Running transaction check ... Installed: func.noarch 0:0.24-1.el5 Dependency Installed: certmaster.noarch 0:0.24-1.el5 pyOpenSSL.x86_64 0:0.6-1.p24.7.2.2 python-simplejson.x86_64 0:2.0.3-2.el5 Complete! [root@server0 ~]# chkconfig certmaster on [root@server0 ~]# service certmaster start Starting certmaster daemon:Certmaster listens on port 51235, we'll need to add that port to our firewall.
[root@server0 ~]# iptables -I RH-Firewall-1-INPUT -p tcp -m state --state NEW,ESTABLISHED,RELATED --dport 51235 -j ACCEPT [root@server0 ~]# cd /etc/sysconfig [root@server0 sysconfig]# iptables-save >iptablesNow, let's add the configuration for func to puppet and restart the puppetmaster (since we will need to change site.pp).
[root@server0 etc]# cd /var/lib/puppet/files/base/etc [root@server0 etc]# mkdir certmaster [root@server0 etc]# cd certmaster/ [root@server0 certmaster]# vi minion.conf [root@server0 certmaster]# cat minion.conf # configuration for minions [main] certmaster = server0.example.com certmaster_port = 51235 log_level = DEBUG cert_dir = /etc/pki/certmaster [root@server0 certmaster]# cd /etc/puppet/manifests/ [root@server0 manifests]# vi func.pp [root@server0 manifests]# cat func.pp class func { remotefile { "/etc/certmaster/minion.conf": mode => 644 } service { funcd: ensure => true, enable => true, hasrestart => true } } [root@server0 manifests]# vi site.pp [root@server0 manifests]# cat site.pp # site.pp import "functions.pp" # define nodes import "nodes.pp" # define classes import "base.pp" import "func.pp" [root@server0 manifests]# vi nodes.pp [root@server0 manifests]# cat nodes.pp node default { include base include func } [root@server0 manifests]# service puppetmaster restart Stopping puppetmaster: [ OK ] Starting puppetmaster: [ OK ]Now on our client, if we restart puppet, we can see the change propagated (we could also wait and the change would be propagated at the next check-in.
[root@client15 ~]# cd /etc/certmaster [root@client15 certmaster]# puppetd --fqdn=$HOSTNAME --test --no-splay --server=server0.example.com --onetime --verbose --factsync info: Retrieving facts info: Caching catalog at /var/lib/puppet/localconfig.yaml notice: Starting catalog run 4c4 certmaster = certmaster --- > certmaster = server0.example.com 8d7 notice: //Node[default]/func/Remotefile[/etc/certmaster/minion.conf]/File[/etc/certmaster/minion.conf]/source: replacing from source puppet://server0.example.com/base//etc/certmaster/minion.conf with contents {md5}7c1ae4564f05e3f9ca50633c89d2a63b notice: //Node[default]/func/Service[funcd]/ensure: ensure changed 'stopped' to 'running' notice: Finished catalog run in 2.67 seconds [root@client15 certmaster]# cat minion.conf # configuration for minions [main] certmaster = server0.example.com certmaster_port = 51235 log_level = DEBUG cert_dir = /etc/pki/certmasterNow, back on server0 we'll need to sign client15's certificate.
[root@server0 ~]# certmaster-ca --list client15.example.com [root@server0 ~]# certmaster-ca --sign client15.example.com /var/lib/certmaster/certmaster/csrs/client15.example.com.csr signed - cert located at /var/lib/certmaster/certmaster/certs/client15.example.com.cert [root@server0 ~]# certmaster-ca --list No certificates to signAt this point out client has connected to our server and requested a certificate, we then signed that certificate. We can now ask the client to do something.
[root@server0 certmaster]# func client15.example.com call hardware info {'client15.example.com': ['REMOTE_ERROR', 'socket.error', "(113, 'No route to host')", ' File "/usr/lib/python2.4/site-packages/func/overlord/client.py", line 433, in process_server\n retval = getattr(conn, meth)(*args[:])\n File "/usr/lib64/python2.4/xmlrpclib.py", line 1096, in __call__\n return self.__send(self.__name, args)\n File "/usr/lib64/python2.4/xmlrpclib.py", line 1383, in __request\n verbose=self.__verbose\n File "/usr/lib64/python2.4/xmlrpclib.py", line 1129, in request\n self.send_content(h, request_body)\n File "/usr/lib64/python2.4/xmlrpclib.py", line 1243, in send_content\n connection.endheaders()\n File "/usr/lib64/python2.4/httplib.py", line 804, in endheaders\n self._send_output()\n File "/usr/lib64/python2.4/httplib.py", line 685, in _send_output\n self.send(msg)\n File "/usr/lib64/python2.4/httplib.py", line 652, in send\n self.connect()\n File "/usr/lib/python2.4/site-packages/certmaster/SSLCommon.py", line 106, in connect\n self.sock.connect((self.host, self.port))\n File "Almost, not quite, we need to open the port on the firewall on the client so we can talk to the funcd running on client15. We'll do this with puppet, there is an iptables module available. We'll just use service and remotefile in this example (We'll also change the default policy from REJECT to DROP)", line 1, in connect\n']}=
[root@server0 ~]# cd /var/lib/puppet/files/base/etc/sysconfig [root@server0 sysconfig]# vi iptables [root@server0 sysconfig]# cat iptables *filter :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [0:0] :Example.com-1-INPUT - [0:0] -A INPUT -j Example.com-1-INPUT -A FORWARD -j Example.com-1-INPUT -A Example.com-1-INPUT -i lo -j ACCEPT -A Example.com-1-INPUT -p icmp --icmp-type any -j ACCEPT -A Example.com-1-INPUT -p 50 -j ACCEPT -A Example.com-1-INPUT -p 51 -j ACCEPT -A Example.com-1-INPUT -p udp --dport 5353 -d 224.0.0.251 -j ACCEPT -A Example.com-1-INPUT -p udp -m udp --dport 631 -j ACCEPT -A Example.com-1-INPUT -p tcp -m tcp --dport 631 -j ACCEPT -A Example.com-1-INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT -A Example.com-1-INPUT -m state --state NEW -m tcp -p tcp --dport 51234 -j ACCEPT -A Example.com-1-INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT -A Example.com-1-INPUT -j DROP COMMIT [root@server0 sysconfig]# cd /etc/puppet/manifests [root@server0 manifests]# vi func.pp [root@server0 manifests]# cat func.pp class func { remotefile { "/etc/certmaster/minion.conf": mode => 644 } service { funcd: ensure => true, enable => true, hasrestart => true } remotefile { "/etc/sysconfig/iptables": mode => 644, notify => Service["iptables"] } service { iptables: ensure => true, enable => true, hasrestart => true } }Now, back on client15, we again could wait for the change to be propagated, but we'll just trigger it.
[root@client15 ~]# puppetd --fqdn=$HOSTNAME --test --no-splay --server=server0.example.com --onetime --verbose --factsync info: Retrieving facts info: Caching catalog at /var/lib/puppet/localconfig.yaml notice: Starting catalog run 1,2d0 # Firewall configuration written by system-config-securitylevel # Manual customization of this file is not recommended. 7,19c5,18 ... notice: //Node[default]/func/Service[iptables]/ensure: ensure changed 'stopped' to 'running' notice: //Node[default]/func/Service[iptables]: Triggering 'refresh' from 2 dependencies notice: Finished catalog run in 2.55 seconds [root@client15 ~]#Back on server0, we'll try our func call again.
[root@server0 ~]# func client15.example.com call hardware info {'client15.example.com': {'bogomips': '7187.63', 'cpuModel': 'Intel(R) Pentium(R) 4 CPU 3.60GHz', 'cpuSpeed': '3590', 'cpuVendor': 'GenuineIntel', 'defaultRunlevel': '3', ... 'systemSwap': '8191', 'systemVendor': 'Dell Inc.'}}At this point you could configure certmaster to automatically sign keys as we did for puppet. Anything we need to do immediately, we can now do in func. If you want to use func for inventory purposes, you'll need to also download a git rpm and install that on server0. If you try to use func-inventory without git, it will work, but changes to the inventory won't be tracked.
[root@server0 ~]# func-inventory git-core is not installed, so no change tracking is available. use --no-git or, better, just install it. [root@server0 ~]# func-inventory --no-gitThe inventory files will be stored in /var/lib/func/inventory.