Installing FreePBX without IPv4 connectivity
My VPS provider of choice is Hetzner Cloud. I’ve been with them for about three years now. I run all of my self-hosted infrastructure there, including my PBXs, client PBXs, my gateway servers (a post for another time), and more.
Hetzner Cloud recently stopped including IPv4 addresses with all of their VPSs. This means that if I don’t want to pay an extra €3.60/month per VPS, I’ve got no IPv4 connectivity.
I recently had a new client request a FreePBX instance. They have no IPv4 requirements, so I went ahead and attempted to set up on a new Hetzner Cloud VPS.
This turned out not to be as simple as I’d expected. As it turns out, asterisk.org, freepbx.org and diguim.com (yes, the Digium domain still hosts some required resources!) have no IPv6 connectivity, which turned out to be a bit of an issue, as the installation wants to download some resources itself. Besides for that, FreePBX has its own update procedure for modules and FreePBX itself.
Here’s everything I ran into, and how I dealt with it.
I am installing FreePBX from source. This will likely still be helpful if you’re using the FreePBX Distro, but there will be very big differences.
Downloading Asterisk and FreePBX
This was the easiest part. I just downloaded the Asterisk and FreePBX tarballs locally, then
scped them to the server.
This would be the same for
DAHDi, but I’m installing this on a VPS, so I didn’t bother with these.
In the “Compile and install Asterisk” stage, after extracting the tarball, the installation guide has you run
contrib/scripts/get_mp3_source.sh. This script does an
svn export from the asterisk.org Gerrit, which is IPv4 only.
(Side note - my understanding is that this can’t be included in the tarball due to patent issues.)
Surprisingly, this repo is not mirrored to Asterisk’s Github. You’ve got two options here:
Download the repo (https://gerrit.asterisk.org/admin/repos/mp3,general) elsewhere and save it to
addons/mp3, then run the script, or
Mirror the repo to Github/any other Git remote (or even another SVN remote, if you really want!) with IPv6 support yourself, and replace the
svn exportline in the script with
git clone [YOUR_GIT_REMOTE]. (This is what I did. Option one is probably quicker.)
make install (depending on what’s been selected at
menuselect) will attempt to download from
downloads.asterisk.org. I dealt with this by setting up a proxy and replacing
downloads.digium.com” on line 112 in
downloads.asterisk.org” on line 25 in
I did this with Traefik on one of my gateway servers:
http: routers: digium-downloads: rule: "Host(`digium.[DOMAIN]`)" entryPoints: - "web" service: digium-downloads asterisk-downloads: rule: "Host(`asterisk.[DOMAIN]`)" entryPoints: - "web" service: asterisk-downloads services: digium-downloads: loadBalancer: passHostHeader: false servers: - url: "http://downloads.digium.com:80" asterisk-downloads: loadBalancer: passHostHeader: false servers: - url: "http://downloads.asterisk.org:80"
You could also set up a transparent proxy and redirect
/etc/hosts. Note that the
Makefile does use HTTPS for
downloads.digium.com, but the site will happily respond on HTTP.
The installer uses NPM to install some components for the web interface. NPM (pre v17 - FreePBX uses v14, which is an LTS supported until April 2023) does support IPv6, but it always attempts to use a v4 address to talk to
You’ll need to force NPM to use IPv6 by overriding DNS in
registry.npmjs.org from the server to get the best address (NPM is behind Cloudflare CDN), and add that to your
FreePBX Modules are hosted at
mirror.freepbx.org, which again, has no IPv6 connectivity.
You can change the remote FreePBX uses after installation, with
# fwconsole setting MODULE_REPO [REPO_HOST].
Again, I used my Traefik proxy server for this:
http: routers: fpbx-modules: rule: "Host(`freepbx.[DOMAIN]`)" entryPoints: - "web" service: fpbx-modules services: fpbx-modules: loadBalancer: passHostHeader: false servers: - url: "http://mirror.freepbx.org:80"
Dashboard not loading
At this point, when you attempt to load the FreePBX dashboard, it may sit at ~80% for about a minute before displaying.
You can solve this by adding the following line to
::1 localhost.localdomain [YOUR_HOSTNAME].
This is because of
sendmail (which runs on every pageload of the dashboard) complaining that your hostname is not an FQDN.
FreePBX does not currently support IPv6 transports, so you’ll need to create them manually.
[ipv6-udp] type=transport protocol=udp bind=[2a01:4f8:1c1b:1788::1]:5060 verify_client=no verify_server=no allow_reload=yes tos=cs3 cos=3
You’ll need this for every endpoint on the system (trunk/extension):
You can get a list of endpoints with
pjsip show endpoints from the Asterisk CLI.
You’ll need this for every registration on the system:
You can get a list of endpoints with
pjsip show registrations from the Asterisk CLI.
While not really to do with the installation, this is something you’ll need to think about.
Very few trunking providers seem to support IPv6 (shout-out to SIPGate - the only provider I was using who does). I’ve got the trunks coming in to my main PBX (dual-stack, IPv6 preferred), and out to this new one.
Multiple Dendrite instances
Hosting multiple Dendrite instances on one server
As mentioned in my previous post, I’m running Dendrite as my Matrix homeserver.
As well as my ideclon.uk Matrix instance, I’m running other instances of Dendrite in the same VM for other purposes. Each of these instances are running as a separate SystemD service.
Here’s the basics of setting up another Dendrite instance on a server already running one.
Note that I am not using Docker.
You'll notice that I'm not using SSL here. SSL is being added by a Traefik proxy. If you're not using a reverse proxy, use
If you are using HTTPS, the default port is 8448, not 8008. (8008 is the default HTTP port, 8448 is the default HTTPS port).
Each instance will need it’s own config file and storage directory. I’m using
You can just copy the default config file and replace:
private_key is the Matrix signing key you’ll generate below.
connection_string, you just need to replace the database name.
Dendrite listens on port 8008 on all interfaces by default. You can override this with the CLI flag
--http-bind-address. Multiple Dendrite instances won’t be able to listen on the same interface/port combo, so you could have Dendrite listen on a different port (as I do - 8008, 8018, 8028…), or on the same port on different IPs (if you have them).
As mentioned in my previous post, other Matrix servers (and clients) will expect to find your server on port 8448. You can deal with this via delegation (see that post), or run a proxy server like Traefik in front of your server and forward based on hostnames.
Generate a new Matrix signing key:
$ ./bin/generate-keys --private-key [NEW_KEY_NAME].pem
Each instance will need it’s own database. Assuming you’re using PostgreSQL (as is recommended in the docs), you can just run
$ sudo -u postgres createdb -O dendrite -E UTF-8 dendrite_[DOMAIN] to create a new database called
dendrite_[DOMAIN], owned by the
SSL / TLS
As mentioned above, this post assumes you’ve set up a Dendrite server before (on the same server you’ll be running this one). This is not a guide on setting up / configuring Matrix. I’m just going to point to the docs on this.
The SystemD service broadly needs to do the following:
Run in your new storage directory
Here’s an example:
Description=[DOMAIN] Dendrite (Matrix Homeserver)
ExecStart=/usr/local/bin/dendrite-monolith-server -config /etc/dendrite/[DOMAIN]/dendrite.monolith.yml –http-bind-address :[PORT]
When running the
./bin/create-account binary, you’ll need to make sure to point it at the correct config file - so
Matrix hosting tips
I’ve recently re setup my Matrix server and there were a few things I wish would have been slightly easier to find. So here they are.
I’m running Dendrite, so some things may be slightly different to Synapse or some other homeservers, but this is mostly just tips on Matrix hosting in general.
Dendrite is running in a VM on a server in my office, and is exposed to the Internet via Traefik running on a cheap VPS. Traefik can talk to Dendrite over Tailscale.
Matrix expects to find your homeserver on port 8448. Dendrite by default listens on port 8008, but this is configurable with the
--http-bind-address CLI flag.
You can really have your homeserver listen on whichever port you like, as long as you configure that in delegation (see below).
Domain / Delegation
I’m @me:ideclon.uk. I needed to have Traefik forward
/_matrix to my Matrix server (and there’s also
/_dendrite for the Dendrite API, but that’s not required). But you don’t need to run your homeserver on the same webserver as your website. For some of my other homeservers, their domains are at
matrix.[DOMAIN_NAME], but I still want the users to be
@[USERNAME]:[DOMAIN_NAME]! To do this, you’ll need delegation.
There are two basic ways to do delegation -
well-known and DNS SRV.
You just need to serve the following two files on your website:
You must set
Access-Control-Allow-Origin * on both of these files. I do this with a
.htaccess file in the
Header add Access-Control-Allow-Origin "*"
The Dendrite docs do a good enough job of this - https://matrix-org.github.io/dendrite/installation/domainname#dns-srv-delegation
My first post - Hello, World!
I don’t really have anything to write here, right now, but hi, I guess!
I’ve left all the default tags below - plus the ones I added.
Bye for now!
tags: keep-this-tag-format, tags-are-optional, beware-with-underscores-in-markdown, example, hello-world, my-first-post