Instalación tradicional de servidor web con Apache

servidor web apache

Las raices y el paso a paso siempre son super necesarios para entender como funciona todo, por eso para nosotros es importante dejarte este #tutorial donde te mostramos la Instalación tradicional de servidor web con Apache sobre #Ubuntu para que puedas alojar tus proyectos.

Ya te habiamos mostrado como con un par de comandos podrias tener tu labotarorio armado gracias a lamp y docker:

Algunos pasos a tener en cuenta:

sudo apt update && sudo apt upgrade -y
sudo apt install apache2

Luego de instalarse, si es tu maquina local y abris un navegador en la ip de la misma, o bien con 127.0.0.1 te va a abrir la pagina de bienvenida! Tambien podes probar con tu ip con http://tuip

mi servidorsito esta corriendo en 192.168.0.2
sudo nano /etc/apache2/apache2.conf

Buscamos la linea:

Cambiamos la palabra None por All y quedaria del siguiente modo:

Luego de guardar vamos a ejecutar los siguientes comandos para activar dos modulos importantes:

sudo a2enmod rewrite
sudo a2enmod headers

sudo a2enmod rewrite

Este comando habilita el módulo mod_rewrite de Apache, que sirve para:

  • Reescribir URLs de forma flexible.
  • Crear URLs amigables (por ejemplo, convertir pagina.php?id=5 en pagina/5).
  • Redireccionamientos internos o externos según reglas definidas en archivos .htaccess o configuración del VirtualHost.

Es muy común en aplicaciones como WordPress, Laravel, Joomla, etc., que requieren URLs limpias o personalizadas.

sudo a2enmod headers

Este comando habilita el módulo mod_headers de Apache, que permite:

  • Manipular encabezados HTTP (headers).
  • Agregar, modificar o quitar encabezados en las respuestas del servidor.
  • Muy útil para temas de seguridad (como añadir Content-Security-Policy, X-Frame-Options, Access-Control-Allow-Origin, etc.).
  • También se usa en CORS, control de caché, políticas de seguridad, etc.

Ahora vamos a dirigirnos a /var/www/html y borramos el index.html existente:

cd /var/www/html
sudo rm index.html
sudo nano index.html

y Copiamos el siguiente codigo de ejemplo:

<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <title>Bienvenido</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <style>
        body {
            background: #f4f4f4;
            font-family: Arial, sans-serif;
            text-align: center;
            padding-top: 100px;
        }
        h1 {
            color: #2c3e50;
        }
        p {
            color: #555;
            font-size: 18px;
        }
    </style>
</head>
<body>
    <h1>Bienvenido al tutorial para instalar Apache2</h1>
    <p>¡Gracias por pasar!</p>
</body>
</html>

Al recargar la web veremos:

Algo que tenemos que tener en claro es que apache por defecto crea un usuario y un grupo que se llama www-data para que administre apache. Algunos usuarios por razones de comodidad requieren cambiar esta configuracion y lo hacen de la siguiente manera (lean sin hacer asi deciden):

Primero cambian de dueño la carpeta html por el usuario normal:

sudo chown -R $USER:$USER /var/www/html

Luego editan el archivo envvars para cambiar el usuario con el cual se ejecuta

sudo nano /etc/apache2/envvars

Para mi algo más sencillo e sagregar el usuario al grupo www-data que en definitiva esta para eso.

sudo usermod -aG www-data ${USER}

No importa cual fuera la decición para aplicar los cambios vamos a reiniciar el servicio de apache con:

sudo service apache2 restart

Luego le que hice fue crear una carpeta dentro de html que se llame tutorial, movi el index.html adentro de la carpeta tutorial y puedo ver a apache trabajando con directorios. Uno podria ser tutorial, otro web2, otro web3, y asi una carpeta por proyecto sin problemas!

Ya que estamos deberiamos crear esta estructura:

/var/www/html/
------------->web1/index.html
------------->web2/index.html

en cada index.html aclarar que es web1 o web2 (solo reemplazen texto).

Apache requiere ServerName eso quiere decir que funciona con dns. Lo más probable es que no uses un servidor local de dns asi que la solucion es estar en editar el archivo hosts:

sudo nano /etc/hosts

y el contenido:

127.0.0.1    web1.local
127.0.0.1    web2.local

Ahora vamos a ir a la configuración de apache2 donde le decimos que existen estos sitios web y que por ende se deben crear Virtual Host

sudo nano /etc/apache2/sites-available/web1.conf

Dentro van algunas configuraciones más o menos dificiles, pero arrancamos siempre por lo facil:

<VirtualHost *:80>
    ServerName web1.local
    DocumentRoot /var/www/html/web1
    Redirect permanent / https://web1.local/
</VirtualHost>

<VirtualHost *:443>
    ServerName web1.local
    DocumentRoot /var/www/html/web1

    SSLEngine on
    SSLCertificateFile /etc/ssl/certs/web1.crt
    SSLCertificateKeyFile /etc/ssl/private/web1.key

    <Directory /var/www/html/web1>
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>

Luego repetimos para web2.local y ponemos el codigo:

<VirtualHost *:80>
    ServerName web2.local
    DocumentRoot /var/www/hmtl/web2
   
</VirtualHost>

<VirtualHost *:443>
    ServerName web2.local
    DocumentRoot /var/www/html/web2

    SSLEngine on
    SSLCertificateFile /etc/ssl/certs/web2.crt
    SSLCertificateKeyFile /etc/ssl/private/web2.key

    <Directory /var/www/html/web2>
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>

Ahora vamos a generar los ssl autofirmados como una simple solucion al https:

sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
  -keyout /etc/ssl/private/web1.key \
  -out /etc/ssl/certs/web1.crt

Ahora vmaos a generar con el segundo:

sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
  -keyout /etc/ssl/private/web2.key \
  -out /etc/ssl/certs/web2.crt

Repetimos la accion.

Y ahora activamos ambos sitios:

sudo a2ensite web1.conf
sudo a2ensite web2.conf
sudo a2enmod ssl

Como activamos ssl autofirmados locales nos va a aparecer (ejemplo con web2.local) que la web es insegura:

Vamos a avanzado y continuar.

Ya tenemos la Instalación tradicional de servidor web con Apache y es importante saberlo por que gracias a los archivos que mostramos, y si nos intereza trabajar con docker vamos a ir pudiendo armar nuestros Dockerfile sin problema.

Un pasito más seria que puedas leer como implementar algo de seguridad en tu servidor linux:

Y que aprendas sobre configuración del archivo .htaccess que es donde se ponen algunas directivas de seguridad. Aca te dejo algunos ejemplos que obviamente dependen de lo que cada uno quiere/tiene

# 1. Evitar listar contenido de directorios
Options -Indexes

# 2. Proteger archivos sensibles
<FilesMatch "(\.env|\.htaccess|\.htpasswd|\.ini|\.log|\.sh|composer\.json|composer\.lock)">
    Require all denied
</FilesMatch>

# 3. Restringir acceso a carpetas específicas
<DirectoryMatch "^.*(includes|private|config|core|scripts)">
    Require all denied
</DirectoryMatch>

# 4. Evitar ejecución de scripts en ciertos directorios (por ejemplo: uploads)
<Directory "/ruta/a/uploads">
    php_flag engine off
    Options -ExecCGI
</Directory>

# 5. Restringir métodos HTTP peligrosos
<LimitExcept GET POST HEAD>
    Require all denied
</LimitExcept>

# 6. Proteger contra XSS, clickjacking, MIME sniffing
Header set X-Content-Type-Options "nosniff"
Header set X-Frame-Options "SAMEORIGIN"
Header set X-XSS-Protection "1; mode=block"

# 7. Forzar HTTPS (si tienes certificado SSL)
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

# 8. Evitar acceso a archivos ocultos (.*)
RedirectMatch 403 /\..*$

# 9. Configurar política de caché (opcional, para rendimiento)
<IfModule mod_expires.c>
    ExpiresActive On
    ExpiresByType image/jpg "access plus 30 days"
    ExpiresByType image/jpeg "access plus 30 days"
    ExpiresByType image/gif "access plus 30 days"
    ExpiresByType image/png "access plus 30 days"
    ExpiresByType text/css "access plus 1 week"
    ExpiresByType application/javascript "access plus 1 week"
    ExpiresByType text/html "access plus 1 day"
</IfModule>

Para este ejemplo nosotros usamos la estructura:

/var/www/html/
├── web1/
└── web2/

Y cada uno de nuestros sitios es distinto (con su propio Virtual Host apuntando a /var/www/html/web1 y /var/www/html/web2), entonces deberiamos colocar un archivo .htaccess dentro de cada uno de esos directorios, así:

/var/www/html/web1/.htaccess
/var/www/html/web2/.htaccess

Para que Apache lea los .htaccess nuestra configuración de Virtual Host (por ejemplo /etc/apache2/sites-available/web1.conf) deberia permitirlo:

<Directory /var/www/html/web1>
AllowOverride All
Require all granted
</Directory>

Luego recargamos la config con:

sudo systemctl reload apache2

Los .htaccess tambien dependen que tecnología usamos ya que no es lo mismo si usamos php u otra cosa. Si fuera php esto seria un ejemplo:

# --- Seguridad básica para sitios PHP ---

# 1. Evita listar archivos en carpetas sin index
Options -Indexes

# 2. Protege archivos sensibles (config, logs, backups, etc.)
<FilesMatch "\.(env|log|ini|sql|bak|htaccess|htpasswd|json)$">
    Require all denied
</FilesMatch>

# 3. Bloquea acceso a archivos ocultos (por ejemplo .git, .env)
RedirectMatch 403 /\..*$

# 4. Protege ciertos directorios (como uploads) de ejecutar scripts PHP
<Directory "/var/www/html/web1/uploads">
    php_flag engine off
    Options -ExecCGI
    Require all denied
</Directory>

# 5. Restringe métodos HTTP peligrosos
<LimitExcept GET POST HEAD>
    Require all denied
</LimitExcept>

# 6. Encabezados HTTP para protección
<IfModule mod_headers.c>
    Header set X-Frame-Options "SAMEORIGIN"
    Header set X-XSS-Protection "1; mode=block"
    Header set X-Content-Type-Options "nosniff"
</IfModule>

# 7. Fuerza HTTPS (si tenés certificado SSL)
<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{HTTPS} off
    RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</IfModule>

# 8. Control de caché (opcional para rendimiento)
<IfModule mod_expires.c>
    ExpiresActive On
    ExpiresByType image/jpg "access plus 30 days"
    ExpiresByType image/jpeg "access plus 30 days"
    ExpiresByType image/png "access plus 30 days"
    ExpiresByType text/css "access plus 7 days"
    ExpiresByType application/javascript "access plus 7 days"
</IfModule>

y luego deberiamos ejecutar estos dos comandos:

sudo a2enmod rewrite headers expires
sudo systemctl restart apache2

(rewrite y headers ya los habiamos habilitado antes solo agregamos expires)

Espero que les sirva mucho y puedan tambien compartir en sus redes!

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *