Co-maintaining a Debian package with Git and git-buildpackage

Although I’m still not entirely comfortable with Git for revision control I partly use it to maintain my Debian packages. Mainly because hg-buildpackage has been abandoned and git-buildpackage is actively maintained. This article deals with co-maintaining a Debian package with Git and git-buildpackage.

Install Git

On the development workstation (where you build the packages – running Sid):

  • aptitude install git-core git-buildpackage pristine-tar

Make sure you set your name and email address in your ~/.gitconfig file via:

  • git config –global ‘<name>’
  • git config –global ‘<email>’

On the publicly available web server (where you publish your repository – Lenny or newer):

  • aptitude install git-core git-daemon-run gitweb 

Move an existing Debian source package under Git control (only if there is not yet a repository containing the package!)

Either: Import the source package into a fresh Git repository

  • git-import-dsc –pristine-tar /path/to/package*.dsc

This creates a package/ directory containing a Git repository with two branches. The default branch “master” contains the debianized source package (like what you would get after running ‘dpkg-source -x *dsc’). The other “upstream” branch contains what was in the orig.tar.gz upstream tarball. You can see the branches with ‘git branch -a’. Each upstream version gets a tag like “upstream/1.3.4” and each Debian package gets a tag like “debian/1.3.4-3”. You can see the tags with “git tag”.

If you want to import further source package versions/revisions you can either run git-import-dsc in the order of their revision numbers or use ‘git-import-dscs’.

Building the package can then be done through:

  • git-buildpackage –git-pristine-tar

The ‘pristine-tar’ is important if a previous revision of this upstream version has already been uploaded to Debian. If you don’t use pristine tars then the created orig.tar.gz may be slightly different (not in content – but as an archive) from what’s already in Debian and the ftp-master will refuse your upload. If you forgot the ‘–pristine-tar’ option then at least make sure you have the orig.tar.gz in ../ that is also in Debian.

Or: Import just the orig.tar.gz into a fresh Git repository and start debianizing

  • mkdir package-name
  • cd package-name
  • git init
  • git-import-orig /path/to/orig.tar.gz
  • …work on Debian package…
  • git add debian… (or “git add .” to add everything that changed)
  • git commit
  • git-buildpackage
  • …upload to Debian… (dput/dupload)
  • git-buildpackage –git-tag

Or: package a new upstream revision

  • git-import-orig /path/to/new.orig.tar.gz

