Stefano Marinelli

Stefano Marinelli's avatar
Stefano Marinelli
npub1mv5m...32l4
BSD.cafe and illumos Cafe "Barista", Founder and System Administrator, Unix enthusiast (FreeBSD, NetBSD, OpenBSD, DragonflyBSD, illumos and Linux), with a keen eye for everything happening in this world and the fascinating beings that populate it. I enjoy music, photography, and, of course, technology. My other blogs: https://it-notes.dragas.net (IT Notes) - https://my-notes.dragas.net (My Notes) - My main Fediverse profile is nostr:npub1ef53dd26zz26wlxa70xrl238fywamsrfp24nxxysesczwv425r0q6tgcpc Powered by: WordPress
<p>Tired of the Linux/Docker &#8220;monoculture&#8221; for WordPress? This article guides you step-by-step through the secure installation of WordPress on FreeBSD using BastilleBSD. Discover how jail separation, performance, and the versatility of ZFS offer a more robust and easily manageable environment, far from common vulnerabilities often linked to poorly maintained plugins. Get ready to make your site more secure and reliable.</p>
WordPress is one of the most widely used platforms for publishing content online. It’s often criticized as an insecure platform, but in reality WordPress itself is secure – [it’s the many plugins, unmaintained or poorly developed, that generate significant vulnerabilities]( ). Many people host WordPress on Linux, often using Docker. While this is a valid approach, there are excellent alternatives – sometimes even better ones – for getting your WordPress site online in a secure, reliable, and updatable manner. The goal is to make the web a safer place and avoid the computing monoculture that increasingly pushes toward uniformity of solutions and setups – an attitude that [I believe is harmful even when the solutions are open source]( ). For this type of setup, therefore, I’ll describe how to accomplish everything using FreeBSD. The jail separation, performance, and ZFS versatility – all reasons that support this choice. This guide will serve as a foundation – everything will work at the end, but it won’t cover all possible combinations or configurations. We’ll be using **[BastilleBSD]( )**, which supports both ZFS and UFS. While FreeBSD’s base system has everything needed to create and run jails, BastilleBSD is incredibly useful for managing them. Since it’s written in shell script and has no database dependencies, management and [backups are straightforward]( ). Furthermore, moving jails becomes extremely simple – either by using the *bastille* command directly or by copying the files (or datasets, if you’re using ZFS). BastilleBSD also supports templates, but for this tutorial, we’ll perform the operations manually to understand each step. First, install Bastille:<code>pkg install bastille</code> Next, run the setup process:<code>bastille setup</code> Now, bootstrap the desired FreeBSD release:<code>bastille bootstrap 14.3-RELEASE update</code> With that, BastilleBSD is ready to go.## Creating the JailsNow, let’s create the jail that will contain Apache, PHP, and WordPress:<code>bastille create apache 14.3-RELEASE 10.0.0.254 bastille0</code> **Note:** This command will only create and assign an IPv4 loopback address. For IPv6, the simplest solution is to assign an address for the jail directly to the host’s interface. To do this, note an available IPv6 address and assign it to the jail. For example, if the host’s network interface is vtnet0:<code>bastille edit apache</code> Add the following lines to the configuration file:<code>ip6 = new;ip6.addr = "vtnet0|2001:0DB8:1::443/64";</code> Restart the jail:<code>bastille restart apache</code> Next, let’s ensure that connections to the host’s ports 80 and 443 are redirected to the apache jail:<code>bastille rdr apache tcp 80 80bastille rdr apache tcp 443 443</code> Now, if using ZFS, let’s create a dedicated dataset for WordPress and mount it in the jail. The reason is simple: decoupling the Apache jail from the WordPress directory will allow for updates, rollbacks, etc. of the Apache jail without touching the WordPress files. I assure you that, in the long run, this approach will save many headaches.<code>zfs create zroot/wordpressbastille mount apache /zroot/wordpress/ /usr/local/www/wordpress nullfs rw 0 0</code> Now, let’s create the jail that will contain MariaDB:<code>bastille create mariadb 14.3-RELEASE 10.0.0.253 bastille0</code>## Configuring the MariaDB JailAccess the MariaDB jail’s console:<code>bastille console mariadb</code> Once inside, install the MariaDB server:<code>pkg install mariadb118-server</code> Enable and start the mysql-server service:<code>service mysql-server enableservice mysql-server start</code> Now, access the MySQL command line to set up the WordPress database:<code>mysql</code> Execute the following SQL commands (you should use more secure user, password, etc.):<code>CREATE USER wp@10.0.0.254 IDENTIFIED BY 'password';CREATE DATABASE wordpress;GRANT ALL PRIVILEGES ON wordpress.* TO wp@10.0.0.254;FLUSH PRIVILEGES;</code> Exit the MariaDB jail console to return to the host.## Configuring the Apache & PHP JailNow, let’s configure the apache jail. First, access its console:<code>bastille console apache</code> Inside the jail, install PHP and all the necessary extensions. We won’t install WordPress from the FreeBSD package – while it’s updated and maintained, I prefer to manage dependencies manually. It will be easier to manage updates in the long term, such as changing PHP versions, etc. At the time of writing this article, for example, the WordPress package depends on PHP 8.3 while I prefer to use 8.4.<code>pkg install php84 php84-bcmath php84-bz2 php84-calendar php84-ctype php84-curl php84-dom php84-exif php84-fileinfo php84-filter php84-ftp php84-gd php84-gettext php84-iconv php84-intl php84-mbstring php84-mysqli php84-opcache php84-pcntl php84-pdo php84-pdo_mysql php84-pecl-imagick php84-phar php84-posix php84-readline php84-session php84-shmop php84-simplexml php84-soap php84-sockets php84-sodium php84-tokenizer php84-xml php84-xmlreader php84-xmlwriter php84-xsl php84-zip php84-zlib</code> Next, install Apache:<code>pkg install apache24</code> Modify /usr/local/etc/apache24/httpd.conf to enable the required modules. Uncomment or add the following lines:<code>LoadModule mpm_event_module libexec/apache24/mod_mpm_event.so#LoadModule mpm_prefork_module libexec/apache24/mod_mpm_prefork.so#LoadModule mpm_worker_module libexec/apache24/mod_mpm_worker.so...LoadModule proxy_module libexec/apache24/mod_proxy.so...LoadModule proxy_fcgi_module libexec/apache24/mod_proxy_fcgi.so...LoadModule ssl_module libexec/apache24/mod_ssl.so...LoadModule rewrite_module libexec/apache24/mod_rewrite.so</code> Enable and start the Apache service:<code>service apache24 enableservice apache24 start</code> To optimize performance, enable PHP-FPM to listen on a socket. Modify the /usr/local/etc/php-fpm.d/www.conf file. Comment out this line:<code>;listen = 127.0.0.1:9000</code> And add these lines:<code>listen = /tmp/php-fpm.socklisten.owner = wwwlisten.group = www</code> Now, we need to configure Apache to use PHP-FPM correctly. Create the file /usr/local/etc/apache24/Includes/php-fpm.conf and add the following:<code>&lt;FilesMatch \.php$&gt; SetHandler proxy:unix:/tmp/php-fpm.sock&lt;/FilesMatch&gt;</code> Restart Apache for the changes to take effect:<code>service apache24 graceful</code> It’s good practice to copy the production PHP template to the final, modifiable php.ini file, which can be customized with the required options and limits:<code>cp /usr/local/etc/php.ini-production /usr/local/etc/php.ini</code> Make any desired changes now (or later), then enable and start PHP-FPM:<code>service php_fpm enableservice php_fpm start</code>## Installing WordPressNavigate to the web server’s root directory:<code>cd /usr/local/www</code> Download and extract the latest version of WordPress:<code>fetch https://wordpress.org/latest.zipunzip latest.zip</code> Set the correct permissions:<code>chown -R www:www wordpress/</code> Now, create an Apache virtual host configuration file at /usr/local/etc/apache24/Includes/wordpress.conf – be sure to modify the “example.com” with your own real domain name:<code>&lt;VirtualHost *:80&gt; ServerAdmin webmaster@example.com ServerName example.com ServerAlias www.example.com DocumentRoot /usr/local/www/wordpress &lt;Directory /usr/local/www/wordpress&gt; DirectoryIndex index.php index.html index.htm Options FollowSymLinks MultiViews AllowOverride All Require all granted &lt;/Directory&gt; ErrorLog "/var/log/httpd-example.com-error.log" CustomLog "/var/log/httpd-example.com-access.log" combined&lt;/VirtualHost&gt;</code> Finally, restart Apache one more time:<code>service apache24 graceful</code> The server will now respond on port 80 with the specified hostname, but this is absolutely not optimal or recommended. It’s therefore appropriate to generate a certificate to enable HTTPS. For a simple solution, I recommend installing certbot with the Apache plugin to manage everything through Apache:<code>pkg install py311-certbot py311-certbot-apache</code> In order to automatically renew the certificates, add this line to /etc/periodic.conf:<code>weekly_certbot_enable="YES"</code> And, once installed, generate the certificate:<code>certbot --apache -d example.com -d www.example.com</code> You can now proceed to connect to the specified URL and begin with the WordPress guided installation, remembering the authentication and database details (the host, in this example, is 10.0.0.253 – not localhost, since we installed it in a dedicated jail). Congratulations, your site is installed and operational. Ready to receive content for publishing. It’s exposed on IPv4 and IPv6, with HTTPS (and automatic certificate renewal, managed directly by FreeBSD) and separated from the database. Generally, I prefer to add an additional jail with a reverse proxy. This way it will be possible to install different software in different jails, ensuring that the reverse proxy “routes” requests correctly. I’ll explain this procedure in a future article. While this is my inaugural FreeBSD post for the BSD Cafe Journal, I’ve actually written extensively on the topic for my own blog, image
<p>I&#8217;m thrilled to share my excitement for EuroBSDCon 2025 in Zagreb! After an incredible experience last year and at BSDCan, I can&#8217;t wait to reconnect with the amazing BSD and open-source community. This year, Jeroen and I are even presenting our talk, &#8220;Liberating the social web using *BSD&#8221;. Come join us!</p>
Yesterday, [the schedule for the next EuroBSDCon]( ), which will be held in Zagreb, Croatia, from 25 to 28 September 2025, was published. Last year I attended EuroBSDCon and it was a fantastic experience. I enjoyed every single moment, and connecting with the people who conceive, develop, disseminate, and are passionate about *BSD and the open-source world was an unforgettable experience. I flooded the Venue with BSD Cafe stickers and attended some incredibly interesting presentations. I wrote about it [in an article for the FreeBSD Journal]( ), where I tried, as much as possible, to convey the positivity I felt at the event. Such a positive experience pushed me, a few months later, [to propose a talk for BSDCan as well]( ) – an incredible experience itself, which I will write about in more detail later. Reading this year’s program, I see a problem that I also had to face last year and last month at BSDCan: there are so many interesting presentations that they will overlap. Fortunately, the video team will provide live streams and recordings of the individual talks, allowing us to watch the presentations even if delayed. In Zagreb, Jeroen ( @h3artbl33d :openbsd: :antifa: – admin of Exquisite.social) and I will present “[Liberating the social web using *BSD]( )” – a 90 minutes presentation where we will talk about our experiences with Exquisite and BSD Cafe – delving into both technical and human details – an incredible experience from both points of view. I suggest taking a look at the program and, if possible, participating. I can assure you it’s definitely worth it. image
<p>After managing hundreds of WordPress sites over the years, one thing is clear: the core is solid &#8211; it’s the outdated, poorly written plugins that open the doors to attacks. At OSDay 2025, I attended a talk that confirmed this and shed light on a massive bug bounty hunt that closed nearly 1,000 vulnerable plugins.</p>
One of the reasons I’m always so happy to attend conferences and technical events (the *real* ones – not the flashy, sponsor-driven ones designed just to sell products or services) is because I get to meet amazing people and always come away having learned something new. I’ve been using WordPress since 2006 and have been managing hundreds of installations from a sysadmin perspective. Over time, I’ve noticed a clear pattern: most hacks and compromises happen through plugins or outdated installations. And often, these installations (and plugins) become outdated because they’ve been patched together so messily that updating them becomes nearly impossible – especially when the PHP version changes. In March 2025, I attended a fantastic conference: [OSDay 2025]( ). I gave a talk on [why I believe it makes perfect sense to consider the BSDs in 2025]( ), but many of the other talks were truly eye-opening. To [mark the launch of the BSD Cafe Journal]( ), I’d like to share the link to a particularly interesting talk by Maciek Palmowski: *“How we closed almost 1k plugins in a month — the biggest WordPress bug bounty hunt.”* What struck me right away was how much his analysis of WordPress security aligned with what I’ve seen over the years: WordPress, out of the box, is reasonably secure. It’s the plugins – often old, unmaintained, or poorly written – that make it vulnerable. I highly recommend watching his talk. It’s definitely worth your time. image
<p>The wait is over! Pour yourself a cup, because The BSD Cafe Journal is officially open! Let the journey into the world of BSDs begin.</p>
Dear friends of the BSD Cafe, This idea has been in my mind since the very beginning of this adventure, almost two years ago. Over time, several people have suggested it. But until recently, I felt the timing just wasn’t right — for many reasons. Today, I believe it finally is. So I’m happy to announce a new service: **The BSD Cafe Journal**.### What is The BSD Cafe Journal?At first, I thought I’d use BSSG for it (I even added multi-author support with this in mind), but in the end, it didn’t feel like the right tool for the job. The idea is to create a **multi-author space**, with content published on a fairly regular basis. A reference point for news, updates, tutorials, technical articles — a place to inform and connect. Just like people in Italy used to stop by cafés to read the newspaper and chat about the day’s news, the BSD Cafe Journal aims to be a space for reading, sharing, and staying informed — all in the spirit of the BSD Cafe.### What it’s Not<li>It’s not here to replace personal blogs, or excellent newsletters like Vermaden’s.</li><li>It’s not an aggregator.</li>### What it *Is*<li>A place where authors can write original content.</li><li>A space to share links to posts on their own blogs or elsewhere.</li><li>A platform to publish guides, offer insights, or dive into technical explanations.</li>### Our Guiding PrinciplesThe guiding principles are the same as always: **positivity, constructive discussion, promoting BSDs and open source in general.**<li><strong>No hype:</strong> Sharing a cool new service is fine, posting non-stop about the latest trend is not.</li><li><strong>No drama, no politics:</strong> The goal is to bring people together, not divide them. To inform, not inflame.</li><li><strong>Respect, tolerance, and inclusivity are key.</strong> Everyone should feel welcome reading the BSD Cafe Journal — never judged, offended, or excluded.</li>### Why WordPress?The platform I’ve chosen is WordPress, for several reasons:<li>It’s <strong>portable</strong> (runs well on all BSDs).</li><li>It has great built-in <strong>role management</strong> (contributors, authors, etc.).</li><li>And — last but not least — it supports <strong>ActivityPub</strong>.</li> This means every author will have their own identity in the Fediverse and can be followed directly, and it’ll also be possible to follow the whole Journal. Original and educational content is encouraged, but it’s also perfectly fine to link to existing articles elsewhere. Personally, I’ll link my technical posts from ITNotes whenever I publish them there. The goal is simple: a **news-oriented site, rich in content, ad-free, respectful of privacy** — all under the BSD Cafe umbrella.### Getting InvolvedContent coordination will happen in a dedicated Matrix room for authors. [There’s also a public room]( ) for discussing ideas, giving feedback, and sharing suggestions. Of course, I can’t do this alone. A journal with no content is just an empty shell. So here’s my **call to action**: Who’s ready to lend a hand? If you enjoy writing, explaining, sharing your knowledge — **the Journal is waiting for you!** image