How to Rewrite URLs with mod_rewrite for Apache on Ubuntu 24.04 LTS using PHP

Image : How to Rewrite URLs with mod_rewrite for Apache on Ubuntu 24.04 LTS using PHP

How to Rewrite URLs with mod_rewrite for Apache on Ubuntu 24.04 LTS using PHP

Mod_rewrite is a powerful and flexible module used to perform URL rewriting, allowing you to manipulate URLs as they are requested by clients.

Why Use mod_rewrite

mod_rewrite is an Apache module that provides a powerful and flexible way to rewrite URLs. Here are some common reasons to use it:

Improving SEO: Clean, descriptive URLs are better for search engine optimization (SEO) and user experience. For example, example.com/products/123 can be rewritten to example.com/products/special-widget, making it more readable and relevant.

Model-View-Controller: Model-View-Controller (m-v-c) is a design pattern used in software development. In the case of M-V-C the Uniform Resource Identifier (URI) for https://www.domain.tld/edit/login/1 is the string user/edit/1. User is the controller, edit is the action or method within the controller, and the number 1 is an argument or the user’s id.

Redirecting URLs: It allows for easy redirection of old URLs to new ones. This is particularly useful when you’ve changed the structure of your website or need to redirect traffic from outdated links.

Creating User-Friendly URLs: You can create user-friendly URLs by hiding query strings and parameters. For example, example.com/article?id=456 can be rewritten to example.com/article/456.

Implementing Custom URL Structures: If you have a dynamic website and want to implement a custom URL structure, mod_rewrite can handle the translation of friendly URLs to the underlying script.

Handling Requests Dynamically: It allows for the handling of requests dynamically based on various conditions, such as redirecting requests based on the user agent, geographical location, or other request headers.

Enforcing HTTPS: You can use mod_rewrite to enforce HTTPS by redirecting all HTTP traffic to HTTPS, enhancing security.

Access Control: You can use rewrite rules to control access to certain parts of your site based on IP addresses, user agents, or other criteria.

Cache-Control: You can use it to manage caching by rewriting URLs in a way that incorporates versioning or other mechanisms to control how content is cached.

Overall, mod_rewrite provides a versatile tool for managing URLs and can be an essential part of maintaining a well-organized, user-friendly, and SEO-optimized website.

Steps to Configure mod_rewrite

1) Run this command on the command line: sudo a2enmod rewrite – enables the Apache mod_rewrite module.

2) After enabling the module, you must restart Apache to apply the changes. On the command line run the command sudo systemctl restart apache2.

3) Creating and configuring the .htaccess file. Change the directory to the docroot of the virtual host. Enter cd /var/www/[doman]/public_html/ on the command line. Then enter the command sudo vi .htaccess. Make sure to replace [doman] with your domain name.

Cut and paste the following code into the file being edited by vi.

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /
    # Remove index.php from the URL
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.*)$ index.php/$1 [L]
</IfModule>

Then save the file.

The .htaccess Directives Explained

<IfModule mod_rewrite.c> : This directive starts a block of configuration that will only be applied if the mod_rewrite module is loaded.

RewriteEngine is a directive used in Apache HTTP Server’s mod_rewrite module. It controls whether URL rewriting rules are enabled or disabled for a particular directory or virtual host.

RewriteBase sets the base URL path for the rewrite rules that follow in the .htaccess file. This is particularly useful when your site is located in a subdirectory, and you need to ensure that your rewrite rules are interpreted correctly relative to that directory.

RewriteCond %{REQUEST_FILENAME} !-f specifies that the rewrite rule following this condition should only be applied if the requested filename does not correspond to an existing file on the server. This is often used in conjunction with RewriteRule to handle URL rewriting, such as redirecting requests to a front controller or a specific script when the requested file isn’t found.

RewriteCond %{REQUEST_FILENAME} !-d is used to apply the following RewriteRule only when the requested URL does not correspond to an existing directory on the server. This is commonly used in scenarios where you want to handle requests dynamically when the requested resource isn’t a real directory, such as routing to a specific script or controller when the directory structure doesn’t match the request.

RewriteRule ^(.*)$ index.php/$1 [L] in summary, this rule tells Apache to redirect any URL request to the root index.php, appending the original URL path to the index.php file for processing. For instance, a request for /something would be internally redirected to index.php, and the string something would be processed accordingly. This setup is commonly used in frameworks or applications where routing is handled by a single entry point, such as index.php, and the rest of the URL is used to determine the specific resource or action(s).

</IfModule> ends the block that was started with the command <IfModule mod_rewrite.c>. All the commands within this block will be applied if the Apache mod_rewrite module is enabled.

The design pattern Model-View-Controller (M-V-C) is a single point of entry model that utilizes the above .htaccess code to transfer the URI entered into the browser, to the root index file. In the case of a PHP M-V-C application, these directives entered into the .htaccess work in conjunction with the PHP function $_SERVER[‘REQUEST_URI’] to determine what controller and method to run along with any arguments. The URL would look something like this your-domain.TLD/controller/method/arg1/argn….

4) For mod_rewrite to work using the above .htaccess directives, you need to configure Apache to allow overrides in your site’s configuration. This is usually done in the <Directory> block of your Apache virtual host configuration files.

At the command line enter cd /etc/apache2/sites-available/.

Enter sudo vi [domain].conf on the command line. Don’t forget to replace [domain] with your domain name.

Insert the following code :

<Directory /var/www/[domain]/public_html/>
    Options Indexes FollowSymLinks
    AllowOverride All
    Require all granted
</Directory>

After editing, save the file and exit the editor.

Replace [domain] with your domain name.

This block specifies that the .htaccess file in the directory listed. is allowed to override any server settings for this directory. This works in conjunction with the above .htaccess file directives.

When complete, your virtual host configuration file should look something like this:

<VirtualHost *:80>
    ServerAdmin webmaster@[domain]
    ServerName [domain]
    ServerAlias www.[domain]
    DocumentRoot /var/www/[domain]/public_html

    <Directory /var/www/[domain]/public_html/>
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/[domain].error.log
    CustomLog ${APACHE_LOG_DIR}/[domain].access.log combined
</VirtualHost>

Replace [domain] with your domain name.

5) Test the Apache configuration by running apachectl configtest.

When you run apachectl configtest, Apache will check your configuration files for any mistakes and report them back to you, allowing you to fix any errors before restarting or reloading the server.

6) Configure the index.php file. Enter the command line command cd /var/www/[domain]/public_html/.

Then enter the command vi index.php.

Replace what is in the index.php file with the following (or create the file if not there):

<?php
    echo '[domain] - ';
    echo $_SERVER['REQUEST_URI'];
?>

In PHP, <?php is the PHP opening tag that signals Apache to start processing PHP code.

echo ‘[domain] – ‘;

echo $_SERVER[‘REQUEST_URI’];

The echo command is used to output data to the browser or the console. In this case, it will echo the string [domain] – ‘ and the output of the PHP command $_SERVER[‘REQUEST_URI’].

The PHP command $_SERVER[‘REQUEST_URI’] returns the URI (Uniform Resource Identifier) of the page being requested.

And the last line, ?> signals to Apache to stop processing PHP code.

Anything between <?php and ?> is treated as PHP code.

6) At this point we need to restart Apache so all these changes take effect. On the command line enter the command sudo systemctl restart apache2.

7) Testing

Ensure your rewrite rules are working correctly by testing them in your browser. Open a browser and enter http://[domain]/controller/method/arg1/arg2/arg3 in the URL of the browser and hit enter. You should see the output of the PHP program we created. The output should look like this: [domain] – /controller/method/arg1/arg2/arg3

8) Troubleshooting

If mod_rewrite doesn’t seem to be working:

Run apachectl configtest from the command line. If there is any configuration issues, address them and run apachectl configtest again. Repeat until all issues are corrected.

Another tool that can help you with the Apache mod_rewrite configuration is to run the following command on the command line : sudo tail -f /var/log/apache2/error.log

