I went through what our own ERP answers to the internet, and closed most of it

The system that holds our customer records

One afternoon I sat down with the web server in front of our ERP and listed every address it answered to from the internet. The list was longer than I liked.

We run our own ERP on our hardware in Tyrol. It is where the contact details, offers, invoices and helpdesk tickets of the people who use Tagfalter, the community sites and our hosting live, and where I keep my own task board. We could have taken a CRM or an invoicing service from a US provider and been done in an hour. We did not, for the same reason we build the data center at all: the records of our customers stay on hardware we own, in Tyrol, in the EU. The other side of that decision is that nobody else guards the door, so that job is mine.

The ERP has to be reachable from outside. Our external accountant works in it without a VPN, from the office and sometimes from a phone, so the web client stays public. That part is a given. What I wanted to know was what else was public that did not need to be.

What I found

The database manager page, the one that can create, copy and drop a whole database, answered to anyone who knew the address. It still asked for a master password, but it was there. The programming interfaces the ERP offers to scripts were open to the whole internet as well; I use them from my own automation, nobody else should. The login page took as many attempts as a client cared to send. On the host itself the process listened on every network address and the internal one would have been enough, the list of databases was visible, and the configuration file was writable by every user on that machine. Public self-registration was switched on, which nobody had ever used on purpose. And on one of the gateway machines an old installation from a project that was long dead still had its own name and answered, with no containers behind it.

None of it was broken in a way an attacker could use directly, as far as I could see. It was simply more than a small company needs to expose.

What I changed

The database manager page now returns 404 for everybody, including me (I open it over the internal network when I need it, which is rare). The script interfaces answer only to our VPN, the management network and the cluster nodes. Login, password reset and signup are limited per address. On the host the ERP listens on the internal address only, hides the database list, keeps its configuration file readable by its owner alone, and signup is by invitation. The dead installation is gone from the gateway. I put the rules into the automation that configures our gateways, so a single gateway deploy carries them too, and checked the result from outside and from the LAN. Then I opened the accounting module on my phone, without VPN, to make sure the accountant's path still worked, and it did.

The master password, a few weeks later

The master password of that database manager had been in the configuration file in plain text since the day I installed the ERP. I rotated it, put the new one into our secrets store, and left only a hash in the file.

Two small things cost me time here. I found both only because I checked the container afterwards; the output of the commands had looked fine. I wrote both into our hardening guideline so I do not find them a second time.

Where this stands

The ERP now shows the internet a login page and little else, the accountant can still do the monthly work, and the nightly backups of it have been green since the change. It is still one server; there is no second instance to take over if that machine fails, and I have not decided when that comes. The rate limits are a first guess, I have not tuned them against real traffic yet. The disks of this machine are encrypted: the system disk and the mirrored pair that hold the ERP database and its attachments are LUKS volumes, so a drive on its own tells nothing. The records of our customers stay in Tyrol, on hardware we run.

Author: René Zingerle, CISSP, SSCP
Last Update: 05.11.2026