sl0http://hubertz.de/blog/2015-02-10T13:17:00+01:00log entry 2015-02-102015-02-10T13:17:00+01:002015-02-10T13:17:00+01:00Johannes Hubertztag:hubertz.de,2015-02-10:/blog/iptables-optimizer-10th.html<p class="first last">iptables-optimizer v0.9.13-1</p>
<div class="section" id="iptables-optimizer-version-0-9-13-1">
<h2>iptables-optimizer version 0.9.13-1</h2>
<p>Guido gave another useful hint, possibly to separate debian
packaging into a debian branch and work on the other code in
the master branch, just to keep upstream and packaging work
stricktly separated. As read in the Wiki, the content of
debian/souce/format was changed to:</p>
<pre class="literal-block">
3.0 (quilt)
</pre>
<p>Debian package version therefore became <tt class="docutils literal"><span class="pre">0.9.13-1</span></tt> in
the the newest changelog entry. And then <tt class="docutils literal">gbp buildpackage</tt>
refused to build but gave a hint to create a patch by using:</p>
<pre class="literal-block">
dpkg-souce --commit
</pre>
<p>This produced a patch file into the debian/patches directory and asked
to guess a name for it. The patch comments were edited and
everything looked fine:</p>
<pre class="literal-block">
gbp buildpackage --git-tag
</pre>
<p>succeeded and tagged correctly. It did a beautiful job and
of course cowbuilder had to be updated before all other steps.</p>
<p>The github <a class="reference external" href="https://github.com/sl0/opti">iptables-optimizer</a> repository is updated now, prebuild
debian and rpm packages are waiting for your <a class="reference external" href="http://hubertz.de/downloads/">downloads</a>:</p>
<pre class="literal-block">
SHA1(iptables-optimizer_0.9.13-1_all.deb)= 9bb92247707d5dc3c30c65ffaf11d634168f14e4
SHA1(iptables-optimizer_0.9.13-1_amd64.build)= d8e72361de8c804769669cb31dba4e201eaa934a
SHA1(iptables-optimizer_0.9.13-1_amd64.changes)= 8f57b4608a97d5f6d8f6cc3eae381acfaa5a8fa1
SHA1(iptables-optimizer_0.9.13-1.debian.tar.xz)= 591d918128b03c8f4088dee0ece189ba956fa9ba
SHA1(iptables-optimizer_0.9.13-1.dsc)= 8fc570e3b3c74694f87638ed8f7738ff80faf6ac
SHA1(iptables-optimizer-doc_0.9.13-1_all.deb)= 45bbe608935ab3f9c46a437d2ea4da5e6a2bddda
</pre>
<p>Your comments are welcome!</p>
<div class="section" id="have-fun">
<h3>Have fun!</h3>
</div>
</div>
log entry 2015-01-162015-01-16T23:57:00+01:002015-01-16T23:57:00+01:00Johannes Hubertztag:hubertz.de,2015-01-16:/blog/iptables-optimizer-9th.html<p class="first last">iptables-optimizer v0.9.13</p>
<div class="section" id="iptables-optimizer-version-0-9-13">
<h2>iptables-optimizer version 0.9.13</h2>
<p>As testing is fun, the shunit2 tests have been improved. Additionally it
is checked now, if the tests are run as real root or in a
fakeroot or user environment. This is checked before the first test is run.
If they are not run by real root, all real tests are skipped for now:</p>
<pre class="literal-block">
hans@jhc ~/devel/opti debian/sid $ fakeroot bash iptables-optimizer-tests.sh
test_Needs_to_run_as_root
ASSERT:[42] expecting-real-root expected:<0> but was:<2>
test_AutoApply_Not_Present
test_AutoApply_Not_Ready
test_AutoApply_Ready
test_AutoApply_Execute
test_AutoApply_Execute_fails_due_to_immutable
test_Modprobe_NetFilter
test_Good_iptables_save_without_log
test_Good_iptables_save_simple_log
test_Run_python_part_without_log
test_Run_python_part_simple_log
test_Run_python_part_verb_log_all_chains
test_Run_python_part_verb_log_in_out_chains
test_Bad_iptables_save
test_Correct_iptables_restore
test_Faulty_iptables_restore
Ran 16 tests.
FAILED (failures=1,skipped=20)
hans@jhc ~/devel/opti debian/sid $
hans@jhc ~/devel/opti debian/sid $ su
root@jhc:/home/hans/devel/opti# bash iptables-optimizer-tests.sh
test_Needs_to_run_as_root
test_AutoApply_Not_Present
test_AutoApply_Not_Ready
test_AutoApply_Ready
test_AutoApply_Execute
test_AutoApply_Execute_fails_due_to_immutable
test_Modprobe_NetFilter
test_Good_iptables_save_without_log
test_Good_iptables_save_simple_log
test_Run_python_part_without_log
test_Run_python_part_simple_log
test_Run_python_part_verb_log_all_chains
test_Run_python_part_verb_log_in_out_chains
test_Bad_iptables_save
test_Correct_iptables_restore
test_Faulty_iptables_restore
Ran 16 tests.
OK
root@jhc:/home/hans/devel/opti# exit
hans@jhc ~/devel/opti debian/sid $
</pre>
<p>After Guido has given another talk about his git buildpackage at
the last <a class="reference external" href="https://wiki.fsfe.org/groups/Bonn">FSFE-Fellowship-meeting</a> (2015-01-12), the master branch
is configured as upstream now, the debian/sid branch as
default debian branch. git-pbuilder is used by default, which
invokes cowbuilder. So all these details no longer need to be
mentioned on the command line invocation of the package build
command:</p>
<pre class="literal-block">
hans@jhc ~/devel/opti debian/sid $ gbp buildpackage --git-tag --git-retag
...
... big bunch of output, may be read later from ../iptables-optimizer_0.9.13_amd64.build
...
hans@jhc ~/devel/opti debian/sid $ ls -ltr ../*0.9.13*
-rw-r--r-- 1 hans hans 81684 Jan 16 22:42 ../iptables-optimizer_0.9.13.tar.xz
-rw-r--r-- 1 hans hans 798 Jan 16 22:42 ../iptables-optimizer_0.9.13.dsc
-rw-r--r-- 1 hans hans 14174 Jan 16 22:43 ../iptables-optimizer_0.9.13_all.deb
-rw-r--r-- 1 hans hans 91516 Jan 16 22:43 ../iptables-optimizer-doc_0.9.13_all.deb
-rw-r--r-- 1 hans hans 1827 Jan 16 22:43 ../iptables-optimizer_0.9.13_amd64.changes
-rw-r--r-- 1 hans hans 46048 Jan 16 22:43 ../iptables-optimizer_0.9.13_amd64.build
hans@jhc ~/devel/opti debian/sid $
</pre>
<p>Using '--git-tag --git-retag' does the release tagging in the git repository on the fly:</p>
<pre class="literal-block">
hans@jhc ~/devel/opti debian/sid $ git log --oneline --decorate
f828f0b (HEAD, tag: debian/0.9.13, origin/debian/sid, debian/sid) changelog was done by: gbp dch -R --auto
c7045a8 version now set to 0.9.13
67d74fe (origin/master, origin/HEAD, master) ID checks for root summarized to REAL_ID, all tests affected
33f92f4 shunit2 test added to check real root vs. fakeroot
6540e16 (tag: debian/0.9.12) missing cloud-sptheme-common added -Build-Depends
...
hans@jhc ~/devel/opti debian/sid $
</pre>
<p>The '--git-retag' is neccessary, if the tag already exists.
All configuration for gbp buildpackage is done in ~/.gbb.conf like this:</p>
<pre class="literal-block">
[DEFAULT]
# tell git-buildpackage howto clean the source tree
cleaner = fakeroot debian/rules clean
# this is how we invoke pbuilder, arguments passed to git-buildpackage will be
# passed to dpkg-buildpackge in the chroot
builder = /usr/bin/git-pbuilder
#
sign-tags = True
keyid = 0x005ea2e3cff5a06f
#
debian-branch = debian/sid
upstream-branch = master
upstream-tag = v%(version)s
[buildpackage]
postbuild = lintian $GBP_CHANGES_FILE
cleaner = /bin/true
pbuilder = True
[dch]
meta = True
id-length = 7
full = True
git-author = True
multimaint-merge = True
# EoF
</pre>
<p>Of course, you need to initialize cowbuilder before starting with gbp buildpackage:</p>
<pre class="literal-block">
hans@jhc ~/devel/opti debian/sid $ DIST=jessie git-pbuilder create
...
hans@jhc ~/devel/opti debian/sid $
</pre>
<p>This creates a cowbuilder base image in /var/cache/pbuilder/base-jessie.cow/.
It is used as a chrooted build environment on each gbp buildpackage invocation...
One of its big advantages over dpkg-buildpackage is to verify the build-dependancies. If
something is missing, the build process will fail. The error messages show you
the reason. It's great!</p>
<p>The github <a class="reference external" href="https://github.com/sl0/opti">iptables-optimizer</a> repository is updated, prebuild debian and rpm
packages are waiting for your <a class="reference external" href="http://hubertz.de/downloads/">downloads</a>.</p>
<p>Your comments are welcome!</p>
<div class="section" id="have-fun">
<h3>Have fun!</h3>
</div>
</div>
log entry 2014-11-202014-11-20T19:57:00+01:002014-11-20T19:57:00+01:00Johannes Hubertztag:hubertz.de,2014-11-20:/blog/iptables-optimizer-8th.html<p class="first last">iptables-optimizer v0.9.12</p>
<div class="section" id="iptables-optimizer-version-0-9-12">
<h2>iptables-optimizer version 0.9.12</h2>
<p>My <a class="reference external" href="http://mentors.debian.net/sponsors">DS</a> made it happen: <a class="reference external" href="https://github.com/sl0/opti">iptables-optimizer</a> has reached
Debian experimental. Thank you very much, Guido!</p>
<p>It has been a long long way from my very first idea to end it up in Debian.
Especially the last changes and tests resulted in reliability. Finally, the
packaging works with gbp buildpackage and git-pbuilder, therefore I'm rather
sure about correct build-dependancies.</p>
<p>In near future I will be happy to present at
one of the upcoming <a class="reference external" href="https://wiki.fsfe.org/groups/Bonn">FSFE-Fellowship-meetings</a> at <a class="reference external" href="http://netzladen.org">Netzladen</a>, Bonn.</p>
<p>I hope to see you there.</p>
<p>Your comments are welcome!</p>
<div class="section" id="have-fun">
<h3>Have fun!</h3>
</div>
</div>
log entry 2014-09-262014-09-26T21:17:00+02:002014-09-26T21:17:00+02:00Johannes Hubertztag:hubertz.de,2014-09-26:/blog/work-one.html<p class="first last">relaunch of website</p>
<div class="section" id="relaunch-of-the-website">
<h2>relaunch of the website</h2>
<p>As I saw a beautiful website in my neighborhood, I was
inspired of a new design for my company <a class="reference external" href="http://hubertz.de">website</a>.</p>
<p>Asking about it I got very useful hints from one of their
very friendly webmasters. I was shown their account on github,
and then I spend another day in my life creating and beautifying
new my virtual home.</p>
<p>Thank you very much, <a class="reference external" href="http://trolug.de">TroLUG</a> has spent a wonderful template for a
well known documentation generator: <a class="reference external" href="http://sphinx-doc.org">Sphinx</a>, completely written in Python
and using reStructuredText and a pythonic configuration. TroLUG webmasters
were inspired by the <a class="reference external" href="http://matplotlib.org">matplotlib</a> webpage.</p>
<p>May the source be with you.</p>
<div class="section" id="have-fun">
<h3>Have fun!</h3>
</div>
</div>
log entry 2014-08-182014-08-18T11:17:00+02:002014-08-18T11:17:00+02:00Johannes Hubertztag:hubertz.de,2014-08-18:/blog/iptables-converter-8th.html<p class="first last">iptables-converter.deb 0.9.5-1 was uploaded to Debian</p>
<div class="section" id="iptables-converter-deb-new-version-has-arrived-in-debian-universe">
<h2>iptables-converter.deb new version has arrived in debian universe</h2>
<p>iptables-converter 0.9.5-1 has been uploaded by the ftp-masters
to the debian mirror servers. It will be visible in testing soon.</p>
<p>Due to the closed two bugs, Toni Mueller has uploaded the converters
new version. Binaries, source and documentation are available for
your convienience.</p>
<p>Comments, suggestions and bugs are welcome anytime.</p>
<p>May the source be with you.</p>
<div class="section" id="have-fun">
<h3>Have fun!</h3>
</div>
</div>
log entry 2014-08-152014-08-15T19:47:00+02:002014-08-15T19:47:00+02:00Johannes Hubertztag:hubertz.de,2014-08-15:/blog/iptables-optimizer-7th.html<p class="first last">iptables-optimizer v0.9.10</p>
<div class="section" id="iptables-optimizer-version-0-9-10">
<h2>iptables-optimizer version 0.9.10</h2>
<p>In the meantime, my initial ITP was converted to an RFP.</p>
<p>I am still working on the iptables-optimizer and its debianization.
A lot of todos are waiting to be done.</p>
<p>Some month ago Guido gave me a hint to <a class="reference external" href="http://code.google.com/p/shunit2/">shunit2</a>, a unittest framework for
shell scripts. So I played a little with it. Soon I was convinced, the
existing shell wrapper for the iptables-optimizer needs to be
rewritten completely.</p>
<p>As untested software is assumed to be broken by design nowadays, I began
writing tests for the wrappers functions. It is a work in progress,
testing is fun.</p>
<p>I started to write the functions and their parameters aside their corresponding tests.
Four steps are identified, four functions are needed:</p>
<pre class="literal-block">
check and apply new rules if present
iptables-save to a file
run the python script
iptables-restore the output of 3rd step
</pre>
<p>Most annoying is, every iptables command needs to be run by uid 0.
So all the tests need to be run by root as well as the optimizer itself.
Therefore the effective uid is tested as well and this test will inform
about missing access rights if it not equals to zero.</p>
<p>All these functions are tested by eleven different tests now:</p>
<pre class="literal-block">
test_AutoApply_Not_Present
test_AutoApply_Not_Ready
test_AutoApply_Ready
test_AutoApply_Execute
test_Needs_to_run_as_root
test_Modprobe_NetFilter
test_Good_iptables_save
test_Run_the_python_part
test_Bad_iptables_save
test_Correct_iptables_restore
test_Faulty_iptables_restore
</pre>
<p>For me some more work is still to be done, especially integrating
the tests and the source file (optimizer-functions) into
the debian package.</p>
<p>The new version of the <a class="reference external" href="https://github.com/sl0/opti">iptables-optimizer</a> will be uploaded when ready.</p>
<p>Many thanks to Kate Ward for writing <a class="reference external" href="http://code.google.com/p/shunit2/">shunit2</a>.</p>
<p>Your comments are welcome!</p>
<div class="section" id="have-fun">
<h3>Have fun!</h3>
</div>
</div>
log entry 2014-06-282014-06-28T23:01:00+02:002014-06-28T23:01:00+02:00Johannes Hubertztag:hubertz.de,2014-06-28:/blog/iptables-converter-7th.html<p class="first last">iptables-converter.deb now handles ipv6 as well</p>
<div class="section" id="iptables-converter-deb-enriched-by-similar-function-for-ipv6">
<h2>iptables-converter.deb enriched by similar function for IPv6</h2>
<p>iptables-converter 0.9.5-1 is released at <a class="reference external" href="https://github.com/sl0/conv">https://github.com/sl0/conv</a></p>
<p>Thanks to Toni Muellers comments and Guido Guenthers bugreports, the converter
is now able to handle shell functions and variables as an error.
From now on it is able to convert ip6tables commands read from a file as well.
Intermixing of iptables and ip6tables commands is not expected at all due to
the different commands for restoring them into the kernel.
The documentation package has been updated.</p>
<p>For your convienience a rpm package is available:</p>
<p><a class="reference external" href="http://hubertz.de/downloads/rpms/">http://hubertz.de/downloads/rpms/</a></p>
<p>The debian package in the testing universe will follow up,
for now the two .deb files are available. You may find them here:</p>
<p><a class="reference external" href="http://hubertz.de/downloads/debian/">http://hubertz.de/downloads/debian/</a></p>
<p>After you download you are encouraged to prove the checksums.</p>
<div class="section" id="have-fun">
<h3>Have fun!</h3>
</div>
</div>
log entry 2014-02-222014-02-22T23:42:00+01:002014-02-22T23:42:00+01:00Johannes Hubertztag:hubertz.de,2014-02-22:/blog/iptables-converter-6th.html<p class="first last">iptables-converter.deb has arrived in the Debian unstable universe</p>
<div class="section" id="iptables-converter-deb-has-arrived-in-the-debian-universe">
<h2>iptables-converter.deb has arrived in the Debian universe</h2>
<p>Thanks to Toni Mueller iptables-converter has reached
the Debian universe in its unstable flavour:</p>
<p><a class="reference external" href="https://packages.debian.org/unstable/iptables-converter">https://packages.debian.org/unstable/iptables-converter</a></p>
<p>iptables-converter changed its version number to 0.9.3-1 to
conform debian version numbering system.</p>
<p>The sources at github.com will be updated soon as a
pull-request has arrived...</p>
<div class="section" id="have-fun">
<h3>Have fun!</h3>
</div>
</div>
log entry 2013-09-092013-09-09T23:57:00+02:002013-09-09T23:57:00+02:00Johannes Hubertztag:hubertz.de,2013-09-09:/blog/iptables-optimizer-6th.html<p class="first last">iptables-optimizer v0.9.9</p>
<div class="section" id="iptables-optimizer-version-0-9-9">
<h2>iptables-optimizer version 0.9.9</h2>
<p><strong>Version 0.9.9</strong> is out. git-buildpackage is a wonderful tool.</p>
<p>And there is still something more left to be done...</p>
<p>Beautiful sphinx documentation is added, so there is more than
a brief manpage and the code to be explored. Especially an explanation
is given why the policy is invariant on exchanging rules in kernelspace.</p>
<p>Although the <a class="reference external" href="https://github.com/sl0/opti">iptables-optimizer</a> documentation source is free and readable at <a class="reference external" href="https://github.com/sl0/">github</a> you may
find ready to view my sphinx html output <a class="reference external" href="http://hubertz.de/documentation/opti">here</a> for your convienience.</p>
<p>As you may like it, similar documentation for my <a class="reference external" href="https://github.com/sl0/conv">iptables-converter</a> is prepared <a class="reference external" href="http://hubertz.de/documentation/conv">there</a> as well.</p>
<p>Your comments are welcome!</p>
<div class="section" id="have-fun">
<h3>Have fun!</h3>
</div>
</div>
log entry 2013-08-172013-08-17T23:57:00+02:002013-08-17T23:57:00+02:00Johannes Hubertztag:hubertz.de,2013-08-17:/blog/iptables-optimizer-5th.html<p class="first last">iptables-optimizer v0.9.8</p>
<div class="section" id="iptables-optimizer-version-0-9-8">
<h2>iptables-optimizer version 0.9.8</h2>
<p><strong>Version 0.9.8</strong> is out. git-buildpackage is a wonderful tool.</p>
<p>After some tries and errors with git-buildpackage it works quite well for me.
A lot of things were changed since the last post, which mentioned 0.9.1</p>
<p>The tests, especially those run by python3, were suspected to fool me. On looking
somehow deeper, I found that it might be a good idea to use 2to3 and then let
nosetests3 do the rest. So it was easy to modify tox.ini:</p>
<pre class="code text literal-block">
# Tox (http://tox.testrun.org/) is a tool for running tests
# in multiple virtualenvs. This configuration file will run the
# test suite on all supported python versions. To use it, "pip install tox"
# and then run "tox" from this directory.
[tox]
envlist = py26, py27, py32, pep8
[testenv]
commands = /usr/local/bin/nosetests
[testenv:py26]
basepython =
python2.6
commands =
python setup.py clean
python setup.py build
/usr/local/bin/nosetests -v iptables_optimizer_tests.py
[testenv:py27]
basepython =
python2.7
commands =
python setup.py clean
python setup.py build
/usr/local/bin/nosetests -v iptables_optimizer_tests.py
[testenv:py32]
basepython =
python3.2
commands =
/usr/bin/2to3 --add-suffix='3' -n -w ./iptables_optimizer.py
/usr/bin/python3.2 setup.py clean
/usr/bin/python3.2 setup.py build
/usr/bin/nosetests3 -v iptables_optimizer_tests.py
[testenv:pep8]
commands = /usr/local/bin/pep8 --show-pep8 --show-source iptables_optimizer.py
</pre>
<p>Now the tests work fine with python3:</p>
<pre class="code text literal-block">
hans@jha:~/gh/opti$ nosetests3 -v
Chain_Test: create a chainobject ... ok
Chain_Test: make partitions from no rules ... ok
Chain_Test: make partitions from one rule a ... ok
Chain_Test: make partitions from one rule d ... ok
Chain_Test: make partitions from one rule r ... ok
Chain_Test: make partitions from one rule l ... ok
Chain_Test: make partitions from two rules aa ... ok
Chain_Test: make partitions from two rules ad ... ok
Chain_Test: make partitions from five rules adaaa ... ok
Chain_Test: optimize an empty chainobject ... ok
Chain_Test: optimize three rules aaa ... ok
Chain_Test: optimize three rules aar ... ok
Chain_Test: optimize five rules aalaa ... ok
Filter_Test: non existant input-file ... ok
Filter_Test: read reference-input ... ok
Filter_Test: optimize, check 30 moves and partitions ... ok
Filter_Test: check output for reference-input ... ok
----------------------------------------------------------------------
Ran 17 tests in 0.037s
OK
hans@jha:~/gh/opti$
</pre>
<p>Invoking tox is simply done by issuing <strong>tox</strong> on the command line, it is rather verbose.
Therefore I only show the last few lines of output containing the results.</p>
<pre class="code text literal-block">
...
pep8 inst-nodeps: /home/hans/deb/opti/.tox/dist/iptables-optimizer-0.9.8.zip
pep8 runtests: commands[0]
___________________________________ summary ____________________________________
py26: commands succeeded
py27: commands succeeded
py32: commands succeeded
pep8: commands succeeded
congratulations :)
hans@jha:~/gh/opti$
</pre>
<p>Another interesting value is the rating of pylint:</p>
<blockquote>
Your code has been rated at 9.55/10*</blockquote>
<p>I'm happy with it.</p>
<p>Of course all the print statements and some error handling had to be rewritten for python3 compatibility, fortunately
python2.6 and 2.7 are able to understand the modified syntax.</p>
<p>Some other changes were done to satisfy debian needs:</p>
<blockquote>
<ol class="arabic simple">
<li><strong>reference-input</strong> and <strong>reference-output</strong> moved to <strong>/var/run/</strong></li>
<li><strong>auto-apply</strong> moved to <strong>/var/cache/iptables-optimizer</strong></li>
<li>Because the <strong>debian/prerm</strong> didn't remove the files for a <strong>dpkg --purge</strong> action,
Tim sent a patch which moves it to <strong>debian/postrm</strong>. Thank you very much, Tim.</li>
</ol>
</blockquote>
<p>Now it seems to work like wanted from the beginning, only a small thing is left:
Remove the deprecated dh_pysupport from then rules and get dh_python2 or dh_python3 instead.</p>
<p>Last week I found another starred repo named <a class="reference external" href="https://github.com/ldx/python-iptables">python-iptables</a> from Juliano Martinez, building a
pythonic interface to libiptc. Becoming familiar with it, external wrapper with iptables-save and -restore
might be obsoleted, and the ugly shell wrapper as well.
Seems to be interesting, only some time is needed.</p>
<p>So there is still something left to be done...</p>
<div class="section" id="have-fun">
<h3>Have fun!</h3>
</div>
</div>
log entry 2013-08-122013-08-12T23:55:00+02:002013-08-12T23:55:00+02:00Johannes Hubertztag:hubertz.de,2013-08-12:/blog/iptables-converter-5th.html<p class="first last">git-buildpackage creates iptables-converter.deb</p>
<div class="section" id="git-buildpackage-creates-iptables-converter-deb-v0-9-1">
<h2>git-buildpackage creates iptables-converter.deb v0.9.1</h2>
<p>The tests done by tox did not show any errors, unfortunately
the iptables_converter.py was not tested with python3 by
misconfiguration of tox. The
configuration for tox environment py32 had to prepare the python3
code. This led to some investigations, calling 2to3 and manual
modifications of the code. Especially the import UserDict had
to be modified, as in python3 there is no longer UserDict
available directly.
It was moved to collections and so the import
now comes in two versions depending on the first fails or not:</p>
<pre class="literal-block">
try:
from UserDict import UserDict
except ImportError:
from collections import UserDict
</pre>
<p>This now works for python 2.6, 2.7 and 3.2, which all are available in the
Debian wheezy universe nowadays.</p>
<p>The print statements had to be modified as well, a template was found by
using 2to3. The genius python creators have put some forward compatibility
into the 2.6 and 2.7 versions to understand the modified python3 syntax
of print as well. So this is easy going:</p>
<pre class="literal-block">
print "COMMIT"
print "# generated from: %s" % (fname)
</pre>
<p>became:</p>
<pre class="literal-block">
print("COMMIT")
print("# generated from: %s" % (fname))
</pre>
<p>As this syntax is compatible to both python2 and python3, it is preferred now.</p>
<p>Documentation is now delivered as a separate debian package. It is written
as reStructuredText and converted to HTML by sphinx. Beautiful.</p>
<p>So the git log comes quite short:</p>
<pre class="literal-block">
commit 47c4b01875e29ad90fdecd306fb58b7b89862213
Author: Johannes Hubertz <johannes@hubertz.de>
Date: Sun Aug 11 23:38:12 2013 +0200
gbp dch did the changelog
commit aadc8a376605efc1936b8c70e17ba1b06a4303a1
Author: Johannes Hubertz <johannes@hubertz.de>
Date: Sun Aug 11 23:36:32 2013 +0200
v0.9.1: tests are enhanced and rewritten, python3.2 now works
iptables-converter.py now compatible to python2.6, 2.7 and 3.2
Makefile: has new targets: rpm and deb
rpm is build py pyhton setup bdist_rpm
deb is build by git-buildpackage and pbuilder
deb creates two packages, binary and doc.
sphinx-config is adapted to test requirements
unittests are numbered now and show classname
</pre>
<p><a class="reference external" href="/downloads/debian">Debian</a> flavor packages of the iptables-converter are available,
<a class="reference external" href="/downloads/rpm">rpm</a> flavor may be found as well.</p>
<div class="section" id="have-fun">
<h3>Have fun!</h3>
</div>
</div>
log entry 2013-08-042013-08-04T12:55:00+02:002013-08-04T12:55:00+02:00Johannes Hubertztag:hubertz.de,2013-08-04:/blog/iptables-converter-4th.html<p class="first last">git-buildpackage creates iptables-converter.deb</p>
<div class="section" id="git-buildpackage-creates-iptables-converter-deb-v0-8">
<h2>git-buildpackage creates iptables-converter.deb v0.8</h2>
<p>As I want to have a wide platform to reach as many users as possible,
I intended to build .deb for iptables-converter. Then I learned some
useful details about git-buildpackage recently. Having started my project with a
git, it should be possible to adapt it to Guidos tool. It was an arousing
way of trials and errors. But finally it is easy going.</p>
<p>Of course you need the usual debian directory and some files there:</p>
<pre class="code text literal-block">
hans@jha:~/gh/conv$ ls -l debian/
total 32
-rw-r--r-- 1 hans hans 822 Aug 2 01:31 changelog
-rw-r--r-- 1 hans hans 2 Jul 23 09:06 compat
-rw-r--r-- 1 hans hans 531 Aug 2 01:40 control
-rw-r--r-- 1 hans hans 1074 Jul 23 09:06 copyright
-rw-r--r-- 1 hans hans 25 Jul 23 09:06 iptables-converter.manpages
-rw-r--r-- 1 hans hans 199 Jul 23 09:06 README.Debian
-rwxr-xr-x 1 hans hans 1024 Jul 23 09:03 rules
drwxr-xr-x 2 hans hans 4096 Jul 23 09:06 source
hans@jha:~/gh/conv$
</pre>
<p>Most of these files are necessary for building a debian packet. Especially
the control file describes some essentials about the .deb:</p>
<pre class="code text literal-block">
Source: iptables-converter
Maintainer: Johannes Hubertz <johannes@hubertz.de>
Section: utils
Priority: optional
Build-Depends: python-all-dev (>= 2.6.6-3-), debhelper (>= 9), python-support
Standards-Version: 3.9.3
Package: iptables-converter
Architecture: all
Depends: ${misc:Depends}, ${python:Depends}, ${sphinxdoc:Depends}
Description: convert set of iptables-commands to iptables-save format
iptables_converter.py: convert iptables in a script to iptables-save
readable format to stdout with [0:0] for iptables-restore -c
</pre>
<p>Within the rules file, which is a makefile, the necessary steps to produce
the .deb are mentioned. The debhelper scripts may be called here. For
tests, debuild may be run in the main directory, it should be able to produce
a .deb file quickly. But everything must be done by hand, that's unwanted.</p>
<p>git-buildpackage works with the master branch or with the debian branch, if
master is upstream. Being upstream, the master branch will do. Tags are
required as configured in gbp.conf:</p>
<pre class="literal-block">
upstream-tag = v%(version)s
</pre>
<p>Here are my tags from the actual git repository:</p>
<pre class="code text literal-block">
hans@jha:~/gh/conv$ git tag -l
v0.6
v0.7
v0.8
</pre>
<p>Annotations are useful, see one as an example:</p>
<pre class="code text literal-block">
hans@jha:~/gh/conv$ git tag -v v0.7
object f10c3ab221458d762579b392f609a2534d21df6e
type commit
tag v0.7
tagger Johannes Hubertz <johannes@hubertz.de> 1374354728 +0200
version 0.7
Thanks: Guido Guenther and Toni Mueller gave very useful hints to do it.
gpg: Unterschrift vom Sa 20 Jul 2013 23:12:10 CEST mittels RSA-Schlüssel ID 8857914A
gpg: Korrekte Unterschrift von "Johannes Hubertz <johannes@hubertz.de>"
gpg: alias "Johannes <johannes@guug.de>"
</pre>
<p>When the source is ready to be released, a changelog entry can be done very easily:</p>
<pre class="literal-block">
gbp dch --release --auto
</pre>
<p>This will sample all the commit logs headlines since the last release and format
them correctly within the debian/changelog on top:</p>
<pre class="literal-block">
iptables-converter (0.8) unstable; urgency=low
* [20c2ed1] manpages also renamed
* [569fdb5] renaming included the deletion of the old file
* [240c595] copy .py to pyshared as well
* [f10c3ab] dh_python necessary for dependencies
* [86be17f] dh_python replaced by python-support reasoned by squeeze install
* [d4be880] Version changed to 0.8
-- Johannes Hubertz <johannes@hubertz.de> Fri, 02 Aug 2013 00:50:59 +0200
iptables-converter (0.7) unstable; urgency=low
...
</pre>
<p>Now the packaging process may be started using gbp:</p>
<pre class="literal-block">
gbp buildpackage --git-pbuilder
</pre>
<p>A lot of output is presented, finally the usual suspects are produced in the
next upper directory:</p>
<pre class="literal-block">
hans@jha:~/gh/conv$ ls -l ../iptables-converter_0.8*
-rw-r--r-- 1 hans hans 6430 Aug 4 10:53 ../iptables-converter_0.8_all.deb
-rw-r--r-- 1 hans hans 20771 Aug 4 10:53 ../iptables-converter_0.8_amd64.build
-rw-r--r-- 1 hans hans 1572 Aug 4 10:53 ../iptables-converter_0.8_amd64.changes
-rw-r--r-- 1 hans hans 608 Aug 4 10:53 ../iptables-converter_0.8.dsc
-rw-r--r-- 1 hans hans 27491 Aug 4 10:53 ../iptables-converter_0.8.tar.gz
</pre>
<p>The .build is the logged output of the build process, as well the desired debian package is on file.
As root a test can give a proof:</p>
<pre class="literal-block">
root@jha:/home/hans/gh/conv# dpkg -i ../iptables-converter_0.8_all.deb
Selecting previously unselected package iptables-converter.
(Reading database ... 223084 files and directories currently installed.)
Unpacking iptables-converter (from .../iptables-converter_0.8_all.deb) ...
Setting up iptables-converter (0.8) ...
Processing triggers for man-db ...
root@jha:/home/hans/gh/conv#
</pre>
<p>Of course it is interesting, which files belong to the package:</p>
<pre class="literal-block">
root@jha:/home/hans/gh/conv# dpkg -L iptables-converter
/.
/usr
/usr/share
/usr/share/python-support
/usr/share/python-support/iptables-converter.public
/usr/share/man
/usr/share/man/man8
/usr/share/man/man8/iptables-converter.8.gz
/usr/share/pyshared
/usr/share/pyshared/iptables_converter.py
/usr/share/doc
/usr/share/doc/iptables-converter
/usr/share/doc/iptables-converter/copyright
/usr/share/doc/iptables-converter/README.Debian
/usr/share/doc/iptables-converter/changelog.gz
/usr/sbin
/usr/sbin/iptables-converter
</pre>
<p>It is so easy to have fun with Debian, git-buildpackage is a great tool.
A prebuild <a class="reference external" href="/downloads/debian">package</a> of the iptables-converter is available for your convenience.</p>
<p>Ah, you ask for other package management systems like rpm? The python setup.py
already gives a chance to have a .rpm, if the rpm package is installed on your
Debian system. These are available for download <a class="reference external" href="/downloads/rpm">here</a>.</p>
<div class="section" id="have-fun">
<h3>Have fun!</h3>
</div>
</div>
log entry 2013-07-312013-07-31T22:13:00+02:002013-07-31T22:13:00+02:00Johannes Hubertztag:hubertz.de,2013-07-31:/blog/fsfe-c3d.html<p class="first last">fsfe-felloship meeting in Dusseldorf</p>
<a class="reference external image-reference" href="http://wiki.fsfe.org/groups/Duesseldorf"><img alt="plussy" src="/blog/img/plussy-sticker.png" style="height: 50.0px;" /></a>
<div class="section" id="fsfe-and-relativity">
<h2>FSFE and relativity</h2>
<p>Today Frank gives a talk for the <a class="reference external" href="http://fsfe.org/fellowship/">FSFE-Fellowship</a> in <a class="reference external" href="http://chaosdorf.de">Chaosdorf</a>, Dusseldorf.</p>
<p><strong>Title: Vom Pythagoras zur speziellen Relativitästheorie</strong></p>
<p>As a prerequisite he asks for some basic calulation capabilities within the participiants,
then we are shown some graphical proof of the well known pythagoraen sentence a² + b² = c².
Next we are introduced into the thinking of playing bowling in a running train. So we have
two inertial systems with a viewer each, one in move and one kept still. The bowl is moved in
the same direction the train moves. The simple addition of the two speeds is best known as
Galilei transformation. A small step forward exchanges the bowl with a light or a flash. And,
surprisingly, the speed of light keeps the same regardless of its own inertial system and
the viewers. Thats the basis of relativity: speed of light is a universal constant.</p>
<p>He continues with showing time dilatition, which comes to relevance only if speed is nearby
the speed of light. So in normal life, we do not mention anything about it. And soon we are
introduced to Lorentz transformation.</p>
<p>Anyhow, if you are moved in relation to me, we both will see each others watch slower than our
own. Of course this effect is visible only at speeds nearby the speed of light. Confusing,
isn't it?</p>
<p>Few minutes later we arrive at E = mc² which was found by Albert <a class="reference external" href="http://en.wikipedia.org/wiki/Albert_Einstein">Einstein</a>.</p>
<p>Some discussion for clearification followed ...</p>
<p>Frank, thank you for preparing the talk. We saw beautiful beamer slides and heard nice wording.
<a class="reference external" href="http://chaosdorf.de">Chaosdorf</a> seems to be worth for coming again ...</p>
</div>
log entry 2013-07-142013-07-14T11:13:00+02:002013-07-14T11:13:00+02:00Johannes Hubertztag:hubertz.de,2013-07-14:/blog/git-buildpackage-workshop.html<p class="first last">git-buildpackage explained by Guido</p>
<a class="reference external image-reference" href="https://wiki.debian.org/PackagingWithGit"><img alt="debian" src="/blog/img/debian-openlogo-nd-100.jpg" style="height: 50.0px;" /></a>
<div class="section" id="participation-at-guidos-introduction-to-his-git-buildpackage">
<h2>Participation at Guidos introduction to his git-buildpackage</h2>
<p>Yesterday Guido invited for his beginners course on git-buildpackage.
Some very nice people met together, it has been an arousing event.
First he gave us a beautiful introduction on his tool, nice beamer slides
have been prepared and the afternoon was very short for the mass of
information. At the end I understood a lot more of the thinking behind
and was able to adapt this to my repositories. There are two for now,
iptables-converter and iptables-optimizer. adm6 still has to wait for
being debianized.</p>
<p>The beamer and tutorial session was put on held for a short break for
a some good barbecue food. Later the session was continued for another
hour or two. Great summer wheather and the very kind debian people
made a wonderful day in my life. The new knowledge will need to settle
down for a while...</p>
<p>Guido, thank you very much for your enlightening workshop!</p>
</div>
log entry 2013-06-242013-06-24T23:57:00+02:002013-06-24T23:57:00+02:00Johannes Hubertztag:hubertz.de,2013-06-24:/blog/iptables-optimizer-4th.html<p class="first last">iptables-optimizer tested</p>
<div class="section" id="iptables-optimizer-version-0-9-1">
<h2>iptables-optimizer version 0.9.1</h2>
<p><strong>Version 0.9.1</strong> is out. Debianization started.</p>
<p>Debuild is working well. But I'm unhappy with it, too many manual actions needed.
I'm dreaming of git-buildpackage, because it's in a git repository already. Guidos gbp might
be a big step forward.</p>
<p>The ITP was issued:</p>
<pre class="code bash literal-block">
Package: wnpp
Severity: wishlist
Owner: Johannes Hubertz <johannes@hubertz.de>
* Package name : python-iptables-optimizer
Version : 0.9.1
Upstream Author : Johannes Hubertz <johannes@hubertz.de>
* URL : https://github.com/sl0/opti.git
* License : GPL3
Programming Lang: Python
Description : sort iptables due to packet-counters
</pre>
<p>It was acknowledged as Bug#714021 by the Debian team.</p>
<p>The software is working and by using debuild produces a Debian package.
Using setup.py you can build a rpm package. What should I want more?</p>
<p><strong>Thanks to the Debian team!</strong></p>
<div class="section" id="have-fun">
<h3>Have fun!</h3>
</div>
</div>
log entry 2013-06-142013-06-14T21:31:00+02:002013-06-14T21:31:00+02:00Johannes Hubertztag:hubertz.de,2013-06-14:/blog/iptables-converter-3rd.html<p class="first last">iptables-converter</p>
<div class="section" id="iptables-converter-startup-to-debian-universe">
<h2>iptables-converter startup to Debian universe</h2>
<blockquote>
<pre class="code bash literal-block">
Package: wnpp
Severity: wishlist
Owner: Johannes Hubertz <johannes@hubertz.de>
* Package name : python-iptables-converter
Version : 0.6
Upstream Author : Johannes Hubertz <johannes@hubertz.de>
* URL : https://github.com/sl0/conv.git
* License : GPL
Programming Lang: Python
Description : convert <span class="nb">set</span> of iptables-commands to iptables-save format
</pre>
</blockquote>
<p>The bugreport was acknowledged as Bug#712263 on June 14th, 2013.</p>
<p><strong>Thanks to the Debian team.</strong></p>
<p>The software is working and by using debuild produces a Debian package.
Using setup.py you can build a rpm package. What should I want more?</p>
<div class="section" id="have-fun">
<h3>Have fun!</h3>
</div>
</div>
log entry 2013-05-062013-05-06T22:13:00+02:002013-05-06T22:13:00+02:00Johannes Hubertztag:hubertz.de,2013-05-06:/blog/pythoncamp2013.html<p class="first last">my second pythoncamp</p>
<a class="reference external image-reference" href="http://pythoncamp.de"><img alt="Pythoncamp.de" src="/blog/img/pythoncamp-logo.png" style="height: 50.0px;" /></a>
<div class="section" id="my-second-pythoncamp-participation">
<h2>My second pythoncamp participation</h2>
<p>Again a two days barcamp was organized by pycologne.de, the cologne python user group.
It was great fun to be on the sponsors list, too.</p>
<p>On Saturday we started at about 0930 local time at GFU Cyrus AG (<a class="reference external" href="http://www.gfu.net">http://www.gfu.net</a>) in Cologne.
About 25 people attended. 2 Days filled up with pythonic talks, turorials and discussions.</p>
<p><a class="reference external" href="http://tox.readthedocs.org/">http://tox.readthedocs.org/</a> I was pointed to by Andi, he is always testing his projects with this tool.
This is a wonderful testsuite for running python unittests on almost any python version.
I preferred python 2.6, 2.7 and 3.2 as these are available on my different Debian machines.</p>
<p>So I found out: There's a lot to do with my python scripts. Anyhow, pythoncamp was a big fun again.</p>
<p><a class="reference external" href="http://pycologne.de">http://pycologne.de</a> will repeat the wonderful event next year, I'm rather sure.</p>
</div>
log entry 2013-04-192013-04-19T19:31:00+02:002013-04-19T19:31:00+02:00Johannes Hubertztag:hubertz.de,2013-04-19:/blog/iptables-optimizer-3rd.html<p class="first last">iptables-optimizer enhanced</p>
<div class="section" id="iptables-optimizer-version-0-9">
<h2>iptables-optimizer version 0.9</h2>
<p><strong>Version 0.9</strong> is out.</p>
<p>The main advantages are:</p>
<blockquote>
<ol class="arabic simple">
<li>Partitiontables are printed to stderr by the python script.</li>
<li>undef policies each are a single partition</li>
<li>filter.show is completely rewritten for testablility</li>
</ol>
</blockquote>
<p>If the wrapper is called with any parameter, usually <strong>-v</strong>, it logs
the partitiontable to syslog. This is a good chance to see what is going on in the chains every run of the iptables-optimizer:</p>
<pre class="literal-block">
#chainname : moves partitions
#INPUT : 4 [1, 41][42, 53][54, 54]
#OUTPUT : 4 [1, 42][43, 54][55, 55]
#logdrop : 0 [1, 1][2, 2]
</pre>
<p>The column titled with <em>chainname</em> just names the chain described in this output line.
<em>moves</em> is the count of rules, which changed their position within the chain.
Within in the paired brackets the numbers show start and end of each partition, the number of
opening brackets corresponds to the number of partitions in this chain.</p>
<p>These numbers are explained easily, they are reasoned by:
(partitionlength = partiton-end - partition-start + 1)</p>
<pre class="code bash literal-block">
chain length action<span class="o">(</span>s<span class="o">)</span>
INPUT <span class="m">41</span> -j ACCEPT
INPUT <span class="m">11</span> -j DROP
INPUT <span class="m">1</span> -j logdrop
OUTPUT <span class="m">42</span> -j ACCEPT
OUTPUT <span class="m">11</span> -j DROP
OUTPUT <span class="m">1</span> -j logdrop
logdrop <span class="m">1</span> -j LOG
logdrop <span class="m">1</span> -j DROP
</pre>
<p>Each line shows a partition in the way of thinking of iptables-optimizer. The
pattern matching part of each rule is not important for it. Just the action
part destinguishes which partition it belongs to. As a result, exchanging rules
within a partition does not change security matters, just performance. Partition
borders must not be changed in position or traversed on iptables-optimizer
operations. Therefore the creation of the partitions is subject to the extensive tests.</p>
<p>The rules for dropping packets are for minimizing the logs, of course. This example is taken from
a dns- and mailserver.</p>
<p>In the last weeks I got out, different python versions have different opinions about
working with the subprocess module. As the iptables-optimizer didn't work on squeeze
(python2.6) because it was written on wheezy (python2.7) I started some investigations.
At last, for me the minor difficult solution
was to remove all the subprocess calls and to keep the file operations pythonic only.
All the rest, iptables-save, iptables-restore and logging is done in a shell wrapper now.
At the pythoncamp I learned something about tox, which was soon adapted to
iptables-optimizer. Now the tests show good results with python versions 2.6, 2.7 and 3.2.</p>
<p>So iptables-optimizer grew to a robust and good performing tool and can be called every minute.</p>
<p>Have fun!</p>
</div>
log entry 2013-03-022013-03-02T11:23:00+01:002013-03-02T11:23:00+01:00Johannes Hubertztag:hubertz.de,2013-03-02:/blog/iptables-converter-2nd.html<p class="first last">iptables-converter</p>
<div class="section" id="iptables-converter-92-tested">
<h2>iptables-converter 92% tested</h2>
<p>Reading the <strong>Python Testing Cookbook</strong> enlightend me, it was a big fun and
had to be adapted to the real world example. Started to write tests
for my iptables-converter in late feburary, yesterday it was finalized
by achieving a coverage of 92% of the code. I assumed this value to be enough.</p>
<blockquote>
<pre class="code bash literal-block">
hans@jhx:~/gh/conv$ nosetests -v --with-coverage
create a Filter group, f.e. filter ... ok
check <span class="m">3</span> valid policies, <span class="m">1</span> exception ... ok
<span class="m">3</span> cases OK, <span class="m">1</span> Exception ... ok
flush filter group, <span class="m">2</span> rules and an invalid chain ... ok
create a new chain in filtergroup, ... ok
insert a rule into an empty chain fails ... ok
insert a rule into a non_existing chain fails ... ok
insert a rule into a nonempty chain works at start ... ok
append a rule to a chain ... ok
try to remove a prefined chain ... ok
try to remove a nonexisting chain ... ok
try to remove an existing chain ... ok
try an ilegal <span class="nb">command</span> ... ok
create a Tables object, check chains ... ok
nat PREROUTING entry ... ok
mangle INPUT entry ... ok
raw OUTPUT entry ... ok
INPUT to not existing chain ... ok
<span class="nb">read</span> non existing file ... ok
<span class="nb">read</span> default file: reference-one, check chains ... ok
procedure main ... ok
Name Stmts Miss Cover Missing
-------------------------------------
conv <span class="m">177</span> <span class="m">15</span> 92% 219, 228-246, 250-251
----------------------------------------------------------------------
Ran <span class="m">21</span> tests in 0.038s
OK
</pre>
</blockquote>
<p>To have reliable results, every method of the two classes is checked at least
once, for an overall check a reference file is written:</p>
<blockquote>
<pre class="code bash literal-block">
hans@jhx:~/gh/conv$ nosetests -v --with-coverage
iptables -F
iptables -t nat -F
iptables -N USER_CHAIN
iptables -A INPUT -p tcp --dport <span class="m">23</span> -j ACCEPT
iptables -A USER_CHAIN -p icmp -j DROP
iptables -P INPUT DROP
iptables -t nat -A POSTROUTING -s 10.0.0.0/21 -p tcp --dport <span class="m">80</span> -j SNAT --to-source 192.168.1.15
iptables -t nat -A PREROUTING -d 192.0.2.5/32 -p tcp --dport <span class="m">443</span> -j DNAT --to-destination 10.0.0.5:1500
</pre>
</blockquote>
<p>The <tt class="docutils literal">iptables_converter.py</tt> reads this file and produces corresponding output
after having reached the end of it. Comparing the output to the hardcoded
reference within the testroutine should show no difference.</p>
<p>The produced output looks like:</p>
<blockquote>
<pre class="code bash literal-block">
hans@jhx:~/gh/conv$ python conv.py -s reference-one
*raw
:OUTPUT ACCEPT <span class="o">[</span>0:0<span class="o">]</span>
:PREROUTING ACCEPT <span class="o">[</span>0:0<span class="o">]</span>
COMMIT
*nat
:OUTPUT ACCEPT <span class="o">[</span>0:0<span class="o">]</span>
:PREROUTING ACCEPT <span class="o">[</span>0:0<span class="o">]</span>
:POSTROUTING ACCEPT <span class="o">[</span>0:0<span class="o">]</span>
-A PREROUTING -d 192.0.2.5/32 -p tcp --dport <span class="m">443</span> -j DNAT --to-destination 10.0.0.5:1500
-A POSTROUTING -s 10.0.0.0/21 -p tcp --dport <span class="m">80</span> -j SNAT --to-source 192.168.1.15
COMMIT
*mangle
:FORWARD ACCEPT <span class="o">[</span>0:0<span class="o">]</span>
:INPUT ACCEPT <span class="o">[</span>0:0<span class="o">]</span>
:POSTROUTING ACCEPT <span class="o">[</span>0:0<span class="o">]</span>
:PREROUTING ACCEPT <span class="o">[</span>0:0<span class="o">]</span>
:OUTPUT ACCEPT <span class="o">[</span>0:0<span class="o">]</span>
COMMIT
*filter
:FORWARD ACCEPT <span class="o">[</span>0:0<span class="o">]</span>
:INPUT DROP <span class="o">[</span>0:0<span class="o">]</span>
:USER_CHAIN - <span class="o">[</span>0:0<span class="o">]</span>
:OUTPUT ACCEPT <span class="o">[</span>0:0<span class="o">]</span>
-A INPUT -p tcp --dport <span class="m">23</span> -j ACCEPT
-A USER_CHAIN -p icmp -j DROP
COMMIT
</pre>
</blockquote>
<p>Writing these tests was funny. It's a good idea to understand what's going on.
So lets dive into the tests a little bit:</p>
<blockquote>
<pre class="code python literal-block">
<span class="ch">#!/usr/bin/env python</span>
<span class="c1">#encoding:utf8</span>
<span class="kn">from</span> <span class="nn">conv</span> <span class="kn">import</span> <span class="n">Chains</span><span class="p">,</span> <span class="n">Tables</span><span class="p">,</span> <span class="n">main</span> <span class="k">as</span> <span class="n">haupt</span>
<span class="kn">import</span> <span class="nn">unittest</span>
<span class="k">class</span> <span class="nc">Chains_Test</span><span class="p">(</span><span class="n">unittest</span><span class="o">.</span><span class="n">TestCase</span><span class="p">):</span>
<span class="sd">'''some tests for class Chain'''</span>
<span class="k">def</span> <span class="nf">test_01_create_a_chain_object</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">"""
create a Filter group, f.e. filter
"""</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertIsInstance</span><span class="p">(</span><span class="n">Chains</span><span class="p">(</span><span class="s2">"filter"</span><span class="p">,</span> \
<span class="p">[</span><span class="s2">"INPUT"</span><span class="p">,</span> <span class="s2">"FORWARD"</span><span class="p">,</span> <span class="s2">"OUTPUT"</span><span class="p">]),</span> <span class="n">Chains</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertEquals</span><span class="p">({},</span> <span class="n">Chains</span><span class="p">(</span><span class="s2">"filter"</span><span class="p">,</span> <span class="p">[]))</span>
<span class="nb">filter</span> <span class="o">=</span> <span class="n">Chains</span><span class="p">(</span><span class="s2">"filter"</span><span class="p">,</span> <span class="p">[</span><span class="s2">"INPUT"</span><span class="p">,</span> <span class="s2">"FORWARD"</span><span class="p">,</span> <span class="s2">"OUTPUT"</span><span class="p">])</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertEquals</span><span class="p">(</span><span class="s2">"filter"</span><span class="p">,</span> <span class="nb">filter</span><span class="o">.</span><span class="n">name</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertEquals</span><span class="p">([</span><span class="s1">'INPUT'</span><span class="p">,</span> <span class="s1">'FORWARD'</span><span class="p">,</span> <span class="s1">'OUTPUT'</span><span class="p">],</span> <span class="nb">filter</span><span class="o">.</span><span class="n">tables</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertEquals</span><span class="p">(</span><span class="s2">"-"</span><span class="p">,</span> <span class="nb">filter</span><span class="o">.</span><span class="n">policy</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertEquals</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="nb">filter</span><span class="o">.</span><span class="n">length</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertEquals</span><span class="p">(</span> \
<span class="p">{</span><span class="s1">'FORWARD'</span><span class="p">:</span> <span class="s1">'ACCEPT'</span><span class="p">,</span> <span class="s1">'INPUT'</span><span class="p">:</span> <span class="s1">'ACCEPT'</span><span class="p">,</span> <span class="s1">'OUTPUT'</span><span class="p">:</span> <span class="s1">'ACCEPT'</span><span class="p">},</span> \
<span class="nb">filter</span><span class="o">.</span><span class="n">poli</span><span class="p">)</span>
<span class="o">...</span>
</pre>
</blockquote>
<p>The first test tries to instanciate an object of class Chains(), it's name is <em>filter</em> and
it shall have some prefined chains, i.e. <em>["INPUT", "FORWARD", "OUTPUT"]</em>. The second
assertion tests, if an empty dictionary equals to an instance of class Chains with no
prefedined chains. Then an object is instanciated from class Chains with the prefined chains
of a linuxkernel, then test, if it's name is <em>filter</em> an controls the names of the chains, their policy
and their length. At last the dictionary is checked in the filter object, where the policies are kept.</p>
<blockquote>
<pre class="code python literal-block">
<span class="o">...</span>
<span class="k">def</span> <span class="nf">test_02_prove_policies</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">"""
check 3 valid policies, 1 exception
"""</span>
<span class="nb">filter</span> <span class="o">=</span> <span class="n">Chains</span><span class="p">(</span><span class="s2">"filter"</span><span class="p">,</span> <span class="p">[</span><span class="s2">"INPUT"</span><span class="p">,</span> <span class="s2">"FORWARD"</span><span class="p">,</span> <span class="s2">"OUTPUT"</span><span class="p">])</span>
<span class="nb">filter</span><span class="o">.</span><span class="n">put_into_fgr</span><span class="p">(</span><span class="s2">"-P INPUT DROP"</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertEquals</span><span class="p">(</span> \
<span class="p">{</span><span class="s1">'FORWARD'</span><span class="p">:</span> <span class="s1">'ACCEPT'</span><span class="p">,</span> <span class="s1">'INPUT'</span><span class="p">:</span> <span class="s1">'DROP'</span><span class="p">,</span> <span class="s1">'OUTPUT'</span><span class="p">:</span> <span class="s1">'ACCEPT'</span><span class="p">},</span> \
<span class="nb">filter</span><span class="o">.</span><span class="n">poli</span><span class="p">)</span>
<span class="nb">filter</span><span class="o">.</span><span class="n">put_into_fgr</span><span class="p">(</span><span class="s2">"-P FORWARD REJECT"</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertEquals</span><span class="p">(</span> \
<span class="p">{</span><span class="s1">'FORWARD'</span><span class="p">:</span> <span class="s1">'REJECT'</span><span class="p">,</span> <span class="s1">'INPUT'</span><span class="p">:</span> <span class="s1">'DROP'</span><span class="p">,</span> <span class="s1">'OUTPUT'</span><span class="p">:</span> <span class="s1">'ACCEPT'</span><span class="p">},</span> \
<span class="nb">filter</span><span class="o">.</span><span class="n">poli</span><span class="p">)</span>
<span class="nb">filter</span><span class="o">.</span><span class="n">put_into_fgr</span><span class="p">(</span><span class="s2">"-P OUTPUT DROP"</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertEquals</span><span class="p">(</span> \
<span class="p">{</span><span class="s1">'FORWARD'</span><span class="p">:</span> <span class="s1">'REJECT'</span><span class="p">,</span> <span class="s1">'INPUT'</span><span class="p">:</span> <span class="s1">'DROP'</span><span class="p">,</span> <span class="s1">'OUTPUT'</span><span class="p">:</span> <span class="s1">'DROP'</span><span class="p">},</span> \
<span class="nb">filter</span><span class="o">.</span><span class="n">poli</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertRaises</span><span class="p">(</span><span class="ne">ValueError</span><span class="p">,</span> <span class="nb">filter</span><span class="o">.</span><span class="n">put_into_fgr</span><span class="p">,</span> <span class="s2">"-P OUTPUT FAIL"</span><span class="p">)</span>
</pre>
</blockquote>
<p>The second test proofs the possible policies, which are predfined by the kernel. An invalid
policy is checked to raise an exception. This seems to be necessary to prevent the
user from unexpected misbehavior of the converter.</p>
<blockquote>
<pre class="code python literal-block">
<span class="o">...</span>
<span class="k">def</span> <span class="nf">test_03_tables_names</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">"""
3 cases OK, 1 Exception
"""</span>
<span class="nb">filter</span> <span class="o">=</span> <span class="n">Chains</span><span class="p">(</span><span class="s2">"filter"</span><span class="p">,</span> <span class="p">[</span><span class="s2">"INPUT"</span><span class="p">,</span> <span class="s2">"FORWARD"</span><span class="p">,</span> <span class="s2">"OUTPUT"</span><span class="p">])</span>
<span class="nb">filter</span><span class="o">.</span><span class="n">put_into_fgr</span><span class="p">(</span><span class="s2">"-t filter -A INPUT -i sl0 -j ACCEPT"</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertEquals</span><span class="p">([</span><span class="s1">'-A INPUT -i sl0 -j ACCEPT '</span><span class="p">],</span> <span class="nb">filter</span><span class="o">.</span><span class="n">data</span><span class="p">[</span><span class="s2">"INPUT"</span><span class="p">])</span>
<span class="nb">filter</span> <span class="o">=</span> <span class="n">Chains</span><span class="p">(</span><span class="s2">"filter"</span><span class="p">,</span> <span class="p">[</span><span class="s2">"INPUT"</span><span class="p">,</span> <span class="s2">"FORWARD"</span><span class="p">,</span> <span class="s2">"OUTPUT"</span><span class="p">])</span>
<span class="nb">filter</span><span class="o">.</span><span class="n">put_into_fgr</span><span class="p">(</span><span class="s2">"-t nat -A OUTPUT -j ACCEPT"</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertEquals</span><span class="p">([</span><span class="s1">'-A OUTPUT -j ACCEPT '</span><span class="p">],</span> <span class="nb">filter</span><span class="o">.</span><span class="n">data</span><span class="p">[</span><span class="s2">"OUTPUT"</span><span class="p">])</span>
<span class="nb">filter</span><span class="o">.</span><span class="n">put_into_fgr</span><span class="p">(</span><span class="s2">"-t nat -A FORWARD -j ACCEPT"</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertEquals</span><span class="p">([</span><span class="s1">'-A FORWARD -j ACCEPT '</span><span class="p">],</span> <span class="nb">filter</span><span class="o">.</span><span class="n">data</span><span class="p">[</span><span class="s2">"FORWARD"</span><span class="p">])</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertRaises</span><span class="p">(</span><span class="ne">ValueError</span><span class="p">,</span> <span class="nb">filter</span><span class="o">.</span><span class="n">put_into_fgr</span><span class="p">,</span> <span class="s2">"-t na -A INPUT"</span><span class="p">)</span>
</pre>
</blockquote>
<p>Here first append to the INPUT filter chain is checked, exactly the same is done
on the OUTPUT and FORWARD filter chains. A try to do it on an invalid group <em>na</em>
necessarily fails, the exception is expected.</p>
<p>...</p>
<p>Userdefined chains creation and deletion is tested, inserting rules into an empty
chain also is expected to fail. To append a rule into a nonempty chain is checked
also. Some more checks are done, even an illegal command is proofed to raise an
exception.</p>
<p>And of course, the tables class is tested as well:</p>
<blockquote>
<pre class="code python literal-block">
<span class="k">class</span> <span class="nc">Tables_Test</span><span class="p">(</span><span class="n">unittest</span><span class="o">.</span><span class="n">TestCase</span><span class="p">):</span>
<span class="sd">'''
Tables: some first tests for the class
'''</span>
<span class="k">def</span> <span class="nf">test_01_create_a_tables_object</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">"""
create a Tables object, check chains
"""</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertIsInstance</span><span class="p">(</span><span class="n">Tables</span><span class="p">(</span><span class="s2">""</span><span class="p">),</span> <span class="n">Tables</span><span class="p">)</span>
<span class="n">tables</span> <span class="o">=</span> <span class="n">Tables</span><span class="p">(</span><span class="s2">""</span><span class="p">)</span>
<span class="n">expect</span> <span class="o">=</span> <span class="p">{</span><span class="s1">'filter'</span><span class="p">:</span> <span class="p">{</span><span class="s1">'FORWARD'</span><span class="p">:</span> <span class="p">[],</span> <span class="s1">'INPUT'</span><span class="p">:</span> <span class="p">[],</span> <span class="s1">'OUTPUT'</span><span class="p">:</span> <span class="p">[]},</span> \
<span class="s1">'raw'</span><span class="p">:</span> <span class="p">{</span><span class="s1">'OUTPUT'</span><span class="p">:</span> <span class="p">[],</span> <span class="s1">'PREROUTING'</span><span class="p">:</span> <span class="p">[]},</span> \
<span class="s1">'mangle'</span><span class="p">:</span> <span class="p">{</span><span class="s1">'FORWARD'</span><span class="p">:</span> <span class="p">[],</span> <span class="s1">'INPUT'</span><span class="p">:</span> <span class="p">[],</span> \
<span class="s1">'POSTROUTING'</span><span class="p">:</span> <span class="p">[],</span> <span class="s1">'PREROUTING'</span><span class="p">:</span> <span class="p">[],</span> <span class="s1">'OUTPUT'</span><span class="p">:</span> <span class="p">[]},</span> \
<span class="s1">'nat'</span><span class="p">:</span> <span class="p">{</span><span class="s1">'OUTPUT'</span><span class="p">:</span> <span class="p">[],</span> <span class="s1">'PREROUTING'</span><span class="p">:</span> <span class="p">[],</span> <span class="s1">'POSTROUTING'</span><span class="p">:</span> <span class="p">[]}}</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertEquals</span><span class="p">(</span><span class="n">expect</span><span class="p">,</span> <span class="n">tables</span><span class="o">.</span><span class="n">data</span><span class="p">)</span>
</pre>
</blockquote>
<p>Are all the prefined chains build from scratch?</p>
<blockquote>
<pre class="code python literal-block">
<span class="o">...</span>
<span class="k">def</span> <span class="nf">test_02_nat_prerouting</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">"""
nat PREROUTING entry
"""</span>
<span class="n">tables</span> <span class="o">=</span> <span class="n">Tables</span><span class="p">(</span><span class="s2">""</span><span class="p">)</span>
<span class="n">line</span> <span class="o">=</span> <span class="s2">"iptables -t nat -A PREROUTING -s 10.0.0.0/21"</span>
<span class="n">line</span> <span class="o">=</span> <span class="n">line</span> <span class="o">+</span> <span class="s2">" -p tcp --dport 80 -j SNAT --to-source 192.168.1.15"</span>
<span class="n">tables</span><span class="o">.</span><span class="n">put_into_tables</span><span class="p">(</span><span class="n">line</span><span class="p">)</span>
<span class="n">expect</span> <span class="o">=</span> <span class="p">[</span><span class="s1">'-A PREROUTING -s 10.0.0.0/21 -p tcp --dport 80 -j SNAT --to-source 192.168.1.15 '</span><span class="p">]</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertEquals</span><span class="p">(</span><span class="n">expect</span><span class="p">,</span> <span class="n">tables</span><span class="o">.</span><span class="n">data</span><span class="p">[</span><span class="s2">"nat"</span><span class="p">][</span><span class="s2">"PREROUTING"</span><span class="p">])</span>
</pre>
</blockquote>
<p>Is a long inputline translated correctly? Filter, nat, mangle and raw table checked also. Check exception
on non existing chain raw INPUT.</p>
<blockquote>
<pre class="code python literal-block">
<span class="o">...</span>
<span class="k">def</span> <span class="nf">test_07_reference_one</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">"""
read default file: reference-one, check chains
"""</span>
<span class="n">tables</span> <span class="o">=</span> <span class="n">Tables</span><span class="p">()</span>
<span class="n">expect</span> <span class="o">=</span> <span class="p">{</span> \
<span class="s1">'filter'</span><span class="p">:</span> <span class="p">{</span><span class="s1">'FORWARD'</span><span class="p">:</span> <span class="p">[],</span> \
<span class="s1">'INPUT'</span><span class="p">:</span> <span class="p">[</span><span class="s1">'-A INPUT -p tcp --dport 23 -j ACCEPT '</span><span class="p">],</span> \
<span class="s1">'USER_CHAIN'</span><span class="p">:</span> <span class="p">[</span><span class="s1">'-A USER_CHAIN -p icmp -j DROP '</span><span class="p">],</span> \
<span class="s1">'OUTPUT'</span><span class="p">:</span> <span class="p">[]},</span> \
<span class="s1">'raw'</span><span class="p">:</span> <span class="p">{</span><span class="s1">'OUTPUT'</span><span class="p">:</span> <span class="p">[],</span> <span class="s1">'PREROUTING'</span><span class="p">:</span> <span class="p">[]},</span> \
<span class="s1">'mangle'</span><span class="p">:</span> <span class="p">{</span><span class="s1">'FORWARD'</span><span class="p">:</span> <span class="p">[],</span> <span class="s1">'INPUT'</span><span class="p">:</span> <span class="p">[],</span> <span class="s1">'POSTROUTING'</span><span class="p">:</span> <span class="p">[],</span> \
<span class="s1">'PREROUTING'</span><span class="p">:</span> <span class="p">[],</span> <span class="s1">'OUTPUT'</span><span class="p">:</span> <span class="p">[]},</span> \
<span class="s1">'nat'</span><span class="p">:</span> <span class="p">{</span><span class="s1">'OUTPUT'</span><span class="p">:</span> <span class="p">[],</span> \
<span class="s1">'POSTROUTING'</span><span class="p">:</span> <span class="p">[</span><span class="s1">'-A POSTROUTING -s 10.0.0.0/21 -p tcp --dport 80 -j SNAT --to-source 192.168.1.15 '</span><span class="p">],</span>
<span class="s1">'PREROUTING'</span><span class="p">:</span> <span class="p">[</span><span class="s1">'-A PREROUTING -d 192.0.2.5/32 -p tcp --dport 443 -j DNAT --to-destination 10.0.0.5:1500 '</span><span class="p">]}}</span>
<span class="bp">self</span><span class="o">.</span><span class="n">maxDiff</span> <span class="o">=</span> <span class="bp">None</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertEquals</span><span class="p">(</span><span class="n">expect</span><span class="p">,</span> <span class="n">tables</span><span class="o">.</span><span class="n">data</span><span class="p">)</span>
<span class="n">tables</span><span class="o">.</span><span class="n">table_printout</span><span class="p">()</span>
</pre>
</blockquote>
<p>This overall test checks reading of a file, and conversion to a result best known to be correct.</p>
<p>All these and some more tests are done in the hope to reach the goal of a <strong>stable and reliable piece of code</strong>.
Recently a firend of mine said: Software without atomated tests is suspected to be broken by design. I agreed.</p>
<div class="section" id="have-fun">
<h3>Have fun!</h3>
</div>
</div>
log entry 2013-02-242013-02-24T23:47:00+01:002013-02-24T23:47:00+01:00Johannes Hubertztag:hubertz.de,2013-02-24:/blog/iptables-optimizer-2nd.html<p class="first last">iptables-optimizer tested</p>
<div class="section" id="iptables-optimizer-95-tested">
<h2>iptables-optimizer 95% tested</h2>
<p>The optimizer grew as well, tests have been build in. Recently I found
a nice abstract description of what I'm doing here, partition is a wording
from settheory:</p>
<img alt="definition" src="/blog/img/opti-partition-def.png" style="height: 122.49999999999999px;" />
<p>This exactly describes my view of a chain divided into parts.</p>
<pre class="code python literal-block">
<span class="k">def</span> <span class="nf">make_partitions</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">"""make_partitions creates a list of 2-Elements-lists,
each representing a consecutive sequence with ACCEPT,
DROP, or the like. One 2-Element-list is called a
partition, it is [p_strt, p_ende], and taken form self.liste
Numbers in partions are Element-Positions, not indices!
It returns len(self.partitions), used for testing purpose.
"""</span>
<span class="bp">self</span><span class="o">.</span><span class="n">partitions</span> <span class="o">=</span> <span class="p">[]</span> <span class="c1"># start with empty list</span>
<span class="n">p_policy</span> <span class="o">=</span> <span class="s2">"DROP"</span>
<span class="n">p_po_old</span> <span class="o">=</span> <span class="bp">None</span>
<span class="n">p_strt</span> <span class="o">=</span> <span class="mi">1</span>
<span class="n">p_ende</span> <span class="o">=</span> <span class="mi">1</span>
<span class="n">last</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">liste</span><span class="p">)</span>
<span class="k">for</span> <span class="n">index</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">last</span><span class="p">):</span> <span class="c1"># iterate complete list</span>
<span class="n">rule_txt</span> <span class="o">=</span> <span class="s2">""</span>
<span class="k">for</span> <span class="n">k</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">liste</span><span class="p">[</span><span class="n">index</span><span class="p">]:</span>
<span class="n">rule_txt</span> <span class="o">=</span> <span class="n">rule_txt</span> <span class="o">+</span> <span class="n">k</span> <span class="o">+</span> <span class="s2">" "</span>
<span class="k">if</span> <span class="s2">"ACCEPT"</span> <span class="ow">in</span> <span class="n">rule_txt</span><span class="p">:</span>
<span class="n">p_policy</span> <span class="o">=</span> <span class="s2">"ACCEPT"</span>
<span class="k">elif</span> <span class="s2">"DROP"</span> <span class="ow">in</span> <span class="n">rule_txt</span><span class="p">:</span>
<span class="n">p_policy</span> <span class="o">=</span> <span class="s2">"DROP"</span>
<span class="k">elif</span> <span class="s2">"REJECT"</span> <span class="ow">in</span> <span class="n">rule_txt</span><span class="p">:</span>
<span class="n">p_policy</span> <span class="o">=</span> <span class="s2">"REJECT"</span> <span class="c1"># we have mercy with LOG or the like</span>
<span class="k">if</span> <span class="n">p_po_old</span> <span class="o">==</span> <span class="bp">None</span><span class="p">:</span> <span class="c1"># initialize old value once</span>
<span class="n">p_po_old</span> <span class="o">=</span> <span class="n">p_policy</span>
<span class="k">if</span> <span class="p">(</span><span class="n">p_policy</span> <span class="o">==</span> <span class="n">p_po_old</span><span class="p">):</span>
<span class="n">p_ende</span> <span class="o">=</span> <span class="n">index</span> <span class="o">+</span> <span class="mi">1</span>
<span class="k">else</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">partitions</span><span class="o">.</span><span class="n">append</span><span class="p">([</span><span class="n">p_strt</span><span class="p">,</span> <span class="n">p_ende</span><span class="p">])</span>
<span class="n">p_strt</span> <span class="o">=</span> <span class="n">index</span> <span class="o">+</span> <span class="mi">1</span>
<span class="n">p_ende</span> <span class="o">=</span> <span class="n">index</span> <span class="o">+</span> <span class="mi">1</span>
<span class="n">p_po_old</span> <span class="o">=</span> <span class="n">p_policy</span>
<span class="c1"># special case: no rules in chain</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">liste</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">partitions</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">elif</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">liste</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">partitions</span> <span class="o">=</span> <span class="p">[[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">]]</span>
<span class="k">else</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">partitions</span><span class="o">.</span><span class="n">append</span><span class="p">([</span><span class="n">p_strt</span><span class="p">,</span> <span class="n">p_ende</span><span class="p">])</span>
<span class="n">retVal</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">partitions</span><span class="p">)</span>
<span class="k">return</span> <span class="n">retVal</span>
</pre>
<p>It was a bit tricky to catch all the cases, some tests showed
errors in the code, which means the code produced wrong results. Testing is great.</p>
<pre class="code bash literal-block">
hans@jha:~/gh/opti$ nosetests -v --with-coverage iptables_optimizer_tests.py
test_01_create_chainobject <span class="o">(</span>iptables_optimizer_tests.Chain_Test<span class="o">)</span> ... ok
test_02_make_partitions_0 <span class="o">(</span>iptables_optimizer_tests.Chain_Test<span class="o">)</span> ... ok
test_02_make_partitions_1a <span class="o">(</span>iptables_optimizer_tests.Chain_Test<span class="o">)</span> ... ok
test_02_make_partitions_1d <span class="o">(</span>iptables_optimizer_tests.Chain_Test<span class="o">)</span> ... ok
test_02_make_partitions_1l <span class="o">(</span>iptables_optimizer_tests.Chain_Test<span class="o">)</span> ... ok
test_02_make_partitions_1r <span class="o">(</span>iptables_optimizer_tests.Chain_Test<span class="o">)</span> ... ok
test_02_make_partitions_2a <span class="o">(</span>iptables_optimizer_tests.Chain_Test<span class="o">)</span> ... ok
test_02_make_partitions_2ad <span class="o">(</span>iptables_optimizer_tests.Chain_Test<span class="o">)</span> ... ok
test_02_make_partitions_5ada <span class="o">(</span>iptables_optimizer_tests.Chain_Test<span class="o">)</span> ... ok
test_03_empty_opti_0 <span class="o">(</span>iptables_optimizer_tests.Chain_Test<span class="o">)</span> ... ok
test_03_insert_three_aaa <span class="o">(</span>iptables_optimizer_tests.Chain_Test<span class="o">)</span> ... ok
test_03_insert_three_aar <span class="o">(</span>iptables_optimizer_tests.Chain_Test<span class="o">)</span> ... ok
test_04_filter_file_NOread <span class="o">(</span>iptables_optimizer_tests.Filter_Test<span class="o">)</span> ... ok
test_05_filter_file_OKread <span class="o">(</span>iptables_optimizer_tests.Filter_Test<span class="o">)</span> ... ok
test_06_optimize_algorithm <span class="o">(</span>iptables_optimizer_tests.Filter_Test<span class="o">)</span> ... ok
test_07_filter_output <span class="o">(</span>iptables_optimizer_tests.Filter_Test<span class="o">)</span> ... ok
Name Stmts Miss Cover Missing
--------------------------------------------------
iptables_optimizer <span class="m">150</span> <span class="m">8</span> 95% 224-231
----------------------------------------------------------------------
Ran <span class="m">16</span> tests in 0.023s
OK
</pre>
<div class="section" id="have-fun">
<h3>Have fun!</h3>
</div>
</div>
log entry 2012-11-092012-11-09T20:46:00+01:002012-11-09T20:46:00+01:00Johannes Hubertztag:hubertz.de,2012-11-09:/blog/iptables-optimizer.html<p class="first last">iptables-optimizer</p>
<div class="section" id="iptables-optimizer">
<h2>iptables-optimizer</h2>
<p>Latency of round about 300ms in a LAN environment is unusual. So investigations were
done. Result: The lot of iptables in some machines were responsible. To reduce the
ruleset seemed to be the only solution, but that's not easy and expensive. Because
you cannot see from a rule, if it is used or not. Perhaps it's unused today or this
week, possibly really important usage only happens once a month, f.e. the rules for
HR to clear their banking affairs, i.e. your salaries?</p>
<p>At first, the iptables-module comment was used to have a distinct number within the
kernel on each rule. That helps to identify rules which are not used. But it is
extremely boring, to look on a self repeating screen showing <tt class="docutils literal">iptables <span class="pre">-nvxL</span></tt>
And it doesn't help at all. It's frustrating.</p>
<p>What's the real reason for the latency? It is the kernels job for every traversing
packet, to find a matching rule and pass it, or after having consulted all rules to
log it and then drop. Having a fixed set of rules for a long time, most of them are
unused most of the time. Traffic is passing only from few rules. Perhaps we could
position the used rules on top of the lists?</p>
<p>That's it! Why not sort the rules on the values of their usagecounters?
<strong>Some restrictions might be important!</strong> But, nevertheless I am electrified from
the idea. No rest until first tries, which are encouraging.</p>
<p>Python can call anything on os-level. subproces is used for that.
The idea grew to have it all in a single script:</p>
<blockquote>
<pre class="code bash literal-block">
iptables-save -c > file
sort the chains on the packetcounters respecting all restictions > sorted
iptables-restore < sorted
</pre>
</blockquote>
<p>Initial commit was on 2012-11-09, pushed to <a class="reference external" href="https://github.com/sl0/opti">https://github.com/sl0/opti</a></p>
<div class="section" id="have-fun">
<h3>Have fun!</h3>
</div>
</div>
log entry 2012-10-232012-10-23T23:51:00+02:002012-10-23T23:51:00+02:00Johannes Hubertztag:hubertz.de,2012-10-23:/blog/thought-two.html<p class="first last">another day in my life</p>
<img alt="four wheels" src="/blog/img/enigma-ausschnitt-klein.png" style="height: 50.0px;" />
<div class="section" id="thoughts">
<h2>Thoughts</h2>
<p>Another day in my life ... Alice, Bob and Marley have been introduced already. So a simple
question is still kept open: What is that stuff at all, you call crypto?</p>
<p>Well, thats not easy. Perhaps a very brief view back shold be done at first. From the greek
we know, they used some simple algorithm to prevent everybody from understanding their messages
sent by their personel. The usage of the <a class="reference external" href="http://en.wikipedia.org/wiki/Skytale">scytale</a> was simple: a leather band around a
cylinder was written longitudinal, the cylinder removed and then the leather band was "unreadable".
The receiver should have a cylinder of the same diameter. From <a class="reference external" href="http://en.wikipedia.org/wiki/Skytale">wikipedia</a> we know: It was mentioned
by Archilochus, who lived in the 7th century BC. A description of
how it operated is not known from before Plutarch (50-120 AD).</p>
<p>Today this procedure would not be assumed to be secure, because of a brute force attack using
different cylinders is easy.</p>
<p>The romans perhaps invented their caesar-cipher, named after Julius Gaius Caesar,
100 BC - 44 BC who is known to have used it. It is a linear substitution of letters,
f.e. 'c' for 'a', 'd' for 'b', 'e' for 'c' and so on.
This is best achieved by having two stripes with the same letters on them which are
misaligned for a constant number of letters. The reciever could test various numbers
for the reverse alignment or knows Caesars often used big secret: 3.
Some webbrowsers have implemented it in their menue: ROT13. Do it twice to have the
initial content. The big secret is the magic number 13. This just fits into the 26 letters
of our common alphabet.</p>
<p>These two examples for cryptographic methods are mentioned to show their usage in ancient
times. Whats about today?</p>
<p>Alice already said: History of cryptography is enriched by errors about the own knowledge.</p>
<p>And that is the truth, seen many times in the last 2000 years.</p>
<p>t.b.c.</p>
<img alt="four wheels" src="/blog/img/enigma-ausschnitt-klein.png" style="height: 50.0px;" />
<p>This little picture was taken on one of my trips to Munich in
the "Deutsches Museum München" from the 4-rotor enigma (marine version).
It's one of the best investigated crypto machines in history.
Thanks to Alan Turing and Marjan Rejewski.</p>
<p>Major flaw was the lack of randomness. ;-)</p>
</div>
log entry 2012-10-202012-10-20T23:47:00+02:002012-10-20T23:47:00+02:00Johannes Hubertztag:hubertz.de,2012-10-20:/blog/iptables-converter.html<p class="first last">iptables-converter</p>
<div class="section" id="iptables-converter-startup">
<h2>iptables-converter startup</h2>
<p>It's boring to wait for a linux machine loading some thousands of iptables.
It's more boring on a slow machine, and so the idea came up to speed up
the process. Recently I got to know, the netfilter-architects mentioned not
to change the iptables-restore format. The ususal suspects were asked to find
a tool. Looking around for some converter outside the kernel wasn't successful.
Nothing was found, probably because of using the wrong keywords. So the idea came up to
write one. Pyhton and me should be able to do it.</p>
<p>My sspe tool (<a class="reference external" href="http://sspe.sourceforge.net">http://sspe.sourceforge.net</a>) generates the iptables in a shellscript
from a common set of firewall rules for many machines. It is written in perl,
it is ugly but useful. No tests at all, only controlled by viewing with own eyes.</p>
<p>A converter could speed up loading time, the benefit would be more time to spend
on the machines.</p>
<p>Initial commit is dated to 2012-11-20 and it is pushed to <a class="reference external" href="https://github.com/sl0/conv">https://github.com/sl0/conv</a></p>
<p>It's not complicated. Read in the shellscript,
write out the iptables a little bit modified. That's all.</p>
<div class="section" id="have-fun">
<h3>Have fun!</h3>
</div>
</div>
log entry 2012-04-292012-04-29T22:13:00+02:002012-04-29T22:13:00+02:00Johannes Hubertztag:hubertz.de,2012-04-29:/blog/pythoncamp2012.html<p class="first last">my first pythoncamp</p>
<a class="reference external image-reference" href="http://pythoncamp.de"><img alt="Pythoncamp.de" src="/blog/img/pythoncamp-logo.png" style="height: 50.0px;" /></a>
<div class="section" id="my-first-pythoncamp-participation">
<h2>My first pythoncamp participation</h2>
<p>A two days barcamp was organized by pycologne.de, the cologne python user group.</p>
<p>On Saturday we started at about 0930 local time at GFU Cyrus AG (<a class="reference external" href="http://www.gfu.net">http://www.gfu.net</a>) in Cologne.
About 30 people attended. 2 Days filled up with pythonic talks, turorials and discussions.
I briefly introduced my adm6, but much more exciting for me was Klaus Bremers talk about his
radonCMS (<a class="reference external" href="https://github.com/kbr/radoncms">https://github.com/kbr/radoncms</a>), which is based on django. Very kind people, all
interested in getting to know new methods, techniques and tricks. Arousing!</p>
<p>Some days later i build my webpage with radonCMS. And reasoned by my paranoia, the content is
taken by wget and put onto my webserver as static content, of course.</p>
<p><a class="reference external" href="http://pycologne.de">http://pycologne.de</a> will repeat the wonderful event next year, sure.</p>
</div>
log entry 2012-04-012012-04-01T23:51:00+02:002012-04-01T23:51:00+02:00Johannes Hubertztag:hubertz.de,2012-04-01:/blog/thought-one.html<p class="first last">a day in my life</p>
<img alt="four wheels" class="align-left" src="/blog/img/enigma-ausschnitt-klein.png" style="height: 50.0px;" />
<div class="section" id="thoughts">
<h2>Thoughts</h2>
<p>A day in my life ... sometimes I can't remember where I got it from, sorry.</p>
<p><tt class="docutils literal">Alice:</tt> History of cryptography is enriched by errors about the own knowledge.</p>
<p><tt class="docutils literal">Bob:</tt> Ah, you mean, I don't know enough?</p>
<p><tt class="docutils literal">Alice:</tt> Yes. You're right.</p>
<p>some hours later ...</p>
<p><tt class="docutils literal">Malroy:</tt> I got your conversation. It's arousing, but totally wrong. You're talking base64 and ascii.</p>
<p><tt class="docutils literal">Alice:</tt> Yes. You're right. Hey Bob, our telepathy has been broken.</p>
<p><tt class="docutils literal">Bob:</tt> You mean, somebody got to know our thoughts?</p>
<p><tt class="docutils literal">Alice:</tt> Yes. You're right. At least, somebody means to have seen them.</p>
<p><tt class="docutils literal">Bob:</tt> Thats not a problem, we don't think about important secrets.</p>
<p><tt class="docutils literal">Alice:</tt> Sorry, now you're wrong. Nobody should know, we are thinking at all, really.</p>
<p><tt class="docutils literal">Bob:</tt> Ok, from 1984 we already know how to hide our thoughts, let's choose a song... We're far behind 1984! They are behind us, and they have learned how to do it best.</p>
<p><tt class="docutils literal">Alice:</tt> <strong>To be paranoid does not mean nobody is behind you.</strong></p>
<p>q.e.d.</p>
<img alt="four wheels" class="align-left" src="/blog/img/enigma-ausschnitt-klein.png" style="height: 50.0px;" />
<p>This little picture was taken on one of my trips to Munich in
the "Deutsches Museum München" from the 4-rotor enigma (marine version).
It's one of the best investigated crypto machines in history.
Thanks to Alan Turing and Marjan Rejewski.</p>
<p>Major flaw was the lack of randomness. ;-)</p>
</div>
log entry 2012-03-312012-03-31T22:13:00+02:002012-03-31T22:13:00+02:00Johannes Hubertztag:hubertz.de,2012-03-31:/blog/findcnt.html<p class="first last">my first python project on github.com</p>
<div class="section" id="my-first-python-project-on-github-com">
<h2>My first python project on github.com</h2>
<div class="section" id="findcnt-find-a-lot-of-regex-in-a-lot-of-files">
<h3><strong>findcnt</strong> - find a lot of regex in a lot of files</h3>
<p>This little tool was written for a friend, who asked how he can have a csv from a
set of regex applied onto a large tree of popular php-files. The regex should
find some flaws in the files, csv should just show counts of them for letting him
know, where to start his work to find vulnarabilities.</p>
<p><strong>findcnt</strong> comes as a <tt class="docutils literal">git</tt> repository and is accompanied with some doctests within
the readme. Some reference data will help to have reliable <tt class="docutils literal">Unittests</tt>.
It is hosted at <a class="reference external" href="https://github.com/sl0/findcnt">https://github.com/sl0/findcnt</a> for your convienience.</p>
<p>The initial commit was on Tue, Jan 10 11:34:47 2012 +0100, some ten hours of writing
my ideas into the python file spread over some weeks resulted in a usable tool.</p>
<p>And of course my program had at least one bug. Short after his first usage my
friend told me, it does not count exactly. Especially if there are two regex in
a single line, it counts only one. That wasn't the expected value.
By using the doctests it was fixed in few minutes. And he was happy, me too.</p>
<p>Last commit was on Wed, Feb 22 23:38:56 2012 +0100</p>
<p>So I learned doctests to be useful.
Software not accompanied by functional tests seems to be broken by design.</p>
<p>And I got to know github.com. It's great, if you're using git.</p>
<div class="section" id="have-fun">
<h4>Have fun!</h4>
</div>
</div>
</div>
log entry 2012-03-022012-03-02T22:13:00+01:002012-03-02T22:13:00+01:00Johannes Hubertztag:hubertz.de,2012-03-02:/blog/guug-ffg-2012.html<p class="first last">guug ffg 2012</p>
<div class="section" id="fruhjahrsfachgesprach-2012-hochschule-munchen">
<h2><strong>Frühjahrsfachgespräch 2012, Hochschule München</strong></h2>
<a class="reference external image-reference" href="http://guug.de"><img alt="German Unix User Group" class="align-right" src="/blog/img/guug-logo.png" style="height: 50.0px;" /></a>
<p>Wonderful days in Munich. Arousing discussions, wonderful talks and great socializing evenings.</p>
<p>Our host Prof. Dr. Jürgen Plate gave us a very nice tutorial on what can be done with
parallel and serial interfaces at a normal computer with some connected sensors,
motors, cameras and whatever. Using Servos, a camera was moved in 2 axes to follow
a hand held yellow box. Funny to see the steering software beeing build in only 3 hours
from some free software components and, of course, a lot of knowledge...</p>
<p>A lot of very interesting talks took all the time, two days conference was totally filled
with to much content. If possible, I would have come twice to see the two tracks
simultaneously. But sorry, no cloning allowed within the guug (<a class="reference external" href="http://guug.de">http://guug.de</a>)</p>
<p>Summary: Most important: Only kind people met. Very eventful days in a nice university within a beautiful city.</p>
</div>
log entry 2011-12-282011-12-28T00:31:00+01:002011-12-28T00:31:00+01:00Johannes Hubertztag:hubertz.de,2011-12-28:/blog/adm6-first.html<p class="first last">adm6 on evolvis git</p>
<img alt="German Unix User Group" class="align-left" src="/blog/img/adm6-logo.png" style="height: 100.0px;" />
<div class="section" id="adm6-on-evolvis-org">
<h2>adm6 on evolvis.org</h2>
<p>August 2011 I had the first talk about adm6 at the cologne python usergroup <a class="reference external" href="http://pyCologne.de">http://pyCologne.de</a>
At various places I repeated to find interested people to join the project, you may find the slides at <a class="reference external" href="http://hubertz.de/papers/">http://hubertz.de/papers/</a></p>
<p>Still going strong...</p>
<p>First entry in git log:</p>
<pre class="literal-block">
commit 672781f6757fac566d55860a26e49a46edccd404
Author: Johannes Hubertz <jhselber@evolvis.org>
Date: Tue Mar 22 23:35:23 2011 +0100
.
Initial first push of python files, Makefile and README.export
.
README.export is a first documentation text containing a very
quick and dirty what do I do with this files
.
Makefile has some targets:
sync: will update remote repository
new: will create a new ~/.adm6.conf and new ~/adm6/XYZ
back: will create a ~adm6-export.tgz and gnupg signed .asc-file
.
Some python files are included:
demo.py to create a clean landscape and adm6.conf
device.py application main, and device specific code
filter6.py filter specific code
hostnet6.py python code to read the hostnet6 file
adm6ConfigParser.py read and evaluate ~/.adm6.conf
</pre>
</div>
<div class="section" id="have-fun">
<h2>Have fun!</h2>
</div>
log start 2011-12-262011-12-26T20:31:00+01:002011-12-26T20:31:00+01:00Johannes Hubertztag:hubertz.de,2011-12-26:/blog/my-first-post.html<p class="first last">startup using pelican</p>
<div class="section" id="pelican-installed-started-up-we-go">
<h2>pelican installed, started, up we go</h2>
<p>It's so easy to startup if you know, which software is fitting your needs:</p>
<pre class="literal-block">
Hundreds of different blog-tools exist.
Few of them are pythonic
some are complicated
pelican seems to be beautiful
</pre>
<p>Pelican <a class="reference external" href="http://getpelican.com">http://getpelican.com</a> fits all I want: It is simple, pythonic and it produces static content.
So the produced web-pages follow the <strong>keep it simple stupid</strong> principle.
ReStructuredText is already known from writing sphinx documentation for adm6,
but that is far from beeing blogged for now.</p>
<div class="section" id="sl0-what-is-that">
<h3>sl0, what is that?</h3>
<p>In the linux operating system we can have a lot of different interfaces to be
used for ip (internet protocol) connections. Most common there is ethernet today, these
interfaces will be named <tt class="docutils literal">eth0, eth1, eth2</tt> and so on. At the times before we had DSL
(digital subscriber line) widely spread, modems and isdn-lines did the job. The very first
way of using these technologies for transportation of ip was called <tt class="docutils literal">slip</tt> (serial line ip),
and the first interface in linuxkernel was named sl0. OK?</p>
<p>Since those first impressions with RFC792 conform technology in 1994 I was convinced, all
those specific vendor technologies would disappear. Thanks to Linus Torvalds and
to all those cool guys spending their time in this arousing system until today.</p>
</div>
<div class="section" id="only-truth">
<h3>only truth!</h3>
<p>My blog will only have content of my own real life. Perhaps not the full truth, but never anything else but truth.
And we know from the rest of the internet, about 50% of the news are faked. We just don't know, which 50%. ;-)</p>
<p>The main guidline is always kept:</p>
<blockquote>
<pre class="code python literal-block">
<span class="n">Python</span> <span class="mf">2.7</span><span class="o">.</span><span class="mi">3</span> <span class="p">(</span><span class="n">default</span><span class="p">,</span> <span class="n">Jan</span> <span class="mi">2</span> <span class="mi">2013</span><span class="p">,</span> <span class="mi">13</span><span class="p">:</span><span class="mi">56</span><span class="p">:</span><span class="mi">14</span><span class="p">)</span>
<span class="p">[</span><span class="n">GCC</span> <span class="mf">4.7</span><span class="o">.</span><span class="mi">2</span><span class="p">]</span> <span class="n">on</span> <span class="n">linux2</span>
<span class="n">Type</span> <span class="s2">"help"</span><span class="p">,</span> <span class="s2">"copyright"</span><span class="p">,</span> <span class="s2">"credits"</span> <span class="ow">or</span> <span class="s2">"license"</span> <span class="k">for</span> <span class="n">more</span> <span class="n">information</span><span class="o">.</span>
<span class="o">>>></span> <span class="kn">import</span> <span class="nn">this</span>
<span class="n">The</span> <span class="n">Zen</span> <span class="n">of</span> <span class="n">Python</span><span class="p">,</span> <span class="n">by</span> <span class="n">Tim</span> <span class="n">Peters</span>
<span class="o">.</span>
<span class="n">Beautiful</span> <span class="ow">is</span> <span class="n">better</span> <span class="n">than</span> <span class="n">ugly</span><span class="o">.</span>
<span class="n">Explicit</span> <span class="ow">is</span> <span class="n">better</span> <span class="n">than</span> <span class="n">implicit</span><span class="o">.</span>
<span class="n">Simple</span> <span class="ow">is</span> <span class="n">better</span> <span class="n">than</span> <span class="nb">complex</span><span class="o">.</span>
<span class="n">Complex</span> <span class="ow">is</span> <span class="n">better</span> <span class="n">than</span> <span class="n">complicated</span><span class="o">.</span>
<span class="n">Flat</span> <span class="ow">is</span> <span class="n">better</span> <span class="n">than</span> <span class="n">nested</span><span class="o">.</span>
<span class="n">Sparse</span> <span class="ow">is</span> <span class="n">better</span> <span class="n">than</span> <span class="n">dense</span><span class="o">.</span>
<span class="n">Readability</span> <span class="n">counts</span><span class="o">.</span>
<span class="n">Special</span> <span class="n">cases</span> <span class="n">aren</span><span class="s1">'t special enough to break the rules.</span>
<span class="n">Although</span> <span class="n">practicality</span> <span class="n">beats</span> <span class="n">purity</span><span class="o">.</span>
<span class="n">Errors</span> <span class="n">should</span> <span class="n">never</span> <span class="k">pass</span> <span class="n">silently</span><span class="o">.</span>
<span class="n">Unless</span> <span class="n">explicitly</span> <span class="n">silenced</span><span class="o">.</span>
<span class="n">In</span> <span class="n">the</span> <span class="n">face</span> <span class="n">of</span> <span class="n">ambiguity</span><span class="p">,</span> <span class="n">refuse</span> <span class="n">the</span> <span class="n">temptation</span> <span class="n">to</span> <span class="n">guess</span><span class="o">.</span>
<span class="n">There</span> <span class="n">should</span> <span class="n">be</span> <span class="n">one</span><span class="o">--</span> <span class="ow">and</span> <span class="n">preferably</span> <span class="n">only</span> <span class="n">one</span> <span class="o">--</span><span class="n">obvious</span> <span class="n">way</span> <span class="n">to</span> <span class="n">do</span> <span class="n">it</span><span class="o">.</span>
<span class="n">Although</span> <span class="n">that</span> <span class="n">way</span> <span class="n">may</span> <span class="ow">not</span> <span class="n">be</span> <span class="n">obvious</span> <span class="n">at</span> <span class="n">first</span> <span class="n">unless</span> <span class="n">you</span><span class="s1">'re Dutch.</span>
<span class="n">Now</span> <span class="ow">is</span> <span class="n">better</span> <span class="n">than</span> <span class="n">never</span><span class="o">.</span>
<span class="n">Although</span> <span class="n">never</span> <span class="ow">is</span> <span class="n">often</span> <span class="n">better</span> <span class="n">than</span> <span class="o">*</span><span class="n">right</span><span class="o">*</span> <span class="n">now</span><span class="o">.</span>
<span class="n">If</span> <span class="n">the</span> <span class="n">implementation</span> <span class="ow">is</span> <span class="n">hard</span> <span class="n">to</span> <span class="n">explain</span><span class="p">,</span> <span class="n">it</span><span class="s1">'s a bad idea.</span>
<span class="n">If</span> <span class="n">the</span> <span class="n">implementation</span> <span class="ow">is</span> <span class="n">easy</span> <span class="n">to</span> <span class="n">explain</span><span class="p">,</span> <span class="n">it</span> <span class="n">may</span> <span class="n">be</span> <span class="n">a</span> <span class="n">good</span> <span class="n">idea</span><span class="o">.</span>
<span class="n">Namespaces</span> <span class="n">are</span> <span class="n">one</span> <span class="n">honking</span> <span class="n">great</span> <span class="n">idea</span> <span class="o">--</span> <span class="n">let</span><span class="s1">'s do more of those!</span>
<span class="o">>>></span>
</pre>
</blockquote>
<img alt="few bits of my memory" class="align-left" src="/blog/img/kernspeicher.png" style="height: 300.0px;" />
<p>Here I show you some bits from my memory, keep in mind: These computers work with electric current.</p>
</div>
</div>
<div class="section" id="have-fun">
<h2>Have fun!</h2>
</div>