If there are any errors in the Apache log you can use Google search and/or you can use [https://chatgpt.com/] Artificial Intelligence (AI).

Some other things you can do is :

– Ensure there are no syntax errors in your .htaccess file or Apache configuration.

– Verify that the .htaccess file is in the correct directory : sudo vi /var/www/[domain]/public_html/.htaccess

– Ensure that the AllowOverride directive is set correctly in your Apache configuration : sudo vi /etc/apache2/sites-available/[domain].conf

– Verify the index.php file is configured properly : sudo vi /var/www/[domain]/public_html/index.php

If your Apache virtual host configuration is not working try the following command line commands in order :

sudo a2enmod rewrite

sudo systemctl restart apache2

apachectl configtest

Conclusion

The Apache mod_rewrite module has many reasons for its use. In this article, we cover how to enable the mod_rewrite module, and how to restart Apache. We learned how to create the .htaccess file and we learned what code to put inside of the .htaccess file. We learned what the .htaccess directives mean and what they do. We configured the Apache virtual host configuration file to take advantage of many of the features of the mod_rewrite module. Mostly how it supports the M-V-C design pattern in PHP. Lastly, we learned how to test and troubleshoot the mod_rewrite configuration.

How to Use Windows Linux MacOS Hosts File Instead of DNS on a Local Network

Image : How to Use Windows Linux MacOS hosts file instead of DNS on a Local Network

The Linux, Windows, and MAC hosts file is a system file used to map hostnames to IP addresses. When a program or user on a Linux, Windows, or MAC system tries to connect to a hostname, the operating system first looks in this file to see if there’s a corresponding IP address. If it finds one, it uses that IP address instead of querying a DNS server.

Couple that with a non-routable top-level domain (TLD) such as .internal the Linux, Windows, and MAC hosts file can be a useful strategy for managing internal network resources without the need for a Domain Name System (DNS) server on your local/private network.

Domain Name System

The DNS system translates human-friendly domain names, like www.example.com, into IP addresses, which are used by computers to identify and communicate with each other over the Internet/intranet. Basically, it acts like a phone book for the Internet/intranet, converting names into numbers so that browsers can load websites.

The .internal TLD

The .internal TLD is not a standard, globally recognized TLD and is intended for internal use only. It’s useful for private networks where you don’t want your internal domain names to conflict with external domain names.

The hosts file on your local machine maps hostnames to IP addresses, which can be used to route traffic within your internal/private network.

Private Non-Routable IP Addresses

  • 10.0.0.0 to 10.255.255.255 (10.0.0.0/8) Note that /8 is a subnet mask in CIDR notation.
  • 172.16.0.0 to 172.31.255.255 (172.16.0.0/12)
  • 192.168.0.0 to 192.168.255.255 (192.168.0.0/16)

How CIDR Notation Works

Network Portion: The prefix length determines the network portion of the IP address. For example, in 192.168.1.0/24, the /24 prefix means the first 24 bits are used to identify the network, and the remaining 8 bits (in a 32-bit IP address) are used for host addresses within this network.

A host is a device that has been assigned an IP address.

Host Portion: The remaining bits after the prefix length are used for individual host addresses within the network. In the /24 example, this means there are 2^8 (256) possible addresses, with 254 usable for hosts (excluding the network address and broadcast address).

Intranet

A network made up of private/non-routable IP addresses is an intranet and is only accessible by authorized users. Unlike the Internet, which is public and accessible to anyone with an Internet connection, an intranet is restricted to members of the organization and is typically used to share information, collaborate on projects, and streamline internal communications.

Intranets often include:

Internal Websites: These might feature company news, policy documents, and other resources.

Collaboration Tools: Such as shared calendars, project management software, and internal messaging systems.

Databases: For storing and retrieving company-specific information.

File Sharing: Systems to upload, download, and manage documents within the organization.

The main goal of an intranet is to facilitate efficient and secure communication and collaboration within an organization, enhancing productivity and ensuring that employees have easy access to the information and tools they need.

Edit the Hosts File

On different operating systems, the hosts file is located in different places:

Windows: C:\Windows\System32\drivers\etc\hosts

Linux/macOS: /etc/hosts

To add an internal domain to your hosts file:

Open the hosts file with a text editor. I use the vi editor on Linux and Notepad on Windows. I have no experience with the MAC.

Add entries in the following format:

<tab>192.168.1.10<tab>myservice.internal

<tab>192.168.1.11<tab>another.internal

Here, 192.168.1.10 and 192.168.1.11 are internal/private/non-routable IP addresses, and myservice.internal and another.internal are your internal domain names.

Save the file and exit the editor.

Testing Your Configuration

To verify the Linux server is running on the IP address you are attempting to use, open an SSH connection using the Linux terminal or on Windows use PuTTY. Then use the ping command to test the hostname like this: ping myservice.internal

If everything is configured correctly, you should see something like:

keith@Kubuntu22:~$ ping 192.168.1.81
PING 192.168.1.81 (192.168.1.81) 56(84) bytes of data.
64 bytes from 192.168.1.81: icmp_seq=1 ttl=64 time=6.42 ms
64 bytes from 192.168.1.81: icmp_seq=2 ttl=64 time=1.79 ms
64 bytes from 192.168.1.81: icmp_seq=3 ttl=64 time=1.85 ms
64 bytes from 192.168.1.81: icmp_seq=4 ttl=64 time=1.82 ms
64 bytes from 192.168.1.81: icmp_seq=5 ttl=64 time=1.49 ms

To test that your configuration is configured correctly, open a browser, enter your local domain in the URL, and hit enter. If all is good you will see the page that comes from that local domain’s virtual host website.

Internal TLD Usage

Naming Conventions: Using a non-standard TLD like .internal helps avoid conflicts with public DNS. Ensure that the naming conventions you use are consistent across your network.

Alternative TLDs: Some organizations use TLDs like .local or .lan for internal domains, although these can also have potential conflicts or limitations, especially with multicast DNS (mDNS) and some network configurations.

For years developers have used the TLD .dev. .dev is now a public TLD and if used on a private network may conflict with its public counterpart.

This is a small network solution. If your network is larger than 2 or 3 computers you may want to consider using a DNS server for your private network.

How I Use My Intranet

I’ve created a small intranet within my home lab. I am a PHP developer and have a handful of devices that I use to develop and test PHP code. This consists of a Windows 10 laptop that runs Oracle’s VirtualBox. VirtualBox is what is called a hypervisor which allows me to create Linux, Apache, MySQL, and PHP (LAMP) web servers (guests) for development and testing.

It should be noted that each of the VirtualBox guests has a unique IP address that allows me to use the .internal top-level domain (TLD) on my Windows 10 hosts file and my Kubuntu (linux) desktop hosts file.

Conclusion

In this article, we learned how to configure a local/private .internal top-level domain. We covered private Non-Routable IP addresses. We learned a bit about how CIDR notation works. We covered how to edit the Linux, Windows, and macOS hosts file to address the need for DNS. Lastly, we tested our configuration.

How to Setup Apache2 Virtual Host in Ubuntu 24.04 LTS

Image : How to Setup Apache2 Virtual Host in Ubuntu 24.04 LTS

On Ubuntu 24.04, Apache2 uses virtual hosts to manage multiple websites on a single server. Each virtual host configuration defines how Apache should handle requests for different domains or subdomains. Understanding how to configure these virtual hosts is crucial for effectively managing multiple sites. Here’s a comprehensive guide to Apache2 virtual host configurations.

Virtual Host Basics

Virtual hosts allow you to run multiple websites on a single Apache server by defining separate configuration files for each site. Apache uses the NameVirtualHost directive (which is now implicit) to route requests based on the domain name or IP address.

My Development Environment

I am a PHP programmer. I believe every PHP Developer should know the fundamentals of Linux and specifically know how to build a virtualization system and should have the skills to build a LAMP stack (Linux, Apache, MySQL, PHP) and have the skills to build and maintain their own development and testing environment.

I am using an old Windows 10 laptop that has an i3 CPU with 2 cores and 4 threads and 16GB of RAM. I’ve installed VirtualBox on it. VirtualBox is a type 2 hypervisor, which means it is installed on top of an operating system.

I use VirtualBox to create virtual machines (guests) for PHP development and testing. These guests consist of Ubuntu 24.04LTS (Linux), Apache, MySQL, and PHP (LAMP stack).

Directory Structure

On Ubuntu, virtual host configurations are usually placed in /etc/apache2/sites-available/, and enabled using symbolic links in /etc/apache2/sites-enabled/.

Configuration File Structure

Each virtual host configuration file typically includes:

  • ServerName: The domain name to which the virtual host responds to.
  • DocumentRoot: The directory where the website’s files are located.
  • ErrorLog: The file where error messages for the virtual host are logged.
  • CustomLog: The file where access logs for the virtual host are recorded.

Example Configuration

Here’s a basic example of a virtual host configuration file located at /etc/apache2/sites-available/example.com.conf:

<VirtualHost *:80>
    ServerAdmin webmaster@example.com
    ServerName example.com
    ServerAlias www.example.com
    DocumentRoot /var/www/example.com/public_html
    ErrorLog ${APACHE_LOG_DIR}/example.com_error.log
    CustomLog ${APACHE_LOG_DIR}/example.com_access.log combined
</VirtualHost>

Configuration Directives Explained

<VirtualHost *:80>: This specifies that the virtual host should respond to requests on port 80 (HTTP). You can also use port 443 for HTTPS.

  • ServerAdmin webmaster@example.com: The email address of the server administrator.
  • ServerName example.com: The primary domain name for this virtual host.
  • ServerAlias www.example.com: Additional domain names or subdomains that should also be handled by this virtual host.
  • DocumentRoot /var/www/example.com/public_html: The directory containing the files for this website.
  • ErrorLog ${APACHE_LOG_DIR}/example.com_error.log: Path to the error log file specific to this virtual host.
  • CustomLog ${APACHE_LOG_DIR}/example.com_access.log combined: Path to the access log file and log format.

Enabling a Virtual Host

After creating or modifying a virtual host configuration file, you need to enable it with the following command:

sudo a2ensite example.com.conf

Then, reload Apache to apply the changes:

sudo systemctl reload apache2

Disabling a Virtual Host

If you need to disable a virtual host, use:

sudo a2dissite example.com.conf

And reload Apache:

sudo systemctl reload apache2

Best Practices

  • Keep Configuration Files Organized: Use clear and descriptive names for your virtual host configuration files.
  • Regularly Check Logs: Monitor error and access logs for troubleshooting.

By following these guidelines and understanding each directive, you can effectively manage multiple websites on your Apache server using virtual hosts.

Conclusion

In this article, we learned how to create and configure a virtual host on a LAMP Ubuntu 24.04LTS server. This consists of creating an Apache2 virtual host configuration file. We also learned what commands are required to complete this task.

How to Setup Apache2 Virtual Host in Ubuntu 24.04 LTS

How to Change the hostname on Ubuntu 24.04LTS Without Rebooting

How to Change the hostname on Ubuntu 24.04lts Without Rebooting

I am a PHP developer and regularly need to change the hostname on Ubuntu 24.04LTS without rebooting.

I need to do this because I clone a basic Ubuntu server so I can create differing installations without having to create everything from scratch.

It is very simple to permanently change the hostname on Ubuntu 24.04LS.

This will take 4 steps.

Let me show you how.

1) At the command line run the command : sudo hostnamectl set-hostname <new-hostname> –static The command hostnamectl set-hostname <new-hostname> –static is used to set the hostname for your system.

