Converting a Varnish 3.0 VMOD to 4.0

So we’re getting closer to releasing the first proper 4.0 version of Varnish Cache. One of the things we need to fix is to get all the vmod writers to make sure their vmod works with the new version.

Here are my notes from doing just that, in the hope to make it simpler for others.

In 4.0, you don’t need the source tree of Varnish any more. The include files will be enough, and pkg-config will find them for you.

Make sure that /usr/lib/pkgconfig/varnishapi.pc and /usr/share/aclocal/varnish.m4 exists. If you installed Varnish in the standard path/prefix, that should work out of the box. Otherwise, you might to add some symlinks for pkg-config and automake to find the source. (I need multiple varnishd versions when debugging customer problems, so I let them live in /opt/varnishX.Y/ on my laptop)

Pull/merge the new Makefile.am files from the master branch of libvmod-example.

Header files: remove bin/varnishd/cache.h and add cache/cache.h.

Vmod functions are now called with a vrt context as first argument. %s/struct sess \*sp/const struct vrt_ctx \*ctx/g

The old sess struct has been split, some data is in vrt_ctx->req, and some is in vrt_vtx->req->sp. Look up what is where in cache/cache.h. 

I’ve put up the 3.0->4.0 diff for vmod_policy.c as a gist: https://gist.github.com/lkarsten/8039861

There was a bit trouble of finding varnishtest, as src/Makefile was missing the reference entirely. I just fixed it by hand for now. Another thing for the 4.0 todolist, then.

And finally; 

lkarsten@immer:~/work/libvmod-policy/src$ make check
/opt/varnish/bin/varnishtest -Dvarnishd=/opt/varnish/sbin/varnishd -Dvmod_topbuild=/home/lkarsten/work/libvmod-policy tests/test01.vtc
# top TEST tests/test01.vtc passed (1.574)

 

I have a working Varnish 4.0 vmod. :-D

Posted in Uncategorized | Tagged , , | 2 Comments

DNS RBL test address for development

If you are writing code that checks a DNS real-time blockhole list (RBL), it looks like 127.0.0.2 is the standard address that is always in the black/white -list.

This is probably know for most sysadmins/security people and whatnot, but wasn’t entirely trivial to find using Google.

lkarsten@immer:~$ dig 2.0.0.127.dnsbl.sorbs.net @8.8.8.8
; <<>> DiG 9.8.4-rpz2+rl005.12-P1 <<>> 2.0.0.127.dnsbl.sorbs.net @8.8.8.8
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 55083
;; flags: qr rd ra; QUERY: 1, ANSWER: 10, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;2.0.0.127.dnsbl.sorbs.net. IN A
;; ANSWER SECTION:
2.0.0.127.dnsbl.sorbs.net. 2562 IN A 127.0.0.10
2.0.0.127.dnsbl.sorbs.net. 2562 IN A 127.0.0.5
2.0.0.127.dnsbl.sorbs.net. 2562 IN A 127.0.0.7
2.0.0.127.dnsbl.sorbs.net. 2562 IN A 127.0.0.2
2.0.0.127.dnsbl.sorbs.net. 2562 IN A 127.0.0.3
2.0.0.127.dnsbl.sorbs.net. 2562 IN A 127.0.0.9
2.0.0.127.dnsbl.sorbs.net. 2562 IN A 127.0.0.14
2.0.0.127.dnsbl.sorbs.net. 2562 IN A 127.0.0.4
2.0.0.127.dnsbl.sorbs.net. 2562 IN A 127.0.0.6
2.0.0.127.dnsbl.sorbs.net. 2562 IN A 127.0.0.8
;; Query time: 17 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: Wed Dec 11 14:12:20 2013
;; MSG SIZE rcvd: 203
lkarsten@immer:~$

Good to be able to actually test your code for hits also.

(this is for libvmod-policy, so you can deny/reject POST/PUT from spammers in Varnish)

Posted in stuff | Tagged , , , , | Leave a comment

Varnish and Ghost blogging software

So there is a new shiny blogging platform out called Ghost. Looks pretty good to me.

