phplist: 2025 instalacion ubuntu-server 22.04

  • Actualizamos
sudo apt update && sudo apt upgrade -y

Instalar MySQL o MariaDB:

  • Instalamos
sudo apt install -y mariadb-server mariadb-client
  • Iniciar el servicio
sudo systemctl start mysql
sudo systemctl enable mysql
sudo systemctl status mysql
  • Asegurar la BD
sudo mysql_secure_installation
  • Resultado
NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MariaDB
      SERVERS IN PRODUCTION USE!  PLEASE READ EACH STEP CAREFULLY!

In order to log into MariaDB to secure it, we'll need the current
password for the root user. If you've just installed MariaDB, and
haven't set the root password yet, you should just press enter here.

Enter current password for root (enter for none): 
OK, successfully used password, moving on...

Setting the root password or using the unix_socket ensures that nobody
can log into the MariaDB root user without the proper authorisation.

You already have your root account protected, so you can safely answer 'n'.

Switch to unix_socket authentication [Y/n] 
Enabled successfully!
Reloading privilege tables..
 ... Success!


You already have your root account protected, so you can safely answer 'n'.

Change the root password? [Y/n] n
 ... skipping.

By default, a MariaDB installation has an anonymous user, allowing anyone
to log into MariaDB without having to have a user account created for
them.  This is intended only for testing, and to make the installation
go a bit smoother.  You should remove them before moving into a
production environment.

Remove anonymous users? [Y/n] Y
 ... Success!

Normally, root should only be allowed to connect from 'localhost'.  This
ensures that someone cannot guess at the root password from the network.

Disallow root login remotely? [Y/n] Y
 ... Success!

By default, MariaDB comes with a database named 'test' that anyone can
access.  This is also intended only for testing, and should be removed
before moving into a production environment.

Remove test database and access to it? [Y/n] Y
 - Dropping test database...
 ... Success!
 - Removing privileges on test database...
 ... Success!

Reloading the privilege tables will ensure that all changes made so far
will take effect immediately.

Reload privilege tables now? [Y/n] Y
 ... Success!

Cleaning up...

All done!  If you've completed all of the above steps, your MariaDB
installation should now be secure.

Thanks for using MariaDB!
  • Crear una base de datos para phpList
sudo mysql -u root -p (ENTER)

CREATE DATABASE phplist CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;

CREATE USER 'phplistuser'@'localhost' IDENTIFIED BY 'phplistuser123';

GRANT ALL PRIVILEGES ON phplist.* TO 'phplistuser'@'localhost';

FLUSH PRIVILEGES;
EXIT;
  • acceso remoto
sudo nano /etc/mysql/mariadb.conf.d/50-server.cnf
  • Y modificar
bind-address            = 127.0.0.1
X
bind-address            = 0.0.0.0
  • otorgar permisos al usuario para conectarse desde cualquier host:
sudo mysql -u root -p

GRANT ALL PRIVILEGES ON phplist.* TO 'phplistuser'@'%' IDENTIFIED BY 'phplistuser123';

FLUSH PRIVILEGES;
  • reinicamos
sudo systemctl restart mariadb
sudo systemctl status mariadb
  • Ahora desde otra maquina podemos probar la conexion
mysql -u phplistuser -p -h 10.0.2.98

Instalar Apache

  • Instalamos
sudo apt install -y apache2
  • Habilitar el módulo mod_rewrite:
sudo a2enmod rewrite
sudo systemctl restart apache2
  • Configurar el VirtualHost para phpList: Crear un archivo de configuración:
sudo nano /etc/apache2/sites-available/phplist.conf
  • Agregarle
<VirtualHost *:80>
    ServerName phplist.una.ac.cr
    DocumentRoot /var/www/html/phplist/public_html/lists/
    <Directory /var/www/html/phplist/public_html/lists>
        Options FollowSymLinks
        AllowOverride All
        Require all granted
        DirectoryIndex index.php index.html
    </Directory>
    ErrorLog ${APACHE_LOG_DIR}/phplist_error.log
    CustomLog ${APACHE_LOG_DIR}/phplist_access.log combined
</VirtualHost>
  • Habilitar el sitio y reiniciar Apache:
sudo a2ensite phplist
sudo systemctl reload apache2

Instalar PHP 8.1 y extensiones necesarias

  • Agregar el repositorio de PHP:
sudo apt install -y software-properties-common
sudo add-apt-repository -y ppa:ondrej/php
sudo apt update
  • Instalar PHP 8.1 con extensiones:
sudo apt install -y php8.1 php8.1-curl php8.1-gd php8.1-imap php8.1-mbstring php8.1-mysql php8.1-xml php8.1-zip php8.1-cli
  • Verificamos los módulos y version de php