2) At the command line run the command : sudo vi /etc/hostname and change the hostname to the new hostname.

Since we are using vi for our editor, to exit press the ESC key followed by the colon key, then the “q” key, and press the enter key.

3) At the command line run the command : sudo vi /etc/hosts and set the host name to the new hostame.

4) At the command line run the command : sudo systemctl restart systemd-hostnamed . The command systemctl restart systemd-hostnamed restarts the systemd-hostnamed service. This service is responsible for managing the system’s hostname and related configuration.

To verify : run the command hostnamectl . You can also issue the command hostname to verify the hostname has been changed.

Notice the hostname on your SSH connection will be the prior hostname. To correct this logout and then log in again.

Conclusion

In this article we learned how to permanently change the hostname on a Ubuntu 24.04LTS server. This will work on a desktop machine as well.

How to Install Linux, Apache, MySQL, and PHP LAMP Stack on Ubuntu 24.04LTS Server

Image : How to Install Linux, Apache, MySQL, and PHP LAMP Stack on Ubuntu 24.04LTS Server

In this article we cover taking an Ubuntu 24.04LTS server and expanding it into a full blown Linux, Apache, MySQL, and PHP (LAMP) web server.

What is a LAMP Stack

A LAMP stack is a popular framework for building and deploying web applications. The acronym stands for:

Linux serves as the operating system.

Apache handles the HTTP/HTTPS web requests.

MySQL manages and stores data – the data engine.

PHP is a programming language that processes the business logic and generates dynamic content.

A LAMP stack is a comprehensive web server that is very popular today, and has been so for 20-plus years.

The LAMP stack is widely used because it provides a robust and reliable platform with open-source components, meaning it’s cost-effective and highly customizable.

My LAMP Development Configuration

I have a Windows 10 laptop that runs VirtualBox virtualization software.

I created an Ubuntu 24.04LTS guest on VirtualBox in preparation for creating a complete LAMP server.

If you have been following along on my YouTube channel or on my blog, you have an idea of what we are doing and where we are going.

I use these local LAMP servers for developing and testing PHP programs.

Ultimately these PHP applications will be moved to a commercial LAMP server.

Prerequisites

You will need to have access to an Ubuntu 24.04LTS server and you will need to have sudo privileges.

I have created a clone of a Ubuntu 24.04LTS server in preparation for creating a LAMP server.

In this article and, associated YouTube video, I will demonstrate all the Linux command line commands necessary to take a bare Ubuntu 24.04LTS server into a full featured LAMP server.

Step 1 is to Update and Upgrade System Packages

The first thing you need to do is update the server to the latest package index. And then upgrade any local packages that need to be updated. And finally remove any non-used packages and Kernels.

This consists 3 commands:

1. sudo apt update

2. sudo apt upgrade

3. sudo apt autoremove

The command sudo apt update – is used to update the list of available packages and their versions from the repositories defined in your system’s configuration files. It doesn’t actually install or upgrade any packages; it simply fetches the latest package information so that you can later install or upgrade packages with up-to-date information or code.

Running apt update regularly ensures that your system has the latest package information.

The sudo apt upgrade command is used to upgrade installed packages.

At this point run the 4 below commands:

1. sudo apt update

2. sudo apt upgrade

3. sudo apt autoremove

4. sudo reboot

sudo apt autoremove is used to remove any old packages and old Kernels.

After running sudo apt autoremove, I would recommend a reboot to ensure everything is loaded properly.

Run sudo reboot to reboot your server.

Step 2 Install the Apache Web Server

This consists 5 commands:

1. sudo apt install apache2

2. sudo systemctl start apache2

3. sudo systemctl stop apache2

4. sudo systemctl enable apache2

5. sudo systemctl status apache2

Run the command sudo apt install apache2 to download and install the Apache2 HTTP server along with any dependencies it requires.

1. sudo systemctl start apache2 – Starts Apache.

2. sudo systemctl stop apache2 – Stops Apache.

3. sudo systemctl enable apache2 – Sets Apache to be started when the server starts up.

4. sudo systemctl status apache2 – Provides the status of Apache.

systemctl is responsible for initializing and managing system services and resources during boot and runtime.

The output of sudo systemctl status apache2 will look something like this:

● apache2.service - The Apache HTTP Server
     Loaded: loaded (/usr/lib/systemd/system/apache2.service; enabled; preset: enabled)
     Active: active (running) since Fri 2024-09-06 21:49:22 UTC; 17min ago
       Docs: https://httpd.apache.org/docs/2.4/
    Process: 799 ExecStart=/usr/sbin/apachectl start (code=exited, status=0/SUCCESS)
   Main PID: 968 (apache2)
      Tasks: 6 (limit: 4614)
     Memory: 19.7M (peak: 19.9M)
        CPU: 437ms
     CGroup: /system.slice/apache2.service
             ├─968 /usr/sbin/apache2 -k start
             ├─995 /usr/sbin/apache2 -k start
             ├─996 /usr/sbin/apache2 -k start
             ├─997 /usr/sbin/apache2 -k start
             ├─998 /usr/sbin/apache2 -k start
             └─999 /usr/sbin/apache2 -k start

