FreeBSD14 and NGINX WITH mod_SSL PHP-FPM

Server blocks, known in Apache as virtual hosts, are the foundation of Nginx’s ability to host multiple domains from a single server.

• Iwan Setiawan WebServer · 15 mins read

When you’re setting up a web server, whether for personal or commercial use, it’s important to understand how the server responds to different types of requests. This knowledge becomes especially relevant when working with Nginx, a popular web server used for its high performance and flexibility in hosting multiple websites on a single machine.

Server blocks, known in Apache as virtual hosts, are the foundation of Nginx’s ability to host multiple domains from a single server. Each block can be configured with specific rules to handle requests for different domain names. This functionality allows Nginx to serve the correct content based on the domain name of the incoming request.

In serving client requests to access the web server, NGINX does not work alone. There are other applications that help it. The role of this third-party application is not only to improve the security system but also often used to integrate NGINX so that it can communicate with other applications.

For security matters, there are many applications that can be used, but the most widely used is OpenSSL. Meanwhile, to connect NGINX with other applications such as databases, PHP is usually used.

In this article, we will discuss how to configure the NGINX web server with OpenSSL and PHP-FPM.

1. System Specifications

  • Sistem FreeBSD: FreeBSD 14.3-PRERELEASE
  • IP Address: 192.168.5.71
  • Hostname: ns4
  • Versi PHP: PHP83
  • Versi NGINX: nginx/1.24.0
  • Dependensi: php83-ctype, php83-mbstring, php83-extensions dan php83-mysqli

2. Configuring NGINX with OpenSSL

The main function of OpenSSL is so that NGINX can run on port 443, which is the HTTPS port supporting the SSL/TLS protocol. By default, configuring NGINX on the FreeBSD system is very easy, even with just a few commands and setting the /etc/rc.conf file on the FreeBSD system, NGINX can run properly.

However, all of that does not guarantee a security system because NGINX can only run on port 80 and does not support a database as a place to store all NGINX data. Because by default NGINX is set to port 80, before we configure PHP-FPM, it would be better if we configure port 443 first. In this article to configure port 443, we use OpenSSL.

a. Create an SSL Certificate

Before you run the OpenSSL command, first create a directory to store the certificate file generated by OpenSSL.

root@ns4:~ # mkdir -p /usr/local/etc/nginx/ssl

In the above command creates an ssl directory, all certificates for NGINX will be stored in this directory. After creating the SSL directory, continue by creating an SSL certificate, as in the following example.

root@ns4:~ # cd /usr/local/etc/nginx/ssl
root@ns4:/usr/local/etc/nginx/ssl # openssl genrsa -des3 -out server.key 2048
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
root@ns4:/usr/local/etc/nginx/ssl #

As always, save the password you created above, because this is just the beginning. The password is needed to authenticate the certificate. Once you have remembered and saved the password, continue with the command below.

root@ns4:/usr/local/etc/nginx/ssl # openssl req -new -key server.key -out server.csr

Before continuing the next command, make a copy of the server.key file above. The name is free, you can determine the name as you wish.

root@ns4:/usr/local/etc/nginx/ssl # cp server.key server.key.backup

The copy file is very important, because we will create an RSA key with it. Then continue with the following command.

root@ns4:/usr/local/etc/nginx/ssl # openssl rsa -in server.key.backup -out server.key
writing RSA key

The next step is to request a certificate signature.

root@ns4:/usr/local/etc/nginx/ssl # openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
Certificate request self-signature ok
subject=C = AU, ST = washington, L = miami, O = mediatama, OU = networking, CN = datainchi.com, emailAddress = datainchi@gmail.com

Once the signature request is approved, create a symlink file from the server.crt file.

root@ns4:/usr/local/etc/nginx/ssl # ln -s /usr/local/etc/nginx/ssl/server.crt /usr/local/etc/nginx/ssl/ssl-bundle.crt

The certificate creation process is complete, now you can set up the NGINX configuration file.

b. Connecting NGINX with SSL Certificate

To connect the SSL certificate that you have created above with NGINX, you must open the main NGINX configuration file, namely /usr/local/etc/nginx/nginx.conf. In that file, you only change a few scripts. An example of an NGINX SSL script can be seen as in the example below.

