I became a Debian Developer
Wed, 04 Feb 2015 18:00 categories: blog, debianThanks to akira for the confetti to celebrate the occasion!
simple email setup
Sun, 30 Nov 2014 16:39 categories: config, debianI was unable to find a good place that describes how to create a simple self-hosted email setup. The most surprising discovery was, how much already works after:
apt-get install postfix dovecot-imapd
Right after having finished the installation I was able to receive email (but
only in in /var/mail
in mbox format) and send email (bot not from any other
host). So while I expected a pretty complex setup, it turned out to boil down
to just adjusting some configuration parameters.
Postfix
The two interesting files to configure postfix are /etc/postfix/main.cf
and
/etc/postfix/master.cf
. A commented version of the former exists in
/usr/share/postfix/main.cf.dist
. Alternatively, there is the ~600k word
strong man page postconf(5). The latter file is documented in master(5).
/etc/postfix/main.cf
I changed the following in my main.cf
@@ -37,3 +37,9 @@
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all
+
+home_mailbox = Mail/
+smtpd_recipient_restrictions = permit_mynetworks reject_unauth_destination permit_sasl_authenticated
+smtpd_sasl_type = dovecot
+smtpd_sasl_path = private/auth
+smtp_helo_name = my.reverse.dns.name.com
At this point, also make sure that the parameters smtpd_tls_cert_file
and
smtpd_tls_key_file
point to the right certificate and private key file. So
either change these values or replace the content of
/etc/ssl/certs/ssl-cert-snakeoil.pem
and
/etc/ssl/private/ssl-cert-snakeoil.key
.
The home_mailbox
parameter sets the default path for incoming mail. Since
there is no leading slash, this puts mail into $HOME/Mail
for each user. The
trailing slash is important as it specifies ``qmail-style delivery'' which
means maildir.
The default of the smtpd_recipient_restrictions
parameter is
permit_mynetworks reject_unauth_destination
so this just adds the
permit_sasl_authenticated
option. This is necessary to allow users to send
email when they successfully verified their login through dovecot. The dovecot
login verification is activated through the smtpd_sasl_type
and
smtpd_sasl_path
parameters.
I found it necessary to set the smtp_helo_name
parameter to the reverse DNS
of my server. This was necessary because many other email servers would only
accept email from a server with a valid reverse DNS entry. My hosting provider
charges USD 7.50 per month to change the default reverse DNS name, so the easy
solution is, to instead just adjust the name announced in the SMTP helo
.
/etc/postfix/master.cf
The file master.cf
is used to enable the submission
service. The following
diff just removes the comment character from the appropriate section.
@@ -13,12 +13,12 @@
#smtpd pass - - - - - smtpd
#dnsblog unix - - - - 0 dnsblog
#tlsproxy unix - - - - 0 tlsproxy
-#submission inet n - - - - smtpd
-# -o syslog_name=postfix/submission
-# -o smtpd_tls_security_level=encrypt
-# -o smtpd_sasl_auth_enable=yes
-# -o smtpd_client_restrictions=permit_sasl_authenticated,reject
-# -o milter_macro_daemon_name=ORIGINATING
+submission inet n - - - - smtpd
+ -o syslog_name=postfix/submission
+ -o smtpd_tls_security_level=encrypt
+ -o smtpd_sasl_auth_enable=yes
+ -o smtpd_client_restrictions=permit_sasl_authenticated,reject
+ -o milter_macro_daemon_name=ORIGINATING
#smtps inet n - - - - smtpd
# -o syslog_name=postfix/smtps
# -o smtpd_tls_wrappermode=yes
Dovecot
Since above configuration changes made postfix store email in a different
location and format than the default, dovecot has to be informed about these
changes as well. This is done in /etc/dovecot/conf.d/10-mail.conf
. The second
configuration change enables postfix to authenticate users through dovecot in
/etc/dovecot/conf.d/10-master.conf
. For SSL one should look into
/etc/dovecot/conf.d/10-ssl.conf
and either adapt the parameters ssl_cert
and ssl_key
or store the correct certificate and private key in
/etc/dovecot/dovecot.pem
and /etc/dovecot/private/dovecot.pem
,
respectively.
The dovecot-core
package (which dovecot-imapd
depends on) ships tons of
documentation. The file
/usr/share/doc/dovecot-core/dovecot/documentation.txt.gz
gives an overview of
what resources are available. The path
/usr/share/doc/dovecot-core/dovecot/wiki
contains a snapshot of the dovecot
wiki at http://wiki2.dovecot.org/. The example configurations seem to be the
same files as in /etc/
which are already well commented.
/etc/dovecot/conf.d/10-mail.conf
The following diff changes the default email location in /var/mail
to a
maildir in ~/Mail
as configured for postfix above.
@@ -27,7 +27,7 @@
#
# <doc/wiki/MailLocation.txt>
#
-mail_location = mbox:~/mail:INBOX=/var/mail/%u
+mail_location = maildir:~/Mail
# If you need to set multiple mailbox locations or want to change default
# namespace settings, you can do it by defining namespace sections.
/etc/dovecot/conf.d/10-master.conf
And this enables the authentication socket for postfix:
@@ -93,9 +93,11 @@
}
# Postfix smtp-auth
- #unix_listener /var/spool/postfix/private/auth {
- # mode = 0666
- #}
+ unix_listener /var/spool/postfix/private/auth {
+ mode = 0660
+ user = postfix
+ group = postfix
+ }
# Auth process is run as this user.
#user = $default_internal_user
Aliases
Now Email will automatically put into the '~/Mail' directory of the receiver. So a user has to be created for whom one wants to receive mail...
$ adduser josch
...and any aliases for it to be configured in /etc/aliases
.
@@ -1,2 +1,4 @@
-# See man 5 aliases for format
-postmaster: root
+root: josch
+postmaster: josch
+hostmaster: josch
+webmaster: josch
After editing /etc/aliases
, the command
$ newaliases
has to be run. More can be read in the aliases(5) man page.
Finishing up
Everything is done and now postfix and dovecot have to be informed about the changes. There are many ways to do that. Either restart the services, reboot or just do:
$ postfix reload
$ doveadm reload
SPF
$ apt-get install postfix-policyd-spf-python
/etc/postfix/main.cf
policy-spf_time_limit = 3600s
/etc/postfix/master.cf
policy-spf unix - n n - - spawn user=nobody argv=/usr/bin/policyd-spf
DNS TXT record with value:
v=spf1 ip4:62.75.219.19 -all
/etc/postfix-policyd-spf-python/policyd-spf.conf
debugLevel = 1
defaultSeedOnly = 1
HELO_reject = SPF_Not_Pass
Mail_From_reject = Fail
PermError_reject = False
TempError_Defer = False
skip_addresses = 127.0.0.0/8,::ffff:127.0.0.0//104,::1//128
FIXME: the skip_addresses
field should also list all hosts that I get email
forwarded from. For example if I get my josch@debian.org email forwarded to
this server, then I should list the debian.org mail relay servers. A list of
these can be found by doing:
ldapsearch -x -LLL -b dc=debian,dc=org -h db.debian.org 'purpose=mail relay' ipHostNumber
Otherwise, senders with an SPF record with only their own IP and a final -all
will see their mail rejected by the server. This is because the email was
forwarded by the debian.org relay but that IP was not in their SPF record.
DKIM
$ apt-get install opendkim opendkim-tools
$ mkdir /etc/mail
$ cd /etc/mail
$ opendkim-genkey -t -s mail -d mister-muffin.de
$ cat mail.txt
/etc/opendkim.conf
Domain mister-muffin.de KeyFile /etc/mail/mail.private Selector mail Canonicalization relaxed/relaxed
/etc/default/opendkim
SOCKET="inet:8891@localhost"
/etc/postfix/main.cf
milter_default_action = accept milter_protocol = 2 smtpd_milters = inet:localhost:8891 non_smtpd_milters = inet:localhost:8891
$ service opendkim restart
$ service postfix restart
bootstrap.debian.net temporarily not updated
Tue, 29 Jul 2014 10:37 categories: debianI'll be moving places twice within the next month and as I'm hosting the machine that generates the data, I'll temporarily suspend the bootstrap.debian.net service until maybe around September. Until then, bootstrap.debian.net will not be updated and retain the status as of 2014-07-28. Sorry if that causes any inconvenience. You can write to me if you need help with manually generating the data bootstrap.debian.net provided.
botch updates
Thu, 05 Jun 2014 07:59 categories: debianMy last update about ongoing development of botch, the bootstrap/build ordering tool chain, was four months ago and about several incremental updates. This post will be of similar nature. The most interesting news is probably the additional data that bootstrap.debian.net now provides. This is listed in the next section. All subsequent sections then list the changes under the hood that made the additions to bootstrap.debian.net possible.
bootstrap.debian.net
The bootstrap.debian.net service used to have botch as a git submodule but now runs botch from its Debian package. This at least proves that the botch Debian package is mature enough to do useful stuff with it. In addition to the bootstrapping results by architecture, bootstrap.debian.net now also hosts the following additional services:
- History of graph size shows how the dependency graph developed over time for a normal self-contained repository plus for both minimizing strategies, updated every five days
- Crossbuild dependency satisfaction gives an overview of reasons why the crossbuild dependency situation cannot yet be analyzed with bug numbers where applicable
- Crossbuild order modifies the metadata of a repository so that the crossbuild dependency situation can be analyzed and then outputs an overview page as it is done for every architecture on the main page
- Source package importance calculates the port metric for source packages on a daily basis
Further improvements concern how dependency cycles are now presented in the
html overviews. While before, vertices in a cycle where separated by commas as
if they were simple package lists, vertices are now connected by unicode
arrows. Dashed arrows indicate build dependencies while solid arrows indicate
builds-from relationships. For what it's worth, installation set vertices now
contain their installation set in their title
attribute.
Debian package
Botch has long depended on features of an unreleased version of dose3
which
in turn depended on an unrelease version of libcudf
. Both projects have
recently made new releases so that I was now able to drop the dose3
git
submodule and rely on the host system's dose3
version instead. This also made
it possible to create a Debian package of botch which currently sits at Debian
mentors. Writing the package also finally made me create a usable
install
target in the Makefile
as well as adding stubs for the manpages of
the 44 applications that botch currently ships. The actual content of these
manpages still has to be written. The only documentation botch currently ships
in the botch-doc
package is an offline version of the wiki on gitorious.
The new page ExamplesGraphs even includes pictures.
Cross
By default, botch analyzes the native bootstrapping phase. That is, assume that
the initial set of Essential:yes
and build-essential
packages magically
exists and find out how to bootstrap the rest from there through native
compilation. But part of the bootstrapping problem is also to create the set of
Essential:yes
and build-essential
packages from nothing via cross
compilation. Botch is unable to analyze the cross phase because too many
packages cannot satisfy their crossbuild dependencies due to multiarch
conflicts. This problem is only about the dependency metadata and not about
whether a given source package actually crosscompiles fine in practice.
Helmut Grohne has done great work with rebootstrap which is regularly run by jenkins.debian.net. He convinced me that we need an overview of what packages are blocking the analysis of the cross case and that it was useful to have a crossbuild order even if that was a fake order just to have a rough overview of the current situation in Debian Sid.
I wrote a couple of scripts which would run dose-builddebcheck
on a
repository, analyze which packages fail to satisfy their crossbuild
dependencies and why, fix those cases by adjusting package metadata accordingly
and repeat until all relevant source packages satisfy their crossbuild
dependencies. The result of this can then be used to identify the packages that
need to be modified as well as to generate a crossbuild order.
The fixes to the metadata are done in an automatic fashion and do not necessarily reflect the real fix that would solve the problem. Nevertheless, I ended up agreeing that it is better to have a slightly wrong overview than no overview at all.
Minimizing the dependency graph size
Installation sets in the dependency graph are calculated independent from each
other. If two binary packages provide A
, then dependencies on A
in
different installation sets might choose different binary packages as providers
of A
. The same holds for disjunctive dependencies. If a package depends on A
| C
and another package depends on C | A
then there is no coordination to
choose C
so to minimize the overall amount of vertices in the graph. I
implemented two methods to minimize the impact of cases where the dependency
solver has multiple options to satisfy a dependency through Provides
and
dependency disjunctions.
The first method is inspired by Helmut Grohne. An algorithm goes through all disjunctive binary dependencies and removes all virtual packages, leaving only real packages. Of the remaining real packages, the first one is selected. For build dependencies, the algorithm drops all but the first package in every disjunction. This is also what sbuild does. Unfortunately this solution produces an unsatisfiable dependency situation in most cases. This is because oftentimes it is necessary to select the virtual disjunctive dependency because of a conflict relationship introduced by another package.
The second method involves aspcud
, a cudf solver which can optimize a
solution by a criteria. This solution is based on an idea by Pietro Abate who
implemented the basis for this idea back in 2012. In contrast to a usual cudf
problem, binary packages now also depend on the source packages they build
from. If we now ask aspcud
to find an installation set for one of the base
source packages (I chose src:build-essential
) then it will return an
installation set that includes source packages. As an optimization criteria the
number of source packages in the installation set is minimized. This solution
would be flawless if there were no conflicts between binary packages. Due to
conflicts not all binary packages that must be coinstallable for this strategy
to work can be coinstalled. The quick and dirty solution is to remove all
conflicts before passing the cudf universe to aspcud
. But this also means
that the solution does sometimes not work in practice.
Test cases
Botch now finally has a test
target in its Makefile
. The test
target
tests two code paths of the native.sh
script and the cross.sh
script.
Running these two scripts covers testing most parts of botch. Given that I did
lots of refactoring in the past weeks, the test cases greatly helped to assure
that I didnt break anything in the process.
I also added autopkgtests to the Debian packaging which test the same
things as the test
target but naturally run the installed version of botch
instead. The autopkgtests were a great help in weeding out some lasts bugs
which made botch depend on being executed from its source directory.
Python 3
Reading the suggestions in the Debian python policy I evaluated the
possibility to use Python 3 for the Python scripts in botch. While I was at it
I added transparent decompression for gzip, bz2 and xz based on the file magic,
replaced python-apt with python-debian because of bug#748922 and added
argparse
argument parsing to all scripts.
Unfortunately I had to find out that Python 3 support does not yet seem to be possible for botch for the following reasons:
- no soap module for Python 3 in Debian (needed for bts access)
- hash randomization is turned on by default in Python 3 and therefore the graph output of networkx is not deterministic anymore (bug#749710)
Thus I settled for changing the code such that it would be compatible with
Python 2 as well as with Python 3. Because of the changed string handling and
sys.stdout
properties in Python 3 this proved to be tricky. On the other
hand this showed me bugs in my code where I was wrongly relying on
deterministic dictionary key traversal.
botch updates
Thu, 06 Feb 2014 14:20 categories: debianMy last update about ongoing development of botch, the bootstrap/build ordering tool chain, was three months ago with the announcement of bootstrap.debian.net. Since then a number of things happened, so I thought an update was due.
New graphs for port metrics
By default, a dependency graph is created by arbitrarily choosing an installation set for binary package installation or source package compilation. Installation set vertices and source vertices are connected according to this arbitrary selection.
Niels Thykier approached me at Debconf13 about the possibility of using this graph to create a metric which would be able to tell for each source package, how many other source packages would become uncompilable or how many binary packages would become uninstallable, if that source package was removed from the archive. This could help deciding about the importance of packages. More about this can be found at the thread on debian-devel.
For botch, this meant that two new graph graphs can now be generated. Instead of picking an arbitrary installation set for compiling a source package or installing a binary package, botch can now create a minimum graph which is created by letting dose3 calculate strong dependencies and a maximum graph by using the dependency closure.
Build profile syntax in dpkg
With dpkg 1.17.2 we now have experimental build profile support in unstable. The syntax which ended up being added was:
Build-Depends: large (>= 1.0), small <!profile.stage1>
But until packages with that syntax can hit the archive, a few more tools need to understand the syntax. The patch we have for sbuild is very simple because sbuild relies on libdpkg for dependency parsing.
We have a patch for apt too, but we have to rebase it for the current apt version and have to adapt it so that it works exactly like the functionality dpkg implements. But before we can do that we have to decide how to handle mixed positive and negative qualifiers or whether to remove this feature altogether because it causes too much confusion. The relevant thread on debian-dpkg starts here.
Update to latest dose3 git
Botch heavily depends on libdose3 and unfortunately requires features which are only available in the current git HEAD. The latest version packaged in Debian is 3.1.3 from October 2012. Unfortunately the current dose3 git HEAD also relies on unreleased features from libcudf. On top of that, the GraphML output of the latest ocamlgraph version (1.8.3) is also broken and only fixed in the git. For now everything is set up as git submodules but this is the major blocker preventing any packaging of botch as a Debian package. Hopefully new releases will be done soon for all involved components.
Writing and reading GraphML
Botch is a collection of several utilities which are connected together in a shell script. The advantage of this is, that one does not need to understand or hack the OCaml code to use botch for different purposes. In theory it also allows to insert 3rd party tools into a pipe to further modify the data. Until recently this ability was seriously hampered by the fact that many botch tools communicated with each other through marshaled OCaml binary files which prevent everything which is not written in OCaml from modifying them. The data that was passed around like this were the dependency graphs and I initially implemented it like that because I didnt want to write a GraphML parser.
I now ended up writing an xmlm based GraphML parser so as of now, botch
only reads and writes ASCII text files in XML (for the graphs) and in rfc822
packages format (for Packages and Sources files) which can both easily be
modified by 3rd party tools. The ./tools
directory contains many Python
scripts using the networkx module to modify GraphML and the apt_pkg module to
modify rfc822 files.
Splitting of tools
To further increase the ability to modify program execution without having to know OCaml, I split up some big tools into multiple smaller ones. Some of the smaller tools are now even written in Python which is probably much more hackable for the general crowd. I converted those tools to Python which did not need any dose3 functionality and which were simple enough so that writing them didnt take much time. I could convert more tools but that might introduce bugs and takes time which I currently dont have much of (who does?).
Gzip instead of bz2
Since around January 14, snapshot.debian.org doesnt offer bzip2 compressed Packages and Sources files anymore but uses xz instead. This is awesome for must purposes but unfortunately I had to discover that there exist no OCaml bindings for libxz. Thus, botch is now using gzip instead of bz2 until either myself or anybody else finds some time to write a libxz OCaml binding.
Self hosting Fedora
Paul Wise made me aware of Harald Hoyer's attempts to bootstrap Fedora. I reproduced his steps for the Debian dependency graph and it turns out that they are a little bit bigger. I'm exchanging emails with Harald Hoyer because it might not be too hard to use botch for rpm based distributions as well because dose3 supports rpm.
The article also made me aware of the tred
tool which is part of graphviz and
allows to calculate the transitive reduction of a graph. This can help
making horrible situations much better.
Dose3 bugs
I planned to generate such simplified graphs for the neighborhood of each source package on bootstrap.debian.net but then binutils stopped building binutils-gold and instead provided binutils-gold while libc6-dev breaks binutils-gold (<< 2.20.1-11). This unfortunately triggered a dose3 bug and thus bootstrap.debian.net will not generate any new results until this is fixed in dose3.
Another dose3 bug affects packages which Conflicts/Replaces/Provides:bar while bar is fully virtual and are Multi-Arch:same. Binaries of different architecture with this property can currently not be co-installed with dose3. Unfortunately linux-libc-dev has this property and thus botch cannot be used to analyze cross builds until that bug is fixed in dose3.
I hope I get some free time soon to be able to look at these dose3 issues myself.
More documentation
Since I started to like the current set of tools and how they work together I ended up writing over 2600 words of documentation in the past few days.
You can start setting up and running botch by reading the first steps and get more detailed information by reading about the 28 tools that botch makes use of as of now.
All existing articles, thesis and talks are linked from the wiki home.