<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[Saiweb]]></title>
  <link href="http://saiweb.co.uk/atom.xml" rel="self"/>
  <link href="http://saiweb.co.uk/"/>
  <updated>2012-05-14T18:59:29+01:00</updated>
  <id>http://saiweb.co.uk/</id>
  <author>
    <name><![CDATA[David Busby]]></name>
    
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[RHEL 6 Openstack via EPEL Keystone installation and integration with Nova and Glance]]></title>
    <link href="http://saiweb.co.uk/openstack/rhel-6-openstack-via-epel-keystone-installation-and-integration-with-nova-and-glance"/>
    <updated>2012-04-22T16:04:00+01:00</updated>
    <id>http://saiweb.co.uk/openstack/rhel-6-openstack-via-epel-keystone-installation-and-integration-with-nova-and-glance</id>
    <content type="html"><![CDATA[<p><img src="http://cdn.saiweb.co.uk/openstack-cloud-software-vertical-small.png"></p>

<p>In this post I follow on from <a href="http://saiweb.co.uk/openstack/rhel-6-openstack-via-epel-nova-and-glance-on-kvm/">Setting up Nova and Glance</a>, and now moving installing and Integrating keystone.
I&#8217;d first like to <a href="https://www.ibm.com/developerworks/mydeveloperworks/wikis/home/wiki/OpenStack?lang=en#configure-nova-api">give credit to IBM developerWorks</a> the guys in #openstack @ freenode IRC, and <a href="http://psycle.com">Psycle Interactive</a> without whom I would not of been able to complete this write up.</p>

<p>Please be aware the following applies to 2011.3 ONLY! (Diablo Final) the configuration to come in Essex is far simpler, if when reading this post your packages are 2012.X you have just installed essex and this is not relevant, anyway here we go &#8230;</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>yum install openstack-keystone</span></code></pre></td></tr></table></div></figure>


<p>Keystone itself has it&#8217;s own tirade of concepts to get to grips with &#8230; tenant, user, role, service, token etc &#8230; I&#8217;m not going to go into detail on those concetps, for that <a href="http://keystone.openstack.org/">Please see the documentation</a>.</p>

<p><strong>Configuring mySQL</strong></p>

<p>First thing I am going to do is change from sqlite to mySQL connection, this involves editing line 54 of /etc/keystone/keystone.conf</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>sql_connection = mysql://keystone:keystone@localhost/keystone</span></code></pre></td></tr></table></div></figure>


<p>Ignoring the default_store configuration at the top of the file, as this states sqllite, from what I can tell this simply instructs keystone to use the sqlAlchemy driver, which we just updated to point to mySQL.</p>

<p>Now like glance we need to restart keystone for the database to be populated.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>service openstack-keystone restart</span></code></pre></td></tr></table></div></figure>


<p>Now run keystone-manage with no args if you see</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>File "/usr/lib/python2.6/site-packages/keystone/manage/__init__.py", line 283, in main
</span><span class='line'>    raise exc
</span><span class='line'>sqlalchemy.exc.OperationalError: (OperationalError) (1044, "Access denied for user 'keystone'@'localhost' to database 'keystone'") None None</span></code></pre></td></tr></table></div></figure>


<p>Review your keystone.conf file and ensure your mySQL credentials are correct, once done start keystone again.</p>

<p><strong>Initial Credentials</strong></p>

<p>Now we need to create an admin Tenant, and add an admin user to this tenancy.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>keystone-manage tenant add adminTenant
</span><span class='line'>SUCCESS: Tenant adminTenant created.
</span><span class='line'>keystone-manage user add adminUser &lt;password&gt;
</span><span class='line'>SUCCESS: User adminUser created.
</span><span class='line'>keystone-manage role add Admin
</span><span class='line'>SUCCESS: Role Admin created successfully.
</span><span class='line'>keystone-manage role grant Admin adminUser
</span><span class='line'>SUCCESS: Granted Admin the adminUser role on None.
</span><span class='line'>keystone-manage role grant Admin adminUser adminTenant
</span><span class='line'>SUCCESS: Granted Admin the adminUser role on adminTenant.</span></code></pre></td></tr></table></div></figure>


<p>Ok so we have just:</p>

<ol>
<li>setup a tenant named adminTenant.</li>
<li>setup a user named adminUser and specified their password.</li>
<li>created an admin role.</li>
<li>assigned the adminUser to the Admin role.</li>
<li>granted adminUser the Admin role to the adminTenant</li>
</ol>


<p>Note: the outputs are a little confusion on the role assignments&#8230;</p>

<p>&#8220;Granted Admin the adminUser role on adminTenant&#8221;,</p>

<p>it appears the string output has the arguments in the wrong order here it should read:</p>

<p>&#8220;Granted adminUser the Admin role on adminTenant&#8221;.</p>

<p>I have however verified the mySQL data and can see the roles being correctly assigned.</p>

<p>Also the output from</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>keystone-manage role grant help
</span><span class='line'>Missing arguments: role grant 'role' 'user' 'tenant (optional)'</span></code></pre></td></tr></table></div></figure>


<p>Confirms the arguments are being entered in the correct order.</p>

<p>i.e.</p>

<div class="highlight"><pre><code class="sql"><span class="n">mysql</span><span class="o">&gt;</span> <span class="k">select</span> <span class="o">*</span> <span class="k">from</span> <span class="n">user_roles</span><span class="p">;</span>
<span class="o">+</span><span class="c1">----+---------+---------+-----------+</span>
<span class="o">|</span> <span class="n">id</span> <span class="o">|</span> <span class="n">user_id</span> <span class="o">|</span> <span class="n">role_id</span> <span class="o">|</span> <span class="n">tenant_id</span> <span class="o">|</span>
<span class="o">+</span><span class="c1">----+---------+---------+-----------+</span>
<span class="o">|</span>  <span class="mi">1</span> <span class="o">|</span>       <span class="mi">1</span> <span class="o">|</span>       <span class="mi">1</span> <span class="o">|</span>      <span class="k">NULL</span> <span class="o">|</span>
<span class="o">|</span>  <span class="mi">2</span> <span class="o">|</span>       <span class="mi">1</span> <span class="o">|</span>       <span class="mi">1</span> <span class="o">|</span>         <span class="mi">1</span> <span class="o">|</span>
<span class="o">+</span><span class="c1">----+---------+---------+-----------+</span>
<span class="mi">2</span> <span class="k">rows</span> <span class="k">in</span> <span class="k">set</span> <span class="p">(</span><span class="mi">0</span><span class="p">.</span><span class="mi">00</span> <span class="n">sec</span><span class="p">)</span>
</code></pre>
</div>


<p>Now we need to configure keystone to recognise these new admin roles.</p>

<p>Lines 41 and 44:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>keystone-admin-role = Admin
</span><span class='line'>keystone-service-admin-role = KeystoneServiceAdmin</span></code></pre></td></tr></table></div></figure>


<p>Edit these to reflect your Admin role accordingly and then restart openstack-keystone
The above shows seperate roles for general and service admin, in my case I set these to the same role, it is of course entirely up to you and your delegation setup.
If you choose to retain the KeystoneServiceAdmin delegation you will need to setup the role as per the Admin role above and run through the grants accordingly.</p>

<p><strong>Setting up the Service token and service definitions</strong></p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>keystone-manage token add 999888777666 adminUser adminTenant 2012-12-23T00:00
</span><span class='line'>SUCCESS: Token 999888777666 created.</span></code></pre></td></tr></table></div></figure>


<p>If instead you get an error:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>ERROR: 'NoneType' object has no attribute 'id'
</span><span class='line'>2012-04-23 12:27:29    ERROR [root] 'NoneType' object has no attribute 'id'
</span><span class='line'>Traceback (most recent call last):
</span><span class='line'>  File "/usr/bin/keystone-manage", line 16, in &lt;module&gt;
</span><span class='line'>    keystone.manage.main()
</span><span class='line'>  File "/usr/lib/python2.6/site-packages/keystone/manage/__init__.py", line 283, in main
</span><span class='line'>    raise exc
</span><span class='line'>AttributeError: 'NoneType' object has no attribute 'id'</span></code></pre></td></tr></table></div></figure>


<p>check your have correctly entered adminUser adminTenant (or the details you have entered) including correct capitilization.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>keystone-manage service add nova compute "Openstack Compute Service"
</span><span class='line'>SUCCESS: Service nova created successfully.
</span><span class='line'>keystone-manage service add glance image "Openstack Image Service"
</span><span class='line'>SUCCESS: Service glance created successfully.
</span><span class='line'>keystone-manage service add keystone identity "Openstack Image Service"
</span><span class='line'>SUCCESS: Service keystone created successfully.</span></code></pre></td></tr></table></div></figure>


<p><strong>Defining endPoints</strong></p>

<p><u>Nova</u>
Here I managed to confuse myself, so let me be clear, this needs the nova_api service ip, not each compute node, meaning you only need one endpoint.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>keystone-manage endpointTemplates add regionOne nova http://&lt;nova_api_ip&gt;:8774/v1.1/%tenant_id% http://&lt;nova_api_ip&gt;:8774/v1.1/%tenant_id% http://&lt;nova_api_ip&gt;:8774/v1.1/%tenant_id% 1 1
</span><span class='line'>SUCCESS: Created EndpointTemplates for nova pointing to http://&lt;nova_api_ip&gt;:8774/v1.1/%tenant_id%</span></code></pre></td></tr></table></div></figure>


<p>The 3 URL arguments are for publicURL, internalURL, adminURL (No idea if that is the order).</p>

<p><u>Glance</u></p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>keystone-manage endpointTemplates add regionOne nova http://&lt;glance_ip&gt;:9292/v1 http://&lt;nova_api_ip&gt;:9292/v1 http://&lt;nova_api_ip&gt;:9292/v1 1 1
</span><span class='line'>SUCCESS: Created EndpointTemplates for glance pointing to http://&lt;glance_ip&gt;:9292/v1</span></code></pre></td></tr></table></div></figure>


<p><u>Keystone</u></p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>keystone-manage endpointTemplates add pi-whc keystone http://&lt;keystone_ip&gt;:5000/v2.0 http://&lt;keystone_ip&gt;:5000/v2.0 http://&lt;keystone_ip&gt;:5000/v2.0 1 1
</span><span class='line'>SUCCESS: Created EndpointTemplates for keystone pointing to http://&lt;keystone_ip&gt;:5000/v2.0.</span></code></pre></td></tr></table></div></figure>


<p><strong>Configuring Nova</strong></p>

<p>Now we have keystone setup we need to configure nova to use keystone for authentication, by editing /etc/nova/api-paste.ini.
Now there are seveal edits required, as such what follows are snippets of those changes.</p>

<p><u>EC2 Section modification</u></p>

<p>line 22 and 27 ([pipeline:ec2cloud] and  [pipeline:ec2admin] sections).</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>pipeline = logrequest totoken authtoken keystonecontext ec2noauth cloudrequest authorizer ec2executor</span></code></pre></td></tr></table></div></figure>


<p>New section for EC2 (in my config lines 60-61)</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>[filter:totoken]
</span><span class='line'>paste.filter_factory = keystone.middleware.ec2_token:EC2Token.factory</span></code></pre></td></tr></table></div></figure>


<p><u>Openstack section modification</u></p>

<p>Modification to [pipeline:openstackapi10] and [pipeline:openstackapi11] sections.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>[pipeline:openstackapi10]
</span><span class='line'>pipeline = faultwrap authtoken keystonecontext ratelimit extensions osapiapp10
</span><span class='line'>
</span><span class='line'>[pipeline:openstackapi11]
</span><span class='line'>pipeline = faultwrap authtoken keystonecontext ratelimit extensions osapiapp11</span></code></pre></td></tr></table></div></figure>


<p><u>Shared section addition</u></p>

<p>We now need to add a complete new subsection to the .ini file</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>##########
</span><span class='line'># Shared #
</span><span class='line'>##########
</span><span class='line'>
</span><span class='line'>[filter:keystonecontext]
</span><span class='line'>paste.filter_factory = keystone.middleware.nova_keystone_context:NovaKeystoneContext.factory
</span><span class='line'>
</span><span class='line'>[filter:authtoken]
</span><span class='line'>paste.filter_factory = keystone.middleware.auth_token:filter_factory
</span><span class='line'>service_protocol = http
</span><span class='line'>service_host = &lt;keystone_ip&gt;
</span><span class='line'>service_port = 5000
</span><span class='line'>auth_host = &lt;keystone_ip&gt;
</span><span class='line'>auth_port = 35357
</span><span class='line'>auth_protocol = http
</span><span class='line'>auth_uri = http://&lt;keystone_ip&gt;:5000/
</span><span class='line'>admin_token = 999888777666</span></code></pre></td></tr></table></div></figure>


<p><strong>NOTE:</strong> you will want to change this to https, but I will not be covering https configuration in this post.</p>

<p>Check that your configuration is working:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>curl -d '{"auth": {"tenantName": "adminTenant", "passwordCredentials":{"username": "adminUser", "password": "password"}}}' -H "Content-type: application/json" http://&lt;keystone_ip&gt;:35357/v2.0/tokens | python -mjson.tool</span></code></pre></td></tr></table></div></figure>


<p>Now restart openstack-nova-api</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>service openstack-nova-api restart</span></code></pre></td></tr></table></div></figure>


<p><u>Verifying nova keystone integration</u></p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>nova --debug --username=adminUser --apikey=&lt;password&gt; --url=http://&lt;keystone_ip&gt;:5000/v2.0 --version=1.1 list
</span><span class='line'>connect: (&lt;keystone_ip&gt;, 5000)
</span><span class='line'>send: 'POST /tokens HTTP/1.1\r\nHost: &lt;keystone_ip&gt;:5000\r\nContent-Length: 69\r\ncontent-type: application/json\r\naccept-encoding: gzip, deflate\r\nuser-agent: python-novaclient\r\n\r\n'
</span><span class='line'>send: '{"passwordCredentials": {"username": "adminUser", "password": "&lt;password&gt;"}}'
</span><span class='line'>reply: 'HTTP/1.1 400 Bad Request\r\n'
</span><span class='line'>header: Content-Type: application/json; charset=UTF-8
</span><span class='line'>header: Content-Length: 60
</span><span class='line'>header: Date: Mon, 23 Apr 2012 14:16:13 GMT
</span><span class='line'>Traceback (most recent call last):
</span><span class='line'>  File "/usr/bin/nova", line 9, in &lt;module&gt;
</span><span class='line'>    load_entry_point('python-novaclient==2.6.1', 'console_scripts', 'nova')()
</span><span class='line'>  File "/usr/lib/python2.6/site-packages/novaclient/shell.py", line 209, in main
</span><span class='line'>    OpenStackComputeShell().main(sys.argv[1:])
</span><span class='line'>  File "/usr/lib/python2.6/site-packages/novaclient/shell.py", line 166, in main
</span><span class='line'>    self.cs.authenticate()
</span><span class='line'>  File "/usr/lib/python2.6/site-packages/novaclient/v1_1/client.py", line 54, in authenticate
</span><span class='line'>    self.client.authenticate()
</span><span class='line'>  File "/usr/lib/python2.6/site-packages/novaclient/client.py", line 140, in authenticate
</span><span class='line'>    auth_url = self._v2_auth(auth_url)
</span><span class='line'>  File "/usr/lib/python2.6/site-packages/novaclient/client.py", line 180, in _v2_auth
</span><span class='line'>    resp, body = self.request(token_url, "POST", body=body)
</span><span class='line'>  File "/usr/lib/python2.6/site-packages/novaclient/client.py", line 87, in request
</span><span class='line'>    raise exceptions.from_response(resp, body)
</span><span class='line'>novaclient.exceptions.BadRequest: Expecting auth (HTTP 400)
</span></code></pre></td></tr></table></div></figure>


<p>Don&#8217;t PANIC! it seems there was never a 2011.3 build for python-novaclient, as such we can &#8220;cheat&#8221; a little, and use 2012.1-1</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>rpm -Uvh http://pbrady.fedorapeople.org/openstack-el6/python-novaclient-2012.1-1.el6.noarch.rpm
</span><span class='line'>nova --debug --os_username=adminUser --os_password=&lt;password&gt; --os_tenant_name=adminTenant --os_auth_url=http://&lt;keystone_ip&gt;:5000/v2.0/ usage-list
</span><span class='line'>connect: (&lt;keystone_ip&gt;, 5000)
</span><span class='line'>send: 'POST /v2.0/tokens HTTP/1.1\r\nHost: &lt;keystone_ip&gt;:5000\r\nContent-Length: 110\r\ncontent-type: application/json\r\naccept-encoding: gzip, deflate\r\naccept: application/json\r\nuser-agent: python-novaclient\r\n\r\n'
</span><span class='line'>send: '{"auth": {"tenantName": "adminTenant", "passwordCredentials": {"username": "adminUser", "password": "psycle"}}}'
</span><span class='line'>reply: 'HTTP/1.1 200 OK\r\n'
</span><span class='line'>header: Content-Type: application/json; charset=UTF-8
</span><span class='line'>header: Content-Length: 924
</span><span class='line'>header: Date: Mon, 23 Apr 2012 15:14:00 GMT
</span><span class='line'>connect: (&lt;nova_ip&gt;, 8774)
</span><span class='line'>send: u'GET /v1.1/1/os-simple-tenant-usage?start=2012-03-26T16:14:00.749451&end=2012-04-24T16:14:00.749491&detailed=1 HTTP/1.1\r\nHost: &lt;keystone_ip&gt;:8774\r\nx-auth-project-id: adminTenant\r\nx-auth-token: 999888777666\r\naccept-encoding: gzip, deflate\r\naccept: application/json\r\nuser-agent: python-novaclient\r\n\r\n'
</span><span class='line'>reply: 'HTTP/1.1 200 OK\r\n'
</span><span class='line'>header: Content-Type: application/json
</span><span class='line'>header: Content-Length: 21
</span><span class='line'>header: Date: Mon, 23 Apr 2012 15:14:00 GMT
</span><span class='line'>Usage from 2012-03-26 to 2012-04-24:
</span><span class='line'>+-----------+-----------+--------------+-----------+---------------+
</span><span class='line'>| Tenant ID | Instances | RAM MB-Hours | CPU Hours | Disk GB-Hours |
</span><span class='line'>+-----------+-----------+--------------+-----------+---------------+
</span><span class='line'>+-----------+-----------+--------------+-----------+---------------+</span></code></pre></td></tr></table></div></figure>


<p>You can also follow diablo more closely by using griddynamics&#8217; rpm package</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>rpm -e --nodeps python-novavclient
</span><span class='line'>rpm -Uvh http://yum.griddynamics.net/yum/diablo/python-novaclient-2011.3-b2489.noarch.rpm
</span><span class='line'>nova --debug --username adminUser --password &lt;password&gt; --tenant_name adminTenant --auth_url http://&lt;keystone_ip&gt;:5000/v2.0/ usage-list
</span><span class='line'>connect: (&lt;keystone_ip&gt;, 5000)
</span><span class='line'>send: 'POST /v2.0/tokens HTTP/1.1\r\nHost: &lt;keystone_ip&gt;:5000\r\nContent-Length: 110\r\ncontent-type: application/json\r\naccept-encoding: gzip, deflate\r\naccept: application/json\r\nuser-agent: python-novaclient\r\n\r\n'
</span><span class='line'>send: '{"auth": {"tenantName": "adminTenant", "passwordCredentials": {"username": "adminUser", "password": "&lt;password&gt;"}}}'
</span><span class='line'>reply: 'HTTP/1.1 200 OK\r\n'
</span><span class='line'>header: Content-Type: application/json; charset=UTF-8
</span><span class='line'>header: Content-Length: 924
</span><span class='line'>header: Date: Mon, 23 Apr 2012 15:27:01 GMT
</span><span class='line'>connect: (&lt;nova_ip&gt;, 8774)
</span><span class='line'>send: u'GET /v1.1/1/os-simple-tenant-usage?start=2012-03-26T16:27:01.859467&end=2012-04-24T16:27:01.859524&detailed=1 HTTP/1.1\r\nHost: &lt;keystone_ip&gt;:8774\r\nx-auth-project-id: adminTenant\r\nx-auth-token: 999888777666\r\naccept-encoding: gzip, deflate\r\naccept: application/json\r\nuser-agent: python-novaclient\r\n\r\n'
</span><span class='line'>reply: 'HTTP/1.1 200 OK\r\n'
</span><span class='line'>header: Content-Type: application/json
</span><span class='line'>header: Content-Length: 21
</span><span class='line'>header: Date: Mon, 23 Apr 2012 15:27:01 GMT
</span><span class='line'>Usage from 2012-03-26 to 2012-04-24:
</span><span class='line'>+-----------+-----------+--------------+-----------+---------------+
</span><span class='line'>| Tenant ID | Instances | RAM MB-Hours | CPU Hours | Disk GB-Hours |
</span><span class='line'>+-----------+-----------+--------------+-----------+---------------+
</span><span class='line'>+-----------+-----------+--------------+-----------+---------------+
</span></code></pre></td></tr></table></div></figure>


<p><strong>BE WARNED</strong></p>

<p>Most of the other commands for myself are presently returning 404 / 500 errors, with the <a href="http://pbrady.fedorapeople.org/openstack-el6/">Essex Release Impending</a> the current EPEL advice seems to be to use Essex, I will update as/when I can with futher information on these issues.</p>

<p>For instance on a: flavor-create a 500 error is encountered with the following logged in api.log</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>...
</span><span class='line'>(nova.api.openstack): TRACE: AttributeError: 'ControllerV11' object has no attribute 'create'
</span><span class='line'>...</span></code></pre></td></tr></table></div></figure>


<p><strong>Configuring Glance</strong></p>

<p>Modify /etc/glance/glance-api.conf</p>

<p>Comment out line 138 and uncomment 140</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>[pipeline:glance-api]
</span><span class='line'>#pipeline = versionnegotiation context apiv1app
</span><span class='line'># NOTE: use the following pipeline for keystone
</span><span class='line'>pipeline = versionnegotiation authtoken auth-context apiv1app</span></code></pre></td></tr></table></div></figure>


<p>Modify lines 165-174 accordingly</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>[filter:authtoken]
</span><span class='line'>paste.filter_factory = keystone.middleware.auth_token:filter_factory
</span><span class='line'>service_protocol = http
</span><span class='line'>service_host = &lt;keystone_ip&gt;
</span><span class='line'>service_port = 5000
</span><span class='line'>auth_host = &lt;keystone_ip&gt;
</span><span class='line'>auth_port = 35357
</span><span class='line'>auth_protocol = http
</span><span class='line'>auth_uri = http://&lt;keystone_ip&gt;:5000/
</span><span class='line'>admin_token = 999888777666</span></code></pre></td></tr></table></div></figure>


<p>now edit /etc/glance/glance-registry.conf and again comment out the current pipline= line and uncomment the keystone line.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>[pipeline:glance-registry]
</span><span class='line'>#pipeline = context registryapp
</span><span class='line'># NOTE: use the following pipeline for keystone
</span><span class='line'>pipeline = authtoken auth-context registryapp</span></code></pre></td></tr></table></div></figure>


<p>Update the authtoken filter accordingly</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>[filter:authtoken]
</span><span class='line'>paste.filter_factory = keystone.middleware.auth_token:filter_factory
</span><span class='line'>service_protocol = http
</span><span class='line'>service_host = &lt;keystone_ip&gt;
</span><span class='line'>service_port = 5000
</span><span class='line'>auth_host = &lt;keystone_ip&gt;
</span><span class='line'>auth_port = 35357
</span><span class='line'>auth_protocol = http
</span><span class='line'>auth_uri = http://&lt;keystone_ip&gt;:5000/
</span><span class='line'>admin_token = 999888777666</span></code></pre></td></tr></table></div></figure>


<p>Restart glance</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>for i in api registry; do service openstack-glance-$i restart; done
</span><span class='line'>Stopping openstack-glance-api:                             [  OK  ]
</span><span class='line'>Starting openstack-glance-api:                             [  OK  ]
</span><span class='line'>Stopping openstack-glance-registry:                        [  OK  ]
</span><span class='line'>Starting openstack-glance-registry:                        [  OK  ]</span></code></pre></td></tr></table></div></figure>


<p><u>testing Keystone</u></p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>nova --debug --username adminUser --password &lt;password&gt; --tenant_name adminTenant --auth_url http://&lt;keystone_ip&gt;:5000/v2.0/ image-list
</span><span class='line'>connect: (&lt;keystone_ip&gt;, 5000)
</span><span class='line'>send: 'POST /v2.0/tokens HTTP/1.1\r\nHost: &lt;keystone_ip&gt;:5000\r\nContent-Length: 110\r\ncontent-type: application/json\r\naccept-encoding: gzip, deflate\r\naccept: application/json\r\nuser-agent: python-novaclient\r\n\r\n'
</span><span class='line'>send: '{"auth": {"tenantName": "adminTenant", "passwordCredentials": {"username": "adminUser", "password": "&lt;password&gt;"}}}'
</span><span class='line'>reply: 'HTTP/1.1 200 OK\r\n'
</span><span class='line'>header: Content-Type: application/json; charset=UTF-8
</span><span class='line'>header: Content-Length: 924
</span><span class='line'>header: Date: Mon, 23 Apr 2012 15:48:56 GMT
</span><span class='line'>connect: (&lt;nova_ip&gt;, 8774)
</span><span class='line'>send: u'GET /v1.1/1/images/detail HTTP/1.1\r\nHost: &lt;keystone_ip&gt;:8774\r\nx-auth-project-id: adminTenant\r\nx-auth-token: 999888777666\r\naccept-encoding: gzip, deflate\r\naccept: application/json\r\nuser-agent: python-novaclient\r\n\r\n'
</span><span class='line'>reply: 'HTTP/1.1 200 OK\r\n'
</span><span class='line'>header: Content-Type: application/json
</span><span class='line'>header: Content-Length: 14
</span><span class='line'>header: Date: Mon, 23 Apr 2012 15:48:56 GMT
</span><span class='line'>+----+------+--------+--------+
</span><span class='line'>| ID | Name | Status | Server |
</span><span class='line'>+----+------+--------+--------+
</span><span class='line'>+----+------+--------+--------+</span></code></pre></td></tr></table></div></figure>


<p>More to follow soon as I work through these issues, and later move onto 2012.X (Essex)</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Git svn - working with branches and tags]]></title>
    <link href="http://saiweb.co.uk/git/git-svn-working-with-branches-and-tags"/>
    <updated>2012-03-26T14:35:00+01:00</updated>
    <id>http://saiweb.co.uk/git/git-svn-working-with-branches-and-tags</id>
    <content type="html"><![CDATA[<p>So as many know I am firmly an advocate of git, and a pesemist when it comes to subversion because well it seems to fail for unresolveable reasons either through use, or through fault of it&#8217;s own (lock files in meta directories for one &#8230;).</p>

<p>Now this is not to say that git is infallable. At any rate here is the best way to use git as an svn client and still maintain access to branches and tags.</p>

<div class="highlight"><pre><code class="bash">git svn init -s &lt;protocol&gt;://&lt;FQDN of server&gt;/&lt;repo path&gt; ./folder_to_checkout_to
</code></pre>
</div>


<p>OR</p>

<div class="highlight"><pre><code class="bash">git svn init -t tags -b branches -T trunk &lt;protocol&gt;://&lt;FQDN of server&gt;/&lt;repo path&gt; ./folder_to_checkout_to
</code></pre>
</div>


<ol>
<li>This initializes an empty git respository in the folder specified (This can also be handy for migrating from subversion)</li>
<li>The examples above use -s for stdlayout, the 2nd example can be used to specify exact locations of trunk,tags,branches.</li>
</ol>


<p>Now we need the data:</p>

<p><code>git svn fetch</code></p>

<p>One thing to note that whilst tags are present within git, subversion tags do not (at this stage) translate into git tags, as such to checkout svn tags (if you are not yet ready to make the jump to using git and want to maintain a subversion server this will needed).</p>

<p><code>git checkout -b tags/tag_name tags/tag_name</code></p>

<p>What does this do? it will checkout the tag from subversion: tag_name and setup a local git branch to track it.</p>

<p>If you are ready however to make the jump to git you can <a href="Conver%20git-svn%20tags%20to%20real%20git%20tags">http://gitready.com/advanced/2009/02/16/convert-git-svn-tag-branches-to-real-tags.html</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[RHEL 6 Openstack via EPEL Nova and Glance on KVM]]></title>
    <link href="http://saiweb.co.uk/openstack/rhel-6-openstack-via-epel-nova-and-glance-on-kvm"/>
    <updated>2012-03-07T16:59:00+00:00</updated>
    <id>http://saiweb.co.uk/openstack/rhel-6-openstack-via-epel-nova-and-glance-on-kvm</id>
    <content type="html"><![CDATA[<p><img src="http://cdn.saiweb.co.uk/openstack-cloud-software-vertical-small.png">
In this post I will cover getting openstack nova and glance services installed from EPEL and configured to the point where an image can be started, this assumes</p>

<ol>
<li>You have a mysql instance installed and running</li>
<li>You have a rabbitmq-server installed and running</li>
<li>You have kvm installed and running (libvirt)</li>
<li>You have selinux set to permissive, as I will not be covering selinux rules here at this time and I do not think disabled is a valid option ;-)</li>
</ol>


<p>I will also be carrying out mySQL configuration of glance and nova, for 2011.3 (Diablo), though most if not all of this should be portable to the Essex release</p>

<p><strong>Install EPEL</strong></p>

<div class="highlight"><pre><code class="bash">rpm -Uvh http://download.fedoraproject.org/pub/epel/6/i386/epel-release-6-5.noarch.rpm
</code></pre>
</div>


<p><strong>Install Nova and Glance</strong></p>

<div class="highlight"><pre><code class="bash">yum -y install openstack-nova openstack-glance
</code></pre>
</div>


<p>yum should take care of all the dependencies here, and install both with a minimal configuration.</p>

<p><strong>Burning and Rebuilding bridges</strong>
<a id="burning-bridges"></a></p>

<p>First thing&#8217;s first KVM is going to install with it&#8217;s own default bridged networking, this provides NAT.</p>

<p>Which is also noted as being <a href="http://www.cyberciti.biz/faq/linux-kvm-disable-virbr0-nat-interface/">very slow</a> (There is/was an note on the wiki@ linux-kvm.org but I have been unable to locate it at the time of writing)</p>

<p>If you are only setting this up for experimentation you can run with the default networking, simply use vibr0 in your nova.conf instead of br0, and ensure you have ipv4 forwarding enabled.</p>

<p><u> Burning Bridges </u></p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>virsh net-list
</span><span class='line'>Name                 State      Autostart
</span><span class='line'>-----------------------------------------
</span><span class='line'>default              active     yes 
</span><span class='line'>virsh net-destroy default
</span><span class='line'>Network default destroyed
</span><span class='line'>virsh net-undefine default
</span><span class='line'>Network default has been undefined
</span><span class='line'>service libvirtd restart</span></code></pre></td></tr></table></div></figure>


<p><u> Building Bridges </u></p>

<p>The theory here is that this configuration of bridge will give us near native network performance, which if you are setting up for use beyond a throwaway sandbox, you really do not want to start introducing bottlenecks.</p>

<p>Shutdown and disable NetworkManager</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>service NetworkManager stop
</span><span class='line'>chkconfig NetworkManager off
</span><span class='line'>chkconfig network on</span></code></pre></td></tr></table></div></figure>


<p>If you know of a NetworkManager friendly way of doing the following please let me know!</p>

<p>In this scenario br0 becomes your current eth0</p>

<p>/etc/sysconfig/network-scripts/ifcfg-br0</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>DEVICE=br0
</span><span class='line'>TYPE=Bridge
</span><span class='line'>BOOTPROTO=static
</span><span class='line'>IPADDR=192.168.99.1
</span><span class='line'>NETMASK=255.255.255.0
</span><span class='line'>GATEWAY=192.168.99.254
</span><span class='line'>ONBOOT=yes
</span><span class='line'>DELAY=0</span></code></pre></td></tr></table></div></figure>


<p>/etc/sysconfig/network-scripts/ifcfg-eth0</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>DEVICE=eth0
</span><span class='line'>BOOTPROTO=none
</span><span class='line'>TYPE=Ethernet
</span><span class='line'>HWADDR=00:11:22:33:44:55
</span><span class='line'>ONBOOT=yes
</span><span class='line'>USERCTL=no
</span><span class='line'>BRIDGE=br0</span></code></pre></td></tr></table></div></figure>


<p>There is plenty more fun to be had here such as bonded interfaces (I myself have a few systems with bonded interfaces as such becoming br0 -> bond0 -> NIC&#8217;s), but that&#8217;s for another time.</p>

<p>Note: you may also use brctl for temporary configurations if you are just experimenting.</p>

<p>Caution: my network dropped out immediatly on my testbox, most likely because networkmanager was running, always ensure you can attach to the head of your box when doing network configuration ;-)</p>

<p>Once you have these configurations in place (Ensuring your have replaced the placeholder IP&#8217;s and MAC address with valid ones) you can now go for a</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>service network restart</span></code></pre></td></tr></table></div></figure>


<p>All being well you&#8217;ll lose and re-establish connection, of you&#8217;ll be attaching a monitor / to kvm over ip.</p>

<p><strong>Configuring Nova</strong></p>

<p>First we&#8217;re going to need a blank database, please ensure you change the placeholder password that follows for something more secure, and amend the host if you are using mySQL on the same host as nova.</p>

<div class="highlight"><pre><code class="sql"><span class="k">create</span> <span class="k">database</span> <span class="n">nova</span><span class="p">;</span>
<span class="k">grant</span> <span class="k">all</span> <span class="k">privileges</span> <span class="k">on</span> <span class="n">nova</span><span class="p">.</span><span class="o">*</span> <span class="k">to</span> <span class="s1">&#39;nova&#39;</span><span class="o">@</span><span class="s1">&#39;localhost&#39;</span> <span class="n">identified</span> <span class="k">by</span> <span class="s1">&#39;nova&#39;</span><span class="p">;</span>
</code></pre>
</div>


<p>Your /etc/nova.conf should resemble this:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>--logdir=/var/log/nova
</span><span class='line'>--state_path=/var/lib/nova
</span><span class='line'>--lock_path=/var/lib/nova/tmp
</span><span class='line'>--dhcpbridge=/usr/bin/nova-dhcpbridge
</span><span class='line'>--dhcpbridge_flagfile=/etc/nova/nova.conf
</span><span class='line'>--injected_network_template=/usr/share/nova/interfaces.template
</span><span class='line'>--libvirt_xml_template=/usr/share/nova/libvirt.xml.template
</span><span class='line'>--vpn_client_template=/usr/share/nova/client.ovpn.template
</span><span class='line'>--credentials_template=/usr/share/nova/novarc.template
</span><span class='line'>--network_manager=nova.network.manager.FlatDHCPManager
</span><span class='line'>--iscsi_helper=tgtadm
</span><span class='line'>--sql_connection=mysql://nova:nova@localhost/nova
</span><span class='line'>--rabbit_host=localhost
</span><span class='line'>--glance_api_servers=localhost:9292
</span><span class='line'>--iscsi_ip_prefix=10.0.0.1
</span><span class='line'>--bridge=br0</span></code></pre></td></tr></table></div></figure>


<p>Setup the database and start the relevant nova services</p>

<div class="highlight"><pre><code class="bash">nova-manage db sync
<span class="k">for </span>i in api network scheduler compute; <span class="k">do </span>service openstack-nova-<span class="nv">$i</span> start; <span class="k">done</span>
<span class="k">for </span>i in api network scheduler compute; <span class="k">do </span>chkconfig openstack-nova-<span class="nv">$i</span> on; <span class="k">done</span>
</code></pre>
</div>


<p>Note: you could also use openstack-nova-db-setup instead of &#8220;nova-manage db sync&#8221;, <em>but</em> it requires mysql-server, which at the time of writing if you have Percona installed will falsely adivse you a need to install mysql-server, Percona need to add: &#8220;Provides: mysql-server&#8221; to their spec ideally.</p>

<p>Remember this is only a basic setup so a lot of the options are left default such as the network_manager, I will cover their options at a later date.</p>

<p>Onto setting up a basic user (Note: this will be replaced in future posts with keystone)</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>nova-manage user admin saiweb
</span><span class='line'>nova-manage project create saiweb saiweb
</span><span class='line'>nova-manage network create saiweb 192.168.99.1/24 1 256 --bridge=br0</span></code></pre></td></tr></table></div></figure>


<p>Take a moment to run a quick check on your services and network</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>nova-manage service list
</span><span class='line'>Binary           Host                                 Zone             Status     State Updated_At
</span><span class='line'>nova-network     oneiroi                              nova             enabled    :-)   2012-03-07 22:21:10
</span><span class='line'>nova-compute     oneiroi                              nova             enabled    :-)   2012-03-07 22:21:12
</span><span class='line'>nova-scheduler   oneiroi                              nova             enabled    :-)   2012-03-07 22:21:10
</span><span class='line'>
</span><span class='line'>nova-manage network list
</span><span class='line'>id      IPv4                IPv6            start address   DNS1            DNS2            VlanID          project         uuid           
</span><span class='line'>1       10.0.0.0/24         None            10.0.0.2        8.8.4.4         None            None            None            7d480f13-47f7-4117-9889-d44f378c3fee
</span></code></pre></td></tr></table></div></figure>


<p>Now we need the nova credentials for this user + project.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>nova-manage project zipfile saiweb saiweb
</span><span class='line'>unzip nova.zip
</span><span class='line'>mv ./{novarc,pk.pem,cert.pem,cacert.pem} ~/.nova/
</span><span class='line'>chmod 700 ~/.nova
</span><span class='line'>chmod 600 ~/.nova/*
</span><span class='line'>rm ./nova.zip
</span><span class='line'>echo ". ~/.nova/novarc" &gt;&gt; ~/.bashrc
</span><span class='line'>source ~/.bashrc
</span><span class='line'>euca-add-keypair nova_key &gt; ~/.nova/nova_key.priv
</span><span class='line'>chmod 600  ~/.nova/nova_key.priv
</span></code></pre></td></tr></table></div></figure>


<p><strong> Configuring Glance </strong></p>

<p>The only change I made was to make glance use mysql.</p>

<div class="highlight"><pre><code class="sql"><span class="k">create</span> <span class="k">database</span> <span class="n">glance</span><span class="p">;</span>
<span class="k">grant</span> <span class="k">all</span> <span class="n">privilges</span> <span class="k">on</span> <span class="n">glance</span><span class="p">.</span><span class="o">*</span> <span class="k">to</span> <span class="s1">&#39;glance&#39;</span><span class="o">@</span><span class="s1">&#39;localhost&#39;</span> <span class="n">identified</span> <span class="k">by</span> <span class="s1">&#39;glance&#39;</span><span class="p">;</span>
</code></pre>
</div>


<p>/etc/glance/glance-resgistry.conf</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>...
</span><span class='line'>sql_connection = mysql://glance:glance@localhost/glance
</span><span class='line'>...</span></code></pre></td></tr></table></div></figure>


<p>Once you have made the change, unlike nova all you need do is start glance and it will setup the database.</p>

<div class="highlight"><pre><code class="bash"><span class="k">for </span>i in api registry; <span class="k">do </span>chkconfig openstack-glance-<span class="nv">$i</span> on; service openstack-glance-<span class="nv">$i</span> start; <span class="k">done</span>
</code></pre>
</div>


<p>Now were going to need an image, I&#8217;m using the <a href="http://www.backtrack-linux.org/">BT5-R2</a> .iso as an example, you could use any of the pre-generated images out there, or even build them using <a href="http://fedoraproject.org/wiki/Getting_started_with_OpenStack_Nova#Building_an_Image_With_Oz">oz</a></p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>glance add name="BT5-R2-Gnome-x64" is_public=True container_format=ovf disk_format=raw &lt; ./BT5R2-GNOME-64.iso</span></code></pre></td></tr></table></div></figure>


<p>Once the import has completed it should appear in your glance index</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>glance index
</span><span class='line'>ID               Name                           Disk Format          Container Format     Size          
</span><span class='line'>---------------- ------------------------------ -------------------- -------------------- --------------
</span><span class='line'>1                BT5-R2-Gnome-x64               raw                  ovf                      2762084352</span></code></pre></td></tr></table></div></figure>


<p>And assuming you setup your nova.conf correctly you should now be able to see this image from nova</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>nova image-list
</span><span class='line'>+----+------------------+--------+
</span><span class='line'>| ID |       Name       | Status |
</span><span class='line'>+----+------------------+--------+
</span><span class='line'>| 1  | BT5-R2-Gnome-x64 | ACTIVE |
</span><span class='line'>+----+------------------+--------+</span></code></pre></td></tr></table></div></figure>


<p>You will also have some default instance sizes aka flavours (commands use american spelling flavor).</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>nova-manage flavor list
</span><span class='line'>m1.medium: Memory: 4096MB, VCPUS: 2, Storage: 40GB, FlavorID: 3, Swap: 0MB, RXTX Quota: 0GB, RXTX Cap: 0MB
</span><span class='line'>m1.large: Memory: 8192MB, VCPUS: 4, Storage: 80GB, FlavorID: 4, Swap: 0MB, RXTX Quota: 0GB, RXTX Cap: 0MB
</span><span class='line'>m1.tiny: Memory: 512MB, VCPUS: 1, Storage: 0GB, FlavorID: 1, Swap: 0MB, RXTX Quota: 0GB, RXTX Cap: 0MB
</span><span class='line'>m1.xlarge: Memory: 16384MB, VCPUS: 8, Storage: 160GB, FlavorID: 5, Swap: 0MB, RXTX Quota: 0GB, RXTX Cap: 0MB
</span><span class='line'>m1.small: Memory: 2048MB, VCPUS: 1, Storage: 20GB, FlavorID: 2, Swap: 0MB, RXTX Quota: 0GB, RXTX Cap: 0MB</span></code></pre></td></tr></table></div></figure>


<p><strong> Booting your first Instance </strong></p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>nova boot --flavor 2 --image 1 "BT5"
</span><span class='line'>+--------------+--------------------------------------+
</span><span class='line'>|   Property   |                Value                 |
</span><span class='line'>+--------------+--------------------------------------+
</span><span class='line'>| accessIPv4   |                                      |
</span><span class='line'>| accessIPv6   |                                      |
</span><span class='line'>| adminPass    | pnFKeVPpbb7bKKy6                     |
</span><span class='line'>| config_drive |                                      |
</span><span class='line'>| created      | 2012-03-07T23:11:59Z                 |
</span><span class='line'>| flavor       | m1.small                             |
</span><span class='line'>| hostId       |                                      |
</span><span class='line'>| id           | 1                                    |
</span><span class='line'>| image        | BT5-R2-Gnome-x64                     |
</span><span class='line'>| key_name     | None                                 |
</span><span class='line'>| metadata     | {}                                   |
</span><span class='line'>| name         | BT5                                  |
</span><span class='line'>| progress     | 0                                    |
</span><span class='line'>| status       | BUILD                                |
</span><span class='line'>| tenant_id    | saiweb                               |
</span><span class='line'>| updated      | 2012-03-07T23:11:59Z                 |
</span><span class='line'>| user_id      | saiweb                               |
</span><span class='line'>| uuid         | fb08be47-2647-4cb2-86d8-867ea0ef4981 |
</span><span class='line'>+--------------+--------------------------------------+
</span><span class='line'>virsh list
</span><span class='line'> Id Name                 State
</span><span class='line'>----------------------------------
</span><span class='line'>  1 instance-00000001    running
</span></code></pre></td></tr></table></div></figure>


<p>And as <a href="https://blueprints.launchpad.net/nova/+spec/iso-boot">iso-boot</a> is not currently complete, this example falls down here, as the instance fails to boot from the .iso file, still you now have</p>

<ol>
<li>Successfully configured nova</li>
<li>Sucessfully configured glance</li>
<li>Have nova using glance</li>
</ol>


<p>All you need do is load a valid image into glance and boot using nova, so now I will be cheating a little I will create a blank 10GB qcow2 image, import it into glance
boot it and use virt-manager to attach the .iso and reboot.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>qemu-img create -f qcow2 blank.qcow2 10G
</span><span class='line'>Formatting 'blank.qcow2', fmt=qcow2 size=10737418240 encryption=off cluster_size=65536
</span><span class='line'>glance add name="blank-10G" is_public=True container_format=bare disk_format=qcow2 &lt; ./blank.qcow2
</span><span class='line'>Added new image with ID: 2
</span><span class='line'>nova boot --flavor 2 --image 2 "BT5"
</span><span class='line'>+--------------+--------------------------------------+
</span><span class='line'>|   Property   |                Value                 |
</span><span class='line'>+--------------+--------------------------------------+
</span><span class='line'>| accessIPv4   |                                      |
</span><span class='line'>| accessIPv6   |                                      |
</span><span class='line'>| adminPass    | H3khDYMwheNNWBV3                     |
</span><span class='line'>| config_drive |                                      |
</span><span class='line'>| created      | 2012-03-07T23:01:50Z                 |
</span><span class='line'>| flavor       | m1.small                             |
</span><span class='line'>| hostId       |                                      |
</span><span class='line'>| id           | 2                                    |
</span><span class='line'>| image        | blank-10G                            |
</span><span class='line'>| key_name     | None                                 |
</span><span class='line'>| metadata     | {}                                   |
</span><span class='line'>| name         | BT5                                  |
</span><span class='line'>| progress     | 0                                    |
</span><span class='line'>| status       | BUILD                                |
</span><span class='line'>| tenant_id    | home                                 |
</span><span class='line'>| updated      | 2012-03-07T23:01:50Z                 |
</span><span class='line'>| user_id      | oneiroi                              |
</span><span class='line'>| uuid         | 05ce2b5d-d03c-442e-99e3-2c079469ec5b |
</span><span class='line'>+--------------+--------------------------------------+</span></code></pre></td></tr></table></div></figure>


<p>Now I cheat I used virt-manager to force off the insance, create and attach an IDE cdrom and set it as the primary boot device.
BT5 boots from the ISO and I can even begin to work through the install to hard drive menus, which as irony would have it prompts me that it needs an 11.5GB partition to install upon :D</p>

<p>I will cover producing proper images in my next openstack post, as the size of the storage volume should not be defined by the image in glance, it should be defined by the falvour being started.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[n2n p2p vpn wtf]]></title>
    <link href="http://saiweb.co.uk/linux/security/n2n-p2p-vpn-wtf"/>
    <updated>2012-03-06T12:26:00+00:00</updated>
    <id>http://saiweb.co.uk/linux/security/n2n-p2p-vpn-wtf</id>
    <content type="html"><![CDATA[<p>First off what is n2n ?</p>

<blockquote><p>n2n is a layer-two peer-to-peer virtual private network (VPN) which allows users to exploit features typical of P2P applications at network instead of application level. This means that users can gain native IP visibility (e.g. two PCs belonging to the same n2n network can ping each other) and be reachable with the same network IP address regardless of the network where they currently belong. In a nutshell, as OpenVPN moved SSL from application (e.g. used to implement the HTTPS protocol) to network protocol, n2n moves P2P from application to network level.</p></blockquote>


<p>So why do I care ?</p>

<p>Some services you may wish to run on a public cloud such as Gluster do not have (at the time of writing) internal TLS (read: encryption), this n2n allows you to establish peer to peer vpn connections, wihtout the need of a single routing device (with some assume caveats I will cover shortly).</p>

<p>So in short you can have your own private network within the cloud environment without affecting that environment, this allows for:</p>

<ol>
<li>TLS for services otherwise sent &#8220;in the clear&#8221;</li>
<li>Potential for Cluster services and floating IP&#8217;s without touching the host network infrastructure.</li>
</ol>


<p><strong> Installation </strong></p>

<p>We are going to use <a href="http://fedoraproject.org/wiki/EPEL">EPEL</a>, why? because I&#8217;m a packager and I will be using redhat for this setup, so admitedly I am a little biased toward RedHat, that said the majority of the following configurations should be portable to other distros, leave a commment if you get stuck I will try to help!</p>

<div class="highlight"><pre><code class="bash">yum -y install n2n
</code></pre>
</div>


<p>And no I&#8217;m not using sudo i.m.o sudo is akin to &#8220;training wheels&#8221;, and somethign I will only generally use if I have too (such as maintaining an auditable system), you are of course welcome to use sudo yourself, I use &#8220;throw away&#8221; vm&#8217;s for all my experimentation so in these cases the ethos is if it&#8217;s broken it gets rebuilt.</p>

<p><strong> SuperNode Setup </strong></p>

<p>First thing&#8217;s first we&#8217;re going to need at least 1 Supernode, as I uderstand it a Supernode is used to register new peers and to retrieve currently connected peers.
Once this list is retrieved the individual nodes will communicate directly (p2p), and not via the supernode.</p>

<p>Caveats to note:</p>

<ol>
<li>If all supernodes are down, only existing peers can communicate, new peers can not.</li>
</ol>


<p>supernode whilst installed does not at the time of writing provide an init.d/sysvinit script, you may use the following:</p>

<div><script src='https://gist.github.com/1986260.js?file=supernode.sh'></script>
<noscript><pre><code>#!/bin/bash

# Author: David Busby &lt;david.busby@psycle.com&gt;

### BEGIN INIT INFO
# Provides:             supernode
# Required-Start:       $network
# Required-Stop:
# Default-Start:        3 5
# Default-Stop:         0 1 2 6
# Short-Description:    supernode daemon, bespoke configuration for Psycle Interactive Ltd
### END INIT INFO
. /etc/rc.d/init.d/functions

exec=`type supernode | awk '{print $3}'`
port=1200
prog='supernode'
pidfile=&quot;/var/run/$prog/$prog.pid&quot;
lockfile=&quot;/var/lock/subsys/$prog&quot;

start() {
    [ -x $exec ] || exit 5
    daemon --user n2n --pidfile $pidfile &quot;$exec -f -l $port &amp;&gt;/dev/null &amp; echo \$! &gt; $pidfile&quot;
    retval=$?
    echo
    [ $retval -eq 0 ] &amp;&amp; touch $lockfile
    return $retval 
}

stop() {
    echo -n $&quot;Stopping $prog: &quot;
    killproc -p $pidfile $prog
    retval=$?
    echo
    [ $retval -eq 0 ] &amp;&amp; rm -f $lockfile
    return $retval
}

restart() {
    stop
    start
}

reload() {
    restart
}

force_reload() {
    restart
}

rh_status() {
    status -p $pidfile $prog
}

rh_status_q() {
    rh_status &gt;/dev/null 2&gt;&amp;1
}


case &quot;$1&quot; in
    start)
        rh_status_q &amp;&amp; exit 0
        $1
        ;;
    stop)
        rh_status_q || exit 0
        $1
        ;;
    restart)
        $1
        ;;
    reload)
        rh_status_q || exit 7
        $1
        ;;
    force-reload)
        force_reload
        ;;
    status)
        rh_status
        ;;
    condrestart|try-restart)
        rh_status_q || exit 0
        restart
        ;;
    *)
        echo $&quot;Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload}&quot;
        exit 2
esac</code></pre></noscript></div>


<p>place the above in /etc/init.d/supernode and chmod +x i.e.</p>

<div class="highlight"><pre><code class="bash">curl -o /etc/init.d/supernode https://raw.github.com/gist/1986260/b66b38da265ea14aac8d0ef7196a9ba98939716c/supernode.sh <span class="o">&amp;&amp;</span> chmod +x /etc/init.d/supernode
</code></pre>
</div>


<p>(Though I really do recommend you read through this code first before trusting it blindly!)</p>

<p>Note: Annoyingly I had to use the -f (foreground) flag to allow the daemon wrapper to function correctly with this process, there is more than likely a better solution, please
feel free to revise the gist it is public.</p>

<p>Now as I have opted to use a non existant n2n account to daemonize the process this will need creating as will the pid directory.</p>

<div class="highlight"><pre><code class="bash">useradd -d /dev/null -s /sbin/nologin n2n
mkdir /var/run/supernode <span class="o">&amp;&amp;</span> chown n2n:n2n /var/run/supernode
</code></pre>
</div>


<p>You will now be able to start your supernode with: /etc/init.d/supernode start.</p>

<p>In my configuration above I have chosen to bind port 1200, you can change this to any port, but remember that your vpn peers will need to be able to access this port.
As such you will need the relevant iptables rules</p>

<div class="highlight"><pre><code class="bash">iptables -N N2N
iptables -I INPUT -j N2N
iptables -A N2N -s &lt;vpn peer&gt; -p udp --dport 1200 -j ACCEPT
</code></pre>
</div>


<p>I highly recomend you limit your firewall to only allow connection from known peers, and that this is done over the internal interface (for which you do not generally pay bandwidth charges).</p>

<p>I also recomend you repeat this process on a 2nd node to provide 2 Supernodes (The maximum allowable) for greater resilliance.</p>

<p><strong> Edge Setup </strong></p>

<p>I have opted for a .conf file approach here, you can of course opt to instead embed everything in the sysvinit script.</p>

<div class="highlight"><pre><code class="bash"><span class="nv">DEVICE</span><span class="o">=</span><span class="s2">&quot;n0&quot;</span>
<span class="nv">ADDRESS</span><span class="o">=</span><span class="s2">&quot;127.16.0.1&quot;</span>
<span class="nv">MAC</span><span class="o">=</span><span class="s2">&quot;00:11:22:33:44:55&quot;</span>
<span class="nv">COMMUNITY</span><span class="o">=</span><span class="s2">&quot;N2N&quot;</span>
<span class="nv">SHAREDKEY</span><span class="o">=</span><span class="s2">&quot;asdf12345&quot;</span>
<span class="nv">SUPER1</span><span class="o">=</span><span class="s2">&quot;1.2.3.4:1200&quot;</span>
<span class="nv">SUPER2</span><span class="o">=</span><span class="s2">&quot;1.2.3.5:1200&quot;</span>
<span class="nv">PORT</span><span class="o">=</span><span class="s2">&quot;1201&quot;</span>
</code></pre>
</div>


<p>Place this in /etc/edge.conf, you can negate ADDRESS if you wish to use DHCP, whilst you can also Negate SUPERNODE2 and MAC I do not recomend doing so for the following reasons.</p>

<ol>
<li>Negating Supernode2 means there is only 1 supernode and as such a single point of failiure in the setup</li>
<li>Negating MAC is valid, however on loss of connection and restoration a new MAC is generated meaning all existing nodes can not communicate with the restored node untill their local ARP caches are cleared,
specifiying a static MAC address ensures immediate restoration of communication.</li>
<li>I have made PORT a requirement, it is technically optional but fixing the port makes your iptables / firewall rules far easier.</li>
<li>Make sure you actually edit the file and replace the args with VALID ones, especially the SHAREDKEY as the above is in no way secure!</li>
<li>Make sure your ip and mac addresses are unique!</li>
</ol>


<p>We need to prep the pid dir again:</p>

<div class="highlight"><pre><code class="bash">mkdir /var/run/edge <span class="o">&amp;&amp;</span> chown n2n:n2n /var/run/edge
</code></pre>
</div>




<div><script src='https://gist.github.com/1986260.js?file=edge.sh'></script>
<noscript><pre><code>#!/bin/bash

# Author: David Busby &lt;david.busby@psycle.com&gt;

### BEGIN INIT INFO
# Provides:             edge
# Required-Start:       $supernode
# Required-Stop:
# Default-Start:        3 5
# Default-Stop:         0 1 2 6
# Short-Descriptioni:   edge daemon, bespoke configuration for Psycle Interactive Ltd
### END INIT INFO
. /etc/rc.d/init.d/functions

exec=`type edge | awk '{print $3}'`
prog='edge'
pidfile=&quot;/var/run/$prog/$prog.pid&quot;
lockfile=&quot;/var/lock/subsys/$prog&quot;
args=&quot;/etc/edge.conf&quot;
uid=`id -u n2n`
gid=`id -g n2n`

start() {
    [ -x $exec ] || exit 5
    [ -f $args ] &amp;&amp; . $args || exit 6
    #Build the command based on optional and mandetory arguments.
    #todo: there has to be a cleaner way of doing this.
    cmd=&quot;$exec -f -d ${DEVICE}&quot;
    [ -z &quot;${ADDRESS}&quot; ] || cmd+=&quot; -a ${ADDRESS}&quot;
    cmd+=&quot; -c ${COMMUNITY} -k ${SHAREDKEY} -l ${SUPER1}&quot;
    [ -z &quot;${SUPER2}&quot; ] || cmd+=&quot; -l ${SUPER2}&quot;
    [ -z &quot;${MAC}&quot; ] || cmd+=&quot; -m ${MAC}&quot;
    cmd+=&quot; -p ${PORT}&quot;
    cmd+=&quot; -u ${uid} -g ${gid}&quot;
    daemon --pidfile $pidfile &quot;$cmd &amp;&gt;/dev/null &amp; echo \$! &gt; $pidfile&quot;
    retval=$?
    echo
    [ $retval -eq 0 ] &amp;&amp; touch $lockfile
    return $retval 
}

stop() {
    echo -n $&quot;Stopping $prog: &quot;
    killproc -p $pidfile $prog
    retval=$?
    echo
    [ $retval -eq 0 ] &amp;&amp; rm -f $lockfile
    return $retval
}

restart() {
    stop
    start
}

reload() {
    restart
}

force_reload() {
    restart
}

rh_status() {
    status -p $pidfile $prog
}

rh_status_q() {
    rh_status &gt;/dev/null 2&gt;&amp;1
}


case &quot;$1&quot; in
    start)
        rh_status_q &amp;&amp; exit 0
        $1
        ;;
    stop)
        rh_status_q || exit 0
        $1
        ;;
    restart)
        $1
        ;;
    reload)
        rh_status_q || exit 7
        $1
        ;;
    force-reload)
        force_reload
        ;;
    status)
        rh_status
        ;;
    condrestart|try-restart)
        rh_status_q || exit 0
        restart
        ;;
    *)
        echo $&quot;Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload}&quot;
        exit 2
esac</code></pre></noscript></div>


<p>place the above in /etc/init.d/edge and chmod +x i.e.</p>

<div class="highlight"><pre><code class="bash">curl -o /etc/init.d/edge https://raw.github.com/gist/1986260/3061d0fb9d6f2ddf1608f01917129d65b8131d33/edge.sh <span class="o">&amp;&amp;</span> chmod +x /etc/init.d/edge
</code></pre>
</div>


<p>(Again I HIGHLY recommend you actually read the code before blindly trusting it!)</p>

<p>Note: the &#8211;user option is negated in this init file. This is because we need to actually create a network interface, something that can only be done as root.
As such we are reliant on the edge binary to drop privileges itself by providing the -u and -g  arguments, these are of course assuming you have allready setup the n2n user, as per above and not just skipped to this section.</p>

<p><strong> Add the Services and set them to run</strong></p>

<div class="highlight"><pre><code class="bash">chkconfig --add supernode
chkconfig --add edge
chkconfig supernode on
chkconfig edge on
</code></pre>
</div>


<p><strong> Modify other services that are reliant on the VPN </strong></p>

<p>Modify the &#8220;Requires&#8221; line in the sysvinit script for each service you want to only start once your VPN has been established.</p>

<div class="highlight"><pre><code class="bash">...
<span class="c"># Required-Start: $local_fs $network $supernode $edge</span>
...
</code></pre>
</div>


<p>Note: Whilst I have opted for requiring supernode here, you do not need this, you can require just your edge service, as the supernode does not have to run on the same device.</p>

<p>You should now be able to reboot and see all required services start up in the correct order.</p>

<p>And done, that&#8217;s where I am ending this blog post,</p>

<ol>
<li>we have setup n2n with supernodes and edge</li>
<li>generated valid sysvinit scripts</li>
</ol>


<p>expect future posts to cover more advanced n2n configuration as I discover the options available.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Wordpress to Octopress]]></title>
    <link href="http://saiweb.co.uk/jekyll/wordpress-to-octopress"/>
    <updated>2012-03-05T19:30:00+00:00</updated>
    <id>http://saiweb.co.uk/jekyll/wordpress-to-octopress</id>
    <content type="html"><![CDATA[<p>So I have as some know been wrestling with <a href="https://github.com/mojombo/jekyll">Jekyll</a>, and have sucessfully been porting my <a href="https://github.com/Oneiroi/saiweb.co.uk">Wordpress posts to markdown</a>.</p>

<p>Why you may ask? Performance!</p>

<p>To facilitate running wordpress on the smalest possible CloudServer I am using <a href="http://varnish-cache.org">Varnish</a> which using Apache as the backend, now with static files I can get all the blogging functionality without the need for Wordpress nor varnish, yet still uncached content can lead to increased load on the server.</p>

<p>Also wordpress does not lend itself to scalability especially with the at the time of writing schema and sql queries (percona-query-advisor flags up a few wordpress core sql queries as non scalable).</p>

<p>But this does not mean you need remove the option of using Wordpress, for you client for instance keeping wordpress in place can aid in content generation simply through ease of use.</p>

<ol>
<li>wordpress used as normal</li>
<li>wordpress content is ported to markdown</li>
<li>markdown used to generate html</li>
</ol>


<p>Now this does have caveats:</p>

<ol>
<li>you&#8217;re going to need to maintain designs in wordpress templates and markdown (_layouts).</li>
<li>you&#8217;re going to need to handel any shortcode plugins in your export process.</li>
<li>you&#8217;re going to need to handel any other content modifying plugins in your export process.</li>
<li>any UGC / Dynamic requests will still need PHP.</li>
</ol>


<p>But it essentially replaces the whole caching layer with static content which then can be pushed to CDN.</p>

<p>And with CDN&#8217;s now supporting index files (<a href="http://docs.amazonwebservices.com/AmazonS3/latest/dev/IndexDocumentSupport.html">S3</a>, and Coming Soon @ <a href="http://feedback.rackspacecloud.com/forums/71021-product-feedback/suggestions/1511991-index-and-404-page-support">CloudFiles</a>) in essence entire sites can be placed on CDN whilst maintaining ease of content generation.</p>

<p>Now don&#8217;t get me wrong, this requires a whole lot of &#8220;glue&#8221; to get working, but the potential for serving an entire web app from CDN without Origin pull / cache headers etc, saves a lot of systems time in scaling and adressing performance issues, or rather makes them &#8220;less critical&#8221; as the &#8220;business&#8221; part of the webapp is all on CDN.</p>

<p>I&#8217;m still getting to grips with Jekyll and by extention Octopress to see what it can achieve, so expect more posts.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[DRBD at CloudServers without the loop device]]></title>
    <link href="http://saiweb.co.uk/drbd/drbd-cloudservers-without-the-loop"/>
    <updated>2012-03-05T19:30:00+00:00</updated>
    <id>http://saiweb.co.uk/drbd/drbd-cloudservers-without-the-loop</id>
    <content type="html"><![CDATA[<h1>DRBD at CloudServers</h1>

<p>This is a short guide on getting DRBD working @ Rackspace CloudServers
Please note I will be resizing the root partition on the cloud server, this is not for the
squeemish!</p>

<p>I highly recomend you only attempt this on new builds or throw away virtual machines, this only works for ext3 filesystems I have not tested nor do I know the implications of trying this on ext4!</p>

<h2>rescue mode</h2>

<p>In this first step we need to place the cloudserver in Rescue mode, so.</p>

<ol>
<li>log into your rackspacecloud portal.</li>
<li>Hosting</li>
<li>Cloud Servers</li>
<li>Click server</li>
<li>Click Rescue</li>
</ol>


<p>Read the prompt::</p>

<pre><code>Placing your Cloud Server into rescue mode will allow you to debug system issues that are preventing it from booting to a usable state.

The rescue boot will use your current server IP and OS distro. Your original server devices will be accessible within the rescue mode as /dev/sda1 (root) and /dev/sda2 (swap). A temporary root password will be flashed when the image has booted. Note: the SSH server key will be different on the rescue image than your server.

Rescue mode is limited to 90 minutes, after which the rescue image is destroyed and the server will attempt to reboot. You may end the rescue mode at any time.
</code></pre>

<p>Note: In rescue mode /dev/xvda becomes /dev/sda</p>

<p>You can shose at this point to connect via SSH or via the Web Console, I will be opting for SSH.</p>

<p>Note: the host key is generated at startup, your ssh client will alert about a miss matching host key if you have allready connected to this host before.
Or as a one off::</p>

<pre><code>ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no user@host
</code></pre>

<p>Do not use this reguarly, unless you enjoy the prospect of being an easy m.i.t.m target.</p>

<p>Now we need to record some information, however the text above is missleading /dev/sda does not exist as a device, this has been confirmed by Rackspace as information from the previous infrastructure (Slicehost I&#8217;d assume), the actual device is: /dev/xvdb (1 Data, 2 Swap) (And with any luck they will correct this soon within the system)</p>

<p>Now we need to do some information collecting so for now just mount /dev/xvdb1 onto /media::</p>

<pre><code>mount /dev/xvdb1 /media
root@RESCUE ~]# df -h &amp;&amp; df &amp;&amp; df -B 4k &amp;&amp; fdisk -l &amp;&amp; fdisk -s /dev/xvdb1
</code></pre>

<p>Filesystem            Size  Used Avail Use% Mounted on
/dev/xvda1            9.4G  894M  8.1G  10% /
tmpfs                 120M     0  120M   0% /dev/shm
/dev/xvdb1             75G  2.1G   69G   3% /media
Filesystem           1K-blocks      Used Available Use% Mounted on
/dev/xvda1             9804120    914776   8391324  10% /
tmpfs                   122228         0    122228   0% /dev/shm
/dev/xvdb1            78440392   2157668  72298188   3% /media
Filesystem           4K-blocks      Used Available Use% Mounted on
/dev/xvda1             2451030    228694   2097831  10% /
tmpfs                    30557         0     30557   0% /dev/shm
/dev/xvdb1            19610098    539417  18074547   3% /media</p>

<p>Disk /dev/xvdb: 81.6 GB, 81604378624 bytes
255 heads, 63 sectors/track, 9921 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000</p>

<pre><code>Device Boot      Start         End      Blocks   Id  System
</code></pre>

<p>/dev/xvdb1   *           1        9922    79690752   83  Linux</p>

<p>Disk /dev/xvda: 10.2 GB, 10200547328 bytes
255 heads, 63 sectors/track, 1240 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x0005781c</p>

<pre><code>Device Boot      Start         End      Blocks   Id  System
</code></pre>

<p>/dev/xvda1   *           1        1241     9960448   83  Linux</p>

<p>Disk /dev/xvdd: 536 MB, 536870912 bytes
255 heads, 63 sectors/track, 65 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000</p>

<pre><code>Device Boot      Start         End      Blocks   Id  System
</code></pre>

<p>/dev/xvdd1               1          65      522112   82  Linux swap / Solaris</p>

<p>Disk /dev/xvdc: 536 MB, 536870912 bytes
255 heads, 63 sectors/track, 65 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000</p>

<pre><code>Device Boot      Start         End      Blocks   Id  System
</code></pre>

<p>/dev/xvdc1               1          65      522112   82  Linux swap / Solaris
79690752</p>

<p>Note: You <em>could</em> in get allthis information before dropping into rescue mode if you really wanted to.</p>

<h2>Perparation</h2>

<p>First a fsck we want it to report a clean FS without attempting any changes so we run this with the -n option, go grab a coffee this will take a while::</p>

<pre><code>umount /media
fsck -n /dev/xvdb1 
fsck from util-linux-ng 2.17.2
e2fsck 1.41.12 (17-May-2010)
/: clean, 62421/9961472 files, 852007/19922688 blocks
</code></pre>

<p>Great we have a clean FS (note it will rpoert erros if the fs is still mounted!) we need to remove the journal, which essentially will turn a ext3 FS into ext2::</p>

<pre><code>tune2fs -O ^has_journal /dev/xvdb1
tune2fs 1.41.12 (17-May-2010)
</code></pre>

<p>Force a filesystem check with e2fsck -f::</p>

<pre><code>e2fsck 1.41.12 (17-May-2010)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/: 62421/9961472 files (0.6% non-contiguous), 819205/19922688 blocks
</code></pre>

<p>Now we can resize the filesystem from the recon above we know that we are presentl using 2.1GB / 75GB so in this case I will &#8220;shave&#8221; 20GB off the top to become the DRBD volume::</p>

<pre><code>resize2fs 1.41.12 (17-May-2010)
Resizing the filesystem on /dev/xvdb1 to 14080000 (4k) blocks.
The filesystem on /dev/xvdb1 is now 14080000 blocks long. 
</code></pre>

<p>Now we need to delete and recreate our partitions::</p>

<p>fdisk /dev/xvdb</p>

<p>WARNING: DOS-compatible mode is deprecated. It&#8217;s strongly recommended to</p>

<pre><code>     switch off the mode (command 'c') and change display units to
     sectors (command 'u').
</code></pre>

<p>Command (m for help): p</p>

<p>Disk /dev/xvdb: 81.6 GB, 81604378624 bytes
255 heads, 63 sectors/track, 9921 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000</p>

<pre><code>Device Boot      Start         End      Blocks   Id  System
</code></pre>

<p>/dev/xvdb1   *           1        9922    79690752   83  Linux</p>

<p>Command (m for help): d<br/>
Selected partition 1</p>

<p>Partition number (1-4): 1
First cylinder (1-9921, default 1): 1
Last cylinder, +cylinders or +size{K,M,G} (1-9921, default 9921): +59136000K</p>

<p>Command (m for help): a
Partition number (1-4): 1</p>

<p>Command (m for help): w
The partition table has been altered!</p>

<p>Calling ioctl() to re-read partition table.
Syncing disks.</p>

<p>Wait how did I get 59136000K for the last cylinder? well we take 14080000 from resize2fs multiply by 4 and again by 1.05, why?</p>

<ol>
<li>4K blocksize</li>
<li>1.05 gives us a 5% saftey buffer</li>
<li>final figure 59136000K</li>
<li>the option a is used to set the bootable flag back onto parition 1</li>
</ol>


<p>Now we check the filesystem::</p>

<pre><code>fsck from util-linux-ng 2.17.2
e2fsck 1.41.12 (17-May-2010)
fsck.ext2: Superblock invalid, trying backup blocks...
fsck.ext2: Bad magic number in super-block while trying to open /dev/xvdb1

The superblock could not be read or does not describe a correct ext2
filesystem.  If the device is valid and it really contains an ext2
filesystem (and not swap or ufs or something else), then the superblock
is corrupt, and you might try running e2fsck with an alternate superblock:
e2fsck -b 8193 &lt;device&gt;
</code></pre>

<p>Awww crap &#8230; right lets find out where that superblock is we run mke2fs with the -n flag this is a dry run, it will not write filesystem changes::</p>

<pre><code> mke2fs -n /dev/xvdb1 
</code></pre>

<p>mke2fs 1.41.12 (17-May-2010)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
3702784 inodes, 14785816 blocks
739290 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=4294967296
452 block groups
32768 blocks per group, 32768 fragments per group
8192 inodes per group
Superblock backups stored on blocks:</p>

<pre><code>32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, 
4096000, 7962624, 11239424
</code></pre>

<p>Ok NONE of these superblock worked for me &#8230; BLAM trashed VM, see why I suggested a throw away!</p>

<h2>Credits</h2>

<p>The following are information sources I used in the production of this method.</p>

<ol>
<li>http://rackerhacker.com/2011/02/13/dual-primary-drbd-with-ocfs2/</li>
<li>http://www.howtoforge.com/linux_resizing_ext3_partitions i</li>
<li>http://www.cyberciti.biz/faq/recover-bad-superblock-from-corrupted-partition/</li>
</ol>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Devops != Sysadmin (What?!)]]></title>
    <link href="http://saiweb.co.uk/linux/devops-not-sysadmin-what"/>
    <updated>2012-03-05T19:21:00+00:00</updated>
    <id>http://saiweb.co.uk/linux/devops-not-sysadmin-what</id>
    <content type="html"><![CDATA[<p>I’m a little perplexed by some posts doing the rounds during the evolutions of what DevOps is that claim it is not Systems Administration &#8230;</p>

<p>Well I for one say if that is the case then no one should be a “DevOps” without a background in Systems administration &#8230; let me explain.</p>

<p>Primarily I work with redhat rpm based systems for web application hosting at what I’d call an advanced level stracing, calling on linux c api’s as needed, fixing packaged and upstreaming the fixes, bug reporting etc (In my opinion something anyone using Opensource in their business should be doing!), I’m not going to go into complete detail on the tools and how I use them on a day to day basis as this moves from the point of this post entirely (<a href="http://oneiroi.github.com/david_busby.html#skills-tree">that and it would take FAR too long to write</a> &#8230;)</p>

<p>I also as part of my job I work in python, ruby, php, bash, tcl, c, c++, whatever tool is needed to do the job, let me say that again for clarity whatever tool is needed to do the job.</p>

<p>I could be a DBA, Sysadmin, TechSupport, Pentester at any given point of the day.</p>

<p>I analyse and profile web applications then go on to design hosting solutions for said applications.</p>

<p>I promote the use of SCM (Git in particular), unit testing and I’ve begun looking at Continuous integration methodologies.</p>

<p>I’m a commiter on the EPEL Openstack packages (Admittedly not as often as I would like at the moment &#8230; deadlines &#8230;), I also have upstream commits for libcloud and boxgrinder.</p>

<p>I work to the ethos that downtime is not acceptable, EVER!
And if that means I have to profile, bugfix and code to ensure that is not the case then I will, I call it adapting and not being rigid.</p>

<p>I am presently looking at Chef to compliment my planned deploy of Openstack, for which I will be writing the configurations, this will in turn allow the development team to get on with their jobs, I already use kickstarts for my KVM deployments, Chef seems like the next logical step.</p>

<p>And whilst “The Cloud” has met with <a href="http://www.saiweb.co.uk/hosting/cloud-hosting-my-views">my skepticism</a>, this is more to do with the over marketing claiming it is the solution to all your aliments &#8230; once you get past all the marketing fluff it is the way forward, and has been as such since a long time before “The Cloud” fluff came along.</p>

<p>So in short, I’m a Systems Administrator and I work damned hard to ensure those systems I administer stay online, if that means I need to work as a Developer, Pentester etc &#8230; then I will.</p>

<p>Whilst I can see that Devops in its current form could be stand alone from Systems Administration, it shouldn’t be &#8230;</p>

<p>You should not carry out Devops without a knowing the platforms you are deploying to, it’s like being a Cardiologist having spent 20 minutes on <a href="http://en.wikipedia.org/wiki/Operation_(game)">Operation</a> (Yes overly melodramatic metaphor, remember uptime for me is that important.)</p>

<p>So what does that make me? aside from an overly paranoid uptime chanting nutter?</p>

<p>On Another note Saiweb.co.uk is 7 years old 26/03/2012 &#8230; I should really add more content &#8230;</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[RedHat mock your SCM]]></title>
    <link href="http://saiweb.co.uk/linux/redhat-mock-your-scm"/>
    <updated>2012-02-03T16:33:19+00:00</updated>
    <id>http://saiweb.co.uk/linux/redhat-mock-your-scm</id>
    <content type="html"><![CDATA[<p>The mock tool can be a wonderful thing, allowing you to produce rpm packages for any rpm based system (assuming your have the written .cfg for it).</p>

<p>What I did find a little lacking on the documentation side was the SCM integration (read: Source Control Management), git/svn etc &#8230;</p>

<p>In short so long as your rpm spec file is in your SCM (and it should be), moc will build your rpm from your sources in scm, which can be used for.</p>

<ol>
<li>bleeding edge builds for testing</li>
<li>builds from &#8220;stable tags&#8221;</li>
</ol>


<p>Yes yes yes &#8230; obvious I know &#8230;</p>

<p>So with no futher ado here is the syntax:</p>

<div class="highlight"><pre><code class="bash">mock -r your_target --scm-enable --scm-option <span class="nv">method</span><span class="o">=</span>git --scm-option <span class="nv">package</span><span class="o">=</span>git_project --scm-option <span class="nv">git_get</span><span class="o">=</span><span class="s1">&#39;git clone git@git_ip_address:SCM_PKG.git SCM_PKG&#39;</span> --scm-option <span class="nv">spec</span><span class="o">=</span><span class="s1">&#39;SCM_PKG.spec&#39;</span> --scm-option <span class="nv">branch</span><span class="o">=</span>1-2 --scm-option <span class="nv">write_tar</span><span class="o">=</span>True -v
</code></pre>
</div>




<ol>
    <li>scm-enable - turns on the use of scm</li>
    <li>scm-option - set an option for the scm in use</li>
</ol>


<p>The above worked for me, you will need to adjust it acordingly, i.e. if your spec file is not named identically to that of your git project: &#8211;scm-option spec=&#8217;specfile_name.spec&#8217;</p>

<p>This will tie me over untill I get chance to play with my <a href="https://github.com/rackspace/monkeyfarm">monkey farm</a></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Gluster resolving a split brain in a replicated setup]]></title>
    <link href="http://saiweb.co.uk/linux/gluster-resolving-a-split-brain-in-a-replicated-setup"/>
    <updated>2011-12-20T12:29:08+00:00</updated>
    <id>http://saiweb.co.uk/linux/gluster-resolving-a-split-brain-in-a-replicated-setup</id>
    <content type="html"><![CDATA[<p>Initially this took about ~7hours to diagnose and fix, with what I have learned about the inner workings of gluster and the tools I am providing opensource this should cut resolution time down to ~5minutes.</p>

<p>Firs you must meet the following conditions:</p>

<ol>
    <li>You are running gluster >= 3.0 <= 3.2 (May also work on 2.x I have not tested, and will not work with future versions if gluster change their use of xattrs)</li>
    <li>You are running a replicated volume (Again I have not tested distributed volumes, in theory remove, re-add and rebalance will fix these) </li>
    <li>You have a &#8220;good&#8221; copy of you data (This is essential this assume you have at least 1 brick with a good copy of the file system</li>
</ol>


<p><strong>Restrain and restore the &#8220;bad&#8221; brick</strong></p>

<ol>
    <li>Shutdown all services that are using the mounted filesystem (i.e. httpd / nginx / *ftpd)</li>
    <li>Unmount all the file systems on the node (glusterfs / nfs / etc &#8230;)</li>
    <li>Grab a copy of <a href="https://github.com/Oneiroi/sysadmin/tree/master/gluster">stripxattr.py</a> make sure you READ the README for installation requirements and usage</li>
    <li>Run stripxattr.py against the backing filesystem on the &#8220;bad&#8221; node ONLY <strong>NOT AGAINST A GLUSTER MOUNT</strong></li>
    <li>From the &#8220;good&#8221; node, not rsync the data: rsync -gioprtv &#8211;progress /path/to/filesystem root@<bad_node>:/path/to</li>
    <li>From the &#8220;good&#8221; node, trigger an &#8221;<a href="http://docs.redhat.com/docs/en-US/Red_Hat_Storage_Software_Appliance/3.2/html/User_Guide/sect-User_Guide-Managing_Volumes-Self_heal.html">auto heal</a>&#8221; this will re-populate the xattr data (this must be done on a glusterfs mount not nfs/cifs/etc&#8230;)</li>
    <li>Download <a href="https://github.com/Oneiroi/sysadmin/tree/master/gluster">listxattr.py</a> once the self heal has completed see the README file for a &#8220;quick and dirty&#8221; consistency check</li>
    <li>All being well you have now resolved a split-brain and can return your node to service</li>
</ol>


<p><strong>Current known gluster issues</strong></p>

<ol>
    <li>NFS is much (48x in tests) faster for small files i.e. php webapps, but does not support distributed locking meaning: all nodes can write to the same file at the same time, this is what cause our original split brain</li>
</ol>


<p>So what is the resolution int his case?</p>

<p>Selective use, use glusterfs for filesystems that you need distributed locking, often in large production deploys php files will not change often, in this case NFS is perfect.</p>

<p>If you are still writing php sessions to a file system then <a href="http://www.saiweb.co.uk/php/high-availability-joomla-wordpress-load-balance-persistant-php-database-sessions">STOP IT</a> and use a database! (Better yet use memcache).</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[An update. I know I haven't been updating...]]></title>
    <link href="http://saiweb.co.uk/via google+/an-update-i-know-i-havent-been-updating"/>
    <updated>2011-11-13T13:53:37+00:00</updated>
    <id>http://saiweb.co.uk/via google+/an-update-i-know-i-havent-been-updating</id>
    <content type="html"><![CDATA[<p>I know I haven&#8217;t been updating a lot lately, esp on my poor blog (<a href="http://saiweb.co.uk/">http://saiweb.co.uk</a>), still I think I have things tied together enough to allow me to update once to everywhere (this post <em>should</em> appear on my blog, twitter, facebook, linkedin etc.</p>

<p>There&#8217;s been a lot developing over the last few months, Openstack being one of my main focuses along with overhauling and provision new internal systems for Openstack to run upon, I have a plan so to speak &#8230;</p>

<p>I have some Openstack posts coming I just need to ensure that all parties are happy with me posting the information &#8220;in the clear&#8221; so to speak.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Pivoting ssh reverse tunnel gateway]]></title>
    <link href="http://saiweb.co.uk/linux/pivoting-ssh-reverse-tunnel-gateway"/>
    <updated>2011-10-06T14:43:02+01:00</updated>
    <id>http://saiweb.co.uk/linux/pivoting-ssh-reverse-tunnel-gateway</id>
    <content type="html"><![CDATA[<p>They say necessity is the mother of invention, if this is true then surely the mother of all fuck ups is shoddy customer service, say an isp that will randomly shut down a port because it has high bandwidth usage without asking the customer about it first, and flat out refusing to do anything for 24hrs &#8230;</p>

<p>In one of the worst customer service experiences I&#8217;ve ever had the miss fortune to have been a part of all access was closed to our in office version control systems due to &#8220;high usage&#8221;, now this is a pretty essential service as you might imagine, how then to restore access, when the restrictions are beyond your control? (And I mean EVERY inbound port was dead &#8230;)</p>

<p>Fortunately it would seem outbound SSH was not affected, so after much vocal drawing and re-drawing many times over on the whiteboard I had a cunning plan &#8230;</p>

<p>Using 3 linux devices I would create the following.</p>

<ol>
<li><p>A device through which using host entries / dns changes the version control would be available whilst not actually running on the box itself.</p></li>
<li><p>An in house device which would be the device on which the tunnels are created in the first place.</p></li>
<li><p>The device(s) on which the version control systems reside.</p></li>
</ol>


<p><strong>Gateway device</strong></p>

<p>On the gateway device sshd_config needs to be updated with:</p>

<div class="highlight"><pre><code class="bash">GatewayPorts yes
</code></pre>
</div>


<p>And sshd reloaded.</p>

<p>Also if you are using a local firewall (i.e. iptables) you will need to setup the appropriate rules as if the service were running natively on the device</p>

<p><strong>Pivot Device</strong></p>

<p>Generate rsa ssh keys and deploy your id_rsa.pub to the gateway device, (update sshd_config to enable RSA Auth if required)</p>

<p>The tunnel.</p>

<div class="highlight"><pre><code class="bash">ssh &lt;Gateway Device&gt; -l root -g -N -R 0.0.0.0:&lt;Service Port&gt;:10.0.0.1:&lt;Service Port&gt;  -vvv
</code></pre>
</div>


<p>Now you only really need to use root if the port you need to gateway is a  privileged port (&lt;1024).</p>

<p>Here 10.0.0.1 is the internal address of the device the connection should &#8220;pivot&#8221; onto.</p>

<p>Once the tunnel was in place the services could be reached via the gateway device, this was essentially a &#8220;poor mans&#8221; NAT in a time of need, I really do not suggest this for long term use.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Linux collection of handy scripts and one liners â Volume 2 (Warning: contains shortcuts)]]></title>
    <link href="http://saiweb.co.uk/linux/linux-collection-of-handy-scripts-and-one-liners-volume-2-warning-contains-shortcuts"/>
    <updated>2011-09-26T15:43:34+01:00</updated>
    <id>http://saiweb.co.uk/linux/linux-collection-of-handy-scripts-and-one-liners-volume-2-warning-contains-shortcuts</id>
    <content type="html"><![CDATA[<p><strong>See if hosts are up using ping in range 60 -> 200</strong></p>

<div class="highlight"><pre><code class="bash"><span class="k">for </span>i in <span class="o">{</span>60..200<span class="o">}</span>; <span class="k">do </span>ping -c 1 -W 1 192.168.1.<span class="nv">$i</span> &gt; /dev/null; <span class="o">([[</span> <span class="nv">$?</span> <span class="o">==</span> 0 <span class="o">]]</span> <span class="o">&amp;&amp;</span> <span class="nb">echo</span> <span class="s2">&quot;$i UP&quot;</span> <span class="o">||</span> <span class="nb">echo</span> <span class="s2">&quot;$i DOWN&quot;</span><span class="o">)</span>;  <span class="k">done</span>
1 UP
2 DOWN
3 UP
...
</code></pre>
</div>


<p>Note: for OSX use &#8220;ping -c 1 -t 1&#8221;</p>

<p><strong>Chaining &#8220;UP&#8221; hosts for a quick (syn) port scan</strong></p>

<div class="highlight"><pre><code class="bash"><span class="k">for </span>i in <span class="o">{</span>60..200<span class="o">}</span>; <span class="k">do </span>ping -c 1 -W 1 192.168.1.<span class="nv">$i</span> &gt; /dev/null; <span class="o">([[</span> <span class="nv">$?</span> <span class="o">==</span> 0 <span class="o">]]</span> <span class="o">&amp;&amp;</span> nc -v -n -z -w1 192.168.1.<span class="nv">$i</span> 20-22<span class="o">)</span>; <span class="k">done</span>
<span class="o">(</span>UNKNOWN<span class="o">)</span> <span class="o">[</span>192.168.1.1<span class="o">]</span> 22 <span class="o">(</span>ssh<span class="o">)</span> open
<span class="o">(</span>UNKNOWN<span class="o">)</span> <span class="o">[</span>192.168.1.3<span class="o">]</span> 22 <span class="o">(</span>ssh<span class="o">)</span> open
</code></pre>
</div>


<p><strong>Recover from a bad mysql password set (Update mysql.users set password=&#8217;Iforgotawherestatemenlulz&#8217;)</strong></p>

<p>Assumes for every user there is an @localhost host, grabs the in memory password hash and resets</p>

<div class="highlight"><pre><code class="bash">mysql -Bse <span class="s1">&#39;Select distinct(user) from mysql.user;&#39;</span> | <span class="k">while </span><span class="nb">read </span>uname; <span class="k">do </span>mysql -Bse <span class="s2">&quot;show grants for &#39;$uname&#39;@&#39;localhost&#39;;&quot;</span> 2&gt;&amp;1 | grep IDENTIFIED | grep -v <span class="s1">&#39;root&#39;</span> | grep -v <span class="s1">&#39;ERROR&#39;</span> | sed <span class="s1">&#39;s|GRANT USAGE ON *.* TO ||g&#39;</span> | sed <span class="s2">&quot;s|@&#39;localhost&#39; IDENTIFIED BY PASSWORD||g&quot;</span> | awk <span class="s1">&#39;{print &quot;Update user set Password=&quot;$2&quot; where User=&quot;$1&quot;;&quot;}&#39;</span> | mysql mysql; <span class="k">done</span>
</code></pre>
</div>


<p>If you&#8217;ve run FLUSH PRIVILEGES; however you == b0ned.</p>

<p><strong>Quick substitute and run</strong></p>

<p>Command1:</p>

<div class="highlight"><pre><code class="bash">ping -c 1 -t 1 192.168.1.1
</code></pre>
</div>


<p>Opps that&#8217;s OSX synatx</p>

<p>Command2:</p>

<div class="highlight"><pre><code class="bash">^-t 1^-W 1
</code></pre>
</div>


<p>et voila corrected syntax.</p>

<p><strong>Shortcuts</strong></p>

<p>!! - Execute last command
!ping - Execute last ping command, can be used to !any command just be careful.
ctrl+r - reverse search, just start typing the cmd for it to search your history, hit tab to complete
ctrl+a - jump to beginning of line
ctrl+e - jump to end of the line</p>

<p><strong>cURL FU</strong></p>

<p>curl -I -L blahblah.tld - Run a HEAD and follow redirects (very handy for quicklooking @ bit.ly short URLS before hitting them in a browser).</p>

<p><strong>python FU</strong></p>

<p>python -m SimpleHTTPServer - serves the current <code>pwd</code> as a browseable directory (Very cool but VERY insecure)
python -m cProfile script.py - generate trace stats for a script execution (Very handy for finding excessive loops)</p>

<p><strong>DNS Fu</strong></p>

<p>Wikipedia over DNS:</p>

<p>host -t txt fu.wp.dg.cx</p>

<p>fu.wp.dg.cx descriptive text &#8220;Fu may refer to: Fu (Technology, especially computer related) (used as a suffix) - relating to a person - Possessing superior skills in an art\; relating to an artifact - representing an expression of high art. code-fu, Perl-fu, C-fu, etc, Fu (literature),&#8221; &#8221; a Chinese genre of rhymed prose, Fu (kana), a symbol in Japanese syllabaries, Fu County, in Shaanxi, China, Fu Foundation&#8230; http://a.vu/w:Fu&#8221;</p>

<p>Useful on <em>some</em> public wifi connections if you just want to look something up quick (dns is not always re-written).</p>

<p>Get all MX servers for a domain:</p>

<p>dig google.co.uk MX</p>

<p>; &lt;&lt;>> DiG 9.6.0-APPLE-P2 &lt;&lt;>> google.co.uk MX
;; global options: +cmd
;; Got answer:
;; ->>HEADER&lt;&lt;- opcode: QUERY, status: NOERROR, id: 64165
;; flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 4, ADDITIONAL: 4</p>

<p>;; QUESTION SECTION:
;google.co.uk.          IN  MX</p>

<p>;; ANSWER SECTION:
google.co.uk.       10800   IN  MX  10 google.com.s9a1.psmtp.com.
google.co.uk.       10800   IN  MX  10 google.com.s9a2.psmtp.com.
google.co.uk.       10800   IN  MX  10 google.com.s9b1.psmtp.com.
google.co.uk.       10800   IN  MX  10 google.com.s9b2.psmtp.com.</p>

<p>;; AUTHORITY SECTION:
google.co.uk.       59925   IN  NS  ns2.google.com.
google.co.uk.       59925   IN  NS  ns3.google.com.
google.co.uk.       59925   IN  NS  ns4.google.com.
google.co.uk.       59925   IN  NS  ns1.google.com.</p>

<p>;; ADDITIONAL SECTION:
ns1.google.com.     158334  IN  A   216.239.32.10
ns2.google.com.     158334  IN  A   216.239.34.10
ns3.google.com.     158741  IN  A   216.239.36.10
ns4.google.com.     158334  IN  A   216.239.38.10</p>

<p>;; Query time: 68 msec
;; SERVER:
;; WHEN: Mon Sep 26 16:41:26 2011
;; MSG SIZE  rcvd: 310</p>

<p><strong>mySQL FU</strong></p>

<p>in one line, take a database, in stream replace content and stream into another db.</p>

<p>mysqldump original_db | sed &#8216;s/content_or_regex_to_replace/content_or_backref_replacement/g&#8217; | mysql destination_db</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[WiFi recon using OSX native tools]]></title>
    <link href="http://saiweb.co.uk/hacking/mac/wifi-recon-using-osx-native-tools"/>
    <updated>2011-09-23T10:13:12+01:00</updated>
    <id>http://saiweb.co.uk/hacking/mac/wifi-recon-using-osx-native-tools</id>
    <content type="html"><![CDATA[<p>So you wanted to get your aircrak suite on under OSX, getting airodump etc to work I can tell you will be a nightmare (infact just dont use a VM with a USB wifi for that, however there is an alternative &#8230;), after a lot of searching there is a native tool under OSX that will let you cap packets, list networks etc.</p>

<p>Credit goes to <a href="http://forum.aircrack-ng.org/index.php?topic=293.msg34031#msg34031">d3in0s</a> for his awesome forum post.</p>

<div class="highlight"><pre><code class="bash">/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport
Usage: airport &lt;interface&gt; &lt;verb&gt; &lt;options&gt;

    &lt;interface&gt;
    If an interface is not specified, airport will use the first AirPort interface on the system.

    &lt;verb is one of the following:
    prefs   If specified with no key value pairs, displays a subset of AirPort preferences <span class="k">for</span>
<span class="k">        </span>the specified interface.

        Preferences may be configured using <span class="nv">key</span><span class="o">=</span>value syntax. Keys and possible values are specified below.
        Boolean settings may be configured using <span class="s1">&#39;YES&#39;</span> and <span class="s1">&#39;NO&#39;</span>.

        DisconnectOnLogout <span class="o">(</span>Boolean<span class="o">)</span>
        JoinMode <span class="o">(</span>String<span class="o">)</span>
            Automatic
            Preferred
            Ranked
            Recent
            Strongest
        JoinModeFallback <span class="o">(</span>String<span class="o">)</span>
            Prompt
            JoinOpen
            KeepLooking
            DoNothing
        RememberRecentNetworks <span class="o">(</span>Boolean<span class="o">)</span>
        RequireAdmin <span class="o">(</span>Boolean<span class="o">)</span>
        RequireAdminIBSS <span class="o">(</span>Boolean<span class="o">)</span>
        RequireAdminNetworkChange <span class="o">(</span>Boolean<span class="o">)</span>
        RequireAdminPowerToggle <span class="o">(</span>Boolean<span class="o">)</span>
        WoWEnabled <span class="o">(</span>Boolean<span class="o">)</span>

    logger  Monitor the driver<span class="s1">&#39;s logging facility.</span>

<span class="s1">   sniff   If a channel number is specified, airportd will attempt to configure the interface</span>
<span class="s1">       to use that channel before it begins sniffing 802.11 frames. Captures files are saved to /tmp.</span>
<span class="s1">       Requires super user privileges.</span>

<span class="s1">   debug   Enable debug logging. A debug log setting may be enabled by prefixing it with a &#39;</span>+<span class="s1">&#39;, and disabled</span>
<span class="s1">       by prefixing it with a &#39;</span>-<span class="err">&#39;</span>.

        AirPort Userland Debug Flags
            DriverDiscovery
            DriverEvent
            Info
            SystemConfiguration
            UserEvent
            PreferredNetworks
            AutoJoin
            IPC
            Scan
            802.1x
            Assoc
            Keychain
            RSNAuth
            WoW
            AllUserland - Enable/Disable all userland debug flags

        AirPort Driver Common Flags
            DriverInfo
            DriverError
            DriverWPA
            DriverScan
            AllDriver - Enable/Disable all driver debug flags

        AirPort Driver Vendor Flags
            VendorAssoc
            VendorConnection
            AllVendor - Enable/Disable all vendor debug flags

        AirPort Global Flags
            LogFile - Save all AirPort logs to /var/log/airport.log

&lt;options&gt; is one of the following:
    No options currently defined.

Examples:

Configuring preferences <span class="o">(</span>requires admin privileges<span class="o">)</span>
    sudo airport en1 prefs <span class="nv">JoinMode</span><span class="o">=</span>Preferred <span class="nv">RememberRecentNetworks</span><span class="o">=</span>NO <span class="nv">RequireAdmin</span><span class="o">=</span>YES

Sniffing on channel 1:
    airport en1 sniff 1


LEGACY COMMANDS:
Supported arguments:
 -c<span class="o">[</span>&lt;arg&gt;<span class="o">]</span> --channel<span class="o">=[</span>&lt;arg&gt;<span class="o">]</span>    Set arbitrary channel on the card
 -z        --disassociate       Disassociate from any network
 -I        --getinfo            Print current wireless status, e.g. signal info, BSSID, port <span class="nb">type </span>etc.
 -s<span class="o">[</span>&lt;arg&gt;<span class="o">]</span> --scan<span class="o">=[</span>&lt;arg&gt;<span class="o">]</span>       Perform a wireless broadcast scan.
                   Will perform a directed scan <span class="k">if </span>the optional &lt;arg&gt; is provided
 -x        --xml                Print info as XML
 -P        --psk                Create PSK from specified pass phrase and SSID.
                   The following additional arguments must be specified with this <span class="nb">command</span>:
                                  --password<span class="o">=</span>&lt;arg&gt;  Specify a WPA password
                                  --ssid<span class="o">=</span>&lt;arg&gt;      Specify SSID when creating a PSK
 -h        --help               Show this <span class="nb">help</span>
</code></pre>
</div>


<p>Credit goes to <a href="http://forum.aircrack-ng.org/index.php?PHPSESSID=osr5e11icl40hib1f57qkh0u35&topic=293.msg34031#msg34031">d3in0s post</a> showing true forum awesomeness.</p>

<div class="highlight"><pre><code class="bash">/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -I
     agrCtlRSSI: -40
     agrExtRSSI: 0
    agrCtlNoise: -92
    agrExtNoise: 0
          state: running
        op mode: station 
     lastTxRate: 54
        maxRate: 54
lastAssocStatus: 0
    802.11 auth: open
      link auth: wpa2-psk
          BSSID: &lt;removed&gt;
           SSID: &lt;removed&gt;
            MCS: -1
        channel: 6
/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -s
                            SSID BSSID             RSSI CHANNEL HT CC SECURITY <span class="o">(</span>auth/unicast/group<span class="o">)</span>
                          &lt;removed&gt; &lt;removed&gt; -41  6       N  -- WPA<span class="o">(</span>PSK/AES,TKIP/TKIP<span class="o">)</span> WPA2<span class="o">(</span>PSK/AES,TKIP/TKIP<span class="o">)</span>
</code></pre>
</div>


<p>Doing a frame cap.</p>

<div class="highlight"><pre><code class="bash">/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport en1 sniff 6
Capturing 802.11 frames on en1.
</code></pre>
</div>


<p>You will see your airport icon changes to <a href="http://cdn.saiweb.co.uk/uploads/2011/09/Screen-shot-2011-09-23-at-11.20.28.png"><img src="http://cdn.saiweb.co.uk/uploads/2011/09/Screen-shot-2011-09-23-at-11.20.28.png" alt="" title="Screen shot 2011-09-23 at 11.20.28" width="45" height="24" class="aligncenter size-full wp-image-1126" /></a> now hit ctrl+c to stop the cap</p>

<div class="highlight"><pre><code class="bash">^CSession saved to /tmp/airportSniff813ZrA.cap.
</code></pre>
</div>



]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[easy_install for python 3]]></title>
    <link href="http://saiweb.co.uk/python/easy_install-for-python-3"/>
    <updated>2011-09-19T20:47:05+01:00</updated>
    <id>http://saiweb.co.uk/python/easy_install-for-python-3</id>
    <content type="html"><![CDATA[<p>easy_install for python3 simple</p>

<div class="highlight"><pre><code class="bash">curl -O http://python-distribute.org/distribute_setup.py
python3 distribute_setup.py
</code></pre>
</div>


<p>Enjoy!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[php mail() - Making it not suck using sendmail]]></title>
    <link href="http://saiweb.co.uk/linux/php/php-mail-making-it-not-suck-using-sendmail"/>
    <updated>2011-09-18T12:22:46+01:00</updated>
    <id>http://saiweb.co.uk/linux/php/php-mail-making-it-not-suck-using-sendmail</id>
    <content type="html"><![CDATA[<p>Ok ok &#8230; as some of the people work with are aware, I did this months ago fro one project, ment to blog and document it then in fact I have a draft post last modified 06/05/2011 covering full spam score reduction, and half finished instructions on setting up a mail relay &#8230; so in the interim of finishing that post I&#8217;m going to cover improving user experience through proper php configuration.</p>

<p>Out of the box, php will use sendmail, and it will do so as follows.</p>

<ol>
    <li>mail() forks sendmail process</li>
    <li>sendmail attempts to send email to destination server</li>
    <li>sendmail returns on send complete</li>
</ol>


<div>Generally this isn&#8217;t a problem but what if at point 2. there is an issue with the destination MTA ? well in that case php will infact sit around waiting fot sendmail to complete, leaving your user with a hung screen / hung ajax call.</div>


<div>So what to do?</div>


<div>Simply put you want to offset the sending email process you do not want the end user sat around waiting for sendmail to finish sending the email, but you do want the email to send &#8230; decisions &#8230; decisions.</div>


<div>So edit yout php.ini .</div>




<div class="highlight"><pre><code class="bash"><span class="nv">sendmail_path</span> <span class="o">=</span> /usr/sbin/sendmail -t -i -O <span class="nv">DeliveryMode</span><span class="o">=</span>b
</code></pre>
</div>


<p>This sets the delivery mode to background, sendmail will return to php near instantly and send the email in the background by placing in into a queue.</p>

<p>TL;DR</p>

<p>Put the above in your php.ini to not hang around to sendmail, and hav it return instantly.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[PenTesting - mySQL password hash generation and lookup]]></title>
    <link href="http://saiweb.co.uk/security/pentesting-mysql-password-hash-generation-and-lookup"/>
    <updated>2011-08-17T12:20:04+01:00</updated>
    <id>http://saiweb.co.uk/security/pentesting-mysql-password-hash-generation-and-lookup</id>
    <content type="html"><![CDATA[<p>One of the worst things you can have in any secure system is a user with a simple password, no matter what steps you take to protect your data, if a privileged user is using a simple password, it&#8217;s akin to having a safe door that&#8217;s glass window.</p>

<p>First off we need to take a hash dump:</p>

<div class="highlight"><pre><code class="bash">mysql -Bse <span class="s1">&#39;select distinct(password),user from mysql.user;&#39;</span> &gt; hashdump.txt
</code></pre>
</div>


<p>Now of course you can do the same using SQL Injection etc (WHY when you have SQLi already? duh privilege escalation!) , I&#8217;m going to cover this from the perspective that you are the administrator looking to strengthen your security &#8230;</p>

<p>Now you have your hashdump you need a hash table with the equivelent passwords within it, for this you will need 2 things</p>

<ol>
<li>A dictionary file</li>
<li><a href="https://github.com/Oneiroi/PenTesting/blob/master/crypto/generators/mysql/csv_gen.py">https://github.com/Oneiroi/PenTesting/blob/master/crypto/generators/mysql/csv_gen.py</a></li>
</ol>


<p>The python script above I wrote to use multiprocessing to map words onto the hash function, and I have had it grind through mySQL hashes at a rate of ~98k per second, there is no &#8220;lookup&#8221; script at this time though one is currently being written.</p>

<div class="highlight"><pre><code class="bash">./csv_gen.py -f /path/to/wordlist.txt -o /output/path/to/output.csv -t &lt;max threads, default 1&gt; <span class="o">[</span>-l optional use legacy <span class="nb">hash</span><span class="o">]</span>
</code></pre>
</div>


<p>once this has ground through your wordlist you will have a CSV file, which will be in the format <hash>,<password>
the script defaults to the new PASSWORD() function, if you are using old_password=1 in your configuration then pass the -l flag to use legacy hashing instead.</p>

<p>ok let&#8217;s assume the following fictional scenario</p>

<ol>
<li>old_passwords is in use, and we want chip&#8217;s password</li>
<li>077b91e3491e2fdd chip</li>
<li></li>
</ol>


<div class="highlight"><pre><code class="bash">grep 077b91e3491e2fdd output.txt
077b91e3491e2fdd,a
</code></pre>
</div>


<ol>
<li>Chip has a password that is just he letter &#8220;a&#8221; which he will tell you is the best password ever &#8230;</li>
</ol>


<p>And that&#8217;s about a simple as it gets you generate a set of hashes and you compare known hashes to your generate set to see if you can discern simple passwords, hopefully going on then to chastise the user and instructing them on proper password etiquette, there are more complicated methods of getting the password from the hash, in the case of old_passwords I believe it is possible to reverse the hash to get the original string for one (so don&#8217;t use old_passwords!)</p>

<p>If you go on to use my python scripts, please let me know how they perform, my test were carried out using an intel i5, I&#8217;d love to know how they perform on other CPUs.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Boxgrinder - setting up a simple CentOS LAMP stack, and deploying it to KVM]]></title>
    <link href="http://saiweb.co.uk/linux/boxgrinder/cloud/boxgrinder-setting-up-a-simple-centos-lamp-stack-and-deploying-it-to-kvm"/>
    <updated>2011-08-16T11:35:54+01:00</updated>
    <id>http://saiweb.co.uk/linux/boxgrinder/cloud/boxgrinder-setting-up-a-simple-centos-lamp-stack-and-deploying-it-to-kvm</id>
    <content type="html"><![CDATA[<p><a href="http://cdn.saiweb.co.uk/uploads/2011/08/boxgrinder_logo_450px.gif"><img class="aligncenter size-full wp-image-1093" title="boxgrinder_logo_450px" src="http://cdn.saiweb.co.uk/uploads/2011/08/boxgrinder_logo_450px.gif" alt="" width="450" height="110" /></a> If you haven&#8217;t tried <a href="http://boxgrinder.org">boxgrinder</a> then you are missing out, it makes it extremely easy to script the generation of a virtual machine for output to Rackspace (<a href="http://www.saiweb.co.uk/linux/boxgrinder-setting-up-a-simple-centos-lamp-stack-and-deploying-it-to-kvm/comment-page-1#comment-49065">Well not yet</a>), ec2, vmware, virtualbox, KVM etc.</p>

<p>In this post I will cover the basic generation of a LAMP (Linux Apache MySQL PHP) stack CentOS appliance, nothing to complicated I assure you, and no magic like auto deployment spin up etc &#8230; that&#8217;s for later &#8230; no skipping ahead!</p>

<p>First of all you&#8217;re going to need <a href="http://boxgrinder.org">boxgrinder</a> I recommend downloading the <a href="http://boxgrinder.org/download/boxgrinder-build-meta-appliance/">Meta appliance</a>, as it has all the tools you need already.</p>

<p>Now I am covering the following.</p>

<ol>
    <li>basic use of boxgrinder-build on the meta appliance</li>
    <li>creation of centos lampstack basic</li>
    <li>deploying the image to KVM</li>
</ol>


<p>I&#8217;m going to have to assume that you are capable of downloading and starting up the meta appliance yourself, and focus more on the stack setup.</p>

<p><strong>Grinding your VM</strong></p>

<p>Ok so you are going to need a YAML file defining the CentOS lamp stack, save this on your meta appliance as <a href="https://github.com/Oneiroi/boxgrinder-appliances/blob/master/CentOS/CentOS-lamp.appl">CentOS-lamp.yaml</a></p>

<div class="highlight"><pre><code class="bash">name: CentOS-lamp
summary: Generic CentOS 5.6 LAMP stack, with some apache &amp;amp; php tuning
version: 1
release: 0
hardware:
cpus: 2
memory: 1024
partitions:
<span class="s2">&quot;/&quot;</span>:
size: 5
<span class="s2">&quot;/var/www&quot;</span>:
size: 15
os:
name: centos
version: 5
password: changeme
</code></pre>
</div>


<p>On your <a href="http://boxgrinder.org/download/boxgrinder-build-meta-appliance/">Meta appliance</a> run.</p>

<div class="highlight"><pre><code class="bash">boxgrinder-build -d CentOS-lamp.appl
</code></pre>
</div>


<p>This process will take a while, so go and get a coffee, this will produce ./build/appliances/x86_64/centos/5/CentOS-lamp/CentOS-lamp-sda.raw once complete, if you run into issues the -d flag is &#8220;debug&#8221; paste your log output int the comments and I will do my best to diagnose and fix your issue.</p>

<p><strong>Deploying to KVM</strong></p>

<p>boxgrinder has SFTP support for pushing to remote servers, you can use this if you like to automate the &#8220;push&#8221; of the image to your KVM server, at the moment automated deployment to KVM is not support but may be <a href="https://issues.jboss.org/browse/BGBUILD-211">coming soon</a>.</p>

<p>Assuming you have placed you image in /var/lib/libvirt/images/</p>

<div class="highlight"><pre><code class="bash">virt-install -n <span class="s2">&quot;Saiweb - CentOS-lamp Demo&quot;</span> -r 1024 --arch<span class="o">=</span>x86_64 --vcpus<span class="o">=</span>1 --os-type<span class="o">=</span>linux --os-variant<span class="o">=</span>rhel5.4 --disk <span class="nv">path</span><span class="o">=</span>/var/lib/libvirt/images/CentOS-lamp.raw,size<span class="o">=</span>20,cache<span class="o">=</span>none,device<span class="o">=</span>disk --accelerate --network<span class="o">=</span>bridge:br0 --vnc --import
</code></pre>
</div>


<p><strong>Post startup</strong></p>

<p>this is a VERY basic setup I have not covered any of the post install options in this post (but I will in future posts), so.</p>

<div class="highlight"><pre><code class="bash">chkconfig httpd on &amp;amp;&amp;amp; service httpd start
chkconfig mysqld on &amp;amp;&amp;amp; service mysqld start
</code></pre>
</div>


<p>This will set your services to automatically start at startup, and start them.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Content purging changes in Varnish 3.0]]></title>
    <link href="http://saiweb.co.uk/linux/hosting/varnish/content-purging-changes-in-varnish-3-0"/>
    <updated>2011-08-12T08:25:45+01:00</updated>
    <id>http://saiweb.co.uk/linux/hosting/varnish/content-purging-changes-in-varnish-3-0</id>
    <content type="html"><![CDATA[<p>If you tie in your web application to automatically PURGE content when you modify it, thus keeping the content &#8220;fresh&#8221; while using Varnish you may notice if you made the jump from 2.x to 3.x that your PURGE VCL is no longer working, I refer you to: <a href="https://www.varnish-software.com/blog/bans-and-purges-varnish-30">https://www.varnish-software.com/blog/bans-and-purges-varnish-30</a></p>

<p>In short replace your usual</p>

<div class="highlight"><pre><code class="bash">sub vcl_hit <span class="o">{</span>
        <span class="k">if</span> <span class="o">(</span>req.request <span class="o">==</span> <span class="s2">&quot;PURGE&quot;</span><span class="o">)</span> <span class="o">{</span>
                <span class="nb">set </span>obj.ttl <span class="o">=</span> 0s;
                error 200 <span class="s2">&quot;Purged.&quot;</span>; <span class="c">#uses error function to return simple confirmation</span>
        <span class="o">}</span>
<span class="o">}</span>
sub vcl_miss <span class="o">{</span>
        <span class="k">if</span> <span class="o">(</span>req.request <span class="o">==</span> <span class="s2">&quot;PURGE&quot;</span><span class="o">)</span> <span class="o">{</span>
                error 404 <span class="s2">&quot;Not in cache.&quot;</span>; <span class="c">#request to purge none existant item</span>
        <span class="o">}</span>
<span class="o">}</span>
</code></pre>
</div>


<p>with</p>

<div class="highlight"><pre><code class="bash">sub vcl_recv <span class="o">{</span>
        <span class="k">if</span> <span class="o">(</span>req.request <span class="o">==</span> <span class="s2">&quot;PURGE&quot;</span><span class="o">)</span> <span class="o">{</span>
                <span class="k">if</span> <span class="o">(</span>!client.ip ~ purge<span class="o">)</span> <span class="o">{</span>
                        error 405 <span class="s2">&quot;Not allowed.&quot;</span>;
                <span class="o">}</span>
                ban<span class="o">(</span><span class="s2">&quot;req.url ~ &quot;</span>+req.url+<span class="s2">&quot; &amp;&amp; req.http.host == &quot;</span>+req.http.host<span class="o">)</span>;
                error 200 <span class="s2">&quot;Purged.&quot;</span>;
        <span class="o">}</span>
...
</code></pre>
</div>


<p>Substituting &#8220;~ purge&#8221; with your ACL name, the above implement wild card purging aswell, if you do not want this and only want PURGE for the exact passed URL replace</p>

<p>&#8220;req.url ~ &#8220;+req.url</p>

<p>with</p>

<p>&#8220;req.url == &#8220;+req.url</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[PHP & Caching an in depth review - Follow up using Varnish]]></title>
    <link href="http://saiweb.co.uk/php/hosting/php-caching-an-in-depth-review-follow-up-using-varnish"/>
    <updated>2011-08-10T20:59:26+01:00</updated>
    <id>http://saiweb.co.uk/php/hosting/php-caching-an-in-depth-review-follow-up-using-varnish</id>
    <content type="html"><![CDATA[<p>Ok, so following up on PHP &amp; Caching with Varnish, let&#8217;s cut to the hard facts shall we?</p>

<p>Using the same tests as <a href="http://www.saiweb.co.uk/hosting/php-caching-an-in-depth-review" title="PHP & Caching an in depth review"></a></p>

<p> ab -c 100 -n 500 -g ./saiweb-nocache-nogzip.bpl http://www.saiweb.co.uk/
This is ApacheBench, Version 2.3 &lt;$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/</p>

<p>Benchmarking www.saiweb.co.uk (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Finished 500 requests</p>

<p>Server Software:        Apache
Server Hostname:        www.saiweb.co.uk
Server Port:            80</p>

<p>Document Path:          /
Document Length:        92719 bytes</p>

<p>Concurrency Level:      100
Time taken for tests:   0.184 seconds
Complete requests:      500
Failed requests:        0
Write errors:           0
Total transferred:      47597095 bytes
HTML transferred:       47379409 bytes
Requests per second:    2716.92 [#/sec] (mean)
Time per request:       36.806 [ms] (mean)
Time per request:       0.368 [ms] (mean, across all concurrent requests)
Transfer rate:          252573.13 [Kbytes/sec] received</p>

<p>Connection Times (ms)</p>

<pre><code>          min  mean[+/-sd] median   max
</code></pre>

<p>Connect:        1    4   1.1      4       6
Processing:     9   31   7.0     32      47
Waiting:        2    7   5.7      4      26
Total:         15   35   6.8     36      53</p>

<p>Percentage of the requests served within a certain time (ms)
  50%     36
  66%     38
  75%     39
  80%     39
  90%     41
  95%     44
  98%     48
  99%     51
 100%     53 (longest request)</p>

<p><a href="http://cdn.saiweb.co.uk/uploads/2011/08/Out.png"><img src="http://cdn.saiweb.co.uk/uploads/2011/08/Out.png" alt="ab -c 100 -n 500 -g ./saiweb-nocache-nogzip.bpl http://www.saiweb.co.uk/" title="ab -c 100 -n 500 -g ./saiweb-nocache-nogzip.bpl http://www.saiweb.co.uk/" width="640" height="480" class="aligncenter size-full wp-image-1070" /></a></p>

<p>2716.92 requests per second with a server load average of 0.1, and in this case varnish is serving cache from disk.</p>

<p>Caching using varnish (Or even nginx / mod_cache) means that PHP does not get executed at all, the cache system grabs the cache content and serves it.</p>

<p>This of course has the benefit of reducing the CPU and memory resources needed for the running of your application, but it does have some caveats.</p>

<ul>
    <li>This only works for GET requests, and content not reliant on Cookies (Truely dynamic content will not cache)</li>
    <li>But on the &#8220;flipside&#8221; Varnish supports ESI, which when setup correctly you can target the dynamic sections of a pag for &#8220;passthrough&#8221; and have the rest cached</li>
<ol>


More details to come, as I have time to add them I have have a lot of posts to make on boxgrinder, KVM, libvirtd etc.

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Fixing OSX Lion AFP the version of the server you are trying to connect to is not supported]]></title>
    <link href="http://saiweb.co.uk/mac/fixing-osx-lion-afp-the-version-of-the-server-you-are-trying-to-connect-to-is-not-supported"/>
    <updated>2011-07-21T13:58:01+01:00</updated>
    <id>http://saiweb.co.uk/mac/fixing-osx-lion-afp-the-version-of-the-server-you-are-trying-to-connect-to-is-not-supported</id>
    <content type="html"><![CDATA[<p>For those using netatalk for AFP shares in this case I am using CentOS, the EL5 compiles are missing the configure lines for the dhx2 extension, which is required by OSX Lion, if you are running x86_64 you can grab this file: <a href='http://cdn.saiweb.co.uk/uploads/2011/07/netatalk-2.0.5-2.x86_64.rpm_.zip'>netatalk-2.0.5-2.x86_64.rpm</a> I have also emailed the Package maintainer @ EPEL with the changes I have made for this RPM so I would like to think that -2 will be available from EPEL soon.</p>

<p>Let me know if you have any issues with my RPM.</p>

<p><strong>UPDATE: <a href="http://koji.fedoraproject.org/koji/buildinfo?buildID=255047">Official Rebuild in testing</a></strong></p>
]]></content>
  </entry>
  
</feed>