listen 443 ssl http2;
server_name  localhost;
ssl_certificate /usr/local/etc/nginx/ssl/ssl-bundle.crt;
ssl_certificate_key /usr/local/etc/nginx/ssl/server.key;

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout  5m;
#ssl_ciphers  HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
add_header Strict-Transport-Security "max-age=63072000" always;

After you change the /usr/local/etc/nginx/nginx.conf script, reload the NGINX server.

root@ns4:/usr/local/etc/nginx/ssl # service nginx restart
Stopping nginx.
Waiting for PIDS: 1334.
Starting nginx.
root@ns4:/usr/local/etc/nginx/ssl #

To prove it, open the Google Chrome web browser, and type “https://192.168.5.71/”.

3. Configuring NGINX with PHP-FPM

PHP-FPM (FastCGI Process Manager) is the most popular alternative PHP implementation of FastCGI. PHP (short for PHP: Hypertext Preprocessor) is one of the most popular open source programming languages ​​on the Internet, used for web development platforms such as Magento, WordPress, or Drupal. Although it was originally designed to pre-process plain text in UTF-8 format.

In simple terms, PHP-FPM is a tool that helps web pages in PHP become faster and more efficient, allowing more people to access the website at the same time. It does this by splitting the processing of the PHP web server, which means that the web server can handle more requests at the same time without overloading the system.

When using PHP-FPM, you can improve the performance of your server, allowing it to handle more requests simultaneously and reducing response times for end users.

When a request is made to a PHP page, the web server sends the request to PHP-FPM, which then starts a separate PHP process to handle the request. This means that instead of the web server handling the request and running PHP on each request, PHP-FPM handles the PHP process separately, allowing the web server to handle more requests in parallel.

PHP-FPM also provides resource management processes, such as the possibility to adjust the number of PHP processes running according to the load on the server and limit the resource usage of the server process.

a. Install PHP83

In order for PHP-FPM to communicate with the NGINX server, you must first install PHP. You can run the PHP installation process with the PKG package or the ports system. In this example, we will install PHP with the ports system.

Before you start installing PHP, enable OpenSSL in the /etc/make.conf file. In the file, type the script below.

DEFAULT_VERSIONS+=ssl=openssl

Once you have activated OpenSSL, start the PHP installation process.

root@ns4:~ # cd /usr/ports/lang/php83
root@ns4:/usr/ports/lang/php83 # make install clean

At the beginning of the installation, you will see a message that requires you to choose some options that you should enable or disable. In order to work with nginx, FPM parameters are required for PHP development.

b. Install PHP83 Dependencies

After installing PHP83, you also need to install PHP dependencies. There are many PHP83 dependencies, but to run PHP-FPM, you only need to install php83-ctype, php83-mbstring, php83-extensions and php83-mysqli dependencies. Below is an example of installing PHP83 dependencies.

root@ns4:~ # cd /usr/ports/textproc/php83-ctype
root@ns4:/usr/ports/textproc/php83-ctype # make install clean
root@ns4:/usr/ports/textproc/php83-ctype # cd /usr/ports/converters/php83-mbstring
root@ns4:/usr/ports/converters/php83-mbstring # make install clean
root@ns4:/usr/ports/converters/php83-mbstring # cd /usr/ports/lang/php83-extensions
root@ns4:/usr/ports/lang/php83-extensions # make install clean
root@ns4:/usr/ports/lang/php83-extensions # cd /usr/ports/databases/php83-mysqli
root@ns4:/usr/ports/databases/php83-mysqli # make install clean

As a note, because I prefer to install application programs with the ports system. When installing php83-mysqli, if an error occurs, as a solution you must install php83-mysqli with the pkg package, then continue by reinstalling php83-mysqli with the ports system.

Below is how to install php83-mysqli with the pkg package.

root@ns4:~ # pkg install databases/php83-mysqli

c. php.ini File Configuration

After the PHP installation process is complete, the main PHP configuration file is located in the /usr/local/etc/ directory. This directory contains two sample configurations php.ini-production and php.ini-development. The production version is used for production sites. Errors are only recorded in the web server log file. The development version is used during development. Errors are displayed on the web page and recorded in the log file.

Go to the directory where the configuration file is located, and copy the php.ini-production or php.ini-development file to php.ini.

