How to Build a Secure and High-Performance Ubuntu Web Server with Apache (Complete Guide)

目次

1. Introduction

What Is an Ubuntu Web Server?

A web server is a system that delivers websites over the internet. Popular web server software includes Apache, Nginx, and LiteSpeed, but the most widely used option on Ubuntu is Apache.
Ubuntu is lightweight, stable, and open-source, making it popular among individuals and companies alike. It is especially well-suited for operating LAMP environments (Linux, Apache, MySQL/MariaDB, PHP), which power many websites and applications.

Who This Article Is For

This guide is designed for beginners building a web server for the first time. It explains how to launch a web server on Ubuntu, install Apache, configure virtual hosts and SSL certificates, and implement optimization and security enhancements.

What You Will Learn

  • How to build a web server on Ubuntu (installing and configuring Apache)
  • How to set up virtual hosts and manage multiple websites
  • How to install free SSL with Let’s Encrypt
  • How to apply security hardening and performance optimization
  • Common troubleshooting steps and solutions

2. Installing Ubuntu and Performing Initial Setup

Required System Specifications

To run Ubuntu as a web server, the following minimum specs are recommended:

ItemMinimum RequirementsRecommended Requirements
OSUbuntu 22.04 LTSUbuntu 22.04 LTS
CPU1GHz or higher2GHz or higher
Memory512MB2GB or higher
Storage10GB or more20GB or more
NetworkInternet connectionHigh-speed connection recommended

Downloading and Installing Ubuntu