If you want to run it behind Varnish, you’ll soon notice it has the usual problem of setting session cookies everywhere leading to 0% hit rate. 

I have written a Varnish VCL configuration for filtering this in the necessary places, while keeping the admin interface working still.

You can find it here:

https://gist.github.com/lkarsten/6683179

Have fun.

Posted in stuff | Tagged , , | 1 Comment

Testing VMODs with Travis (travis-ci.org)

Travis CI is a service where open source software can run tests automatically on commits. It hooks into github in a silky smooth way.

If you’re developing a Varnish module (VMOD), you probably have started out with our libvmod-example package. It has all the automake magic you need, as well as some simple test cases to test your vmod. Given that you’ve written som varnishtest testcases for it (you really should), you now can get travis to run them as well!

I’ve put a small recipe for this into the libvmod-example package.

Feel free to play around with it, feedback appreciated. For the travis setup bits, consult the travis getting started guide. The final result is something like this, shown for libvmod-cookie:

https://travis-ci.org/lkarsten/libvmod-cookie

Posted in stuff | Tagged , , , , , | Leave a comment

GSM A5/1 rainbow tables in Oslo, Norway

The A5/1 encryption algorithm used in (traditional) GSM networks were proven to be breakable by brute force back in 2009/2010. This means that GSM calls can be intercepted, decoded and listened to by anyone. (SMS also, but that is a different story)

To do this easily you need a 1600 GB big rainbow table.

These files are/were available on bittorrent; a mirror of the torrents is available. The original source on reflextor.com is unavailable.

I’m offering the files for sale on disk or as paid download.

The intent with this is to facilitate further research and experimentation. Drop me an email and we’ll figure out the details.

(PS: I still have the Ettus URSP2 with all daughterboards/cables/antennas needed to play around with this. I don’t use much any longer, available for sale/donation to a good cause..)

Updated 2013-10-23: Clarified language.

Posted in stuff | Tagged , , , , , , | 19 Comments

Building a Varnish VMOD on Debian

From the tutorials department, here are some quick notes on how to install a Varnish VMOD from source.

This is slightly complicated because Varnish demands that a VMOD must be built against the same git commit (or release) as the one that is running. This will be relaxed in future versions.

Current setup is a standalone Varnish VM on Debian Wheezy with Varnish installed from varnish package archives (3.0.4-1~wheezy.)

1. Get the vmod

lkarsten@lb1:~$ git clone https://github.com/lkarsten/libvmod-cookie.git
Cloning into 'libvmod-cookie'...
remote: Counting objects: 253, done.
remote: Compressing objects: 100% (131/131), done.
remote: Total 253 (delta 132), reused 232 (delta 112)
Receiving objects: 100% (253/253), 49.51 KiB, done.
Resolving deltas: 100% (132/132), done.
lkarsten@lb1:~$

2. Get and configure the source tree for the running Varnish

Verify first that you have the necessary package repositories enabled:

lkarsten@lb1:~$ grep varnish /etc/apt/sources.list
deb http://repo.varnish-cache.org/debian/ wheezy varnish-3.0
deb-src http://repo.varnish-cache.org/debian/ wheezy varnish-3.0
lkarsten@lb1:~$

After that, continue with the juicy parts:

