Modern Kannel: A No-WAP, Systemd-Ready SMS Gateway

Publish date: 2025-07-05

Disclaimer: I have no relation to the Kannel development team or the official Kannel project. This is an independent hobby project based on a Kannel SVN snapshot.

💾 Source Code

📦 GitHub Repository: github.com/vaska94/kannel

Forked from SVN snapshot. Cleaned, modernized, and ready for Rocky Linux 10.


If you’ve worked with SMS gateways in the past decade, you’ve likely encountered Kannel. For those unfamiliar, Kannel is an open-source gateway that allows you to send and receive SMS messages via HTTP, SMPP, or other protocols — typically used by telcos, banks, and bulk SMS providers. Originally designed as both a WAP (Wireless Application Protocol) gateway and SMS gateway, Kannel has been a workhorse of mobile messaging infrastructure since the early 2000s. But times have changed, and WAP has gone the way of the dodo. It was time for Kannel to evolve.

The Problem: Legacy Bloat

Kannel’s codebase had accumulated significant technical debt over its 20+ year history. The project still carried extensive WAP functionality that nobody uses anymore - entire directories dedicated to WML scripts, WBMP image handling, and WAP push services. This legacy code wasn’t just dead weight; it was actively hampering modern deployments:

The stable Kannel 1.4.5 release simply won’t build on modern distributions like Rocky Linux 10 due to library incompatibilities. Even after fixing the build issues, Kannel 1.4.5 kept crashing when using Redis for DLR storage — which was the tipping point that led to this project. I switched to an SVN snapshot version because it contains many fixes, especially for Redis DLR storage support. The only distro still providing Kannel packages is Debian 12, built with ancient libraries. As a Rocky Linux shop, I wasn’t thrilled about running several Debian servers just for SMS gateway functionality.

The Solution: Radical Simplification

Working with Claude AI, I embarked on a modernization journey that would strip Kannel down to its essential purpose: being an excellent SMS gateway. Development was done on Arch Linux (bleeding edge is perfect for catching compatibility issues early), with production deployment targeted at Rocky Linux 10 - a solid enterprise choice for SMS infrastructure. Here’s what I accomplished:

1. Complete WAP Removal

I performed surgical removal of all WAP-related functionality:

# Removed directories:
- wap/           # WAP gateway implementation
- wmlscript/     # WML script engine
- radius/        # RADIUS authentication
- soap/          # Legacy SOAP/ParlayX support
- debian/        # Outdated packaging
- solaris/       # Solaris-specific files (RIP Solaris)

# Removed files:
- bb_udp.c       # WDP/UDP bearer functionality
- seewbmp        # WBMP image viewer
- pixmapgen.pl   # WBMP converter

This wasn’t just a rm -rf operation. I carefully traced through the codebase, removing --disable-wap configure flags, NO_WAP preprocessor blocks, and cleaning up the build system to work without these components.

2. Modern SSL/TLS Support

The old SSL certificates were using 1024-bit RSA with MD5 signatures - completely unacceptable for modern OpenSSL 3.5.0 (especially on Rocky Linux 10 with its strict crypto policies). I replaced them with proper 2048-bit RSA certificates using SHA256:

# Added convenient make targets:
make ssl-certs        # Generate new certificates
make ssl-certs-clean  # Clean up certificate files

3. Systemd Integration

Perhaps the most impactful modernization was adding proper systemd service files. No more ancient init.d scripts, or running services as root! The new services include:

Here’s a snippet from the bearerbox service file:

[Service]
Type=simple
User=kannel
Group=kannel
ExecStart=/usr/local/sbin/bearerbox -v 0 /etc/kannel/kannel.conf
Restart=on-failure
RestartSec=10

# Security hardening
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/var/log/kannel /var/spool/kannel

4. Test Infrastructure Fixes

The test suite was broken due to:

I fixed all of these issues, ensuring tests run cleanly and reliably.

5. PHP Script Modernization

The kannel-monitor PHP script has been updated to support PHP 8.x, ensuring compatibility with modern PHP deployments.

The Results

The modernized Kannel is:

Getting Started with Modern Kannel

Setting up the modernized Kannel is now straightforward:

# Clone the modernized version
git clone https://github.com/vaska94/kannel.git
cd kannel

# Install dependencies 
# For Rocky Linux 10:
sudo dnf install gcc make autoconf automake libtool libxml2-devel \
                 openssl-devel pkgconfig mariadb-devel postgresql-devel \
                 sqlite-devel hiredis-devel

# For Arch Linux:
sudo pacman -S base-devel autoconf automake libtool libxml2 openssl \
               mariadb-libs postgresql-libs sqlite hiredis

# Bootstrap the build system
autoreconf -fvi -I /usr/share/gettext/m4

# Configure with desired options
./configure --enable-ssl --with-ssl=/usr --disable-ssl-thread-test \
            --with-mysql --with-pgsql --with-sqlite3 --with-redis \
            ac_cv_sys_file_offset_bits=64

# Build and install
make -j4
sudo make install

# Set up systemd services
sudo ./contrib/systemd/setup-kannel-user.sh
sudo cp contrib/systemd/*.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable kannel-bearerbox kannel-smsbox

Platform Considerations

Developing on Arch Linux and deploying to Rocky Linux 10 highlighted some interesting platform differences:

Lessons Learned

This modernization effort taught me several valuable lessons:

  1. Don’t be afraid to delete code: Removing 10,000+ lines of WAP code made the project more maintainable, not less capable.

  2. Systemd is a game changer: The old init.d scripts were so poorly designed that we had almost zero logging visibility. Systemd made everything more convenient - journalctl works beautifully, and I was able to split Kannel into two separate services (bearerbox and smsbox) with proper dependencies.

  3. AI-assisted refactoring works: Claude AI was instrumental in understanding the complex interdependencies and safely removing legacy code. However, I didn’t just vibe coding with the AI - I carefully reviewed and tested every change. AI makes mistakes and misses details, but it’s incredibly helpful for accelerating development. What would have taken weeks was completed in a single night using Sublime Text, extensive grep searches, and AI assistance.

  4. Tests are your safety net: The comprehensive test suite gave me confidence that SMS functionality remained intact.

Production Performance

I’ve tested this modernized Kannel extensively in production at Sender.ge, and the results speak for themselves:

Kudos to the original Kannel development team for building such a solid foundation that’s still performant after 20+ years!

What’s Next?

With the WAP baggage gone, our Kannel fork can focus on what it does best: reliable SMS delivery. The immediate challenges ahead:

🏷️ Help Name This Project!

To avoid confusion with the original Kannel project, I’m considering renaming this modernized fork. Current ideas:

Got a better name? Drop your suggestions on X @vaska94 - contributions and ideas welcome!


The code is available at github.com/vaska94/kannel. If you’re running an old Kannel installation, consider upgrading to this streamlined version. Your ops team (and your security auditors) will thank you.


Final Note on AI Usage

Yes, I used AI to help write this article based on my thoughts and experiences. This is NOT an AI-generated article - I provided all the technical information, insights, and experiences, then carefully reviewed everything. I’m making the point that AI can have genuinely useful applications beyond creating junk vibe code. When you have the correct understanding of your domain and can carefully review every change to avoid weird modifications, AI becomes a powerful tool for real-world projects.

Have you modernized any legacy systems recently? What challenges did you face? Reach out on X @vaska94.