Ubuntu can be downloaded from the official website (https://ubuntu.com/download/server). Download the ISO file and install it in a virtual machine such as VirtualBox or VMware, or on a dedicated server or VPS.

Installation Steps:

  1. Create installation media
  • USB drive (using tools such as Rufus)
  • Mount the ISO file in a virtual machine
  1. Follow the installation wizard
  • Select your preferred language
  • Verify network connectivity
  • Set the username and password
  • Install the SSH server (optional—you can install it later)
  1. Reboot after installation completes
  2. Log in and begin initial configuration

Basic Initial Setup

After installation, perform the following initial setup steps.

  1. Update all packages
sudo apt update && sudo apt upgrade -y

→ Applies security patches and updates software packages.

  1. Set the timezone
sudo timedatectl set-timezone Asia/Tokyo

→ Sets the system time to Japan Standard Time (JST).

  1. Enable the firewall
sudo ufw enable

→ Activates the firewall to protect the system from unauthorized access.

  1. Configure SSH (for remote management)
  • Check if SSH is enabled
    sudo systemctl status ssh
  • If disabled, enable it
    sudo systemctl enable --now ssh

After completing these steps, your Ubuntu server is ready to be set up as a fully functional web server.

3. Installing and Configuring Apache

What Is Apache?

Apache (Apache HTTP Server) is an open-source web server known for its stability, extensibility, and strong security features. Approximately 30% of servers worldwide use Apache.

Key Features:

  • Free and open-source
  • Modular architecture for easy extensions
  • SSL/TLS support for HTTPS configuration
  • Virtual hosts for hosting multiple websites

Installing Apache

On Ubuntu, Apache can be installed easily using the apt package manager.

Install Apache

Run the following commands to install Apache:

sudo apt update
sudo apt install apache2 -y

Verify the Installation

After installation, check the Apache version:

apache2 -v

Example output:

Server version: Apache/2.4.52 (Ubuntu)
Server built:   2023-07-01T12:34:56

If version information appears, Apache has been installed correctly.

Starting, Stopping, and Restarting Apache

Apache is managed using the systemctl command.

Start Apache

sudo systemctl start apache2

Apache will now begin accepting web requests.

Enable Automatic Startup

sudo systemctl enable apache2

Check Apache Status

Use this command to verify whether Apache is running:

sudo systemctl status apache2

Example output:

● apache2.service - The Apache HTTP Server
   Loaded: loaded (/lib/systemd/system/apache2.service; enabled; vendor preset: enabled)
   Active: active (running) since ...

Restart or Stop Apache

Restart Apache after modifying configuration settings:

sudo systemctl restart apache2

To temporarily stop Apache:

sudo systemctl stop apache2

Verifying Apache Operation

To confirm that Apache is running properly, access the server’s IP address.

1. Check Your Server’s IP Address

hostname -I

Or check the external IP:

curl ifconfig.me

2. Verify in a Web Browser

Enter the following in your browser:

http://<your-server-ip>/

For local setups:

http://localhost/

You should see Apache’s default page (/var/www/html/index.html).

Example default page:

Apache2 Ubuntu Default Page
It works!

If this message appears, Apache is functioning properly.

Configuring the Firewall

Ubuntu uses UFW (Uncomplicated Firewall) to manage firewall rules.
After installing Apache, external access to HTTP (port 80) and HTTPS (port 443) may still be blocked.

Allow Apache Through the Firewall

sudo ufw allow 'Apache'

To allow HTTPS as well:

sudo ufw allow 'Apache Full'

Check Firewall Status

sudo ufw status

Example output:

Status: active

To                         Action      From
--                         ------      ----
Apache                     ALLOW       Anywhere
Apache (v6)                ALLOW       Anywhere (v6)

If this appears, Apache traffic is allowed through the firewall.

Summary

So far, you have installed Apache on Ubuntu and completed essential setup steps.
Key points covered:

  • How to install Apache
  • How to start and enable Apache
  • How to verify Apache operation in a browser
  • How to configure UFW firewall rules
  • Overview of Apache’s basic configuration files

4. Configuring Virtual Hosts (Managing Multiple Sites)

What Are Virtual Hosts?

Virtual hosts allow you to host multiple domains (or subdomains) on a single Apache server.
For example, one server can host both example.com and test.com.

There are two types of virtual hosts:

  1. Name-based Virtual Hosts
  • Multiple sites share the same IP address
  • The most common method
  1. IP-based Virtual Hosts
  • Each site uses a different IP address
  • Requires multiple network interfaces on a single server

In most cases, name-based virtual hosts are used.

Steps to Configure Virtual Hosts

1. Create Required Directories

Create a separate directory for each website:

sudo mkdir -p /var/www/example.com/public_html
sudo mkdir -p /var/www/test.com/public_html

2. Change Directory Ownership

Ensure Apache can read the files by setting the owner to www-data:

sudo chown -R www-data:www-data /var/www/example.com/public_html
sudo chown -R www-data:www-data /var/www/test.com/public_html

3. Create Placeholder HTML Files

Create a basic index.html file for testing:

echo "<h1>Welcome to example.com</h1>" | sudo tee /var/www/example.com/public_html/index.html
echo "<h1>Welcome to test.com</h1>" | sudo tee /var/www/test.com/public_html/index.html

4. Create Virtual Host Configuration Files

Virtual host configuration files are stored in the /etc/apache2/sites-available/ directory.

Virtual host configuration for example.com

Create and edit the configuration file with the following command:

sudo nano /etc/apache2/sites-available/example.com.conf

Configuration file contents:

<VirtualHost *:80>
    ServerAdmin admin@example.com
    ServerName example.com
    ServerAlias www.example.com
    DocumentRoot /var/www/example.com/public_html

    <Directory /var/www/example.com/public_html>
        Options -Indexes +FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/example.com_error.log
    CustomLog ${APACHE_LOG_DIR}/example.com_access.log combined
</VirtualHost>

Virtual host configuration for test.com

sudo nano /etc/apache2/sites-available/test.com.conf

Add the following contents:

<VirtualHost *:80>
    ServerAdmin admin@test.com
    ServerName test.com
    ServerAlias www.test.com
    DocumentRoot /var/www/test.com/public_html

    <Directory /var/www/test.com/public_html>
        Options -Indexes +FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/test.com_error.log
    CustomLog ${APACHE_LOG_DIR}/test.com_access.log combined
</VirtualHost>

5. Enable the Virtual Hosts

After creating the configuration files, enable the virtual hosts using a2ensite:

sudo a2ensite example.com.conf
sudo a2ensite test.com.conf

Test Apache’s configuration

Check for syntax errors:

sudo apachectl configtest

Example output:

Syntax OK

If there are no errors, restart Apache:

sudo systemctl restart apache2

6. Verify Locally (Edit the hosts File)

To test virtual hosts locally, edit your PC’s hosts file.

sudo nano /etc/hosts

Add the following lines:

127.0.0.1 example.com
127.0.0.1 test.com

Save the file, then open a browser and visit:

http://example.com/

You should see “Welcome to example.com”.

Likewise, visiting:

http://test.com/

should display “Welcome to test.com”.

7. Troubleshooting Virtual Hosts

If virtual hosts are not working correctly, check the following:

1. Check Apache error logs

sudo tail -f /var/log/apache2/error.log

2. Confirm the configuration files are enabled

ls /etc/apache2/sites-enabled/

If the correct .conf files are listed, the virtual hosts are active.

3. Check Apache port settings

Verify that port 80 (HTTP) is configured:

sudo nano /etc/apache2/ports.conf

Ensure the following line exists:

Listen 80

Summary

This section explained how to configure virtual hosts in Apache on Ubuntu.
Key takeaways:

  • Concept and purpose of virtual hosts
  • Creating directories for each site
  • Creating and enabling virtual host configuration files
  • Local testing methods using the hosts file
  • Troubleshooting common issues

5. Introducing SSL/TLS (Enabling HTTPS)

What Is SSL/TLS?

SSL (Secure Sockets Layer) and TLS (Transport Layer Security) are encryption technologies used to ensure secure communication over the internet.

Benefits of Enabling SSL/TLS

Encrypts communication (reduces the risk of data being intercepted or altered)
Improves Google SEO ranking (HTTPS sites are prioritized)
Prevents browser security warnings (HTTP sites show “Not Secure”)
Protects login credentials and online transactions

Today, TLS (TLS 1.2 / 1.3) is recommended, and older SSL versions (SSL 3.0 and earlier) are deprecated.

Obtaining a Free SSL Certificate with Let’s Encrypt

Let’s Encrypt is a Certificate Authority (CA) that provides free SSL certificates.
Using certbot, you can easily issue a certificate and configure it with Apache.

Install the Let’s Encrypt Client (Certbot)

Install certbot, the official Let’s Encrypt client:

sudo apt update
sudo apt install certbot python3-certbot-apache -y

Automate Apache SSL Configuration

You can automatically configure Apache using the following command:

sudo certbot --apache -d example.com -d www.example.com

This command performs:

  1. Domain validation (HTTP-01 challenge)
  2. SSL certificate issuance
  3. Automatic Apache SSL configuration
  4. Optional redirect from HTTP to HTTPS

Verify SSL Operation

Access the following URL to confirm HTTPS is enabled:

https://example.com/

If your browser displays a padlock icon, SSL is successfully applied.

Manually Configuring SSL for Apache

If you do not wish to use certbot --apache, you can configure SSL manually.

1. Enable Apache’s SSL Module

sudo a2enmod ssl
sudo systemctl restart apache2

2. Configure the SSL Virtual Host

Edit the SSL configuration file /etc/apache2/sites-available/example.com-le-ssl.conf:

sudo nano /etc/apache2/sites-available/example.com-le-ssl.conf

Configuration example:

<VirtualHost *:443>
    ServerAdmin admin@example.com
    ServerName example.com
    ServerAlias www.example.com
    DocumentRoot /var/www/example.com/public_html

    SSLEngine on
    SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem

    <Directory /var/www/example.com/public_html>
        Options -Indexes +FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/example.com_error.log
    CustomLog ${APACHE_LOG_DIR}/example.com_access.log combined
</VirtualHost>

3. Enable SSL Configuration and Restart Apache

sudo a2ensite example.com-le-ssl.conf
sudo systemctl restart apache2

Automatic Renewal of SSL Certificates

Let’s Encrypt certificates are valid for 90 days. To avoid manual renewals, configure automatic updates.

1. Test Certbot Automatic Renewal

sudo certbot renew --dry-run

2. Check Renewal Schedule

Certbot’s auto-renewal schedule is stored under /etc/cron.d/certbot.

sudo systemctl list-timers | grep certbot

SSL Troubleshooting

1. SSL Certificate Not Applied

Solution: Restart Apache and verify configuration

sudo systemctl restart apache2
sudo apachectl configtest

2. Certificate Has Expired

sudo certbot renew --force-renewal

3. Let’s Encrypt Validation Errors

Solution: Check firewall rules

sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw reload

Summary

This section explained how to install and configure free SSL using Let’s Encrypt.
Key takeaways:

  • Basics of SSL/TLS
  • Configuring Apache with Let’s Encrypt
  • Manual SSL configuration
  • Automatic certificate renewal
  • Troubleshooting SSL issues

6. Enhancing Web Server Security

Configuring the Firewall (UFW)

Ubuntu uses UFW (Uncomplicated Firewall) to block unnecessary traffic and protect the server.

Check the current firewall settings

sudo ufw status

Allow only required ports

By default, block all incoming traffic and allow only required ports:

sudo ufw default deny incoming
sudo ufw default allow outgoing

Open required ports:

  • SSH (Port 22)
sudo ufw allow 22/tcp
  • HTTP (Port 80)
sudo ufw allow 80/tcp
  • HTTPS (Port 443)
sudo ufw allow 443/tcp

Enable the firewall

sudo ufw enable

Strengthening SSH Security

SSH is a common target of brute-force attacks if left with default settings. Strengthen security by applying proper configurations.

Change the SSH Port

sudo nano /etc/ssh/sshd_config

Modify these lines:

Port 2222  # Change from 22 to any unused port
PermitRootLogin no  # Disable root login
PasswordAuthentication no  # Disable password login (use SSH keys only)

Restart SSH:

sudo systemctl restart ssh

Install Fail2Ban

Fail2Ban protects your server by temporarily banning IP addresses that attempt repeated SSH login failures.

sudo apt install fail2ban -y

Edit the configuration:

sudo nano /etc/fail2ban/jail.local

Add the following:

[sshd]
enabled = true
port = 2222
maxretry = 3
bantime = 600

Enable Fail2Ban:

sudo systemctl restart fail2ban
sudo systemctl enable fail2ban

Hardening Apache

Hide Apache Version Information

sudo nano /etc/apache2/conf-available/security.conf

Change the following settings:

ServerTokens Prod
ServerSignature Off

Apply the changes:

sudo systemctl restart apache2

Disable Directory Listing

sudo nano /etc/apache2/apache2.conf

Locate the directory block and update:

<Directory /var/www/>
    Options -Indexes +FollowSymLinks
    AllowOverride All
    Require all granted
</Directory>

Restart Apache:

sudo systemctl restart apache2

Disable Unnecessary Apache Modules

sudo a2dismod autoindex
sudo a2dismod status
sudo systemctl restart apache2

Adding Security Headers

Security headers protect your website from attacks such as cross-site scripting and clickjacking.

Enable mod_headers

sudo a2enmod headers
sudo systemctl restart apache2

Add Security Headers

sudo nano /etc/apache2/sites-available/example.com.conf

Add the following inside the <VirtualHost> block:

<IfModule mod_headers.c>
    Header always set X-Content-Type-Options "nosniff"
    Header always set X-XSS-Protection "1; mode=block"
    Header always set X-Frame-Options "SAMEORIGIN"
    Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
</IfModule>

Restart Apache:

sudo systemctl restart apache2

Troubleshooting

Check Firewall Settings

sudo ufw status

Check Apache Configuration for Errors

sudo apachectl configtest

Output example:

Syntax OK

Cannot Connect via SSH After Changing Port

If SSH does not connect after changing the port, specify the new port when connecting:

ssh -p 2222 user@server-ip

Summary

This section explained how to strengthen the security of your web server.
Key takeaways:

  • Configuring UFW firewall rules
  • Securing SSH (port change, Fail2Ban)
  • Apache security hardening (hide version info, disable listing)
  • Adding security headers

7. Performance Optimization

Tuning Apache

The default Apache configuration may not offer optimal performance. By applying the following adjustments, you can achieve significantly higher performance.

Optimizing the MPM (Multi-Processing Module)

The MPM (Multi-Processing Module) determines how Apache handles requests.

Check the current MPM:

apachectl -M | grep mpm

Example output:

mpm_prefork_module (shared)

If mpm_prefork_module is enabled, switching to mpm_event can improve performance.

Change the MPM:

sudo a2dismod mpm_prefork
sudo a2enmod mpm_event
sudo systemctl restart apache2

Enable KeepAlive

KeepAlive (persistent connections) allows clients to reuse existing connections, reducing request overhead.

Edit the configuration file:

sudo nano /etc/apache2/apache2.conf

Confirm the following settings:

KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 5

Restart Apache:

sudo systemctl restart apache2

Using Cache

By utilizing browser cache and server-side cache, you can reduce unnecessary requests and significantly improve response speed.

Enable mod_expires (Browser Cache)

sudo a2enmod expires
sudo systemctl restart apache2

Add the following to /etc/apache2/sites-available/example.com.conf:

<IfModule mod_expires.c>
    ExpiresActive On
    ExpiresDefault "access plus 1 month"
    ExpiresByType image/jpg "access plus 1 year"
    ExpiresByType image/jpeg "access plus 1 year"
    ExpiresByType image/png "access plus 1 year"
    ExpiresByType text/css "access plus 1 month"
    ExpiresByType application/javascript "access plus 1 month"
</IfModule>

Restart Apache:

sudo systemctl restart apache2

Enable mod_cache (Server Cache)

sudo a2enmod cache cache_disk
sudo systemctl restart apache2

Add the following to /etc/apache2/sites-available/example.com.conf:

<IfModule mod_cache.c>
    CacheEnable disk /
    CacheRoot /var/cache/apache2/mod_cache_disk
    CacheDefaultExpire 86400
</IfModule>

Restart Apache:

sudo systemctl restart apache2

Enable Compression

Use mod_deflate to compress website data and reduce transfer size.

Enable mod_deflate

sudo a2enmod deflate
sudo systemctl restart apache2

Add the following to /etc/apache2/sites-available/example.com.conf:

<IfModule mod_deflate.c>
    AddOutputFilterByType DEFLATE text/html text/plain text/xml
    AddOutputFilterByType DEFLATE text/css
    AddOutputFilterByType DEFLATE application/javascript
    AddOutputFilterByType DEFLATE image/svg+xml
</IfModule>

Restart Apache:

sudo systemctl restart apache2

Resource Limiting

To prepare for heavy traffic or potential malicious access, set resource limits using Apache modules.

Enable mod_ratelimit

sudo a2enmod ratelimit
sudo systemctl restart apache2

Add the following to /etc/apache2/sites-available/example.com.conf:

<Location />
    SetOutputFilter RATE_LIMIT
    SetEnv rate-limit 200
</Location>

Restart Apache:

sudo systemctl restart apache2

Troubleshooting Performance Issues

Check the Apache Error Log

sudo tail -f /var/log/apache2/error.log

Check Apache Load Status

sudo apachectl status

Check CPU and Memory Usage

top

or

htop

If htop is not installed:

sudo apt install htop

Summary

This section explained how to optimize web server performance.
Key takeaways:

  • Tuning Apache (MPM optimization and KeepAlive settings)
  • Using cache (browser cache and server cache)
  • Data compression with mod_deflate
  • Resource control using mod_ratelimit

8. Troubleshooting

Apache Will Not Start

If Apache fails to start, a configuration error is the most common cause.

1. Check Error Messages

sudo systemctl status apache2

2. Test Configuration

sudo apachectl configtest

If the output includes “Syntax error”, verify the path or settings listed in the error message.

3. Restart Apache

sudo systemctl restart apache2

Cannot Access the Server

If the server cannot be accessed in a browser, verify the following items.

1. Check Firewall Settings

sudo ufw status

Ensure that ports 80 and 443 are allowed.

2. Check Apache Status

sudo systemctl status apache2

3. Check Server IP Address

hostname -I

Virtual Hosts Not Working

If virtual hosts do not behave as expected, re-check the configuration.

1. Confirm Virtual Host Files Are Enabled

ls /etc/apache2/sites-enabled/

If your .conf is not listed, enable it:

sudo a2ensite example.com.conf
sudo systemctl restart apache2

2. Check Hostname Resolution

If testing locally, ensure the /etc/hosts file contains:

127.0.0.1 example.com

3. Check the DocumentRoot Path

Incorrect paths often cause virtual host issues.

DocumentRoot /var/www/example.com/public_html

SSL Certificate Issues

1. HTTPS Not Working

Confirm SSL is enabled:

sudo apachectl -M | grep ssl

Enable if necessary:

sudo a2enmod ssl
sudo systemctl restart apache2

2. Certificate Has Expired

sudo certbot renew

3. Let’s Encrypt Validation Fails

HTTP validation requires that port 80 is open.

sudo ufw allow 80/tcp
sudo systemctl restart apache2

Slow Website Performance

1. Check Server Load

top

2. Review Apache Logs

sudo tail -f /var/log/apache2/access.log

3. Confirm Cache Settings

Ensure mod_expires, mod_cache, and mod_deflate are enabled.

Permission Errors (403 Forbidden)

This error typically indicates incorrect file or directory permissions.

1. Check Directory Ownership

sudo chown -R www-data:www-data /var/www/example.com

2. Check Directory Permissions

sudo chmod -R 755 /var/www/example.com

Error Log Monitoring

Always monitor error logs during troubleshooting:

sudo tail -f /var/log/apache2/error.log

Summary

This section provided methods for troubleshooting common issues with your Ubuntu web server.
Key points:

  • Apache startup errors and configuration checks
  • Firewall and network-related issues
  • Virtual host configuration problems
  • SSL certificate errors and renewals
  • Performance and permission troubleshooting

9. Summary

In this article, we explained how to build a complete web server environment on Ubuntu using Apache, along with security enhancements, performance optimization, and troubleshooting techniques.

By following this guide, you can operate a stable, secure, and high-performance web server suitable for both personal projects and business-grade applications.

✔ Key Points Covered in This Guide

  • Installing Ubuntu and performing initial system configuration
  • Installing and configuring Apache
  • Setting up virtual hosts to manage multiple websites
  • Enabling HTTPS using free SSL certificates from Let’s Encrypt
  • Enhancing server security (UFW, SSH hardening, Apache settings)
  • Improving performance (caching, compression, MPM tuning)
  • Troubleshooting common issues during server operation

✔ What You Can Achieve After Completing This Guide

  • Host multiple websites on a single Ubuntu server
  • Ensure secure communication using modern SSL/TLS
  • Improve site speed and reliability using caching and compression
  • Quickly diagnose and resolve issues using Apache logs and system tools

✔ Recommended Next Steps

  • Install PHP and MySQL/MariaDB to build a full LAMP environment
  • Deploy WordPress or another CMS
  • Implement automatic backup solutions
  • Consider using cloud services (AWS, GCP, Azure, etc.)

With proper configuration and maintenance, an Ubuntu web server can deliver long-term stability and outstanding performance.
We hope this guide helps you build a reliable and secure server environment.

侍エンジニア塾