lkarsten@lb1:~$ apt-get source varnish 
Reading package lists... Done 
Building dependency tree 
Reading state information... Done 
NOTICE: 'varnish' packaging is maintained in the 'Git' version control system at: 
git://git.debian.org/pkg-varnish/pkg-varnish.git 
Need to get 2,060 kB of source archives. 
Get:1 http://repo.varnish-cache.org/debian/ wheezy/varnish-3.0 varnish 3.0.4-1 (dsc) [2,334 B] 
Get:2 http://repo.varnish-cache.org/debian/ wheezy/varnish-3.0 varnish 3.0.4-1 (tar) [2,044 kB] 
Get:3 http://repo.varnish-cache.org/debian/ wheezy/varnish-3.0 varnish 3.0.4-1 (diff) [14.1 kB] 
Fetched 2,060 kB in 0s (11.4 MB/s) 
gpgv: keyblock resource `/home/lkarsten/.gnupg/trustedkeys.gpg': file open error 
gpgv: Signature made Fri 14 Jun 2013 11:56:48 CEST using RSA key ID 87218D9C 
gpgv: Can't check signature: public key not found 
dpkg-source: warning: failed to verify signature on ./varnish_3.0.4-1.dsc 
dpkg-source: info: extracting varnish in varnish-3.0.4 
dpkg-source: info: unpacking varnish_3.0.4.orig.tar.gz 
dpkg-source: info: applying varnish_3.0.4-1.diff.gz 
lkarsten@lb1:~$
lkarsten@lb1:~$ cd varnish-3.0.4
lkarsten@lb1:~/varnish-3.0.4$ ./autogen.sh
[..]
lkarsten@lb1:~/varnish-3.0.4$ ./configure --prefix=/usr
[..]
lkarsten@lb1:~/varnish-3.0.4$ make

If configure or make fails, you might need some additional packages. Run an apt-get build-dep varnish and work from there. (if editline fails on you, remember to rerun configure after installing it)

3. Build and install the vmod

lkarsten@lb1:~$ cd libvmod-cookie/
lkarsten@lb1:~/libvmod-cookie$ ./autogen.sh
+ aclocal -I m4
+ libtoolize --copy --force
libtoolize: putting auxiliary files in `.'.
libtoolize: copying file `./ltmain.sh'
libtoolize: putting macros in AC_CONFIG_MACRO_DIR, `m4'.
libtoolize: copying file `m4/libtool.m4'
libtoolize: copying file `m4/ltoptions.m4'
libtoolize: copying file `m4/ltsugar.m4'
libtoolize: copying file `m4/ltversion.m4'
libtoolize: copying file `m4/lt~obsolete.m4'
+ autoheader
+ automake --add-missing --copy --foreign
configure.ac:8: installing `./config.guess'
configure.ac:8: installing `./config.sub'
configure.ac:11: installing `./install-sh'
configure.ac:11: installing `./missing'
src/Makefile.am: installing `./depcomp'
+ autoconf
lkarsten@lb1:~/libvmod-cookie$ 
lkarsten@lb1:~/libvmod-cookie$ ./configure VARNISHSRC=~/varnish-3.0.4/
[..]
# and finally
lkarsten@lb1:~/libvmod-cookie$ make
[..]
libtool: link: ( cd ".libs" && rm -f "libvmod_cookie.la" && ln -s "../libvmod_cookie.la" "libvmod_cookie.la" )
make[2]: Leaving directory `/home/lkarsten/libvmod-cookie/src'
make[2]: Entering directory `/home/lkarsten/libvmod-cookie'
rst2man README.rst vmod_cookie.3
make[2]: Leaving directory `/home/lkarsten/libvmod-cookie'
make[1]: Leaving directory `/home/lkarsten/libvmod-cookie'
lkarsten@lb1:~/libvmod-cookie$ 
lkarsten@lb1:~/libvmod-cookie$ sudo make install
[..]
/bin/mkdir -p '/usr/local/share/man/man3'
 /usr/bin/install -c -m 644 vmod_cookie.3 '/usr/local/share/man/man3'
make[2]: Leaving directory `/home/lkarsten/libvmod-cookie'
make[1]: Leaving directory `/home/lkarsten/libvmod-cookie'
lkarsten@lb1:~/libvmod-cookie$

At this point you should have the two vmod files available for Varnish:

lkarsten@lb1:~/libvmod-cookie$ ls -l /usr/lib/varnish/vmods/
total 64
-rwxr-xr-x 1 root root 966 Jul 29 11:11 libvmod_cookie.la
-rwxr-xr-x 1 root root 41538 Jul 29 11:11 libvmod_cookie.so
-rw-r--r-- 1 root root 16128 Jun 17 13:38 libvmod_std.so
lkarsten@lb1:~/libvmod-cookie$

And you are done!

“import cookie” should now work without issue in your /etc/varnish/default.vcl.

Posted in stuff | Tagged , , , , | 4 Comments