Sep 06 21:49:15 firstinstall systemd[1]: Starting apache2.service - The Apache HTTP Server...
Sep 06 21:49:22 firstinstall apachectl[859]: AH00558: apache2: Could not reliably determine the server's full>
Sep 06 21:49:22 firstinstall systemd[1]: Started apache2.service - The Apache HTTP Server.


Verify Apache is configured properly by entering the following command in a browser URL http://<your server's IP Address>/

Step 3 Activate and Configure the Uncomplicated Firewall (UFW)

This consists of 6 commands:

1. sudo ufw enable

2. sudo ufw disable

3. sudo ufw status

4. sudo ufw app list

5. sudo ufw allow ‘Apache Full’

6. sudo ufw allow ‘OpenSSH’

Ubuntu uses the Uncomplicated Firewall (UFW).

The Uncomplicated Firewall is a wrapper that makes it easier to manage the Linux built-in iptables firewall. In other words, iptables is the actual firewall.

For our purposes, we will use a subset of the UFW commands. Basically, all we need from UFW is to open the Apache server’s ports, along with opening the OpenSSH ports. UFW can do a lot more than we will cover here.

Enable and start UFW: sudo ufw enable This activates the firewall with default settings.

1. sudo ufw disable turns off the firewall.

2. sudo ufw status shows whether UFW is active and displays the rules currently in place.

In Ubuntu, the Uncomplicated Firewall (UFW) simplifies the process of managing firewall rules. UFW has predefined application profiles for commonly used services.

To allow the Apache web server port 80 (not secured/HTTP) and port 443 (secured/ HTTPS) issue the command sudo ufw allow ‘Apache Full’

To allow the OpenSSH port to be opened, issue the command sudo ufw allow ‘OpenSSH’

At this point you can run sudo ufw status to verify how UFW is configured.

To verify Apache is still available access http://<your server’s IP>/ in your web browser.

Step 4 Install the MySQL Data Server

We will cover 6 commands:

1. sudo apt install mysql-server

2. sudo systemctl start mysql

3. sudo systemctl stop mysql

4. sudo systemctl enable mysql

5. sudo systemctl status mysql

6. sudo mysql_secure_installation

To install the MySQL package and all of its dependencies run ”sudo apt install mysql-server“.

Run sudo systemctl enable mysql to ensure MySQL starts on every reboot.

The command sudo systemctl start mysql starts the data engine.

The command sudo systemctl stop mysql stops the data engine.

sudo systemctl enable mysql sets MySQL to start on boot.

sudo systemctl status mysql provides the status of the MySQL data engine.

sudo mysql_secure_installation is a shell script that secures your MySQL installation. We will not cover this in this article.

Step 5 Install PHP

We will cover 2 commands:

1. sudo apt install php libapache2-mod-php php-mysql

2. php -v

To install PHP run the command sudo apt install php libapache2-mod-php php-mysql

on the command line.

To verify the PHP programming language has been installed, run the command php -v.

Step 6 Install Command-Line PHP

We will cover 2 commands:

1. sudo apt install php-cli

2. php -v

To install the PHP command line package issue the command sudo apt install php-cli.

To verify issue the command php -v

Step 7 Test Your LAMP Stack

Test PHP

Vi instructions:

1) To utilize vi issue the command “vi <file-name>”.

2) Once a file is opened using vi, press the “i” to go into insert mode.

3) Then copy the below-provided code and then place your cursor into vi and press the CTRL P keyboard combination. This will insert the text into the file being edited by vi.

4) Press the “esc” key to put vi into command mode.

5) Then press the colon key “:” Look to the lower left of the vi editor.

6) Then press the “w” key followed by the “q” key. The lowercase “w” is for write and the lowercase “q” is for quit.

Enter the command sudo vi /var/www/html/info.php

Cut and paste the following code into the file being edited.

<?php
phpinfo();
?>

Test using a browser by entering the following in the URL of the browser and then press the enter key. http://<your-ip-address>/info.php

Test PHP/MySQL Connection

Enter the command sudo mysql

Enter the command ALTER USER ‘root’@’localhost’ IDENTIFIED WITH mysql_native_password BY ‘password’;

Enter the command exit;

Enter the command sudo vi /var/www/html/test-db-connection.php

Cut and paste the following into the file test-db-connection.php

<?php
$servername = "localhost";
$username = "root";
$password = "password";
// Create connection
$conn = mysqli_connect($servername, $username, $password);
// Check connection
if (!$conn) {
    die("Connection failed: " . mysqli_connect_error());
}
echo "Connected successfully";
?>

Test the connection using a browser by entering the following in the URL of the browser and then pressing the enter key. http://<your-ip-address>/test-db-connection.php

If you would like to check the status of MySQL enter the command sudo systemctl status mysql

Test Command line PHP

Cut and paste the following 3 lines into the file test-cli.php

Enter the command sudo vi /var/www/html/test-cli.php

Cut and paste the following.

<?php
    echo "PHP CLI is working!\n";
?>

On the command line issue the command “php /var/www/html/test-cli.php”.

Troubleshooting

The command sudo systemctl status mysql will display the current status of the MySQL service, including whether it is active, inactive, or failed. If MySQL is running properly, you should see an output indicating that the service is active and running. If it’s not running or has issues, the status output will provide some details on the problem.

Conclusion

In this article, I covered how to install Apache, MySQL, and PHP on Linux, a LAMP Stack on Ubuntu 24.04LTS Server. Then we test that the configuration to verify it is working correctly. I use Ubuntu 24.04 LTS, Apache2, MySQL and PHP to build web apps.

How to Clone a VirtualBox Virtual Machine| Clone Ubuntu 24.04 server VirtualBox

This article will cover the steps necessary to clone a virtual machine (VM) on VirtualBox.

I am a PHP developer and use virtual machines running Linux for development and testing.

My configuration consists of a Windows 10 laptop with VirtualBox running on it. VirtualBox is virtualization software that allows one the ability to add guest virtual machines (VMs).

In my case, I use this configuration to build website hosting configurations. I create these web hosting servers using Linux, Apache, MySQL, and PHP (LAMP).

I start by creating a Ubuntu 24.04LTS server as a VM on VirtualBox. Then I create a LAMP setup as a VM and then clone it for a project.

LAMP stands for Linux, Apache, MySQL, and PHP.

There are 7 steps to create a clone.

Step 1 is to stop the VM to be cloned, if it is running.

Step 2 Right mouse click on the VM to be cloned

Step 3 Click on Clone from the drop-down menu

Step 4 Give the clone a name. Fill in the path. And in the MAC address policy drop-down select “Generate new MAC address for all network adapters”. For the clone to be a viable server on your network it needs a different MAC address from the server that is being cloned. The clone will also need a different IP address from the server that is being cloned.

Step 5 Select Full clone for “Clone type” as full.

How to Determine What IP Address Your Server is Using

If you are using VirtualBox, once the VM is activated, you will have the opportunity to log in. Once logged in you can use the commands “ip a” and/or ifconfig”. Both provide the same information.

Ifconfig was not available on my server so I had to install it by installing “net-tools”.

To install net-tools issue the command:

sudo apt install net-tools

After installing net-tools you will be able to issue the command ifconfig.

The output from ifconfig:

enp0s3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.1.80  netmask 255.255.255.0  broadcast 192.168.1.255
        inet6 fe80::a00:27ff:fe9a:8638  prefixlen 64  scopeid 0x20<link>
        ether 08:00:27:9a:86:38  txqueuelen 1000  (Ethernet)
        RX packets 2461  bytes 2039625 (2.0 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 700  bytes 92619 (92.6 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 114  bytes 9992 (9.9 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 114  bytes 9992 (9.9 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

The output from ip a :

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host noprefixroute 
       valid_lft forever preferred_lft forever
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 08:00:27:9a:86:38 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.80/24 brd 192.168.1.255 scope global enp0s3
       valid_lft forever preferred_lft forever
    inet6 fe80::a00:27ff:fe9a:8638/64 scope link 
       valid_lft forever preferred_lft forever

This output gives us the same information.

An Example of a Dynamic (DHCP) IP Address Configuration

Log into your server.

Issue the following command: “cd /etc/netplan” and press the enter key.

Then issue the command “vdir” and press the enter key.

There should be a file that end in .yaml in that directory.

Mine is : 50-cloud-init.yaml

At that point enter “sudo vi 50-cloud-init.yaml”. Make sure you use your file’s name in place of mine.

Sudo allows you to become the root user/superuser. Vi is my Linux command line editor of choice.

At this point, the configuration file will be opened in vi.

Your file should look very similar to the following:

# This file is generated from information provided by the datasource.  Changes
# to it will not persist across an instance reboot.  To disable cloud-init's
# network configuration capabilities, write a file
# /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg with the following:
# network: {config: disabled}
network:
    ethernets:
        enp0s3:
            dhcp4: true
    version: 2

If your file looks like this one your network is configured for dynamic IP allocation or Dynamic Host Configuration Protocol (DHCP). This means you will need to read and follow this article: https://www.phpcoderusa.com/how-to-change-ip-address-from-dhcp-to-static-in-ubuntu/

An Example of a Static IP Address Configuration

Log into your server.

Issue the following command: “cd /etc/netplan” and press the enter key.

Then issue the command “vdir” and press the enter key.

There should be a file that end in .yaml in that directory.

Mine is: 50-cloud-init.yaml

At that point enter “sudo vi 50-cloud-init.yaml”. Make sure you use your file’s name in place of mine.

Sudo allows you to become the root user/superuser. Vi is my Linux command line editor of choice.

At this point, the configuration file will be opened in vi.

Your file should look very similar to the following:

# This file is generated from information provided by the datasource.  Changes
# to it will not persist across an instance reboot.  To disable cloud-init's
# network configuration capabilities, write a file
# /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg with the following:
# network: {config: disabled}
network:
    ethernets:
        enp0s3:
            addresses:
            - 192.168.1.80/24
            nameservers:
                addresses:
                - 8.8.8.8
                - 8.8.4.4
                search: []
            routes:
            -   to: default
                via: 192.168.1.1
    version: 2

This is the configuration for a static IP address.

Backup Current Network Configuration before Starting

Backing up your configuration files before changing them is a good habit to get into.

This is easy to do. For example, file 50-cloud-init.yaml is easily backed up by just making a copy of the file with a change to the file name. Here is the command :

sudo cp 50-cloud-init.yaml 50-cloud-init.yaml-original

Cp is the copy command. Notice I added “-original” to the file name.

So now we should have two files in the directory :

1) 50-cloud-init.yaml – the working configuration file

2) 50-cloud-init.yaml-original – a backup of the original configuration file.

You can verify by using the vdir command, which lists the contents of the directory we are in.

Making a backup of the original backup file could save you some pain if you need to figure out how the server was originally configured.

Changing a Static IP Address

This is a two step process assuming your server is already configured with a static IP.

Step 1 :

Issue the command “sudo vi /etc/netplan/50-cloud-init.yaml” on the command line. Replace your file’s name for my file’s name.

You can make several changes to this file:

network:
    ethernets:
        enp0s3:
            addresses:
            - 192.168.1.80/24
            nameservers:
                addresses:
                - 8.8.8.8
                - 8.8.4.4
                search: []
            routes:
            -   to: default
                via: 192.168.1.1
    version: 2

1) Change the IP of the server by replacing the current IP address. This file shows an IP address of 192.168.1.80. Change it to what you would like it to be.

2) Change the name servers. This file shows Google’s name servers of 8.8.8.8 and 8.8.4.4. You can change them to other name server values.

3) Change the gateway which in this file is 192.168.1.1. Change it to another gateway if need be.

4) The subnet can be modified by editing the subnet that is part of the IP address. In this case the IP along with the subnet is 192.168.1.80/24. Notice the “/24”. That is the subnet for this configuration. You can modify the “/24” to increase or decrease the number of IP addresses that are available in the configured network.

Step 2 :

In the static configuration file “/etc/netplan/50-cloud-init.yaml” you will notice that there is some notes. These notes must be followed. They are listed as follows:

# This file is generated from information provided by the datasource.  Changes
# to it will not persist across an instance reboot.  To disable cloud-init's
# network configuration capabilities, write a file
# /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg with the following:
# network: {config: disabled}

The notes say we must create a file “/etc/cloud/cloud.cfg.d/99-disable-network-config.cfg” and write the following into it: “network: {config: disabled}”, in the folder /etc/cloud/cloud.cfg.d/.

This can be accomplished by issuing the command “sudo vi /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg”.

If the file is empty add the line: “network: {config: disabled}” and save it.

If you are using vi press the “i” key to place vi into insert mode, then copy and paste the line. Then press the escape key to move vi into command mode. Then press the colon key followed by “wq”. Then press the enter key.

The “wp” are for write and quite.

At this point issue the command “sudo netplan try”. If there are no errors you can issue “sudo netplan apply”.

If there are no errors you have success.

Potential Error That Might Occur During This Process

If your configuration file is not indented properly, you will get an error.

Here is what it might look like :

Error in network definition: expected mapping (check indentation)

ethernets:

The error tells you where the error is located. In this case, it is an indentation error.

Edit the configuration file and verify it is configured correctly.

Then issue the command “sudo netplan try”. If all is correct you might see a message that the configuration will automatically be accepted.

If not issue the command “sudo netplan apply”.

Verifying the IP Has Been Changed

To verify the configuration has taken place you can issue the commands “ip a” and/or “ifconfig”.

I would recommend that you power off your server and then power it back on and then verify the IP is correct.

Conclusion

In this article, we learn how to clone an existing guest on VirtualBox. We learn how to give the clone a unique MAC address and a unique IP address. We learn what an IP is, why it is important, and how to manage IP addresses on an Ubuntu 24.04LTS Server. We learn how to identify a static IP address configuration and a dynamic IP address configuration. Then we learn how to change the static IP from one address to another. We learn the Linux commands “ip a”, “ifconfig” and learn a bit about the Linux editor vi. And finally, we learn it is a good practice to back up a configuration file before we modify it.

Change a Static IP Address in Ubuntu Using the Command Line | Change the IP Address in Ubuntu 24.04

Image of Change a Static IP Address in Ubuntu Using the Command Line

This article will cover the steps necessary to change a static IP to another static IP.

I am a PHP developer and use virtual machines running Linux for PHP development and testing.

My configuration consists of a Windows 10 laptop with VirtualBox running on it. VirtualBox is virtualization software that allows one to add guest virtual machines (VMs).

In my case, I use this configuration to build website hosting configurations. I create these web hosting servers using Linux, Apache, MySQL, and PHP (LAMP).

What is an IP Address

Simply stated an IP address is the address of a device on a network and/or internet. An IP is like the address of your house or your phone number on your phone.

What Is a Static IP Address

A static IP is an IP address that does not change. There are two types of IP addresses. 1) There is dynamic which is given by the router and 2) static which is configured never to change.

The Benefits of a Static IP

In the case of web servers, they must have static IP addresses. The static IP is required because of how servers work and how other devices interact with them.

This article is about changing a static IP address on the Ubuntu 24.04LTS server.

Step 1 is to identify how the server is configured.

How to Determine What IP Address Your Server is Using

If you are using VirtualBox, once the VM is activated, you will be able to log in.  Once logged in you want to use the commands “ip a” and ifconfig”. Both provide the same information.

Ifconfig was not available on my server so I had to install it by installing “net-tools”.

To install net-tools issue the command:

sudo apt install net-tools

After installing net-tools you will be able to issue the command ifconfig.

The output from ifconfig :

enp0s3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.1.80  netmask 255.255.255.0  broadcast 192.168.1.255
        inet6 fe80::a00:27ff:fe9a:8638  prefixlen 64  scopeid 0x20<link>
        ether 08:00:27:9a:86:38  txqueuelen 1000  (Ethernet)
        RX packets 478  bytes 330373 (330.3 KB)
        RX errors 0  dropped 1  overruns 0  frame 0
        TX packets 165  bytes 18169 (18.1 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 96  bytes 7624 (7.6 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 96  bytes 7624 (7.6 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

The command “ip a” will provide the same information, just in a different format.

An Example of a Dynamic (DHCP) Configuration

Log into your server.

Issue the following command: “cd /etc/netplan” and press the enter key.

Then issue the command “vdir” and press the enter key.

There should be a file that ends in .yaml in that directory.

Mine is :  50-cloud-init.yaml

At that point enter “sudo vi 50-cloud-init.yaml”. Make sure you use your file’s name in place of mine.

Sudo allows you to become the root user/superuser. Vi is my editor of choice.

At this point, the configuration file will be opened in vi.

Your file should look very similar to the following:

# This file is generated from information provided by the datasource.  Changes
# to it will not persist across an instance reboot.  To disable cloud-init's
# network configuration capabilities, write a file
# /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg with the following:
# network: {config: disabled}
network:
    ethernets:
        enp0s3:
            dhcp4: true
    version: 

If your file looks like this one your network is configured for dynamic IP allocation or Dynamic Host Configuration Protocol (DHCP). This means you will need to read and follow this article : How to Change IP Address From DHCP to Static in Ubuntu

An Example of a Static Configuration

Log into your server.  

Issue the following command : “cd /etc/netplan” and press the enter key.

Then issue the command “vdir” and press the enter key.

There should be a file that ends in .yaml in that directory.

Mine is :  50-cloud-init.yaml

At that point enter “sudo vi 50-cloud-init.yaml”. Make sure you use your file’s name in place of mine.

Sudo allows you to become the root user/superuser. Vi is my editor of choice.

At this point, the configuration file will be opened in vi.

Your file should look very similar to the following:

# This file is generated from information provided by the datasource.  Changes
# to it will not persist across an instance reboot.  To disable cloud-init's
# network configuration capabilities, write a file
# /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg with the following:
# network: {config: disabled}
network:
    ethernets:
        enp0s3:
            addresses:
            - 192.168.1.80/24
            nameservers:
                addresses:
                - 8.8.8.8
                - 8.8.4.4
                search: []
            routes:
            -   to: default
                via: 192.168.1.1
    version: 2

This is the configuration for a static IP address.

Backup Current Network Configuration Before Starting

It is a good habit to get into – backing up your configuration files before changing them.

This is easy to do. For example, file 50-cloud-init.yaml is easily backed up by just making a copy of the file with a change to the file name. Here is the command :

sudo cp 50-cloud-init.yaml 50-cloud-init.yaml-original

Cp is the copy command. Notice I added “-original” to the back up file name.  

So now we should have two files in the directory :

1) 50-cloud-init.yaml – the working configuration file

2) 50-cloud-init.yaml-original – the original configuration file that is a backup of the original configuration.

You can verify by using the vdir command, which lists the contents of the directory we are in.

Making a backup of the original backup file could save you some pain if you need to figure out how the server was originally configured.

Changing a Static IP

This is a two-step process assuming your server is already configured with a static IP.

Step 1 :

Issue the command “sudo vi /etc/netplan/50-cloud-init.yaml” on the command line. Replace your file name for mine.

You can make several changes to this file :

# This file is generated from information provided by the datasource.  Changes
# to it will not persist across an instance reboot.  To disable cloud-init's
# network configuration capabilities, write a file
# /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg with the following:
# network: {config: disabled}
network:
    ethernets:
        enp0s3:
            addresses:
            - 192.168.1.80/24
            nameservers:
                addresses:
                - 8.8.8.8
                - 8.8.4.4
                search: []
            routes:
            -   to: default
                via: 192.168.1.1
    version: 2

1) Change the IP of the server by replacing the current IP address. This file shows an IP of 192.168.1.80.  Change it to what you would like it to be.

2) Change the name servers. This file shows Google’s name servers of 8.8.8.8 and 8.8.4.4. You can change them to other name server values.

3) Change the gateway which in this file is 192.168.1.1. Change it to another gateway if need be.

4) The subnet can be modified by editing the subnet that is part of the IP address. In this case, the IP along with the subnet is 192.168.1.80/24. Notice the “/24”. That is the subnet for this configuration. You can modify the “/24” to increase or decrease the number of IP addresses that are available in the configured network.

Step 2 :

In the static configuration file “/etc/netplan/50-cloud-init.yaml” you will notice that there is some notes. These notes must be followed.

# This file is generated from information provided by the datasource.  Changes
# to it will not persist across an instance reboot.  To disable cloud-init's
# network configuration capabilities, write a file
# /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg with the following:
# network: {config: disabled}

This can be accomplished by issuing the command “sudo vi /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg”.

If the file is empty add the line : “network: {config: disabled}” and save it.

If you are using vi press the “i” key to place vi into insert mode, then copy and paste the line. Then press the escape key to place vi into command mode. Then press the colon key followed by “wq”.

The “wq” is for write and quit.

At this point issue the command “sudo netplan try”. If there are no errors you can issue “sudo netplan apply”.  

If there are no errors you have success.

Potential Error That Might Occur During This Process

If your configuration file is not indented properly, you will get an error.

Here is what it might look like :

Error in network definition: expected mapping (check indentation)

ethernets:”

The error tells you where the error is located. In this case, it is an indentation error.

Edit the configuration file and verify it is configured correctly.  

Then issue the command “sudo netplan try”. If all is correct you might see a message that the configuration will automatically be accepted.

If not issue the command “sudo netplan apply”.

Verifying the IP Has Been Changed

To verify the configuration has taken place you can issue the commands “ip a” and/or  “ifconfig”.

I would recommend that you power off your server and then power it back on and the verifying the IP is correct.

Conclusion

In this article, we learn what an IP is, why it is important, and how to manage IP addresses on an Ubuntu 24.04LTS server. We learned how to identify a static and a dynamic configuration. Then we learned how to change the static IP from one address to another.

How to change IP address from DHCP to static in Ubuntu

How to Change a Dynamic IP Address to a Static IP Address

I am a PHP programmer using Ubuntu for Linux, Apache, MySQL, and PHP (LAMP ) servers, and I need a static IP address on that server.

If for some reason the server is configured with Dynamic Host Configuration Protocol (DHCP) I will need to convert the IP configuration to static.

Under DHCP the router assigns an IP address to the device. This IP may change on subsequent reboots.

In this article, I will show you how to convert a DHCP configuration to a static IP configuration on Ubuntu server 24.04LTS.

I have a Windows laptop that runs VirtualBox and the Ubuntu server is a guest on VirtualBox.

The first thing to do is to determine the network interface name.

To do so I need to ensure VirtualBox and the Ubuntu server are up and running.

To access a Ubuntu server I use PuTTY to Secure Shell (SSH) into the server. This will require you to know the existing IP address or domain name of the server.

Since I created the server as a VirtualBox guest it is easy for me to gain (SSH) access by simply launching the server.

Step 1 is to log into the Ubuntu Server on the command line. Since this is a server it will not have a Graphical user interface (GUI).

Step 2 is to update the server’s repository. We do so by entering the below command on the command line.

sudo apt update

Step 3 is upgrading those packages. This means if there are packages that can be upgraded to a newer version they will be upgraded.

sudo apt upgrade

Step 4 is to remove any old and non-used packages and any old Kernels.

sudo apt autoremove

Step 4 is to install net-tools. Net-tools is a collection of networking utilities.

  • arp
  • hostname
  • ifconfig
  • ipmaddr
  • iptunnel
  • mii-tool
  • nameif
  • netstat
  • plipconfig
  • rarp
  • route
  • slattach

Of which we will be only using ifconfig.

sudo apt install net-tools

Step 5 is to run ifconfig on the command line.

This is the output from my Ubuntu server:

$ ifconfig

