<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Sankasaurus &#187; tutorial</title>
	<atom:link href="http://blog.pas.net.au/tag/tutorial/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.pas.net.au</link>
	<description>Just another tech blog - ranting since 2006</description>
	<lastBuildDate>Wed, 25 Aug 2010 21:40:45 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Fighting with SELinux and Nagios</title>
		<link>http://blog.pas.net.au/2009/05/fighting-with-selinux-and-nagios/</link>
		<comments>http://blog.pas.net.au/2009/05/fighting-with-selinux-and-nagios/#comments</comments>
		<pubDate>Sat, 02 May 2009 17:25:55 +0000</pubDate>
		<dc:creator>Peter Sankauskas</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[howto]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[nagios]]></category>
		<category><![CDATA[sys-admin]]></category>
		<category><![CDATA[tech]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://blog.pas.net.au/?p=25</guid>
		<description><![CDATA[I can&#8217;t believe it, but I won! I have been trying to set up Nagios on a RHEL5 machine running SELinux and have been loosing the fight for the last 3 days. But today, I win! This is such a win, it is worth sharing.
Now that I have won though, I believe this is not [...]]]></description>
			<content:encoded><![CDATA[<p>I can&#8217;t believe it, but I won! I have been trying to set up Nagios on a RHEL5 machine running SELinux and have been loosing the fight for the last 3 days. But today, I win! This is such a win, it is worth sharing.</p>
<p>Now that I have won though, I believe this is not Nagios specific at all, and if I had bothered to learn about SELinux, this may have been obvious. Anyway, the error Nagios was giving me was:</p>
<div style="text-align:center;"><strong><span style="color:#ff0000;">Error: Could not stat() command file &#8216;/usr/local/nagios/var/rw/nagios.cmd&#8217;! </span><br />
The external command file may be missing, Nagios may not be running, and/or Nagios may not be checking external commands.<br />
<span style="color:#ff0000;">An error occurred while attempting to commit your command for processing.</span><br />
<span style="text-decoration:underline;"><span style="color:#0000ff;">Return from whence you came </span></span></strong></div>
<p>As you may have already guess, the solution has nothing to do with the location or permissions of the file, the file was not missing, Nagios was running, and Nagios was checking external commands. The final line of the message is great though, and I can only hope we start to see more old English in error messages.</p>
<p>The problem of course, was that SELinux was enabled and stopping this blatant security violation. You can check to see if SELinux is on by running:</p>
<div style="margin-left:40px;font-family:courier new,monospace;">$ /usr/sbin/getenforce<br />
Enforcing</div>
<p>If you got &#8220;Permissive&#8221; or &#8220;Disabled&#8221;, then this post is not for you. To see SELinux&#8217;s side of things, check out <strong><span style="font-family:courier new,monospace;">/var/log/messages</span></strong>:</p>
<div style="margin-left:40px;"><span style="font-family:courier new,monospace;">setroubleshoot: SELinux is preventing ping (ping_t) &#8220;read write&#8221; to /usr/local/nagios/var/spool/checkresults/checkrXH96b (usr_t). For complete SELinux messages. run sealert -l 1ffc2533-42b5-4e04-b7ab-a81bb7d02040</span><br style="font-family:courier new,monospace;" /><br />
<span style="font-family:courier new,monospace;"> setroubleshoot: SELinux is preventing ping (ping_t) &#8220;read write&#8221; to /usr/local/nagios/var/spool/checkresults/checkrZxsA1 (usr_t). For complete SELinux messages. run sealert -l 178ba2d4-0822-47eb-9e32-bfaa19ee3c4b</span><br style="font-family:courier new,monospace;" /><br />
<span style="font-family:courier new,monospace;"> setroubleshoot: SELinux is preventing cmd.cgi (httpd_sys_script_t) &#8220;getattr&#8221; to /usr/local/nagios/var/rw/nagios.cmd (httpd_sys_content_t). For complete SELinux messages. run sealert -l 4df0946e-8816-4b90-a7d1-37e743697b9c </span></div>
<p>As you can see, SELinux is trying to give you a hint with that <strong>sealert</strong> bit, so you should take it.</p>
<div style="margin-left:40px;font-family:courier new,monospace;">$ sealert -l 1ffc2533-42b5-4e04-b7ab-a81bb7d02040<br />
Summary:</p>
<p>SELinux is preventing ping (ping_t) &#8220;read write&#8221; to<br />
/usr/local/nagios/var/spool/checkresults/checkrXH96b (usr_t).</p>
<p>Detailed Description:</p>
<p><em>&#8230; (removed from post)</em></p>
<p>Raw Audit Messages</p>
<p>host=myhost.myisp.host type=AVC msg=audit(1241217029.141:125305): avc:  denied  { read write } for  pid=32379 comm=&#8221;ping&#8221; path=&#8221;/usr/local/nagios/var/spool/checkresults/checkrXH96b&#8221; dev=sda3 ino=52894945 scontext=user_u:system_r:ping_t:s0 tcontext=user_u:object_r:usr_t:s0 tclass=file</p>
<p>host=myhost.myisp.host type=SYSCALL msg=audit(1241217029.141:125305): arch=c000003e syscall=59 success=yes exit=0 a0=153952a0 a1=15395330 a2=7fff75c5eb40 a3=0 items=0 ppid=32378 pid=32379 auid=503 uid=508 gid=508 euid=0 suid=0 fsuid=0 egid=508 sgid=508 fsgid=508 tty=(none) ses=1392 comm=&#8221;ping&#8221; exe=&#8221;/bin/ping&#8221; subj=user_u:system_r:ping_t:s0 key=(null)</p></div>
<p>That raw audit message is <strong>GOLD</strong>! There is some other information in there, but nothing about what the next step should be to create a policy and make it permanent. Using <strong><span style="font-family:courier new,monospace;">chron</span></strong> I have heard is a temporary fix. The solution is copying that raw audit message into an empty file and running <strong>audit2allow</strong> to create a policy:</p>
<div style="margin-left:40px;font-family:courier new,monospace;">$ cat &gt; /tmp/tmp-nagiosping<br />
host=myhost.myisp.host type=AVC msg=audit(1241217029.141:125305): avc:  denied  { read write } for  pid=32379 comm=&#8221;ping&#8221; path=&#8221;/usr/local/nagios/var/spool/checkresults/checkrXH96b&#8221; dev=sda3 ino=52894945 scontext=user_u:system_r:ping_t:s0 tcontext=user_u:object_r:usr_t:s0 tclass=file</p>
<p>host=myhost.myisp.host type=SYSCALL msg=audit(1241217029.141:125305): arch=c000003e syscall=59 success=yes exit=0 a0=153952a0 a1=15395330 a2=7fff75c5eb40 a3=0 items=0 ppid=32378 pid=32379 auid=503 uid=508 gid=508 euid=0 suid=0 fsuid=0 egid=508 sgid=508 fsgid=508 tty=(none) ses=1392 comm=&#8221;ping&#8221; exe=&#8221;/bin/ping&#8221; subj=user_u:system_r:ping_t:s0 key=(null)<br />
<em>* Ctrl-D *</em></p>
<p>$ audit2allow -M NagiosPing &lt; /tmp/tmp-nagiosping</p>
<p>******************** IMPORTANT ***********************<br />
To make this policy package active, execute:</p>
<p>semodule -i NagiosPing.pp</p></div>
<p>This creates a file call NagiosPing.pp which contains the SELinux policy needed to make these errors go away. The only thing left to do is to install this policy:</p>
<div style="margin-left:40px;"><span style="font-family:courier new,monospace;">$ semodule -i NagiosPing.pp</span></div>
<p>If your setup was like mine, SELinux was actually preventing 3 different actions, needing 3 different policies. HA! That is easy now &#8211; just repeat the steps until Nagios is doing your bidding.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.pas.net.au/2009/05/fighting-with-selinux-and-nagios/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Django and Google App Engine Tutorial</title>
		<link>http://blog.pas.net.au/2009/02/django-and-google-app-engine-tutorial/</link>
		<comments>http://blog.pas.net.au/2009/02/django-and-google-app-engine-tutorial/#comments</comments>
		<pubDate>Tue, 17 Feb 2009 19:45:00 +0000</pubDate>
		<dc:creator>Peter Sankauskas</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[google app engine]]></category>
		<category><![CDATA[howto]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[tech]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://pas256.wordpress.com/2009/02/17/django-and-google-app-engine-tutorial/</guid>
		<description><![CDATA[Hi have been playing around with Google App Engine for a while now, and wanted to learn Django on a new application I am building. The two articles I started with are:

Using the Google App Engine Helper for Django
Using Django 1.0 on App Engine with Zipimport

Both Django and GAE are being developed as I write [...]]]></description>
			<content:encoded><![CDATA[<p>Hi have been playing around with Google App Engine for a while now, and wanted to learn Django on a new application I am building. The two articles I started with are:</p>
<ul>
<li><a href="http://code.google.com/appengine/articles/appengine_helper_for_django.html">Using the Google App Engine Helper for Django</a></li>
<li><a href="http://code.google.com/appengine/articles/django10_zipimport.html">Using Django 1.0 on App Engine with Zipimport</a></li>
</ul>
<p>Both Django and GAE are being developed as I write this, so although these instructions are kind of recent, they are already out of date, or rely on you having knowledge of Django. Since there are a lot of others with no Python or Django experince wanting to learn, I thought I would make a tutorial that works as of today, but who knows a month from now or even tomorrow.</p>
<p>Note: This tutorial is written for Linux. Mac/Windows users will have to translate <img src='http://blog.pas.net.au/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<h3><span style="font-weight:bold;">Create django.zip</span></h3>
<p>Django comes as a .tar.gz file, but we want a zip file to take advantage of the Zipimport library, so some conversion is needed.</p>
<ol>
<li><a href="http://www.djangoproject.com/download/">Download the latest Django</a> and untar the file (in this case, it is 1.0.2)</li>
<li>cd Django-1.0.2-final</li>
<li>Create the zip file, but without the admin section since App Enging supplies it&#8217;s own<br />
zip -r ~/django.zip django -x &#8216;django/contrib/admin*&#8217;</li>
</ol>
<p><span style="font-weight:bold;">Get the Helper</span></p>
<p>The App Engine Helper or Django is an open source bootstrapper for getting Django started on App Engine. Downloading it from the website will currently give you quite an old version (r52) which will not work in this tutorial. Instead, use subversion to get the latest (r74).</p>
<ol>
<li>cd ~</li>
<li>svn export http://google-app-engine-django.googlecode.com/svn/trunk/ gae-django-tutorial</li>
<li>cd gae-django-tutorial</li>
<li>mv ~/django.zip .</li>
</ol>
<p><span style="font-weight:bold;">Setup App Engine</span></p>
<p>As you would with any GAE application, edit the app.yaml file to refer to your application ID. The Helper also needs to know where your Google App Engine SDK is, since it is going to change how you start the development server, so create a link to it:</p>
<ol>
<li>cd gae-django-tutorial</li>
<li>ln -s /path/to/google_appengine .google_appengine</li>
</ol>
<p><span style="font-weight:bold;">Start the development server</span></p>
<p>Django has a different way of running the development server. Instead of using dev_appserver.py to start the dev server, do the following:</p>
<ol>
<li>python manage.py runserver</li>
</ol>
<p>If everything is running correctly, you should see something like:</p>
<pre>INFO:root:Server: appengine.google.com
INFO:root:Checking for updates to the SDK.
INFO:root:The SDK is up to date.
INFO:root:Running application google-app-engine-django on port 8000: http://localhost:8000</pre>
<p>However, if you are like me and saw an error like the following:</p>
<pre>ImportError: No module named antlr3</pre>
<p>Then you will need to install the antlr3 python module. Luckily this is easy.</p>
<ol>
<li>Go to <a href="http://www.antlr.org/download/Python">http://www.antlr.org/download/Python</a> and download the latest zip</li>
<li>unzip antlr_python_runtime-3.1.zip</li>
<li>cd antlr_python_runtime-3.1</li>
<li>sudo python setup.py install</li>
</ol>
<p>Lets see the site! When you go to <a href="http://localhost:8000/">http://localhost:8000/</a> you should see a page saying &#8220;It worked!   Congratulations on your first Django-powered page.&#8221;<br />
Pretty (un)impressive huh?</p>
<p>Ok, now lets start doing something. Kill the server by pressing Ctrl-C. The <a href="http://docs.djangoproject.com/en/dev/intro/tutorial01/#intro-tutorial01">Django tutorial</a> is the next stop, which involves creating the Polls Django app. You can read through there to get a full understanding. For simplicity, I am only what I did to get it working.</p>
<ol>
<li>python manage.py startapp polls</li>
<li>cd polls</li>
<li>Edit models.py
<pre>from appengine_django.models import BaseModel
from google.appengine.ext import db

class Poll(BaseModel):
  question = db.StringProperty()
  pub_date = db.DateTimeProperty('date published')

class Choice(BaseModel):
  poll = db.ReferenceProperty(Poll)
  choice = db.StringProperty()
  votes = db.IntegerProperty()</pre>
</li>
<li>Edit views.py (notice that order_by() from the Django tutorial is just order() here)
<pre>from django.template import Context, loader
from polls.models import Poll
from django.http import HttpResponse

def index(request):
  latest_poll_list = Poll.objects.all().order('-pub_date')[:5]
  t = loader.get_template('polls/index.html')
  c = Context({
    'latest_poll_list': latest_poll_list,
  })
  return HttpResponse(t.render(c))</pre>
</li>
<li>cd ..</li>
<li>Edit urls.py and add to urlpatterns<br />
(r&#8217;^polls/&#8217;, &#8216;polls.views.index&#8217;),</li>
<li>mkdir -p templates/polls</li>
<li>cd templates/polls</li>
<li>Create index.html
<pre>{% if latest_poll_list %}
&lt;ul&gt;
{% for poll in latest_poll_list %}
  &lt;li&gt;{{ poll.question }}&lt;/li&gt;
{% endfor %}
&lt;/ul&gt;
{% else %}
  &lt;p&gt;No polls are available.&lt;/p&gt;
{% endif %}</pre>
</li>
<li>cd ../..</li>
<li>Edit settings.py and add to INSTALLED_APPS<br />
&#8216;polls&#8217;,</li>
<li>Now you can run the dev server again:<br />
python manage.py runserver</li>
<li>And go to:
<p>http://localhost:8000/polls/</li>
<li>You should see the message &#8220;No polls are available.&#8221;</li>
</ol>
<p><span style="font-weight:bold;">Adding some data</span></p>
<p>You can go through the rest of the Django Tutorial to fill out the rest of the views. One last thing to know is the admin site. To view it, go to:</p>
<ol>
<li><a href="http://localhost:8000/_ah/admin">http://localhost:8000/_ah/admin</a></li>
</ol>
<p>Notice that the Datastore Viewer is empty &#8211; it doesn&#8217;t even know about our Poll or Choice Models. Don&#8217;t panic. Go back to your terminal, and terminate the dev server. Now run:</p>
<ol>
<li>python manage.py shell</li>
</ol>
<p>This brings up a special python shell with the Django environment set up for you. Now you can run:<br />
&gt;&gt;&gt; from polls.models import Poll, Choice<br />
&gt;&gt;&gt; import datetime<br />
&gt;&gt;&gt; p = Poll(question=&#8221;What&#8217;s up?&#8221;, pub_date=datetime.datetime.now())<br />
&gt;&gt;&gt; p.save()</p>
<p>You have just created a new Poll. To end the shell, press Ctrl-D.</p>
<p>If you start the dev server again (or if you never stopped it in the first place), you should be able to go to:<br />
<a href="http://localhost:8000/polls/">http://localhost:8000/polls/</a><br />
to see you new Poll, and go to the admin site:<br />
<a href="http://localhost:8000/_ah/admin/datastore">http://localhost:8000/_ah/admin/datastore</a><br />
to see and create new Polls</p>
<p>Easy huh? <img src='http://blog.pas.net.au/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.pas.net.au/2009/02/django-and-google-app-engine-tutorial/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
	</channel>
</rss>