Setting client.ip in Varnish VCL with libvmod-ipcast

I’ve written a new Varnish 3.0 VMOD called ipcast.

It has a single function; ipcast.clientip(ipstring) which sets the internal Varnish variable client.ip to whatever IPv4/IPv6 address you give as the argument.

You need this if you want to do ACL checks on connections done through a load balancer or SSL terminator. In those cases client.ip would be 127.0.0.1 and you get the real client’s IP address in the X-Forwarded-For (or similar) header.

You can find it here:

https://github.com/lkarsten/libvmod-ipcast

Here is some example VCL to illustrate how it works. I think the regex needs some work, suggestions/pull requests are welcome.

import ipcast;
acl friendly_network {
    "192.0.2.0"/24;
}
sub vcl_recv {
    if (req.http.X-Forwarded-For !~ ",") {
        set req.http.xff = req.http.X-Forwarded-For;
    } else {
        set req.http.xff = regsub(req.http.X-Forwarded-For,
                "^[^,]+.?.?(.*)$", "\1");
    }

    if (ipcast.clientip(req.http.xff) != 0) {
        error 400 "Bad request";
    }

    if (client.ip !~ friendly_network) {
            error 403 "Forbidden";
    }
}
Posted in stuff | Tagged , , , , | Leave a comment

libvmod-cookie; simpler cookie handling in Varnish VCL

I’ve written a Varnish module (VMOD) to simplify handling of HTTP cookies in Varnish VCL.

In essence it does the usual stuff you’d usually do with regular expressions, but with much simpler syntax and readability.

It works by parsing the req.http.Cookie into a small data structure. Afterwards you can add/delete/filter the list, and finally ask for a combined string back again.

Here is the list of functions:

  • cookie.parse(cookiestring) – parse the http.req.Cookie string.
  • cookie.get(cookiename) – get the value of a single parsed cookie.
  • cookie.set(cookiename, cookievalue) – set the value of a cookie.
  • cookie.delete(cookiename) – delete a single cookie.
  • cookie.filter_except(filterstring). Delete all cookies but the ones matching the names in the comma-separated filterstring (“cookie1,cookie2,cookie3″.) This should be quite useful.
  • cookie.get_string() – return the parsed string.

You can find it here:

https://github.com/lkarsten/libvmod-cookie

Posted in Uncategorized | Tagged , , , , | 7 Comments

Internet routing with Quagga/Linux on Free Internet eXchange Oslo (FIXO)

I run a small internet routing AS (autonomous system), mostly to keep my routing skills up to date (somewhat).

AS56809 get transit from Blix Solutions AS, and it is also present on Free Internet eXchange Oslo (FIXO for short). FIXO can be compared to the somewhat bigger NIX peering point also in Oslo.

If you want to run BGP with Quagga on FIXO, here are a few hints on how to do it. This is made with quagga 0.99.14 from debs on debian wheezy. Let me add that I’m fairly inexperienced at this stuff, so there might be bad advise in this post :)

Make some access lists your networks in it, handy for filtering what routes you will be sending to peers:

conf t
access-list as64496-networks permit 192.0.2.0/24
access-list as64496-networks deny deny

ipv6 prefix-list ipv6-as64496-networks seq 2 permit 2001:db8::/32
ipv6 prefix-list ipv6-as64496-networks seq 10 deny any

Basic quagga/BGP setup:

conf t
password <pw>
ip forwarding
ipv6 forwarding

router bgp 64496
bgp router-id x.x.x.x
network 192.0.2.0/24
address-family ipv6
network 2001:db8::/32

Make some peer groups that contain most of the boilerplate stuff:

router bgp 64496
neigh fixo-peers maximum-prefix 100
neigh fixo-peers soft-reconfiguration inbound
neigh fixo-peers distribute-list as64496-networks out

address-family ipv6
neighbor fixo-peers activate
neighbor fixo-peers soft-reconfiguration inbound
neighbor fixo-peers maximum-prefix 100
neighbor fixo-peers prefix-list ipv6-as64496-networks out