root@ns4:~ # cd /usr/local/etc
root@ns4:/usr/local/etc # cp php.ini-production php.ini

Open the php.ini configuration file and make changes to the php.ini script. Set it according to your work needs and computer devices. In the /usr/local/etc/php.ini file, you activate the script below.

cgi.fix_pathinfo=0

d. Configuration File /usr/local/etc/php-fpm.d/www.conf

As we have discussed above, the main PHP83 configuration file is php.ini. While the PHP-FPM configuration file is /usr/local/etc/php-fpm.conf. Now you see the last script of the php-fpm.conf file there is a script include=/usr/local/etc/php-fpm.d/*.conf. This means that the PHP-FPM configuration is set with a pool, and the default pool is located in the /usr/local/etc/php-fpm.d directory.

You can customize the default pool according to your needs. However, creating a separate pool is standard practice to have better control over resource allocation for each FPM process.

This file contains all the main PHP-FPM settings. To run PHP-FPM with NGINX you must enable several scripts in the /usr/local/etc/php-fpm.d/www.conf file, as in the following example.

user = www
group = www
listen = /var/run/php-fpm.sock
listen.owner = www
listen.group = www
listen.mode = 0660

e. Configuration File /usr/local/etc/nginx/nginx.conf

The purpose of this configuration is to connect NGINX with PHP-FPM. In order for PHP-FPM to run with NGINX, you must type a PHP script in the NGINX configuration file. Below is an example of a script that you must type in the /usr/local/etc/nginx/nginx.conf file.

location ~ \.php$ {
        try_files $uri =404;
	root  /usr/local/www/nginx;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass unix:/var/run/php-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $request_filename;
        include fastcgi_params;
    		   }

f. Enable PHP-FPM

After you set the PHP-FPM and NGINX configuration files, you need to enable it so that PHP-FPM can run during the boot process. In the /etc/rc.conf file, type the script below.

php_fpm_enable="YES"

To get PHP-FPM up and running, reload NGINX and PHP-FPM.

root@ns4:~ # service php-fpm restart
Performing sanity check on php-fpm configuration:
[15-May-2025 10:45:54] NOTICE: configuration file /usr/local/etc/php-fpm.conf test is successful
Stopping php_fpm.
Waiting for PIDS: 965.
Performing sanity check on php-fpm configuration:
[15-May-2025 10:45:54] NOTICE: configuration file /usr/local/etc/php-fpm.conf test is successful
Starting php_fpm.


root@ns4:~ # service nginx restart
Stopping nginx.
Waiting for PIDS: 798.
Starting nginx.
root@ns4:~ #

3. Checking nginx and PHP

Make sure the UNIX socket is open by checking PHP-FPM whether it is using a UNIX socket, use the sockstat command below.

root@ns4:~ # sockstat -u | grep php-fpm
www      php-fpm      807 9   stream /var/run/php-fpm.sock
www      php-fpm      806 9   stream /var/run/php-fpm.sock
root     php-fpm      805 5   stream -> [805 7]
root     php-fpm      805 7   stream -> [805 5]
root     php-fpm      805 8   stream /var/run/php-fpm.sock

Once everything is set up, the next step is to check it. Is PHP-FPM connected to NGINX. The first step you have to do is delete the default symlink directory “/usr/local/www/nginx” and create another directory.

root@ns4:~ # unlink /usr/local/www/nginx
root@ns4:~ # mkdir -p /usr/local/www/nginx

Now go to ‘/usr/local/www’ directory and copy the default ‘index.html’ file from ‘nginx-dist’ directory.

root@ns4:~ # cd /usr/local/www
root@ns4:/usr/local/www # cp nginx-dist/index.html nginx/

To check all the above configurations, you create an index.php file in the /usr/local/www directory. In the /usr/local/www/index.php file, you type the script below.

<?php 
phpinfo(); 
?>

Now test the nginx configuration and make sure there are no errors, then restart the NGINX and PHP-FPM services.

root@ns4:~ # nginx -t
root@ns4:~ # service nginx restart
root@ns4:~ # service php-fpm restart

Open your web browser and type the server IP address “https://192.168.5.71/info.php”, in your browser’s address bar.

Now you will get a snippet of information about your PHP installation and configuration. If it looks like the image above, you can be sure that the NGINX server is connected to PHP-FPM.