Or: pull the existing repository from your co-maintainer

  • git clone URL (for example: git clone git://

What your co-maintainer did is in origin/upstream (the orig.tar.gz’s content) and origin/master (the debianized directory). Incidentally Git merged the origin/master into your own ‘master’ branch that you are now on. To make sure you are following the co-maintainers upstream branch, too, you’ll have to run:

  • git checkout -b upstream –track origin/upstream

The ‘–track’ option altered the .git/config file and added a [branch “upstream”] section telling Git where you fetched it from. That means you can later just say “git pull” and you will get both the ‘master’ and the ‘upstream’ repository merged into your repository automatically.

Now you will have these branches:

  • upstream (a copy of the origin/upstream – must not change)
  • master (where you do the Debian package work in just like you had no repository underneath)
  • origin/upstream (where you co-maintainer unpackaged the orig.tar.gz using git-import-orig)
  • origin/master (the debianization that your co-maintainer did so far)
  • pristine-tar (optional – information on how to build the binary-identical orig.tar.gz that is in Debian)

Work on the Debian package

  • …work…work…work…
  • git add (what you added/changed)
  • git commit
  • git-buildpackage

If you like the package:

  • …upload to Debian… (dput/dupload)
  • git-buildpackage –git-tag

And then…

Publish your own works to your public repository so that your co-maintainer can fetch what you did

The most efficient protocol to transport Git repositories and their changes is the git:// protocol. (You could also dump your repository into a web server’s htdocs directory and let others fetch it with HTTP.) 


The Debian project is offering Git hosting at You can request a new repository there through a process defined in the Debian wiki.

Using Github

Github is a nifty web service that allows hosting of Git repository. While it’s debatable that Git is actually decentralized and a central repository doesn’t make sense it’s still nice to have a place to pull and push changes. (Of course this applies to as well.) Repositories up to 100 MB that are public are free (beer). They also offer paid plans.

Setting up git-daemon

git-daemon is a software to serve repositories through the git:// protocol. It looks for repositories in /var/cache/git on your public (web-) server. Put up your Git repository as a “bare” repository there. (“Bare” Git repositories just consists of what’s usually in the project’s .git directory but the directory is called project.git)

This will create a copy of your repository on the ‘myserver’. “–mirror” makes it push all the branches (so you don’t miss to push the “upstream” branch) and tags (without upstream/* and debian/* tags git-buildpackage would be very unhappy).

Log into ‘myserver’, go into /var/cache/git/myproject.git and touch the file “git-daemon-export-ok” there. It tells git-daemon that this repository is allowed to be displayed publicly. (I personally prefer to change /etc/sv/git-daemon/run and add the “–export-all” option there. Because if I clone my repository into /var/cache/git I know what I’m doing and don’t accidentally put up something private there.)

To simplify pushing I recommend:

Then you can just:

  • git push

…in the future and get all your commited changes online to the public server.

Now tell your co-maintainers about it so they can “git pull git://myserver/myproject.git” from your server. Make sure you always “git pull” before you start working on the package.

Setting up gitweb (optional)

If you want to show what repositories you are offering you can run ‘gitweb’ on your web server. Just “aptitude install gitweb” on the server and follow the instructions in /usr/share/doc/gitweb/README*

See also

How do I create my own Certificate Authority (CA)

CA is short for Certificate Authority. A CA issues certificates for i.e. email accounts, web sites or Java applets. Actually this only expresses a trust relationship. If you trust the CA then you automatically trust all the certificates that have been issued by the CA. This article helps you set up your own tiny CA using the OpenSSL software.

Common web browsers already “ship” with a number of CAs. That means you usually trust companies like Verisign, AOL and Microsoft. (Do you really?) If you like to see which CAs are currently trusted:

  • Mozilla Firefox: Edit / Preferences / Advanced / Certificates / Manage Certificaes / Authorities
  • Internet Explorer: Extras / Internet options / Content / Certificates / Trusted Root CAs

Your own CA

Certificates usually do not come for free. An excellent exception is the first free CA: CaCert. Currently not all browsers have their certificate built in. Microsoft only seems to trust CAs if they pay an unrealistic amount of money – who’s surprised? It is worth spreading the word since this CA is about trust instead of money.

Otherwise having a valid certificate for your server often just means that you spend money to big companies called trust centers. But perhaps you just need a certificate (i.e. for your private web server running HTTPS at home) and do not really care whether the CA is contained in other people’s browsers. Then you should consider creating your own CA. The only difference is that your clients will get a warning when contacting your server that the CA is not (yet) trusted. This can be either safely ignored or you can make them install your CA’s certificate. It is also a good solution if you need a company-wide CA.

First you need to to install OpenSSL. On Debian this means running apt-get install openssl. Go to the directory where you want to create the files that make up the CA. Next type: /usr/lib/ssl/misc/ -newca

The script will create a new directory named demoCA. The CA’s private key (keep it safe!) and the public key/certificate (which you may need to give to your clients) will be put there. The public certificate is the demoCA/cacert.pem file. It does not matter really what you enter into the fields. Just pick a meaningful name for the common name field so that it’s clear you are looking at a CA – not a person. So name it “ACME Lasagna Certifiate Authority” instead of “Peters Blaphemic’s Fun Certificate”. Pick something that sounds official.

Notice: the CA has an expiry date. The default setting is one year. You may want to edit the file and set Days to ten years.

Create a certificate

Now that you have your own CA you can create certificates for servers. That means you have to do two steps:

  • Your “client” creates a private key (.key) and a certificate request (.req):
    /usr/lib/ssl/misc/ -newreq

  • You sign that request with your CA’s key and create a certificate (.crt) that you send to the client:
    /usr/lib/ssl/misc/ -sign

Note: If your “client” does not send you a certificate request you can create all the necessary files for them.

To simplify things you may want to use my script makecert that you can use to quickly create new certificates for i.e. Apache SSL servers. Run it like this:


You will get three files:

  • (the client’s private key)
  • (the client’s certificate request)
  • (the client’s signed certificate)

The certificate request is just an intermediate file that is not necessary to run a server using that certificate. You just need the private key and the certificate.

If you like to use that certificate for an Apache web server you need to put the private key (.key) and the certificate (.crt) into the same file and call it apache.pem.


cat mailserver.mydomain.crt > apache.pem

Sign a request

Some server create a certificate request (SAP, IIS). You will get that request as a file from the client. Use the following command on that request file:

ca -policy policy_anything -notext -in -days 3650 -out

Some tricks

Show all information about a certificate:

openssl x509 -noout -text < crt

Calculate the MD5 fingerprint of a certificate:

openssl x509 -noout -fingerprint < crt

Calculate the SHA1 fingerprint of a certificate:

openssl x509 -sha1 -noout -fingerprint < crt

The ‘makecrt’ script

# Create SSL certificates
# Christoph Haas <>


if [ -z "$1" ]; then
echo "Usage: $0 [host.domain]"
exit 10

echo "Creating certificate for host $1"

echo "My Country"
echo "My Region"
echo "My City"
echo "My Company"
echo "My Department"
echo $1
echo "webmaster@$1"
) |
openssl req -new -nodes -keyout $1.key -out $1.req -days $DAYS
openssl ca -policy policy_anything -notext -days $DAYS -out $1.crt -infiles $1.req
chmod go= $1.crt $1.key $1.req

Christoph’s OpenVPN Mini-FAQ

OpenVPN is an open-source SSL VPN software. It allows you to connect different (private) networks securely over the internet. It’s the perfect alternative to all the crappy SSL VPN appliances that the salesmen desperately try to sell. See my OpenVPN FAQ for additional questions and answers.

(This is not the official OpenVPN FAQ. It’s just my personal answers to my personal questions.)

IPs and routing

How do I assign my users fixed IP addresses?

Use ”client-config-dir” and push the IP addresses to a certain client using this line in the client-specific configuration file:


This will assign John_Doe the IP address The other IP address is assigned to the OpenVPN server – you won’t see it there through ifconfig though.

The server also needs to route this IP (or a range) through the tunnel. So your server.conf needs to contain a route entry for all the static IPs that you will assign:


Which iptables rules are needed to allow OpenVPN connections?

First you need to allow UDP 1194 incoming and outgoing connections on your main interface: 

iptables -A INPUT -i eth0 -p udp --dport 1194 -j ACCEPT
iptables -A OUTPUT -o eth0 -p udp --dport 1194 -j ACCEPT

Next you need to allow certain traffic going through the tunnel. If you don’t want any restrictions then use: 

iptables -A INPUT -i tun0 -j ACCEPT
iptables -A OUTPUT -o tun0 -j ACCEPT
iptables -A FORWARD -o tun0 -j ACCEPT 

How do I make a network on the remote side of the tunnel accessible?

You need both a route and an iroute configuration directive on your server. 


Note: the iroute statement best belongs in the ”client-config-dir” directory. The route statement needs to be in your global server configuration file.

Also don’t forget to route that network to your OpenVPN server. The route and iroute statements will just tell OpenVPN that this network is supposed to be reached through a VPN tunnel. 

How do I let remote Windows clients browse my network?

Network browsing requires WINS to function across a router even in a full AD network. You will need to configure a WINS server and point your remote users to it.

You will also need to prevent them from assuming responsibility for maintaining the browse list. This is done with a couple of registry changes:


Make sure that IsDomainMaster and MaintainServerList are both set to FALSE.

Of course, any firewalling you are doing in the tunnel will need to allow the underlying NetBIOS traffic.

John A. Sullivan III 


How do I revoke a certificate?

If you want to permanently revoke access for a certain user you need to revoke the certificate that you issued. Revoking means that you list that certificate in a certificate revocation list (CRL). Once your OpenVPN server has a crl-verify option set that points to your CRL the certificates of new incoming connections will be checked against that CRL. If a certificate is listed there the access is denied. See the make-crl and revoke-full commands as part of Easy-RSA. And don’t forget to copy the new CRL to the OpenVPN server. You do not need to restart the server since the CRL is considered automatically everytime a user connects. 

Why is it bad to use static keys?

  • anyone can create an OpenVPN server and fool users (man-in-the-middle-attack)
  • you cannot revoke access for one user but need to distribute a new static key to everyone else 

Which files do I need to keep secret?

The private keys (suffix ‘.key’) need to be kept secret. The certitifcates (suffix ‘.crt’) can be exchanged freely and even sent through unsecured channels like email.


Who is currently connected to my OpenVPN server? 

TELNET interface

Use the TELNET interface and issue a status command. 

Status file

Add these lines to your server configuration file: 

status status.log 5
status-version 2

This will write the current status of the OpenVPN server to the given logfile every 5 seconds in the configuration directory. Lines starting with CLIENT_LIST show you the connected users.

If you like to collect statistics on how many users are online at a given time (MRTG creates nice graphs) you can use this one-liner: 

grep ^CLIENT_LIST /etc/openvpn/status.log | wc -l 

How can I disconnect a client from the OpenVPN server?

Use the TELNET interface and issue a kill command on the common name of the client. The client will be able to reconnect though unless you revoke its certificate. Killing a client may be useful if you have changed a configuration file in the client-config-dir.

Do I have to restart OpenVPN after every configuration change?

Changes to the global configuration file (e.g. /etc/openvpn/server.conf) require a restart of the OpenVPN service. Consider using the ”client-config-dir” option to set client-specific parameters. Such configuration files will be read when a client connects and do not require a restart.

From time to time you will need to restart the server e.g. if you need to add a route entry. Consider adding this lien to your server configuration though: 

keepalive 1 5
push "persist-key"
push "persist-tun"

It will make the client send a "ping" to the server every second. If there is no reply to that "ping" after 5 seconds then the connection will be re-initiated. The default connection timeout is very large and will surely annoy your users. If they get disconnected for less than 10 seconds they will complain less likely. The persist-* settings will make the client keep the tunnel device open so existing connections won’t be interrupted during the renegotiation. Otherwise permanent connections like shell sessions would be disconnected.

How do I use the ‘client-config-dir’ parameter?

The client config directory is a location where you put custom client-specific configuration files. Example in your global configuration (e.g. /etc/openvpn/server.conf):

client-config-dir /etc/openvpn/clients

Then put files with the common names of your users there. The common name must match the filename exactly. Let’s pretend you have a user with the common name "John_Doe" on his certificate. Create a file /etc/openvpn/clients/John_Doe and make it contain configuration directives that should only apply to John Doe. The following directives are allowed there:

  • push
  • push-reset
  • iroute
  • ifconfig-push
  • config

Example /etc/openvpn/clients/John_Doe:


This will assign John Doe the IP on his side of the VPN tunnel. Also the server will learn that the network is on John’s side of the VPN tunnel and route packets there. (Note that you also need to create a "route" in your global configuration to make the OpenVPN server learn this route. The "route" command does not work within a client-config-dir configuration file.)

The charming advantage of client-config-dir configurations is that you don’t need to restart your OpenVPN server to make changes to these files work. Every time a client connects the client-config-dir will be searched for an appropriate file and if one is found the configuration will be applied.

There is also a special DEFAULT file that contains settings in case there is no configuration file for a certain client.

How can I access the TELNET management console?

You need to start OpenVPN with the --management option. For example --management 12345 as a startup parameter will get you access to the TELNET console on port 12345 on localhost. Accessing the console then is as easy as telnet localhost 12345. This is what you get:

Connected to localhost.
Escape character is '^]'.
>INFO:OpenVPN Management Interface Version 1 -- type 'help' for more info

This is a security risk though because everybody can access the console without any further authentication.


Does OpenVPN work with Juniper/Nortel/Checkpoint VPNs?

No. OpenVPN just works with other OpenVPN clients/servers. OpenVPN is not an IPSEC software. It uses SSL to create VPN tunnels instead.

© 2021 - Proudly powered by theme Octo