Despliegue de VPS Linux con servicios gestionados
- Postfix, con el que tengo de forma totalmente controlada un servicio de correo electrónico totalmente personalizado.
- Dovecot, doy acceso IMAP a mi correo electrónico.
- nginx, este proxy da acceso a todos los servicios que están publicados en internet, teniendo en cuenta que sólo se expone de dichos servicios lo realmente interesante, y por supuesto "poco conflictivo"
- Taiga, es un gestor SCRUM al estilo de Jira, pero 100% opensource, diseñado y publicado por Kaleidos
- Penpot, es una herramienta para diseño de UI, similar a Figma o Zeplin, pero igualmente opensource, está desplegado internamente sobre docker (no queda otra), también diseñado y publicado por Kaleidos.
- Jenkins, herramienta opensource por antonomasia para la gestión de CI/CD. A tener en cuenta que Jenkins se publica sobre nginx, la instalación corre sobre localhost, excluida de internet.
- RoundcubeEmail, interfaz web que facilita el acceso al correo electrónico, sin más.
- Open WebUI, interfaz web para usar modelos LLM de pesos abiertos de forma sencilla, similar a gemini, chatgpt y otros.
- Servicios Rest basados en Ktor, he programado diversos servicios REST utilizando Ktor Server (con Kotlin como lenguaje de programación) y han sido publicados en internet gracias a nginx.
- Sitio web personal, diseñado usando Kotlin Multiplatform y Compose para el diseño visual.
- PostgreSQL, SGBD por antonomasia en el mundo del software libre, da servicio de base de datos a la mayoría de servicios que se exponen en el VPS.
- Sshd, sistema de acceso al VPS, tanto para acceso consola para secureFTP
- Ollama, sistema opensource de provisión de modelos LLM de pesos abiertos, no expuesto a internet.
Hoja de ruta
- Instalación de servicios básicos (este mismo post).
- Instalación de ecosistema Kaleidos.
- Instalación de Jenkins.
- Instalación de Servicios REST basados en KTOR.
- Instalación de ecosistema IA (Ollama + Open-WebUI).
Descripción del VPS
Servicios instalados (HOW-TO)
sshd, o cómo conectarnos en remoto
- Instalamos el servicio sshd (tengamos en cuenta que el VPS "inicialmente" nos permite conectarnos a la consola desde el propio proveedor web.
# apt-get install sshd - Una vez instalado, parametrizaremos el servicio (/etc/ssh). En principio deberíamos tener las configuraciones del servicio segmentadas en la carpeta /etc/ssh/sshd_config.d, pero en muchas ocasiones esta carpeta está vacía y la configuración se realiza de forma monolítica en el fichero sshd_config. Es en este fichero donde vamos a configurar los distintos tipos de conexión certificados a utilizar etc. Es un fichero típico de pares "Clave Configuración" "Valor Parámetro".
- Una vez configurado, simplemente reiniciaremos el servicio con service sshd restart, y ya tan solo nos quedará probar la conexión desde fuera con ssh usuario@dominiovps.com
Lo primero, la seguridad de las comunicaciones
- Tu propio certificado, junto a su clave privada en un fichero adicional.
- Un Certificado Intermedio para la entidad certificadora (CA).
- El certificado Root de la entidad certificadora (CA).
- Tu propio certificado
- Certificado CA intermedio
- Certificado Raiz CA
Servicio de Bases de Datos
- Descargar postgresql utilizando el gestor de paquetes, en mi caso, apt. Tengamos en cuenta que el proceso de descarga suele permitirnos configurar ciertos aspectos del servicio, como el usuario de sistema que lo lanzará (normalmente, postgres), la ruta en la que se almacenará la base de datos, la contraseña del usuario admin (de nuevo, por defecto postgres), etc.
- Configurar el motor, normalmente, sólo permitiremos conexiones locales y autenticadas a la base de datos, para ello, debemos editar el fichero pg_hba.conf, el cual suele estar ubicado en /etc/postgresql/<tu versión de postgres>/main/. Como ejemplo de un pg_hba_conf:
# TYPE DATABASE USER ADDRESS METHOD
local all all peer
host all all 127.0.0.1/32 scram-sha-256
- Reiniciaremos el servicio usando systemctl postgresql restart como root para aplicar los cambios.
- Optimizar / tunear la configuración. Existen infinidad de sitios en los que se nos indica como podemos tunear nuestra instalación de postgres para adaptarla a nuestras necesidades (por ejemplo, número de procesos simultáneos, timeouts, tamaños de página, logging, etc). Estos parámetros van a depender y mucho de nuestra instalación concreta y del tipo de rendimiento que vayamos a requerir. El grueso de cambios para tunear nuestra base de datos se harán en el fichero postgresql.conf. Entre las configuraciones "interesantes" está la de cifrar las conexiones a la base de datos de manera automática, simplemente hay que buscar la clave que permite configurar las conexiones ssl y agregar la ruta a los certificados de la sección "Lo primero, la seguridad en las comunicaciones".
nginx, el todo en uno
- Instalamos nginx, en debian es extremadamente fácil, como root: apt-get install nginx, como principal ventaja, ya tenemos todo configurado y preparado para empezar a trabajar.
- Como recomendación, instalar también php, indispensable, por las características de nginx que php-fpm esté instalado, ya que va a ser el responsable de servir páginas PHP (nginx NO sirve páginas php, solo es un proxy que redirige el tráfico a los sitios que relacionamos con php-fpm.
- Al igual que antes, es muy recomendable instalar python3, ya que muchos sitios (como taiga) utilizan python a la hora de poner el servicio a la escucha.
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
events {
worker_connections 768;
# multi_accept on;
}
http {
log_format debug_format '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'rt=$request_time uct="$upstream_connect_time" uht="$upstream_header_time" urt="$upstream_response_time" '
'host="$host" upstream="$upstream_addr"';
##
# Basic Settings
##
sendfile on;
tcp_nopush on;
types_hash_max_size 2048;
# server_names_hash_bucket_size 64;
# server_name_in_redirect off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
##
# SSL Settings
##
ssl_certificate /etc/ssl/certs.afalabarce.dev/certs/afalabarce.dev.crt;
ssl_certificate_key /etc/ssl/certs.afalabarce.dev/private/afalabarce.dev.rsa;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;
##
# Logging Settings
##
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
##
# Gzip Settings
##
gzip on;
##
# Virtual Host Configs
##
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
Correo electrónico
- postfix
- opendkim, necesario para postfix para filtrado DKIM
- dovecot-core
- dovecot-imapd
- dovecot-lmptd, sustituye al clásico sistema de sockets de unix, útil para su integración con postfix.
- dovecot-sieve, ideal para crear filtros en el lado del servidor (el típico filtrado que permite reorganizar correo automáticamente).
- dovecot-managesieved, el demonio que controlará la ejecución de los filtros usando lenguaje sieve. Muy útil para clientes webmail, como por ejemplo, roundcube.
- /etc/postfix/main.cf, las partes más importantes de este fichero es la configuración de TLS, de lo más importante, es que hay que dar compatibilidad con protocolos TLS viejos, ya que por ejemplo, las administraciones públicas en España, aún utilizan versiones bastante desactualizadas, y el efecto es que si envían un email, postfix lo rechazaría por no tener el protocolo soportado.
# Debian specific: Specifying a file name will cause the first
# line of that file to be used as the name. The Debian default
# is /etc/mailname.
smtpd_banner = $myhostname ESMTP $mail_name (Debian/GNU)
biff = no
# appending .domain is the MUA's job.
append_dot_mydomain = no
# Uncomment the next line to generate "delayed mail" warnings
delay_warning_time = 4h
readme_directory = no
# See http://www.postfix.org/COMPATIBILITY_README.html -- default to 2 on
# fresh installs.
compatibility_level = 2
# TLS parameters
tls_random_source = dev:/dev/urandom
smtpd_tls_CAfile = /etc/ssl/certs.afalabarce.dev/certs/afalabarce.dev.ca.pem
smtpd_tls_cert_file=/etc/ssl/certs.afalabarce.dev/certs/afalabarce.dev.pem
smtpd_tls_key_file=/etc/ssl/certs.afalabarce.dev/private/afalabarce.dev.pem
smtpd_tls_security_level = maysmtpd_tls_loglevel = 1
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtpd_use_tls = yes
smtpd_tls_received_header = yes
smtpd_tls_ask_ccert = yes
smtpd_tls_ccert_verifydepth = 2
smtpd_client_restrictions = permit_mynetworks, permit_sasl_authenticated
smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination
smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination
#Enable TLS Encryption when Postfix sends outgoing emails
smtp_tls_security_level = may
smtp_tls_loglevel = 1
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
#Enforce TLSv1.3 or TLSv1.2
smtpd_tls_mandatory_protocols = >=TLSv1.2
smtpd_tls_protocols = >=TLSv1.2
smtp_tls_protocols = >=TLSv1.2
smtp_tls_mandatory_protocols = >=TLSv1.2
myhostname = mail.afalabarce.dev
mydomain = afalabarce.dev
myorigin = /etc/mailname
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
mydestination = $myhostname localhost $mydomain localhost.$mydomain, localhost, localhost.localdomain
mynetworks_style = subnet
#relayhost = localhost
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all
inet_protocols = all
mailbox_transport = lmtp:unix:private/dovecot-lmtp
smtputf8_enable = no
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yes
smtpd_tls_auth_only = yes
smtpd_sasl_authenticated_header = yes
broken_sasl_auth_clients = yes
virtual_mailbox_domains = $virtual_mailbox_maps
virtual_alias_maps = $virtual_maps
smtp_use_tls = yes
disable_vrfy_command = yes
mynetworks =
smtpd_sender_restrictions = permit_mynetworks,permit_sasl_authenticated
smtp_send_xforward_command = yes
smtpd_authorized_xforward_hosts = 127.0.0.0/8 [::1]/128
virtual_mailbox_base = /var/qmail/mailnames
virtual_uid_maps = static:30
virtual_gid_maps = static:31
mailman_destination_recipient_limit = 1
virtual_mailbox_limit = 0
smtpd_tls_ciphers = medium
smtpd_tls_mandatory_ciphers = medium
tls_medium_cipherlist = kEECDH:+kEECDH+SHA:kEDH:+kEDH+SHA:+kEDH+CAMELLIA:kECDH:+kECDH+SHA:kRSA:+kRSA+SHA:+kRSA+CAMELLIA:!aNULL:!eNULL:!SSLv2:!MD5:!DES:!EXP:!SEED:!IDEA:!3DES
tls_preempt_cipherlist = yes
queue_directory = /var/spool/postfix
meta_directory = /etc/postfix
setgid_group = postdrop
command_directory = /usr/sbin
sample_directory = /etc/postfix
newaliases_path = /usr/bin/newaliases
mailq_path = /usr/bin/mailq
sendmail_path = /usr/sbin/sendmail
mail_owner = postfix
daemon_directory = /usr/lib/postfix/sbin
manpage_directory = /usr/share/man
html_directory = /usr/share/doc/postfix/html
data_directory = /var/lib/postfix
shlib_directory = /usr/lib/postfix
home_mailbox = Maildir/
#SPF Settings
policyd-spf_time_limit = 3600
smtpd_recipient_restrictions =
permit_mynetworks,
permit_sasl_authenticated,
reject_unauth_destination,
check_policy_service unix:private/policyd-spf
# Milter configuration
milter_default_action = accept
milter_protocol = 6
smtpd_milters = local:opendkim/opendkim.sock
non_smtpd_milters = $smtpd_milters
message_size_limit = 30720000
- /etc/dovecot/conf.d/10-ssl.conf
##
## SSL settings
##
# SSL/TLS support: yes, no, required. <doc/wiki/SSL.txt>
ssl = yes
# PEM encoded X.509 SSL/TLS certificate and private key. They're opened before
# dropping root privileges, so keep the key file unreadable by anyone but
# root. Included doc/mkcert.sh can be used to easily generate self-signed
# certificate, just make sure to update the domains in dovecot-openssl.cnf
ssl_cert = </etc/ssl/certs.afalabarce.dev/certs/afalabarce.dev.crt
ssl_key = </etc/ssl/certs.afalabarce.dev/private/afalabarce.dev.rsa
# If key file is password protected, give the password here. Alternatively
# give it when starting dovecot with -p parameter. Since this file is often
# world-readable, you may want to place this setting instead to a different
# root owned 0600 file by using ssl_key_password = <path.
#ssl_key_password =
# PEM encoded trusted certificate authority. Set this only if you intend to use
# ssl_verify_client_cert=yes. The file should contain the CA certificate(s)
# followed by the matching CRL(s). (e.g. ssl_ca = </etc/ssl/certs/ca.pem)
ssl_client_ca_dir = /etc/ssl/certs
# SSL DH parameters
# Generate new params with `openssl dhparam -out /etc/dovecot/dh.pem 4096`
# Or migrate from old ssl-parameters.dat file with the command dovecot
# gives on startup when ssl_dh is unset.
ssl_dh = </usr/share/dovecot/dh.pem
# Minimum SSL protocol version to use. Potentially recognized values are SSLv3,
# TLSv1, TLSv1.1, and TLSv1.2, depending on the OpenSSL version used.
ssl_min_protocol = TLSv1.2
# Prefer the server's order of ciphers over client's.
ssl_prefer_server_ciphers = yes
- /etc/dovecot/conf.d/15-mailboxes.conf
##
## Mailbox definitions
##
# Each mailbox is specified in a separate mailbox section. The section name
# specifies the mailbox name. If it has spaces, you can put the name
# "in quotes". These sections can contain the following mailbox settings:
#
# auto:
# Indicates whether the mailbox with this name is automatically created
# implicitly when it is first accessed. The user can also be automatically
# subscribed to the mailbox after creation. The following values are
# defined for this setting:
#
# no - Never created automatically.
# create - Automatically created, but no automatic subscription.
# subscribe - Automatically created and subscribed.
#
# special_use:
# A space-separated list of SPECIAL-USE flags (RFC 6154) to use for the
# mailbox. There are no validity checks, so you could specify anything
# you want in here, but it's not a good idea to use flags other than the
# standard ones specified in the RFC:
#
# \All - This (virtual) mailbox presents all messages in the
# user's message store.
# \Archive - This mailbox is used to archive messages.
# \Drafts - This mailbox is used to hold draft messages.
# \Flagged - This (virtual) mailbox presents all messages in the
# user's message store marked with the IMAP \Flagged flag.
# \Important - This (virtual) mailbox presents all messages in the
# user's message store deemed important to user.
# \Junk - This mailbox is where messages deemed to be junk mail
# are held.
# \Sent - This mailbox is used to hold copies of messages that
# have been sent.
# \Trash - This mailbox is used to hold messages that have been
# deleted.
#
# comment:
# Defines a default comment or note associated with the mailbox. This
# value is accessible through the IMAP METADATA mailbox entries
# "/shared/comment" and "/private/comment". Users with sufficient
# privileges can override the default value for entries with a custom
# value.
# NOTE: Assumes "namespace inbox" has been defined in 10-mail.conf.
namespace inbox {
# These mailboxes are widely used and could perhaps be created automatically:
mailbox Drafts {
special_use = \Drafts
}
mailbox Junk {
special_use = \Junk
}
mailbox Trash {
special_use = \Trash
}
# For \Sent mailboxes there are two widely used names. We'll mark both of
# them as \Sent. User typically deletes one of them if duplicates are created.
mailbox Sent {
special_use = \Sent
}
mailbox "Sent Messages" {
special_use = \Sent
}
# If you have a virtual "Flagged" mailbox:
mailbox virtual/Flagged {
special_use = \Flagged
comment = All my flagged messages
}
# If you have a virtual "Important" mailbox:
mailbox virtual/Important {
special_use = \Important
comment = All my important messages
}
}
- Registro MX, que enlazará nuestro dominio mail.afalabarce.dev e indicará a los smtp que es ese host el que tiene capacidad de recibir correos para afalabarce.dev (en mi caso).
- A, dominio "@" y con valor la ip del servidor, imprescindible para reverse dns, también muy necesario.
- TXT, que apunta al host mail, con valor "v=spf1 a -all".
- Varios CNAME con valores MUY específicos que habrá establecer para plataformas como Microsoft o Gmail. Este último punto es bastante tedioso, ya que hay que hacer bastantes pruebas para que microsoft nos envíe los problemas que suceden.
Comentarios
Publicar un comentario