php -v
php -m
  • Para que los cambios tengan efecto, reinicia el servidor web:
sudo systemctl restart apache2
  • Asegurarte de que PHP está habilitado en Apache:
sudo apt install libapache2-mod-php8.1
sudo systemctl restart apache2
  • Configurar parámetros opcionales (como upload_max_filesize, post_max_size
  • abrimos el archivo
sudo nano /etc/php/8.1/apache2/php.ini
  • Busca y ajusta:
memory_limit = 256M
upload_max_filesize = 64M
post_max_size = 64M
max_execution_time = 300
  • Reinicamos
sudo systemctl restart apache2
  • Creamos un archivo phpinfo para ver su funcionamiento
echo "<?php phpinfo(); ?>" | sudo tee /var/www/html/info.php

Descargar e instalar phpList

  • Descargamos
cd /tmp

wget https://sourceforge.net/projects/phplist/files/phplist/3.6.15/phplist-3.6.15.tgz
  • Extraer e instalar:
sudo tar -xvzf phplist-3.6.15.tgz -C /var/www/html/
sudo mv /var/www/html/phplist-* /var/www/html/phplist
sudo chown -R www-data:www-data /var/www/html/phplist
sudo chmod -R 755 /var/www/html/phplist
  • Editar el archivo de configuración:
sudo nano /var/www/html/phplist/public_html/lists/config/config.php
  • Y modificamos los datos de la BD
  • Ademas como el virtual host pusimos la ruta /var/www/html/phplist/public_html/lists/
  • Vamos agregar esta variables en el archivo config.php
nano /var/www/html/phplist/public_html/lists/config/config.php
  • agregamos al final
$pageroot = '/';
  • Y tambien agregamos el idioma
$default_system_language = "es";
  • Le damos inicializar la BD
  • Y completamos los datos
  • Y se crea la BD
  • le decimos que nos queremos subcribir
  • Y le damos continuar
  • Nos indica que tenemos configuraciones pendientes
  • Para garantizar el envio vamos a modificar que cada 8 segundos envie un correo dando 450 por hora
  • Abrimos el archivo de configuración
nano /var/www/html/phplist/public_html/lists/config/config.php
  • Y le agregamos
define('MAILQUEUE_THROTTLE', 8);         // cada 8 segundos enviará 1 email

Configurar cron

  • Instalamos
apt install php8.1-cli
  • Creamos el archivo
cd /usr/local/bin
nano /usr/local/bin/phplist
  • Y le agreganmos
#!/bin/bash
/usr/bin/php /var/www/html/phplist/public_html/lists/admin/index.php -c /var/www/html/phplist/public_html/lists/config/config.php $*
  • Le damos permisos
chmod 755 /usr/local/bin/phplist
  • Ya podriamos procesar las lista con el siguiente comandfo
phplist -pprocessqueue
  • Resultado
root@phplist:/usr/local/bin# phplist -pprocessqueue
phpList - phpList version 3.6.15 (c) 2000-2025 phpList Ltd, https://www.phplist.com
phpList - Recently sent : 0
phpList - Comenzado [0.0059690000] (127)
phpList - Enviando en lotes de 1,000 correos [0.0002760000] (128)
phpList - Estadio de script: 6 [0.0006850000] (132)
phpList - Finalizado, Nada que hacer [0.0002590000] (133)
phpList - Acabado, todo hecho [0.0018370000] (136)
  • Agregamos un cron que procese la cola cada 5 minutos y los rebotes una vez al día
crontab -e
  • Agregamos
0-59/5 * * * * phplist -pprocessqueue > /dev/null 2>&1
0 3 * * * phplist -pprocessbounces > /dev/null 2>&1
  • Ahora que el procesamiento va se trabajado por el cron tenemos que indicarle a phplist que algunos enlaces van a desaparecer
  • abrimos el archivo de configuración
nano /var/www/html/phplist/public_html/lists/config/config.php
  • Y modificamos
define('MANUALLY_PROCESS_BOUNCES', 1);
X
define('MANUALLY_PROCESS_BOUNCES', 0); // que los rebotes se trabajen una vez por día por el cron
  • Y agregamos
define ("MANUALLY_PROCESS_QUEUE",0); // que las colas sean tartadas por el cron

Instalación de postfix y configuración de correo

  • Instalamos
apt install postfix mailutils
  • Seleccionar las siguientes opciones al instalar el postfix
-> Sistema: Satelite
-> Nombre del servicio: phplist
-> Maquina de Reenvio: mail.una.ac.cr
  • Revisamos el nombre del host
nano /etc/hostname
  • Debe estar con el nombre completo
phplist.una.ac.cr
  • revisamos el archivo host
nano /etc/hosts
  • Agregamos al archivo
127.0.0.1   phplist phplist.una.ac.cr
  • Abrimos el archivo de configuración
nano /etc/postfix/main.cf
  • Y tambien comentamos todo lo referente a TLS
# TLS parameters
#smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
#smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
#smtpd_tls_security_level=may

#smtp_tls_CApath=/etc/ssl/certs
#smtp_tls_security_level=may
#smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
  • y reniciamos el servicio
systemctl restart postfix
systemctl status postfix

Configuracion del dns interno y reverso

  • Ahora debemos abrir el DNS
  • Abrimos Consola DB
  • Lo primero es abriri consolaBD
  • Y ubicar la aplicación
  • Bitvise SSh Client
  • Cargamos el perfil de DNS
  • Darle conectar
  • Se va a conectar con el usuario dalpizar
z<agTn&!=@p{U[
  • Cerramos la ventana
  • Nos abre la terminal
  • nos loogeamos con el usuario cgiroot
su - cgiroot 

gpcCPE&x3]B-Fm
  • Ingresamos a la ruta
cd /etc/bind
  • abrimos el archivo
nano /etc/bind/interno.data
  • Modificamos el serial
  • Y buscamos la ip del nuevo servidor para agregar el registro A en el dns
  • por ejemplo
  • y ahora abrimos el archivo reverso dependiendo de la red
nano /etc/bind/reverso.10.0.2
nano /etc/bind/reverso.10.0.3
  • le modificamos el serial
  • y agregamos o modificamos la ip y dominio requerido
  • NOTA: recuerde que termina en punto .
  • reinicamos el servicio
/etc/init.d/named restart
  • y revisamos la cola
tail -f /var/log/named/general.log
  • Resultado
  • ahora debemo probar que resulva el dominio y el reverso
  • podemos hacerlo con
dig @localhost phplist.una.ac.cr
  • o de forma individual pero solo sirve dentro de propio dns
nslookup -> ENTER
(ip) 10.0.2.98 -> ENTER
(dominio) openemm.una.ac.cr

exit

Configuración de hora

  • Si ejecutamos
timedatectl
  • Retorna
               Local time: mar 2025-01-21 17:09:53 UTC
           Universal time: mar 2025-01-21 17:09:53 UTC
                 RTC time: mar 2025-01-21 17:09:53
                Time zone: Etc/UTC (UTC, +0000)
System clock synchronized: yes
              NTP service: active
          RTC in local TZ: no
  • Esta incorreto ejecutamos
sudo timedatectl set-timezone America/Costa_Rica

configuraciones de PHP.ini

  • abrimos el archivo
sudo nano /etc/php/8.1/apache2/php.ini
  • buscamos
;date.timezone =
  • Y lo modificamos por
date.timezone = "America/Costa_Rica"
  • Adjuntos
upload_max_filesize = 64M
post_max_size = 64M
  • Tiempo de ejecución de scripts
max_execution_time = 300
memory_limit = 256M
  • Para cuando se importan listas grandes de correos
max_input_vars = 5000
  • para utilizar sendmail
sendmail_path = /usr/sbin/sendmail -t -i
  • con este comando podemos ver la ruta del sendmail
which sendmail
  • habilitar los logs de error pero ocultar los errores para evitar poner información sensible
error_reporting = E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED
log_errors = On
error_log = /var/log/phplist_errors.log
display_errors = Off
  • Reiniciamos
sudo systemctl restart apache2

Configuración de apache

  • Abrimos el archivo
nano /etc/apache2/apache2.conf
  • Y modificamos esto
<Directory /var/www/>
        Options Indexes FollowSymLinks
        AllowOverride None
        Require all granted
</Directory>
  • Por esto para evitar el listado de los archivos
<Directory /var/www/>
        Options FollowSymLinks
        AllowOverride None
        Require all granted
</Directory>
  • Ahora le podemos agregar esto para solo permitir estos metodos
<LimitExcept GET POST HEAD>
        Require all denied
    </LimitExcept>
  • Quedando así
  • En /usr/share
<Directory /usr/share>
        AllowOverride None
        Require all granted
</Directory>

X

<Directory /usr/share>
        AllowOverride None
        Require all denied
</Directory>
  • Verificamos que se encuentre bloquedo el acceso a archivos .ht…
<FilesMatch "^\.ht">
        Require all denied
</FilesMatch>
  • Abrimos el archivo
nano /etc/apache2/conf-available/charset.conf
  • Y modificamos
#AddDefaultCharset UTF-8
X
AddDefaultCharset UTF-8
  • Abrimos el archivo
nano /etc/apache2/conf-available/security.conf
  • Modificamos
ServerTokens OS
X
ServerTokens Prod

ServerSignature On
x
ServerSignature Off
  • reiniciamos
sudo systemctl restart apache2