enp0s3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
       inet 192.168.1.112  netmask 255.255.255.0  broadcast 192.168.1.255
       inet6 fe80::a00:27ff:fefd:65fc  prefixlen 64  scopeid 0x20<link>
       ether 08:00:27:fd:65:fc  txqueuelen 1000  (Ethernet)
       RX packets 726  bytes 347718 (347.7 KB)
       RX errors 0  dropped 0  overruns 0  frame 0
       TX packets 266  bytes 36629 (36.6 KB)
       TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
       inet 127.0.0.1  netmask 255.0.0.0
       inet6 ::1  prefixlen 128  scopeid 0x10<host>
       loop  txqueuelen 1000  (Local Loopback)
       RX packets 96  bytes 7624 (7.6 KB)
       RX errors 0  dropped 0  overruns 0  frame 0
       TX packets 96  bytes 7624 (7.6 KB)
       TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

We need two bits of information 1) the network device is enp0s3, and 2) the IP address of this server is 192.168.1.112.

We can also use the command “ip a”. It will return something like this:

$ ip a

: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host noprefixroute 
       valid_lft forever preferred_lft forever
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 08:00:27:fd:65:fc brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.112/24 brd 192.168.1.255 scope global enp0s3
       valid_lft forever preferred_lft forever
    inet6 fe80::a00:27ff:fefd:65fc/64 scope link 
       valid_lft forever preferred_lft forever

This tells us the same two things:

  1. For this server, the network device is enp0s3. Yours might be eth0 or something to that effect.
  2. The IP of this server is 192.168.1.112

Netplan is the default network management tool. Netplan was introduced to Ubuntu in 2016.

In the directory /etc/netplan/ we will find a file named something like “50-cloud-init.yaml”

From a DHCP configuration:

File: /etc/netplan/50-cloud-init.yaml

# This file is generated from information provided by the datasource.  Changes
# to it will not persist across an instance reboot.  To disable cloud-init's
# network configuration capabilities, write a file
# /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg with the following:
# network: {config: disabled}
network:
    ethernets:
        enp0s3:
            dhcp4: true
    version: 2


Notice the line “ This file is generated from information provided by the datasource Changes to it will not persist across an instance reboot.”.

Then there is the second to the last line that says we must create a file /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg. And the last line says we must write “network: {config: disabled}” into that file and save it.

From a static configuration :

File: /etc/netplan/50-cloud-init.yaml

# This file is generated from information provided by the datasource.  Changes
# to it will not persist across an instance reboot.  To disable cloud-init's
# network configuration capabilities, write a file
# /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg with the following:
# network: {config: disabled}
network:
    version: 2
    ethernets:
        enp0s3:
            addresses:
            - 192.168.1.83/24
            nameservers:
                addresses:
                - 8.8.8.8
                - 8.8.4.4
                search: []
            routes:
            -   to: default
                via: 192.168.1.1

We change the server to a static IP by editing it’s configuration. To do so enter the following command: (not the file name might be different)

sudo vi /etc/netplan/50-cloud-init.yaml, and create a configuration like this:

network:
    version: 2
    ethernets:
        enp0s3:
            addresses:
            - 192.168.1.83/24
            nameservers:
                addresses:
                - 8.8.8.8
                - 8.8.4.4
                search: []
            routes:
            -   to: default
                via: 192.168.1.1

Replace:

  • 192.168.1.83/24 with your server’s IP and submask
  • 8.8.8.8 and 8.8.4.4 are Google’s name servers, which you can keep or use your own.
  • 192.168.1.1 is the gateway and you need to replace it with your own.

Then create the file /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg and add to it “network: {config: disabled}” and save it.

Once you have completed these steps test the configuration with the command “netplan try”. If there are no errors, issue the command “netplan apply”.

To confirm the configuration is working, issue the command “ip a”. If this shows the correct IP address then power down your server and then power it on again. Issue the command “ip a”. If this shows the correct IP address, you have successfully changed your Ubuntu 24.04LTS network configuration from dynamic to static.

Note if your remote connection loses its connection, the changes you have made may have taken effect and you will need to establish a new remote connection.

Conclusion

In this article, we have taken an Ubuntu 24.04LTS server that was initially configured with a dynamic network connection configuration (DHCP) to a static IP. This required editing the network configuration and changing it to a static configuration. We also created a file that disabled the network from automatically reverting back to the original configuration.

Can AI Write PHP Code?

Image : Can AI Write PHP Code?

I asked ChatGPT 3.5 “Can AI write PHP code?”. ChatGPT 3.5 is a free version of Artificial Intelligence.

I’ve been a freelance PHP developer since 2006. I consider myself to be a senior developer.

https://youtu.be/k7CNqcKxKTg

Here is what ChatGPT responded:

Yes, AI can be trained to generate PHP code. PHP is a widely used scripting language for web development, so some models and tools can assist in generating PHP code snippets or even more complex scripts.

However, it’s important to note a few things:

1.**Quality and Intent**: The quality of AI-generated code can vary. AI can produce syntactically correct code based on training data, but it might not always produce efficient or well-structured code that adheres to best practices or security guidelines without careful oversight.

2.**Use Cases**: AI-generated PHP code can be useful for generating boilerplate code, automating repetitive tasks, or even suggesting solutions based on specifications. It can help developers save time and focus on higher-level aspects of development.

3.**Limitations**: AI models are trained on existing data and patterns. They might struggle with highly specialized or novel requirements that deviate significantly from the data they were trained on.

4.**Human Oversight**: Regardless of AI assistance, human oversight, and validation are crucial. Developers should review and test all generated code to ensure it meets project requirements and standards.

In summary, AI can write PHP code and assist developers in various ways. Still, it is most effective as a tool to augment human creativity and expertise rather than replace it entirely.

I’ve been experimenting with ChatGPT 3.5 for maybe 6 weeks as of the writing of this article. I am interested in article writing and PHP code creation.

Before we get started, let’s discuss what is known as prompts. Prompts are the way to interact with ChatGPT 3.5. The better the prompt the better the reply from ChatGPT 3.5.

It is a learning experience.

The other thing that needs to be discussed immediately is the more PHP programming experience the developer has, increases the potential for using and implementing PHP code produced by ChatGPT 3.5.

Recently my local Linux group discussed using AI to generate code. The consensus was that in the short term, there would be little change. The short term is maybe the next 3 years.

The group felt that at some point the junior and mid-range PHP developers would be displaced.

The group also found this scenario interesting in that as the senior developers retire or exit programming there would be no one to replace them, as the juniors and mid-range developers would be non-existent. It might take 6 to 10 years to create a senior developer.

Let me give you a few examples.

If I ask AI to “create a login script in PHP using the MySQL database”. ChatGPT responded:

Creating a login script in PHP using MySQL involves several steps, including connecting to the database, querying user credentials, and validating the login. Below is a basic example of how you can implement this:

1.**Create a MySQL Database:**

First, you need a MySQL database with a table to store user information. Here’s an example SQL to create a `users` table:

CREATE TABLE users (
    id INT(11) AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(50) NOT NULL,
    password VARCHAR(255) NOT NULL, — Hashed password
    email VARCHAR(100) NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

Note: Always hash passwords before storing them in the database for security reasons.

Use PHP’s `password_hash()` function for this purpose.

2.**PHP Login Script:**

Create a PHP script (`login.php`) that handles the login process. Here’s an example:

<?php
session_start();
// Database connection parameters
$host = 'localhost';
$db = 'your_database';
$user = 'your_username';
$pass = 'your_password';
// Create connection
$conn = new mysqli($host, $user, $pass, $db);
// Check connection
if ($conn->connect_error)
{
    die("Connection failed: " . $conn->connect_error);
}
// Check if form was submitted
if ($_SERVER['REQUEST_METHOD'] === 'POST')
{
    $username = trim($_POST['username']);
    $password = trim($_POST['password']);
    // Prepare the SQL statement
    $stmt = $conn->prepare("SELECT password FROM users 
        WHERE username = ?");
    $stmt->bind_param("s", $username);
    $stmt->execute();
    $stmt->store_result();
    // Check if user exists
    if ($stmt->num_rows > 0) 
    {
        $stmt->bind_result($hashedPassword);
        $stmt->fetch();
        // Verify the password
        if (password_verify($password, $hashedPassword)) 
        {
            // Set session variables
            $_SESSION['username'] = $username;
            header("Location: welcome.php"); // Redirect to welcome page
            exit();
        } else {
            $error = "Invalid username or password.";
        }
    } else {
        $error = "Invalid username or password.";
    }
    $stmt->close();
}
$conn->close();
?>

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width,
            initial-scale=1.0">
        <title>Login</title>
    </head>
    <body>
        <h2>Login</h2>
        <?php if (isset($error)): ?>
            <div style="color: red;">
           <?php echo $error; ?></div>
        <?php endif; ?>
        <form action="login.php" method="post">
            <label for="username">Username:</label>
            <input type="text" name="username" id="username" required>
            <br>
            <label for="password">Password:</label>
            <input type="password" name="password" id="password" required>
            <br>
            <button type="submit">Login</button>
        </form>
    </body>
</html>

Instructions:

Database Setup: Ensure you have a MySQL database with a users table containing username (VARCHAR) and password (VARCHAR) fields. Use password_hash() when storing passwords.

Testing: Access login.php in your web browser, enter your credentials and check the behavior on both successful and failed logins.

Redirect Page: Create a welcome.php file to greet the user after login.

Security Notes:

Ensure your site uses HTTPS to protect user credentials.

Implement measures against SQL injection (this script uses prepared statements, which helps).

Consider adding Cross-Site Request Forgery (CSRF) protection for your forms.

Secure session management practices should be followed.

Feel free to customize the layout and logic to fit your application’s needs!

I ask “Should a cookie be implemented?” AI responds:

Implementing cookies can enhance user experience, especially for remembering user sessions or preferences. However, it’s important to handle them securely. Here are some points to consider regarding cookies in the context of a login system:

When to Use Cookies

Remember Me Functionality: Allow users to stay logged in even after closing their browser. This is usually done by storing a cookie with a token.

User Preferences: Save user-specific settings, like theme or language.

Security Considerations

Secure and HttpOnly Flags: Set the Secure flag for cookies to ensure they are only sent over HTTPS. The HttpOnly flag prevents client-side scripts from accessing the cookie, reducing the risk of XSS attacks.

SameSite Attribute: Use the SameSite attribute to help protect against CSRF attacks by controlling how cookies are sent with requests.

Token-Based Authentication: If you implement a “Remember Me” feature, use a securely generated token stored in the cookie, linked to the user’s session on the server.

Example of Implementing Cookies

Here’s a modified version of the login script that includes a “Remember Me” feature:

Updated login.php

<?php
session_start();
// Database connection parameters
$host = 'localhost';
$db = 'your_database';
$user = 'your_username';
$pass = 'your_password';
// Create connection
$conn = new mysqli($host, $user, $pass, $db);
// Check connection
if ($conn->connect_error)
{
    die("Connection failed: " . $conn->connect_error);
}
// Check if form was submitted
if ($_SERVER['REQUEST_METHOD'] === 'POST')
{
    $username = trim($_POST['username']);
    $password = trim($_POST['password']);
    $rememberMe = isset($_POST['remember_me']);
    // Prepare the SQL statement
    $stmt = $conn->prepare("SELECT password FROM users 
        WHERE username = ?");
    $stmt->bind_param("s", $username);
    $stmt->execute();
    $stmt->store_result();
    // Check if user exists
    if ($stmt->num_rows > 0) 
    {
        $stmt->bind_result($hashedPassword);
        $stmt->fetch();
        // Verify the password
        if (password_verify($password, $hashedPassword)) 
        {
            // Set session variables
            $_SESSION['username'] = $username;
            // Handle "Remember Me" functionality
            if ($rememberMe) 
            {
                // Generate a token
                $token = bin2hex(random_bytes(16));
                // Store the token in the database with the username
                $stmt = $conn->prepare("UPDATE users SET 
                    remember_token = ? WHERE username = ?");
                $stmt->bind_param("ss", $token, $username);
                $stmt->execute();
                setcookie("remember_me", $token, time() + 
                    (86400 * 30), "/", "", true, true); // 30 days
            }
            header("Location: welcome.php"); // Redirect to welcome page
            exit();
        } else {
            $error = "Invalid username or password.";
        }
    } else {
        $error = "Invalid username or password.";
    }
    $stmt->close();
}
$conn->close();
?>

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, 
            initial-scale=1.0">
        <title>Login</title>
    </head>
    <body>
        <h2>Login</h2>
        <?php if (isset($error)): ?>
            <div style="color: red;"><?php echo $error; ?></div>
        <?php endif; ?>
        <form action="login.php" method="post">
            <label for="username">Username:</label>
            <input type="text" name="username" id="username" required>
            <br>
            <label for="password">Password:</label>
            <input type="password" name="password" 
                id="password" required>
            <br>
            <label for="remember_me">
            <input type="checkbox" name="remember_me" 
                id="remember_me"> Remember Me
            </label>
            <br>
            <button type="submit">Login</button>
        </form>
    </body>
</html>

Additional Steps

Database Changes: Ensure your users table has a remember_token column to store the token.

Token Validation: On subsequent visits, check if the cookie is set. If it is, validate the token against the database and log the user in automatically.

Logout Logic: Clear the cookie and remove the token from the database when a user logs out.

Conclusion

Using cookies responsibly can enhance user experience, but always prioritize security by following best practices.

ChatGPT can make mistakes. Check important info.

Summary

I asked ChatGPT to create a PHP login script as an example and to answer the question “Can AI write PHP code?”. It does a great job. This experiment reinforces my statement that to effectively use AI to generate code, requires a senior developer.

Upon request, AI-generated login cookie code with lots of comments and explanations.

All in all, I think using AI, as a senior developer, might reduce development time by 30% – 50% – a big savings.

I did not mention that AI can have what is referred to as hallucinations. It would be worth your time to understand AI hallucinations.

What is a Full-Stack PHP Developer

Some say a full-stack PHP developer is someone who can program both on the client-side and the server-side. The server side is programming in PHP and the client-side is programming in the browser using JavaScript.

Others define a full-stack developer as someone who can troubleshoot both the software layer and the server layer.

I like both definitions. I think a full-stack PHP developer is someone who has, at least, enter-level PHP web server system administrative skills and the ability to deal with the full programming stack.

Lets Break That Down

There are two parts to this – The software layer and the Linux PHP hosting layer.

I believe all PHP developers should have a basic familiarity with Linux. I think a PHP programmer should use Linux on their desktop (unless there is a reason not to) and have the skills to configure a basic LAMP or LEMP testing server.

The PHP web server Consists of:

LAMP stands for:

Linux – The operating system.

Apache – The web server.

MySQL – The data engine.

PHP – The programming language.

LEMP stands for:

Linux – The operating system.

NGINX – The web server.

MySQL – The data engine.

PHP – The programming language.

Notice the difference is Apache vs NGINX web servers.

The software layer consists of:

Hypertext Markup Language (HTML) – HTML is the bones or structure of the website.

Cascading Style Sheets (CSS) – CSS gives a website its look and feel

JavaScript, JavaScript library or framework, and AJAX – JavaScript and the associated frameworks and AJAX are used to create interactive web pages.

The PHP programming language – PHP is a server-side programming language which means it runs on the server and sends output to the browser.

Structured Query Language (SQL) – SQL is used by the developer to talk to the MySQL data engine.

There is a lot to know. Knowing and being able to work with all that has been outlined above, in my opinion, makes one a full-stack developer.

You Might Find This Article Worthwhile : Skills a PHP Programmer Should Have

Conclusion

What a Full-Stack PHP developer is can depend on who is defining what a Full-Stack PHP Developer is. There are two definitions 1) a PHP programmer that can program both on the server-side and on the client-side, and 2) a PHP developer than can troubleshoot both the client-side software, the server-side software, AND the PHP web hosting server itself.

I believe a PHP developer must have basic Linux hosting skills. This does not mean this developer needs to be a production server administrator. What I am saying is this PHP developer should be able to configure a LAMP or LEMP stack for testing.