Adding a new IPv4 peering:

conf t
router bgp 64496
neigh 91.198.176.x remote-as yyyy
neigh 91.198.176.x peer-group fixo-peers
neigh 91.198.176.x desc foo@bar.com, +47 1234

Adding a new IPv6 peering:

conf t
router bgp 64496
neigh 2001:7f8:41:0:xxxx:1 remote-as yyyy
neigh 2001:7f8:41:0:xxxx:1 desc foo@bar.com, +47 1234

address-family ipv4 unicast
no neigh 2001:7f8:41:0:xxxx:1 activate
address-family ipv6
neigh 2001:7f8:41:0:xxxx:1 peer-group fixo-peers

Making sure it works

After you’ve set things up, you need to verify that the peering comes up (Established state), and that you’re sending (and receiving) the routes you intend. A common mistake is to send the peer your whole routing table, which is why the distribute-list/prefix-list is in there.

Some handy commands are:

# show how this peering is doing. you want Established.
show ip bgp neigh 91.198.176.xx
# show what routes you are sending to this peer, should be the 1-5 routes you have in the as64496-networks access list.
show ip bgp nei 91.198.176.xx advertised-routes
# what you are getting from the peer. Tab-completion in vtysh is a pain on this command.
show ip bgp neigh 91.198.176.xx received-routes

# reset the peering.
clear ip bgp neigh 91.198.176.xx

If you are running IPv6 peerings, you’ll soon notice that the CLI commands are quite incoherent.

# general overview is under the ordinary ip bgp listing:
show ip bgp nei 2001:7f8:41:0:xxxx:1

# but, if you want to see advertised (and received) routes, these are here:
show ipv6 bgp nei 2001:7f8:41:0:xxxx:1 advertised-routes

Route server

Fixo operates a set of route servers. This is in essence BGP routers that only contains routes, and passes leaves the next-server in announcements as they were. In essence it means that you peer with the route server and get all the routes of all the others that also peer with it. Saves you a lot of emails.

Setting up the peering is identical to any ipv4/ipv6 peering, except that you need to tag/mark the routes you want redistributed by it with a community.

route-map fixo-routeserver-out permit 10 
 set community 61300:61300

Quagga doesn’t allow you to set a route-map on a single member of a peer-group, so you will have to duplicate some config for these two peers.

neighbor 91.198.176.253 remote-as 61300
neighbor 91.198.176.253 description fixo-routeserver-1
neighbor 91.198.176.253 soft-reconfiguration inbound
neighbor 91.198.176.253 maximum-prefix 300
neighbor 91.198.176.253 distribute-list as64496-networks out
neighbor 91.198.176.253 route-map fixo-routeserver-out out

All done!

Posted in Uncategorized | Tagged , , , | Leave a comment

Guidelines for ticketing systems (rant)

If you are writing a ticketing/support request system, make sure to remember the following:

  • It is ok to mangle the subject line if you are the ticketing system.
  • Absolutely no UTF8 support. ø Ã¥ ought to do it.
  • Make sure to include all of the ticket information when notifying the requestor of ticket state change.
  • Do not indicate which part has actually changed, the requestor can guess this easily.
  • All time references should be in local time without any indication of time zone. The requestor will know where you do business and where the support staff is working from.
  • Only insane users has wider screens than 800 pixels. (Hello, osTicket.)

If you are writing the interface used by the support personnel:

  • Any web page must have at least 60 links with similar names.
  • Make a bad re-implementation of SQL as query language. Require this for any searches for old tickets. (Yes, I am looking at you Request Tracker.)
  • Text fields for writing customer replies in must not disable Ctrl-W or ESC, so that bash/vim users are rightfully punished when using muscle memory key bindings.
  • Page loads should take at the minimum 10 seconds.
  • Always show full ticket history, especially that the system has sent copies of email to all involved. The most recent information should be the last to load.
  • Use javascript to render the menu bar after everything else is done. This keeps the user from skipping to another ticket too soon.

It is the law that all ticketing systems must adhere to this golden standard.

Posted in stuff | Tagged , , , , , , | Leave a comment