Watch
1
0
Fork
You've already forked mirrors
0
forked from MxOS/mirrors

feat(mirrors): initial architecture, specifications, automation tools, and canonical guide

Establish community mirror network on IPFS for Fedora and CentOS Stream 10:
- Modular documentation and specifications under docs/
- Master canonical guide under README.rst with client and node operator workflows
- Ingestion, upstream sync, and Cloudflare DNSLink automation scripts in bin/
- Reverse proxy configs (Nginx/Caddy) and systemd timer units in etc/ and systemd/

Signed-off-by: Rénich Bon Ćirić <renich@evalinux.com>
Co-authored-by: Gemini AI <renich+gemini@evalinux.com>
This commit is contained in:
Rénich Bon Ćirić 2026-10-08 22:17:27 -06:00
commit 0397fc8cc4
Signed by: renich
GPG key ID: AB2A9F49384FE324
32 changed files with 1700 additions and 0 deletions

7
.gitignore vendored Normal file
View file

@ -0,0 +1,7 @@
# Archivos locales y temporales
*.log
*.tmp
staging/
logs/
cache/
.DS_Store

237
README.rst Normal file
View file

@ -0,0 +1,237 @@
=========================================================
Red de Espejos Comunitarios de Software Libre sobre IPFS
=========================================================
Infraestructura de distribución soberana, descentralizada y de alta resiliencia para distribuciones Linux de la familia RPM, operada por la `Fundación MxOS`_ bajo el dominio canónico ``mirrors.mx-os.mx``.
.. _Fundación MxOS: https://mx-os.mx
Propósito y Misión
==================
Históricamente, los usuarios e instituciones en México y Latinoamérica han dependido de espejos universitarios aislados o enlaces transfronterizos hacia redes de entrega de contenido comerciales en Estados Unidos. Esta dependencia genera latencia, costos recurrentes de transferencia y vulnerabilidad ante caídas de enlaces internacionales.
La red de espejos de MxOS replantea la entrega de paquetes utilizando el Sistema de Archivos Interplanetario (IPFS). Al emplear direccionamiento por contenido y distribución entre pares (P2P), el espejo se convierte en una red colaborativa donde cualquier integrante de la comunidad o institución académica puede donar almacenamiento y ancho de banda local, deduplicando transferencias y acelerando descargas dentro de redes locales o nacionales.
Arquitectura y Principios de Operación
======================================
El sistema opera sobre cuatro pilares técnicos:
1. **Direccionamiento por contenido inmutable:** Cada archivo, paquete RPM y metadato se divide en bloques criptográficos referenciados por su identificador de contenido (CID). Si dos versiones comparten paquetes idénticos, estos se deduplican en el almacenamiento global.
2. **Distribución entre pares con Bitswap:** Al solicitar un paquete, el demonio Kubo lo descarga simultáneamente de todos los nodos guardianes disponibles que lo posean en la red local o internet (puerto 4001 TCP/UDP).
3. **Puntero canónico con DNSLink:** Para evitar lidiar con hashes cambiantes en cada sincronización, el dominio ``mirrors.mx-os.mx`` cuenta con registros TXT DNSLink (``_dnslink.mirrors.mx-os.mx``) que apuntan al CID raíz más reciente con una propagación de 300 segundos.
4. **Puente HTTP para compatibilidad universal:** Quienes no cuenten con un nodo IPFS pueden consumir el espejo directamente a través de HTTP/HTTPS mediante el terminador web que reenvía peticiones hacia el enjambre.
Consumo del Espejo desde Clientes DNF
=====================================
Existen dos formas de utilizar el espejo comunitario en tus estaciones de trabajo y servidores:
Opción recomendada: Conexión mediante nodo IPFS local
------------------------------------------------------
Al contar con Kubo activo en tu equipo (escuchando en ``127.0.0.1:8080``), los paquetes se descargan por la red P2P. Si otro equipo en tu misma red de área local ya descargó una actualización, tu máquina la obtendrá a la velocidad del cable o wifi local sin salir a internet.
Para Fedora (versiones 43, 44, 45 o Rawhide)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Crea el archivo ``/etc/yum.repos.d/fedora-mxos-ipfs.repo`` con privilegios administrativos:
.. code-block:: ini
[fedora-mxos-ipfs]
name=Fedora $releasever - $basearch (Espejo MxOS IPFS)
baseurl=http://127.0.0.1:8080/ipns/mirrors.mx-os.mx/fedora/releases/$releasever/Everything/$basearch/os/
enabled=1
metadata_expire=6h
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-$releasever-$basearch
[fedora-updates-mxos-ipfs]
name=Fedora $releasever Updates - $basearch (Espejo MxOS IPFS)
baseurl=http://127.0.0.1:8080/ipns/mirrors.mx-os.mx/fedora/updates/$releasever/$basearch/
enabled=1
metadata_expire=6h
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-$releasever-$basearch
Para CentOS Stream 10
~~~~~~~~~~~~~~~~~~~~~
Crea el archivo ``/etc/yum.repos.d/centos-stream-mxos-ipfs.repo``:
.. code-block:: ini
[cs10-baseos-mxos-ipfs]
name=CentOS Stream 10 - BaseOS (Espejo MxOS IPFS)
baseurl=http://127.0.0.1:8080/ipns/mirrors.mx-os.mx/centos-stream/10-stream/BaseOS/$basearch/os/
enabled=1
metadata_expire=6h
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
[cs10-appstream-mxos-ipfs]
name=CentOS Stream 10 - AppStream (Espejo MxOS IPFS)
baseurl=http://127.0.0.1:8080/ipns/mirrors.mx-os.mx/centos-stream/10-stream/AppStream/$basearch/os/
enabled=1
metadata_expire=6h
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
Opción estándar: Conexión HTTPS directa
---------------------------------------
Si tu equipo no ejecuta un demonio IPFS, puedes configurar tus repositorios apuntando directamente al punto de entrada HTTPS:
.. code-block:: ini
[fedora-mxos-https]
name=Fedora $releasever - $basearch (MxOS HTTPS)
baseurl=https://mirrors.mx-os.mx/fedora/releases/$releasever/Everything/$basearch/os/
enabled=1
metadata_expire=6h
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-$releasever-$basearch
Guía para Operadores de Nodos Guardianes
========================================
Los nodos guardianes son la columna vertebral de la red. Cualquier persona con una computadora de escritorio, servidor casero o máquina virtual puede unirse al enjambre y alojar partes del catálogo.
Paso 1: Instalación de Kubo
---------------------------
Kubo está empaquetado para Fedora y CentOS Stream en el repositorio Copr de MxOS:
.. code-block:: bash
sudo dnf copr enable renich/kubo
sudo dnf install kubo
Paso 2: Inicialización y servicio systemd
----------------------------------------
Se recomienda operar Kubo en modo usuario no privilegiado (rootless):
.. code-block:: bash
# Inicializar el almacén en ~/.ipfs
ipfs init
# Habilitar e iniciar el servicio persistente de usuario
systemctl --user enable --now ipfs.service
Paso 3: Apertura del puerto del enjambre en el cortafuegos
----------------------------------------------------------
Para permitir que otros nodos descarguen bloques desde tu nodo, abre el puerto 4001:
.. code-block:: bash
sudo firewall-cmd --permanent --add-port=4001/tcp
sudo firewall-cmd --permanent --add-port=4001/udp
sudo firewall-cmd --reload
Paso 4: Pineo granular por cuota de almacenamiento
--------------------------------------------------
No necesitas descargar los cientos de gigabytes del espejo completo. Elige el nivel que mejor se adapte a tu capacidad:
* **Nivel 1: Imágenes ISO de Fedora (~15 GB)**
.. code-block:: bash
ipfs pin add /ipns/mirrors.mx-os.mx/fedora/iso
* **Nivel 2: Sistema Base de CentOS Stream 10 (~15 GB)**
.. code-block:: bash
ipfs pin add /ipns/mirrors.mx-os.mx/centos-stream/10-stream/BaseOS
* **Nivel 3: Paquetería AppStream y Everything (~80 a 150 GB)**
.. code-block:: bash
ipfs pin add /ipns/mirrors.mx-os.mx/fedora/releases/44/Everything
ipfs pin add /ipns/mirrors.mx-os.mx/centos-stream/10-stream/AppStream
* **Nivel 4: Espejo maestro completo (~300 GB)**
.. code-block:: bash
ipfs pin add /ipns/mirrors.mx-os.mx
Estructura del Catálogo Canónico
================================
El árbol publicado bajo ``/ipns/mirrors.mx-os.mx`` respeta rigurosamente las convenciones de rutas de Fedora y CentOS Stream:
.. code-block:: text
mirrors.mx-os.mx/
├── README.rst <- Documento de bienvenida e instrucciones
├── fedora/
│ ├── iso/ <- Imágenes de instalación de Fedora
│ ├── releases/ <- Árbol Everything por versión y arquitectura
│ └── updates/ <- Repositorios de actualizaciones continuas
└── centos-stream/
├── iso/ <- Medios de instalación de CentOS Stream
└── 10-stream/
├── BaseOS/ <- Paquetes base y núcleo del sistema
├── AppStream/ <- Módulos y aplicaciones adicionales
└── CRB/ <- CodeReady Linux Builder
Seguridad e Integridad Criptográfica
====================================
La seguridad en la red de espejos descansa en dos barreras independientes e infranqueables:
1. **Integridad de bloques:** La naturaleza direccionada por contenido de IPFS garantiza que ningún bit pueda alterarse en tránsito; si un bloque difiere de su hash, el cliente lo descarta automáticamente.
2. **Firmas GPG oficiales:** El gestor DNF valida cada RPM contra la llave pública oficial del proyecto correspondiente (ubicada en ``/etc/pki/rpm-gpg/``). Ni los operadores de nodos ni atacantes intermedios pueden inyectar código no firmado.
Herramientas y Automatización en este Repositorio
================================================
Este repositorio contiene los scripts de gestión y automatización de la infraestructura:
* `bin/mxos-mirror-sync.bash`_: Sincronización diferencial upstream mediante rsync preservando metadatos.
* `bin/mxos-mirror-ingest.bash`_: Ingesta UnixFS en Kubo con soporte de filestore (``--nocopy``).
* `bin/mxos-dnslink-update.bash`_: Actualización desatendida del registro DNSLink en Cloudflare mediante API REST.
* `bin/mxos-mirror.bash`_: Orquestador integral del ciclo completo (sincronizar, ingerir y publicar).
* `etc/caddy/Caddyfile`_: Plantilla de proxy inverso para Caddy.
* `etc/nginx/mirrors.mx-os.mx.conf`_: Plantilla de configuración para Nginx.
* `systemd/`_: Unidades de servicio y temporizadores de systemd para tareas programadas.
.. _bin/mxos-mirror-sync.bash: bin/mxos-mirror-sync.bash
.. _bin/mxos-mirror-ingest.bash: bin/mxos-mirror-ingest.bash
.. _bin/mxos-dnslink-update.bash: bin/mxos-dnslink-update.bash
.. _bin/mxos-mirror.bash: bin/mxos-mirror.bash
.. _etc/caddy/Caddyfile: etc/caddy/Caddyfile
.. _etc/nginx/mirrors.mx-os.mx.conf: etc/nginx/mirrors.mx-os.mx.conf
.. _systemd/: systemd/
Documentación Técnica Detallada
===============================
Para profundizar en las especificaciones y manuales, consulta el directorio `docs/`_:
* `docs/index.rst`_: Índice general de la documentación.
* `docs/business/spec.rst`_: Modelo estratégico, justificación e incentivos comunitarios.
* `docs/functional/spec.rst`_: Especificación de catálogo modular, pineo y telemetría pasiva.
* `docs/technical/spec.rst`_: Arquitectura de red, resolución DNSLink y puente MirrorManager.
* `docs/guides/index.rst`_: Manuales paso a paso para operadores, clientes y replicación autónoma.
* `docs/project/roadmap.rst`_: Fases de ejecución y seguimiento del proyecto.
.. _docs/: docs/
.. _docs/index.rst: docs/index.rst
.. _docs/business/spec.rst: docs/business/spec.rst
.. _docs/functional/spec.rst: docs/functional/spec.rst
.. _docs/technical/spec.rst: docs/technical/spec.rst
.. _docs/guides/index.rst: docs/guides/index.rst
.. _docs/project/roadmap.rst: docs/project/roadmap.rst
Canales de Comunidad y Contacto
===============================
* **Canal oficial de Telegram:** `@mx_os_mx`_
* **Sitio web:** `mx-os.mx`_
* **Repositorios de código:** `git.mx-os.mx`_
.. _@mx_os_mx: https://t.me/mx_os_mx
.. _mx-os.mx: https://mx-os.mx
.. _git.mx-os.mx: https://git.mx-os.mx
Licenciamiento
==============
Este proyecto opera bajo un modelo de licenciamiento dual:
* **Documentación y especificaciones:** Licenciadas bajo `Creative Commons Atribución-CompartirIgual 4.0 Internacional`_ (CC-BY-SA-4.0).
* **Herramientas, scripts y configuraciones:** Licenciadas bajo la `Licencia MIT`_.
.. _Creative Commons Atribución-CompartirIgual 4.0 Internacional: https://creativecommons.org/licenses/by-sa/4.0/
.. _Licencia MIT: https://opensource.org/license/mit

118
bin/mxos-dnslink-update.bash Executable file
View file

@ -0,0 +1,118 @@
#!/usr/bin/bash
set -euo pipefail
IFS=$'\n\t'
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
# Cargar configuración si existe
if [[ -f "${REPO_ROOT}/etc/mirrors.env" ]]; then
# shellcheck source=/dev/null
source "${REPO_ROOT}/etc/mirrors.env"
fi
CF_ZONE_ID="${CF_ZONE_ID:-2bd35b00a854bc77cfd38009f977ea3c}"
MIRRORS_DNSLINK_RECORD="${MIRRORS_DNSLINK_RECORD:-_dnslink.mirrors.mx-os.mx}"
resolve_cf_token() {
if [[ -n "${CF_API_TOKEN:-}" ]]; then
echo "${CF_API_TOKEN}"
return 0
fi
if command -v gopass >/dev/null 2>&1; then
local token
token="$(gopass show -f cloudflare.com/renich@evalinux.com 2>/dev/null | awk '/^API Token:/ {print $3}' | tr -d '[:space:]')"
if [[ -n "${token}" ]]; then
echo "${token}"
return 0
fi
fi
echo "Error: No se encontró token de Cloudflare en CF_API_TOKEN ni en GoPass." >&2
return 1
}
update_or_create_dnslink() {
local token="$1"
local record_name="$2"
local cid="$3"
local dnslink_content="dnslink=/ipfs/${cid}"
echo "==> Actualizando registro DNSLink para ${record_name}..."
# Buscar si el registro ya existe
local search_response
search_response="$(curl -4 --max-time 15 -s -X GET \
"https://api.cloudflare.com/client/v4/zones/${CF_ZONE_ID}/dns_records?type=TXT&name=${record_name}" \
-H "Authorization: Bearer ${token}" \
-H "Content-Type: application/json")"
local record_id
record_id="$(echo "${search_response}" | jq -r '.result[0].id // empty')"
if [[ -n "${record_id}" ]]; then
local update_response
update_response="$(curl -4 --max-time 15 -s -X PUT \
"https://api.cloudflare.com/client/v4/zones/${CF_ZONE_ID}/dns_records/${record_id}" \
-H "Authorization: Bearer ${token}" \
-H "Content-Type: application/json" \
-d "{\"type\":\"TXT\",\"name\":\"${record_name}\",\"content\":\"${dnslink_content}\",\"ttl\":300}")"
if echo "${update_response}" | jq -e '.success' >/dev/null 2>&1; then
echo " Registro ${record_name} actualizado exitosamente -> ${dnslink_content}"
else
echo "Error actualizando registro ${record_name}:" >&2
echo "${update_response}" | jq .errors >&2
return 1
fi
else
local create_response
create_response="$(curl -4 --max-time 15 -s -X POST \
"https://api.cloudflare.com/client/v4/zones/${CF_ZONE_ID}/dns_records" \
-H "Authorization: Bearer ${token}" \
-H "Content-Type: application/json" \
-d "{\"type\":\"TXT\",\"name\":\"${record_name}\",\"content\":\"${dnslink_content}\",\"ttl\":300}")"
if echo "${create_response}" | jq -e '.success' >/dev/null 2>&1; then
echo " Registro ${record_name} creado exitosamente -> ${dnslink_content}"
else
echo "Error creando registro ${record_name}:" >&2
echo "${create_response}" | jq .errors >&2
return 1
fi
fi
}
main() {
local target_cid="${1:-}"
if [[ -z "${target_cid}" ]]; then
if [[ ! -t 0 ]]; then
read -r target_cid
fi
fi
if [[ -z "${target_cid}" ]]; then
echo "Uso: $0 <CID_RAÍZ>" >&2
echo " O pase el CID por tubería estándar: echo \$CID | $0" >&2
exit 1
fi
# Limpiar prefijo si viene con /ipfs/
target_cid="${target_cid#/ipfs/}"
local token
token="$(resolve_cf_token)"
update_or_create_dnslink "${token}" "${MIRRORS_DNSLINK_RECORD}" "${target_cid}"
echo "==> Verificando resolución DNSLink canónica..."
if command -v ipfs >/dev/null 2>&1; then
local resolved
resolved="$(ipfs resolve "/ipns/${MIRRORS_DOMAIN}" 2>/dev/null || true)"
echo " IPFS resolve /ipns/${MIRRORS_DOMAIN} -> ${resolved:-pendiente de propagación}"
fi
}
main "$@"

92
bin/mxos-mirror-ingest.bash Executable file
View file

@ -0,0 +1,92 @@
#!/usr/bin/bash
set -euo pipefail
IFS=$'\n\t'
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
if [[ -f "${REPO_ROOT}/etc/mirrors.env" ]]; then
# shellcheck source=/dev/null
source "${REPO_ROOT}/etc/mirrors.env"
fi
MIRRORS_STAGING_DIR="${MIRRORS_STAGING_DIR:-$HOME/.local/share/mxos-mirrors/staging}"
IPFS_USE_NOCOPY="${IPFS_USE_NOCOPY:-false}"
log() {
local level="$1"
shift
local timestamp
timestamp="$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
echo "{\"timestamp\":\"${timestamp}\",\"level\":\"${level}\",\"message\":\"$*\"}"
}
usage() {
cat << USAGE
Uso: $0 [OPCIONES] [DIRECTORIO_STAGING]
Ingesta el directorio de staging en Kubo (IPFS) generando el grafo UnixFS DAG y retornando el CID raíz.
Opciones:
--nocopy Utiliza la extensión filestore (--nocopy) para evitar duplicación en disco
-h, --help Muestra este mensaje de ayuda
USAGE
exit 1
}
main() {
local use_nocopy="${IPFS_USE_NOCOPY}"
local staging_dir="${MIRRORS_STAGING_DIR}"
while [[ $# -gt 0 ]]; do
case "$1" in
--nocopy)
use_nocopy="true"
shift
;;
-h|--help)
usage
;;
*)
staging_dir="$1"
shift
;;
esac
done
if [[ ! -d "${staging_dir}" ]]; then
log "ERROR" "Directorio de staging no encontrado: ${staging_dir}" >&2
exit 1
fi
# Asegurar que README.rst esté presente en la raíz
if [[ -f "${REPO_ROOT}/README.rst" && ! -f "${staging_dir}/README.rst" ]]; then
cp "${REPO_ROOT}/README.rst" "${staging_dir}/README.rst"
fi
log "INFO" "Iniciando ingesta UnixFS de ${staging_dir} en Kubo..."
local ipfs_args=(add -r --cid-version=1 --hash=sha2-256 -Q)
if [[ "${use_nocopy}" == "true" ]]; then
ipfs_args+=(--nocopy)
fi
local root_cid
root_cid="$(ipfs "${ipfs_args[@]}" "${staging_dir}")"
if [[ -z "${root_cid}" ]]; then
log "ERROR" "Fallo en la generación del CID raíz." >&2
exit 1
fi
log "INFO" "Ingesta completada exitosamente. CID raíz: ${root_cid}"
# Asegurar pineo local del nuevo CID
ipfs pin add "${root_cid}" >/dev/null 2>&1 || true
# Salida limpia del CID por stdout
echo "${root_cid}"
}
main "$@"

159
bin/mxos-mirror-sync.bash Executable file
View file

@ -0,0 +1,159 @@
#!/usr/bin/bash
set -euo pipefail
IFS=$'\n\t'
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
if [[ -f "${REPO_ROOT}/etc/mirrors.env" ]]; then
# shellcheck source=/dev/null
source "${REPO_ROOT}/etc/mirrors.env"
fi
MIRRORS_STAGING_DIR="${MIRRORS_STAGING_DIR:-$HOME/.local/share/mxos-mirrors/staging}"
MIRRORS_LOG_DIR="${MIRRORS_LOG_DIR:-$HOME/.local/share/mxos-mirrors/logs}"
FEDORA_UPSTREAM_RSYNC="${FEDORA_UPSTREAM_RSYNC:-rsync://dl.fedoraproject.org/pub/fedora/linux}"
CENTOS_UPSTREAM_RSYNC="${CENTOS_UPSTREAM_RSYNC:-rsync://mirror.stream.centos.org/centos-stream}"
log() {
local level="$1"
shift
local timestamp
timestamp="$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
echo "{\"timestamp\":\"${timestamp}\",\"level\":\"${level}\",\"message\":\"$*\"}"
}
usage() {
cat << USAGE
Uso: $0 [OPCIONES]
Sincroniza repositorios oficiales de software libre hacia el directorio de staging local.
Opciones:
-d, --distro <fedora|centos|all> Distribución a sincronizar (predeterminado: all)
-n, --dry-run Simula la sincronización sin transferir datos
-t, --target <directorio> Directorio de destino de staging (predeterminado: ${MIRRORS_STAGING_DIR})
-h, --help Muestra este mensaje de ayuda
USAGE
exit 1
}
sync_fedora() {
local target_dir="$1"
local dry_run_flag="$2"
local fedora_target="${target_dir}/fedora"
log "INFO" "Iniciando sincronización de Fedora hacia ${fedora_target}..."
mkdir -p "${fedora_target}"
# En modo prueba de concepto inicial, sincronizamos metadatos y estructura
local rsync_cmd=(
rsync -avSHP --delete-delay --delay-updates
--exclude="*.iso"
--exclude="*.raw.xz"
--exclude="debug/"
--exclude="source/"
--timeout=60
)
if [[ "${dry_run_flag}" == "true" ]]; then
rsync_cmd+=("--dry-run")
fi
rsync_cmd+=(
"${FEDORA_UPSTREAM_RSYNC}/releases/43/Everything/x86_64/os/repodata"
"${fedora_target}/releases/43/Everything/x86_64/os/"
)
log "INFO" "Ejecutando: ${rsync_cmd[*]}"
"${rsync_cmd[@]}" || log "WARN" "Sincronización parcial o simulada de Fedora."
}
sync_centos() {
local target_dir="$1"
local dry_run_flag="$2"
local centos_target="${target_dir}/centos-stream"
log "INFO" "Iniciando sincronización de CentOS Stream hacia ${centos_target}..."
mkdir -p "${centos_target}"
local rsync_cmd=(
rsync -avSHP --delete-delay --delay-updates
--exclude="*.iso"
--exclude="debug/"
--exclude="source/"
--timeout=60
)
if [[ "${dry_run_flag}" == "true" ]]; then
rsync_cmd+=("--dry-run")
fi
rsync_cmd+=(
"${CENTOS_UPSTREAM_RSYNC}/10-stream/BaseOS/x86_64/os/repodata"
"${centos_target}/10-stream/BaseOS/x86_64/os/"
)
log "INFO" "Ejecutando: ${rsync_cmd[*]}"
"${rsync_cmd[@]}" || log "WARN" "Sincronización parcial o simulada de CentOS Stream."
}
sync_readme() {
local target_dir="$1"
log "INFO" "Copiando README.rst canónico hacia la raíz de staging..."
cp "${REPO_ROOT}/README.rst" "${target_dir}/README.rst"
}
main() {
local distro="all"
local dry_run="false"
local target="${MIRRORS_STAGING_DIR}"
while [[ $# -gt 0 ]]; do
case "$1" in
-d|--distro)
distro="$2"
shift 2
;;
-n|--dry-run)
dry_run="true"
shift
;;
-t|--target)
target="$2"
shift 2
;;
-h|--help)
usage
;;
*)
echo "Opción desconocida: $1" >&2
usage
;;
esac
done
mkdir -p "${target}" "${MIRRORS_LOG_DIR}"
sync_readme "${target}"
case "${distro}" in
fedora)
sync_fedora "${target}" "${dry_run}"
;;
centos)
sync_centos "${target}" "${dry_run}"
;;
all)
sync_fedora "${target}" "${dry_run}"
sync_centos "${target}" "${dry_run}"
;;
*)
echo "Distribución no válida: ${distro}" >&2
exit 1
;;
esac
log "INFO" "Sincronización upstream finalizada exitosamente."
}
main "$@"

141
bin/mxos-mirror.bash Executable file
View file

@ -0,0 +1,141 @@
#!/usr/bin/bash
set -euo pipefail
IFS=$'\n\t'
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
if [[ -f "${REPO_ROOT}/etc/mirrors.env" ]]; then
# shellcheck source=/dev/null
source "${REPO_ROOT}/etc/mirrors.env"
fi
MIRRORS_STAGING_DIR="${MIRRORS_STAGING_DIR:-$HOME/.local/share/mxos-mirrors/staging}"
MIRRORS_DOMAIN="${MIRRORS_DOMAIN:-mirrors.mx-os.mx}"
usage() {
cat << USAGE
Uso: $0 <COMANDO> [OPCIONES]
Herramienta de orquestación de la Red de Espejos Comunitarios de MxOS.
Comandos:
sync Sincroniza paquetes y metadatos upstream hacia el directorio de staging
ingest Ingesta el directorio de staging en Kubo generando el CID raíz
publish Actualiza el registro DNSLink en Cloudflare con un CID específico
run-all Ejecuta el flujo completo: sincronizar, ingerir y publicar en DNSLink
status Muestra el estado de resolución, demonio IPFS y registro DNSLink
replicate Replica el CID raíz actual hacia el nodo público web0.mx-os.mx
help Muestra este mensaje de ayuda
USAGE
exit 1
}
cmd_status() {
echo "=========================================================="
echo " Estado de la Red de Espejos MxOS (${MIRRORS_DOMAIN})"
echo "=========================================================="
echo -n "1. Demonio IPFS local: "
if command -v ipfs >/dev/null 2>&1 && ipfs id >/dev/null 2>&1; then
local peer_id
peer_id="$(ipfs id -f='<id>\n')"
echo "Activo (PeerID: ${peer_id})"
else
echo "Inactivo o no instalado"
fi
echo -n "2. Registro DNSLink en Cloudflare (_dnslink.${MIRRORS_DOMAIN}): "
local dns_val
dns_val="$(dig +short TXT "_dnslink.${MIRRORS_DOMAIN}" @1.1.1.1 2>/dev/null || echo "No resoluble")"
echo "${dns_val:-Sin registro}"
echo -n "3. Resolución canónica IPFS (/ipns/${MIRRORS_DOMAIN}): "
if command -v ipfs >/dev/null 2>&1; then
local ipns_val
ipns_val="$(ipfs resolve "/ipns/${MIRRORS_DOMAIN}" 2>/dev/null || echo "Error de resolución")"
echo "${ipns_val}"
else
echo "No disponible (sin cliente ipfs)"
fi
echo -n "4. Punto final HTTPS público (https://${MIRRORS_DOMAIN}/): "
local http_code
http_code="$(curl -s -o /dev/null -w "%{http_code}" "https://${MIRRORS_DOMAIN}/" 2>/dev/null || echo "Fallo de conexión")"
echo "Código HTTP ${http_code}"
echo "=========================================================="
}
cmd_replicate() {
local target_cid="${1:-}"
if [[ -z "${target_cid}" ]]; then
target_cid="$(ipfs resolve "/ipns/${MIRRORS_DOMAIN}" 2>/dev/null || true)"
target_cid="${target_cid#/ipfs/}"
fi
if [[ -z "${target_cid}" ]]; then
echo "Error: No se pudo determinar el CID raíz a replicar." >&2
exit 1
fi
echo "==> Replicando DAG ${target_cid} hacia web0.mx-os.mx..."
# shellcheck disable=SC2029
ipfs dag export "${target_cid}" | ssh root@web0.mx-os.mx \
"ipfs --api=/ip4/127.0.0.1/tcp/5001 dag import && ipfs --api=/ip4/127.0.0.1/tcp/5001 pin add ${target_cid}"
echo "==> Replicación completada con éxito en web0."
}
cmd_run_all() {
echo "==> [Paso 1/4] Sincronización upstream..."
"${SCRIPT_DIR}/mxos-mirror-sync.bash"
echo "==> [Paso 2/4] Ingesta UnixFS en Kubo..."
local root_cid
root_cid="$("${SCRIPT_DIR}/mxos-mirror-ingest.bash")"
echo " Nuevo CID raíz: ${root_cid}"
echo "==> [Paso 3/4] Publicación en DNSLink Cloudflare..."
"${SCRIPT_DIR}/mxos-dnslink-update.bash" "${root_cid}"
echo "==> [Paso 4/4] Replicación hacia nodo público web0..."
cmd_replicate "${root_cid}"
echo "==> Flujo completado exitosamente."
cmd_status
}
main() {
local cmd="${1:-}"
shift || true
case "${cmd}" in
sync)
"${SCRIPT_DIR}/mxos-mirror-sync.bash" "$@"
;;
ingest)
"${SCRIPT_DIR}/mxos-mirror-ingest.bash" "$@"
;;
publish)
"${SCRIPT_DIR}/mxos-dnslink-update.bash" "$@"
;;
run-all)
cmd_run_all
;;
status)
cmd_status
;;
replicate)
cmd_replicate "$@"
;;
help|--help|-h|"")
usage
;;
*)
echo "Comando desconocido: ${cmd}" >&2
usage
;;
esac
}
main "$@"

18
docs/business/spec.rst Normal file
View file

@ -0,0 +1,18 @@
==================================
Especificación de Negocio y Misión
==================================
Visión General
==============
La distribución tradicional de software libre enfrenta una creciente centralización en redes de entrega de contenido (CDNs) comerciales y una pesada carga financiera de transferencia de datos para los espejos universitarios y comunitarios. En México, la ausencia histórica de un espejo primario local para Fedora y CentOS Stream obliga a que cada instalación y actualización transite por enlaces internacionales hacia servidores en Estados Unidos.
La iniciativa de espejos de MxOS replantea este modelo utilizando el Sistema de Archivos Interplanetario (IPFS) para conformar una red de guerrilla donde cualquier persona u organización puede aportar almacenamiento local y ancho de banda, democratizando la infraestructura y blindándola contra fallos o censura.
Documentos del Dominio
======================
.. toctree::
:maxdepth: 1
specs/mision-vision
specs/incentivos-comunidad

View file

@ -0,0 +1,27 @@
====================================
Modelo de Participación e Incentivos
====================================
Filosofía de Participación
==========================
La participación en la red de espejos de MxOS es voluntaria, descentralizada y respetuosa de la privacidad. No se requiere registro obligatorio de cuentas ni instalación de agentes de telemetría invasivos para formar parte del enjambre.
Incentivos para Colaboradores
=============================
Para reconocer el esfuerzo de quienes donan almacenamiento, electricidad y ancho de banda, MxOS establece los siguientes mecanismos:
Salón de Guardianes del Espejo
------------------------------
* **Reconocimiento público opcional:** Los operadores de nodos que decidan asociar voluntariamente su identificador de nodo (PeerID) con su perfil de la comunidad o GitLab aparecerán en el tablero de honor de ``mirrors.mx-os.mx``.
* **Insignias y trazabilidad:** Distinciones honoríficas basadas en la constancia del nodo en el enjambre y el nivel de repositorios respaldados.
Servicios de Red Comunitaria
----------------------------
* **Subdominios comunitarios:** Operadores con nodos activos y verificados podrán solicitar subdominios personalizados bajo ``*.mx-os.mx`` para sus proyectos personales de software libre.
* **Prioridad de enrutamiento:** Listado público de pares recomendados para conexión directa (peering estático) entre nodos de MxOS dentro de puntos de intercambio de tráfico de internet (IXP) en México.
Garantías de Privacidad
=======================
* El enjambre utiliza los mecanismos criptográficos nativos de libp2p y la tabla hash distribuida (DHT).
* La presencia del nodo se verifica mediante el anuncio público de bloques provistos (find providers).
* No se recopilan historiales de navegación, patrones de paquetes instalados por clientes individuales ni datos de hardware del usuario.

View file

@ -0,0 +1,28 @@
=====================================
Misión y Soberanía de Infraestructura
=====================================
Contexto y Problemática
=======================
Las distribuciones de software libre dependen de redes geolocalizadas de servidores espejo para entregar paquetes y archivos de imagen a millones de computadoras. Este esquema adolece de problemas estructurales en economías en desarrollo:
* **Asimetría de infraestructura:** México carece de un espejo oficial activo de Fedora o CentOS Stream en MirrorManager, dependiendo exclusivamente de enlaces transfronterizos.
* **Costo de transferencia insostenible:** Un espejo tradicional debe sincronizar petabytes mensuales mediante rsync y HTTP hacia miles de usuarios, requiriendo enlaces simétricos dedicados inaccesibles para comunidades pequeñas.
* **Desperdicio de ancho de banda:** Cientos de computadoras en la misma colonia, universidad o edificio de oficinas descargan de manera redundante los mismos paquetes de actualización desde servidores remotos.
Misión de MxOS
==============
La Fundación MxOS impulsa la soberanía tecnológica en sistemas operativos. La misión de esta iniciativa consiste en:
1. Desacoplar la distribución de software del direccionamiento por ubicación (servidores específicos) y migrarla al direccionamiento por contenido criptográfico mediante IPFS.
2. Permitir que cualquier persona con una laptop, servidor casero o almacenamiento conectado a red (NAS) se sume a la red de distribución según su capacidad de disco disponible.
3. Establecer el primer espejo comunitario federado de Fedora y CentOS Stream 10 en México, coordinado por la comunidad y auditado abiertamente.
4. Documentar y empaquetar todo el procedimiento para que cualquier otra comunidad pueda replicar espejos similares para cualquier proyecto de software libre.
Impacto Regional
================
La implementación de esta red produce tres beneficios inmediatos:
* **Aceleración en red local:** En universidades y redes locales, un paquete caliente se descarga únicamente una vez desde la red externa; los siguientes equipos lo obtienen a velocidad de enlace local vía Bitswap.
* **Resiliencia ante caídas de enlace:** En caso de fallos en rutas internacionales o saturación de CDNs, los repositorios permanecen disponibles entre los pares locales.
* **Autonomía tecnológica:** Reduce la dependencia hacia infraestructura comercial privada sin sacrificar la verificación criptográfica oficial provista por las firmas GPG de los proyectos originales.

26
docs/functional/spec.rst Normal file
View file

@ -0,0 +1,26 @@
========================
Especificación Funcional
========================
Visión General
==============
Este documento define los requisitos funcionales del sistema de espejos comunitarios sobre IPFS. El sistema debe permitir la ingesta programada de paquetes desde fuentes oficiales, su publicación bajo un esquema de direccionamiento canónico, el pineo selectivo por parte de la comunidad y el consumo transparente desde clientes convencionales de Linux.
Requisitos Funcionales del Sistema
==================================
* **[FUNC-001] Ingesta y Catálogo Modular de Repositorios:** El sistema debe sincronizar y catalogar periódicamente los repositorios oficiales de Fedora y CentOS Stream 10 sin alterar sus metadatos ni firmas GPG.
* **[FUNC-002] Pineo Granular por Niveles:** El sistema debe permitir a los colaboradores almacenar y respaldar subárboles específicos según su disponibilidad de almacenamiento, sin obligar la descarga de la totalidad del espejo.
* **[FUNC-003] Publicación Canónica con DNSLink:** El sistema debe mantener una referencia mutable controlada bajo el dominio ``mirrors.mx-os.mx`` que apunte al identificador de contenido (CID) raíz más reciente.
* **[FUNC-004] Tablero de Métricas Públicas:** El sistema debe presentar un portal web público con estadísticas en tiempo real sobre nodos activos, volumen distribuido y mapa de distribución geográfica sin recolectar telemetría en el cliente.
* **[FUNC-005] Consumo Nativo en Clientes DNF:** El sistema debe posibilitar que cualquier instalación estándar de Fedora o CentOS Stream configure repositorios locales apuntando al gateway HTTP de IPFS.
Documentos del Dominio
======================
.. toctree::
:maxdepth: 1
specs/catalogo-modular
specs/pineo-granular
specs/tablero-metricas

View file

@ -0,0 +1,40 @@
================================
Catálogo Modular de Repositorios
================================
Identificador Funcional: [FUNC-001]
Objetivo
========
Definir la organización y jerarquía lógica de los archivos y repositorios servidos bajo la red comunitaria de espejos de MxOS, asegurando coherencia con los árboles estándar de Fedora y CentOS Stream.
Estructura del Árbol Canónico
=============================
El árbol servido bajo ``/ipns/mirrors.mx-os.mx`` debe dividirse en ramas bien delimitadas por distribución, tipo de contenido y arquitectura:
.. code-block:: text
mirrors.mx-os.mx/
├── fedora/
│ ├── iso/
│ │ ├── 44/
│ │ └── 45/
│ ├── releases/
│ │ ├── 44/Everything/x86_64/os/
│ │ └── 45/Everything/x86_64/os/
│ └── updates/
│ ├── 44/x86_64/
│ └── 45/x86_64/
└── centos-stream/
├── iso/
│ └── 10-stream/
└── 10-stream/
├── BaseOS/x86_64/os/
├── AppStream/x86_64/os/
└── CRB/x86_64/os/
Criterios de Aceptación
=======================
1. La estructura de directorios debe respetar estrictamente los nombres esperados por las variables ``$releasever`` y ``$basearch`` de DNF.
2. Los metadatos de repositorio (ejemplo: ``repodata/repomd.xml``) deben ser idénticos a los publicados por los servidores primarios upstream para garantizar la verificación de firmas criptográficas.
3. La sincronización upstream debe preservar atributos de tiempo y enlaces relativos para asegurar la validez de los paquetes.

View file

@ -0,0 +1,34 @@
================================
Especificación de Pineo Granular
================================
Identificador Funcional: [FUNC-002]
Objetivo
========
Permitir que cualquier usuario o entidad colaboradora participe en la red de distribución respaldando únicamente una porción específica de los repositorios, adaptándose a sus restricciones de almacenamiento en disco.
Niveles de Participación
========================
El sistema clasifica el contenido en cuatro niveles de compromiso de almacenamiento:
.. table:: Niveles de almacenamiento para colaboradores
:widths: auto
+-------+-----------------------------+--------------------+-----------------------------+
| Nivel | Contenido | Tamaño Aproximado | Perfil de Nodo Recomendado |
+=======+=============================+====================+=============================+
| 1 | Imágenes ISO de instalación | 10 a 25 GB | Laptops, equipos personales |
+-------+-----------------------------+--------------------+-----------------------------+
| 2 | Sistema Base (BaseOS) | 15 a 30 GB | Servidores caseros, mini PCs|
+-------+-----------------------------+--------------------+-----------------------------+
| 3 | Distribución completa única | 80 a 150 GB | Servidores de oficina, labs |
+-------+-----------------------------+--------------------+-----------------------------+
| 4 | Espejo integral (Todo) | 300+ GB | Servidores dedicados, NAS |
+-------+-----------------------------+--------------------+-----------------------------+
Comportamiento de Resolución
============================
1. Cuando un colaborador solicita pinear una subruta (ejemplo: ``/ipns/mirrors.mx-os.mx/fedora/iso``), el demonio de IPFS debe resolver el CID específico de esa carpeta en el grafo UnixFS y aplicar el pin recursivo exclusivamente a dicho subnodo.
2. Los bloques ajenos a la subruta seleccionada no deben ser transferidos ni almacenados en el nodo local.
3. El proceso de sincronización debe reemplazar los pines anteriores cuando el CID de la subruta cambie, liberando espacio mediante recolección de basura si el usuario lo configura.

View file

@ -0,0 +1,21 @@
================================
Tablero de Métricas del Enjambre
================================
Identificador Funcional: [FUNC-004]
Objetivo
========
Proporcionar visibilidad pública en tiempo real sobre el estado del enjambre de distribución, permitiendo a la comunidad auditar la disponibilidad de los repositorios y visualizar el crecimiento de la red.
Requisitos del Tablero
======================
* **Descubrimiento descentralizado:** Las métricas de pares deben obtenerse consultando la tabla hash distribuida (DHT) de IPFS para los CIDs activos del catálogo, sin requerir que los nodos instalen software cliente adicional o transmitan telemetría privada.
* **Mapa de nodos:** Representación geográfica aproximada a nivel ciudad o estado basada en la resolución de direcciones IP públicas de los pares descubiertos.
* **Métricas visibles:**
* Número total de nodos proveedores activos en las últimas 24 horas.
* Volumen total estimado de almacenamiento distribuido en el enjambre.
* Desglose de disponibilidad por componente (ISOs, CentOS Stream 10, Fedora).
* Tiempo transcurrido desde la última sincronización upstream.
* **Transparencia y código abierto:** El código fuente completo del tablero debe residir en el repositorio público de Git de MxOS.

View file

@ -0,0 +1,68 @@
======================================
Configuración de Clientes DNF con IPFS
======================================
Propósito
=========
Este manual detalla cómo configurar el gestor de paquetes DNF en cualquier estación de trabajo o servidor local para consumir paquetes directamente desde el enjambre de IPFS a través del gateway HTTP local (puerto 8080).
Ventajas
========
* **Velocidad máxima:** Los paquetes que tú o tus vecinos de red local hayan pineado se descargan a la velocidad máxima de la interfaz local sin saturar tu conexión hacia internet.
* **Seguridad criptográfica íntegra:** Las firmas GPG oficiales de Fedora y CentOS Stream siguen siendo verificadas por DNF contra las llaves oficiales instaladas en ``/etc/pki/rpm-gpg/``.
Configuración para Fedora
=========================
Crea un archivo de repositorio en ``/etc/yum.repos.d/fedora-mxos-ipfs.repo`` con el siguiente contenido:
.. code-block:: ini
[fedora-mxos-ipfs]
name=Fedora $releasever - $basearch (Espejo MxOS IPFS)
baseurl=http://127.0.0.1:8080/ipns/mirrors.mx-os.mx/fedora/releases/$releasever/Everything/$basearch/os/
enabled=1
metadata_expire=6h
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-$releasever-$basearch
[fedora-updates-mxos-ipfs]
name=Fedora $releasever Updates - $basearch (Espejo MxOS IPFS)
baseurl=http://127.0.0.1:8080/ipns/mirrors.mx-os.mx/fedora/updates/$releasever/$basearch/
enabled=1
metadata_expire=6h
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-$releasever-$basearch
Configuración para CentOS Stream 10
===================================
Crea un archivo en ``/etc/yum.repos.d/centos-stream-mxos-ipfs.repo``:
.. code-block:: ini
[cs10-baseos-mxos-ipfs]
name=CentOS Stream 10 - BaseOS (Espejo MxOS IPFS)
baseurl=http://127.0.0.1:8080/ipns/mirrors.mx-os.mx/centos-stream/10-stream/BaseOS/$basearch/os/
enabled=1
metadata_expire=6h
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
[cs10-appstream-mxos-ipfs]
name=CentOS Stream 10 - AppStream (Espejo MxOS IPFS)
baseurl=http://127.0.0.1:8080/ipns/mirrors.mx-os.mx/centos-stream/10-stream/AppStream/$basearch/os/
enabled=1
metadata_expire=6h
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
Prueba de Funcionamiento
========================
Limpia la caché de metadatos de DNF y verifica la comunicación con el gateway local:
.. code-block:: bash
# Limpiar cachés previas
sudo dnf clean all --disablerepo="*" --enablerepo="*-mxos-ipfs"
# Comprobar la actualización de metadatos
sudo dnf check-update --disablerepo="*" --enablerepo="*-mxos-ipfs"

View file

@ -0,0 +1,73 @@
===========================================
Manual de Autonomía Técnica: Hazlo Tú Mismo
===========================================
Propósito y Filosofía
=====================
La misión fundamental de la Fundación MxOS no es monopolizar la distribución, sino transferir el conocimiento y capacitar a cualquier comunidad, escuela o empresa para que construya y opere su propia infraestructura de distribución soberana de software libre.
Este manual documenta el procedimiento completo para levantar un espejo de guerrilla sobre IPFS para cualquier proyecto o distribución desde cero.
Arquitectura Mínima Requerida
=============================
Para operar tu propio espejo primario necesitas:
1. Un servidor con almacenamiento adecuado para el conjunto de paquetes a respaldar.
2. Demonio Kubo instalado y configurado con la extensión filestore.
3. Un dominio propio con control sobre los registros DNS autoritativos para configurar DNSLink.
4. Servidor web (Caddy, Nginx o Apache) para proporcionar terminación TLS y proxy inverso.
Procedimiento Paso a Paso
=========================
1. Configuración de Filestore en Kubo
-------------------------------------
Por defecto, agregar archivos a IPFS duplica su tamaño al copiarlos al almacén de bloques. Para evitar este desperdicio masivo de disco al sincronizar repositorios de cientos de gigabytes, habilita el filestore en la configuración de Kubo:
.. code-block:: bash
# Detener el servicio antes de modificar la configuración
systemctl --user stop ipfs.service
# Habilitar filestore y experimental nocopy
ipfs config --json Experimental.FilestoreEnabled true
# Iniciar nuevamente el servicio
systemctl --user start ipfs.service
2. Sincronización Upstream con rsync
------------------------------------
Descarga los paquetes desde el espejo oficial más cercano hacia un directorio local (ejemplo: ``/srv/mirrors/debian/`` o ``/srv/mirrors/archlinux/``):
.. code-block:: bash
rsync -avSHP --delete-delay \
rsync://espejo.upstream.org/repositorio/ \
/srv/mirrors/mi-proyecto/
3. Ingesta por Referencia (nocopy)
----------------------------------
Genera el grafo UnixFS sin duplicar archivos en disco utilizando la opción ``--nocopy``:
.. code-block:: bash
CID=$(ipfs add -r --nocopy --cid-version=1 --hash=sha2-256 -Q /srv/mirrors/mi-proyecto/)
echo "El nuevo CID raíz es: $CID"
4. Publicación en el Dominio con DNSLink
----------------------------------------
Accede al panel de control o servidor DNS autoritativo de tu dominio (ejemplo: ``tudominio.org``) y crea o actualiza el registro TXT para tu subdominio de espejos:
.. code-block:: zone
_dnslink.espejos.tudominio.org. 300 IN TXT "dnslink=/ipfs/<CID_OBTENIDO>"
A partir de este momento, cualquier persona en el mundo puede resolver y pinear tu repositorio ejecutando:
.. code-block:: bash
ipfs pin add /ipns/espejos.tudominio.org
5. Exposición Dual HTTP / IPFS
------------------------------
Configura un proxy inverso que reciba las conexiones HTTP convencionales y las envíe al gateway local de IPFS en ``127.0.0.1:8080/ipns/espejos.tudominio.org/``. De este modo, los usuarios tradicionales pueden seguir consumiendo el repositorio vía HTTP/HTTPS mientras tú te beneficias del enjambre P2P de respaldo.

17
docs/guides/index.rst Normal file
View file

@ -0,0 +1,17 @@
================
Manuales y Guías
================
Visión General
==============
Esta sección contiene manuales prácticos paso a paso para sumarse a la red comunitaria de espejos, configurar clientes locales de Fedora y CentOS Stream para consumir los repositorios desde IPFS, y replicar toda la infraestructura de distribución para otros proyectos de software libre.
Índice de Manuales
==================
.. toctree::
:maxdepth: 1
operador-nodo
cliente-dnf
hazlo-tu-mismo

View file

@ -0,0 +1,84 @@
==================================
Guía del Operador de Nodo Guardián
==================================
Propósito
=========
Este manual explica cómo configurar un nodo local de IPFS en Fedora o CentOS Stream para unirse al enjambre de MxOS y pinear selectivamente los repositorios oficiales según la cuota de disco que desees donar.
Requisitos Previos
==================
* Fedora 43, 44, 45, Rawhide o CentOS Stream 10.
* Acceso a privilegios administrativos mediante ``sudo``.
* Espacio en disco libre según el nivel de almacenamiento elegido (desde 10 GB en adelante).
Paso 1: Instalación de Kubo desde Copr
======================================
Kubo se encuentra empaquetado para la familia de distribuciones Fedora y CentOS Stream en el repositorio Copr de MxOS:
.. code-block:: bash
sudo dnf copr enable renich/kubo
sudo dnf install kubo
Paso 2: Inicialización e Inicio del Servicio
============================================
Se recomienda ejecutar el demonio en modo usuario rootless gestionado por systemd:
.. code-block:: bash
# Inicializar el almacén local de IPFS en el directorio de usuario (~/.ipfs)
ipfs init
# Habilitar e iniciar el servicio persistente de usuario
systemctl --user enable --now ipfs.service
# Verificar que el servicio esté activo y funcionando
systemctl --user status ipfs.service
Paso 3: Apertura de Puertos en el Cortafuegos
=============================================
Para que otros pares en internet y en tu red local puedan descargar bloques desde tu nodo, abre el puerto de escucha del enjambre (4001):
.. code-block:: bash
sudo firewall-cmd --permanent --add-port=4001/tcp
sudo firewall-cmd --permanent --add-port=4001/udp
sudo firewall-cmd --reload
Paso 4: Pineo Granular por Nivel
================================
Selecciona el comando correspondiente a la rama que tu almacenamiento permita respaldar:
* **Nivel 1: Imágenes ISO de Fedora (~15 GB)**
.. code-block:: bash
ipfs pin add /ipns/mirrors.mx-os.mx/fedora/iso
* **Nivel 2: Sistema Base de CentOS Stream 10 (~15 GB)**
.. code-block:: bash
ipfs pin add /ipns/mirrors.mx-os.mx/centos-stream/10-stream/BaseOS/x86_64/os
* **Nivel 3: CentOS Stream 10 Completo (~75 GB)**
.. code-block:: bash
ipfs pin add /ipns/mirrors.mx-os.mx/centos-stream/10-stream
* **Nivel 4: Espejo Completo de MxOS (300+ GB)**
.. code-block:: bash
ipfs pin add /ipns/mirrors.mx-os.mx
Paso 5: Automatización de la Sincronización
===========================================
Dado que los paquetes y metadatos se actualizan periódicamente en upstream, el CID raíz en DNSLink cambiará.
Para mantener tus pines al día:
1. Resuelve periódicamente la subruta deseada con ``ipfs resolve -r /ipns/mirrors.mx-os.mx/<subruta>``.
2. Aplica el nuevo pin y retira el pin anterior.
3. Puedes programar este refresco mediante un temporizador de systemd en tu sesión de usuario (``~/.config/systemd/user/mxos-sync.timer``).

19
docs/index.rst Normal file
View file

@ -0,0 +1,19 @@
=============================================
Documentación de Espejos Comunitarios de MxOS
=============================================
Bienvenido a la documentación maestra de la iniciativa de espejos de software libre sobre IPFS de la Fundación MxOS.
Este compendio detalla los principios de diseño, especificaciones funcionales y técnicas, manuales de adopción y la hoja de ruta para operar una red de distribución por pares resiliente para Fedora, CentOS Stream y proyectos afines en México y la región.
Contenido
=========
.. toctree::
:maxdepth: 2
business/spec
functional/spec
technical/spec
guides/index
project/roadmap

38
docs/project/roadmap.rst Normal file
View file

@ -0,0 +1,38 @@
====================================
Hoja de Ruta del Proyecto de Espejos
====================================
Visión General
==============
Esta hoja de ruta establece la secuencia cronológica de ejecución para implementar, validar, publicar y federar la red comunitaria de espejos sobre IPFS de la Fundación MxOS.
El plan se divide en tres fases secuenciales regidas por dependencias estrictas y trazabilidad directa hacia las especificaciones funcionales y técnicas del proyecto.
Fases de Ejecución
==================
.. toctree::
:maxdepth: 1
roadmaps/fase-1-poc
roadmaps/fase-2-tablero
roadmaps/fase-3-federacion-upstream
Matriz de Fases y Entregables
=============================
.. table:: Resumen de fases del proyecto
:widths: auto
+-------+------------------------------------+--------------------------+-----------------------+
| Fase | Denominación | Entregable Principal | Dependencia Crítica |
+=======+====================================+==========================+=======================+
| 1 | Prueba de Concepto y Publicación | Nodo servidor operativo, | Dominio DNSLink y |
| | Canónica | DNSLink y sync inicial | paquete Copr de Kubo |
+-------+------------------------------------+--------------------------+-----------------------+
| 2 | Tablero de Métricas del Enjambre | Portal público web con | Nodos proveedores |
| | | mapa y conteo de nodos | activos en la DHT |
+-------+------------------------------------+--------------------------+-----------------------+
| 3 | Federacion e Integración Upstream | Registro en MirrorManager| Estabilidad de Fase 1 |
| | | y RFC en listas upstream | y Fase 2 demostrada |
+-------+------------------------------------+--------------------------+-----------------------+

View file

@ -0,0 +1,45 @@
=================================================
Fase 1: Prueba de Concepto y Publicación Canónica
=================================================
Objetivo
========
Validar de punta a punta la ingesta, generación de DAGs UnixFS, actualización de registros DNSLink y resolución de subrutas para Fedora y CentOS Stream 10 bajo ``mirrors.mx-os.mx``.
Trazabilidad: [FUNC-001], [FUNC-002], [FUNC-003], [TECH-001], [TECH-002], [TECH-003]
Hitos de la Fase
================
Hito 1.1: Aprovisionamiento del Nodo Cabecera de MxOS
-----------------------------------------------------
Poner en marcha el entorno de almacenamiento y el demonio Kubo en la infraestructura de servidores de la Fundación MxOS.
* **Tarea 1.1.1 [TECH-001]:** Configurar el directorio de staging en el servidor y habilitar la extensión filestore en Kubo.
* *Bloqueado por:* Ninguno.
* *Desbloquea:* Tarea 1.1.2.
* **Tarea 1.1.2 [TECH-001]:** Ejecutar la sincronización rsync inicial de imágenes ISO de Fedora y el repositorio BaseOS de CentOS Stream 10.
* *Bloqueado por:* Tarea 1.1.1.
* *Desbloquea:* Tarea 1.1.3.
* **Tarea 1.1.3 [TECH-001]:** Realizar la ingesta por referencia con ``ipfs add -r --nocopy`` y verificar la integridad de los CIDs generados.
* *Bloqueado por:* Tarea 1.1.2.
* *Desbloquea:* Tarea 1.2.1.
Hito 1.2: Configuración de DNSLink y Validación de Subrutas
-----------------------------------------------------------
Establecer la delegación DNS inmutable y verificar la granularidad del enjambre.
* **Tarea 1.2.1 [TECH-003]:** Crear el registro TXT ``_dnslink.mirrors.mx-os.mx`` con el CID raíz de la ingesta.
* *Bloqueado por:* Tarea 1.1.3.
* *Desbloquea:* Tarea 1.2.2.
* **Tarea 1.2.2 [TECH-002]:** Validar la resolución y pineo recursivo exclusivo de subrutas (ejemplo: ``/ipns/mirrors.mx-os.mx/centos-stream/10-stream/BaseOS``) desde un nodo cliente externo.
* *Bloqueado por:* Tarea 1.2.1.
* *Desbloquea:* Hito 1.3.
Hito 1.3: Redacción del Post Inicial en el Sitio de MxOS
--------------------------------------------------------
Publicar el artículo de presentación en ``mx-os.mx`` y convocar a los primeros operadores guardianes.
* **Tarea 1.3.1 [FUNC-003]:** Redactar y publicar el artículo de lanzamiento en la web de MxOS enlazando al manual de operadores.
* *Bloqueado por:* Tarea 1.2.2.
* *Desbloquea:* Fase 2.

View file

@ -0,0 +1,42 @@
========================================
Fase 2: Tablero de Métricas del Enjambre
========================================
Objetivo
========
Desarrollar, empaquetar y desplegar el portal web público de estadísticas en tiempo real y mapa de nodos distribuido, publicado como software libre en el repositorio de Git de MxOS.
Trazabilidad: [FUNC-004], [TECH-004]
Hitos de la Fase
================
Hito 2.1: Motor de Recolección Descentralizada
----------------------------------------------
Crear el servicio en segundo plano que sondea la DHT para identificar los nodos activos.
* **Tarea 2.1.1 [TECH-004]:** Implementar el colector pasivo que consulta periódicamente ``ipfs dht findprovs`` para los CIDs activos del espejo.
* *Bloqueado por:* Fase 1 (Tarea 1.2.2).
* *Desbloquea:* Tarea 2.1.2.
* **Tarea 2.1.2 [TECH-004]:** Integrar la base de datos local MaxMind GeoLite2 para resolver la geolocalización aproximada (país y estado) sin almacenar direcciones IP completas.
* *Bloqueado por:* Tarea 2.1.1.
* *Desbloquea:* Hito 2.2.
Hito 2.2: Interfaz Web Pública Reactiva
---------------------------------------
Construir el portal web ligero de visualización para la comunidad.
* **Tarea 2.2.1 [FUNC-004]:** Diseñar la interfaz con mapa interactivo y contador de nodos activos.
* *Bloqueado por:* Tarea 2.1.2.
* *Desbloquea:* Tarea 2.2.2.
* **Tarea 2.2.2 [FUNC-004]:** Integrar el tablero en la infraestructura web de MxOS bajo ``mirrors.mx-os.mx``.
* *Bloqueado por:* Tarea 2.2.1.
* *Desbloquea:* Hito 2.3.
Hito 2.3: Publicación del Repositorio de Código Abierto
-------------------------------------------------------
Liberar el código del tablero para auditoría comunitaria.
* **Tarea 2.3.1 [FUNC-004]:** Documentar las instrucciones de despliegue y publicar el repositorio bajo licencia libre en el Git de la Fundación MxOS.
* *Bloqueado por:* Tarea 2.2.2.
* *Desbloquea:* Fase 3.

View file

@ -0,0 +1,37 @@
=========================================
Fase 3: Federación e Integración Upstream
=========================================
Objetivo
========
Consolidar el puente HTTP para registrar a MxOS formalmente ante MirrorManager de Fedora, y presentar la propuesta técnica oficial ante las listas de desarrollo de Fedora y CentOS para fomentar la adopción nativa de IPFS.
Trazabilidad: [FUNC-005], [TECH-005]
Hitos de la Fase
================
Hito 3.1: Despliegue del Puente Inverso HTTP y Validación MirrorManager
-----------------------------------------------------------------------
Habilitar la fachada web pública para clientes DNF tradicionales.
* **Tarea 3.1.1 [TECH-005]:** Configurar el proxy inverso (Caddy/Nginx) en ``mirrors.mx-os.mx`` apuntando al gateway local de Kubo.
* *Bloqueado por:* Fase 1 (Tarea 1.2.2).
* *Desbloquea:* Tarea 3.1.2.
* **Tarea 3.1.2 [TECH-005]:** Implementar el protocolo de sondeo y verificación de sincronización requerido por MirrorManager (archivo ``report_mirror``).
* *Bloqueado por:* Tarea 3.1.1.
* *Desbloquea:* Tarea 3.1.3.
* **Tarea 3.1.3 [FUNC-005]:** Dar de alta el espejo de MxOS en la base de datos de MirrorManager de Fedora como espejo oficial para México.
* *Bloqueado por:* Tarea 3.1.2.
* *Desbloquea:* Hito 3.2.
Hito 3.2: Propuesta Técnica Upstream (RFC)
------------------------------------------
Presentar la arquitectura a los equipos de infraestructura de Fedora y CentOS.
* **Tarea 3.2.1 [FUNC-005]:** Redactar el documento de propuesta (RFC) detallando los beneficios de ahorro de transferencia para upstream, mitigación de caídas y modelo de distribución comunitaria.
* *Bloqueado por:* Tarea 3.1.3 y Fase 2 (Tarea 2.2.2).
* *Desbloquea:* Tarea 3.2.2.
* **Tarea 3.2.2 [FUNC-005]:** Publicar la propuesta en los foros de discusión de Fedora (categoría Infrastructure) y en la lista de correo ``centos-devel`` para abrir el diálogo sobre soporte nativo en DNF.
* *Bloqueado por:* Tarea 3.2.1.
* *Desbloquea:* Proyecto completado.

27
docs/technical/spec.rst Normal file
View file

@ -0,0 +1,27 @@
======================
Especificación Técnica
======================
Visión General
==============
Este documento consolida la arquitectura de ingeniería del sistema de distribución de espejos de MxOS. Describe cómo interactúan el demonio Kubo de IPFS, el subsistema de resolución DNSLink, la capa de ingesta automatizada y el puente HTTP para MirrorManager.
Mapeo de Requisitos Técnicos
============================
* **[TECH-001] Ingesta Upstream y Empaquetado UnixFS:** Cumple con `[FUNC-001]`. Sincroniza directorios remotos y genera la estructura de bloques direccionada por contenido.
* **[TECH-002] Direccionamiento de Subnodos DAG:** Cumple con `[FUNC-002]`. Permite la extracción y pineo recursivo de CIDs secundarios en ramas del árbol de archivos.
* **[TECH-003] Topología DNSLink y Delegación:** Cumple con `[FUNC-003]`. Implementa el registro TXT canónico en la zona DNS de MxOS para el enrutamiento inmutable.
* **[TECH-004] Descubridor de Proveedores DHT:** Cumple con `[FUNC-004]`. Ejecuta sondeos de red hacia la DHT para compilar métricas de nodos proveedores sin telemetría.
* **[TECH-005] Puente Inverso HTTP y MirrorManager:** Cumple con `[FUNC-005]`. Conecta peticiones DNF estándar con el gateway local de Kubo y expone el punto de entrada oficial para el proyecto Fedora.
Documentos del Dominio
======================
.. toctree::
:maxdepth: 1
specs/arquitectura-distribucion
specs/resolucion-dnslink
specs/puente-mirrormanager
specs/ingesta-repositorios

View file

@ -0,0 +1,58 @@
=======================================
Arquitectura de Distribución sobre IPFS
=======================================
Identificadores Técnicos: [TECH-001], [TECH-002]
Diagrama de Flujo del Sistema
=============================
.. code-block:: text
+------------------------+ +---------------------------+
| Upstream RHEL / Fedora | ---> | Nodo Servidor MxOS |
+------------------------+ +---------------------------+
|
v
+---------------------------+
| Generación de UnixFS DAG |
| (ipfs add / filestore) |
+---------------------------+
|
v
+---------------------------+
| Actualización DNSLink |
| _dnslink.mirrors.mx-os.mx |
+---------------------------+
|
+-------------------------+-------------------------+
| |
v v
+-----------------------------+ +-----------------------------+
| Colaborador Nivel 1 (ISOs) | <== Bitswap P2P ==> | Colaborador Nivel 2 (BaseOS)|
| ipfs pin add /.../fedora/iso| | ipfs pin add /.../BaseOS |
+-----------------------------+ +-----------------------------+
| |
v v
+-----------------------------+ +-----------------------------+
| Gateway local (puerto 8080) | | Gateway local (puerto 8080) |
+-----------------------------+ +-----------------------------+
| |
v v
+-----------------------------+ +-----------------------------+
| Cliente DNF (localhost) | | Cliente DNF (localhost) |
+-----------------------------+ +-----------------------------+
Componentes Principales
=======================
Demonio Kubo
------------
* **Implementación:** Kubo (Go-IPFS) versión empaquetada para Fedora/CentOS en Copr (``renich/kubo``).
* **Almacén de bloques:** Base de datos badgerds o flatfs para alto rendimiento en lecturas aleatorias.
* **Protocolos de transporte:** TCP y QUIC habilitados en el puerto 4001 para transversalidad óptima de NAT y firewalls residenciales.
* **Gateway local:** Escucha en ``127.0.0.1:8080`` permitiendo acceso HTTP sin exponer la interfaz de control RPC (puerto 5001).
Direccionamiento UnixFS DAG
---------------------------
Cada repositorio se procesa como un grafo acíclico dirigido (DAG) de UnixFS v1/v2. Los archivos grandes (imágenes ISO) se fragmentan en bloques de 1 MB con funciones hash SHA-256 o BLAKE3, garantizando que si dos versiones comparten paquetes o bloques de datos idénticos, estos se dedupliquen automáticamente en el almacén global.

View file

@ -0,0 +1,31 @@
====================================
Ingesta de Repositorios y Telemetría
====================================
Identificadores Técnicos: [TECH-001], [TECH-004]
Flujo de Ingesta Upstream
=========================
El ciclo de actualización del nodo central de MxOS se ejecuta de manera automatizada mediante temporizadores de systemd y comprende cuatro etapas:
1. **Sincronización diferencial con rsync:** Se obtienen los paquetes y metadatos actualizados desde los espejos de nivel 1 (Tier-1) de Fedora y CentOS Stream hacia un directorio de preparación (staging) local.
2. **Generación del grafo UnixFS (Filestore):** Para evitar la duplicación de cientos de gigabytes en el disco del servidor, se utiliza la función ``--nocopy`` de Kubo con el subsistema filestore habilitado:
.. code-block:: bash
ipfs add -r --nocopy --cid-version=1 --hash=sha2-256 /srv/mirrors/staging/
3. **Actualización de Registros DNSLink:** El CID raíz resultante de la ingesta se publica automáticamente en el servidor de nombres de MxOS mediante actualización dinámica de DNS (RFC 2136 / nsupdate) o vía la API de gestión de zona.
4. **Anuncio en el enjambre:** El nodo central anuncia la provisión de los nuevos CIDs a la DHT de IPFS.
Descubrimiento de Nodos y Telemetría Pasiva
===========================================
Para alimentar el tablero público en ``mirrors.mx-os.mx`` sin violar la privacidad de los colaboradores, el servicio recolector opera de la siguiente forma:
1. **Consulta a la DHT:** Se invoca periódicamente la interfaz RPC de Kubo o la instrucción de línea de comandos para consultar proveedores del CID raíz activo:
.. code-block:: bash
ipfs dht findprovs -n 0 <CID_RAÍZ>
2. **Extracción de multiaddrs:** El comando retorna los identificadores de par (PeerID) y las direcciones de red asociadas (IPv4/IPv6 y puertos de escucha).
3. **Geolocalización aproximada en memoria:** Las direcciones IP públicas se contrastan contra una base de datos local MaxMind GeoLite2 para extraer únicamente el país y estado o región.
4. **Almacenamiento temporal:** Los datos agregados (número de pares, concentración geográfica y latencia de respuesta) se consolidan en una base de datos SQLite/libSQL o en memoria para ser consumidos por la interfaz web reactiva.

View file

@ -0,0 +1,68 @@
==================================
Puente HTTP y Fedora MirrorManager
==================================
Identificador Técnico: [TECH-005]
Integración con MirrorManager
=============================
Fedora gestiona su infraestructura de distribución global mediante MirrorManager (`mirrormanager2`). Para registrar formalmente a MxOS como el primer espejo oficial en México, se requiere:
1. Exposición de puntos finales HTTP y HTTPS estables y de alta velocidad.
2. Soporte para el protocolo de verificación de sincronización (archivo ``report_mirror``).
3. Respuesta rápida en peticiones GET y HEAD para metadatos de repositorio.
Topología del Puente Inverso
============================
En el servidor cabecera de MxOS (ejemplo: ``mirrors.mx-os.mx``), un servidor web de alto rendimiento (Caddy o Nginx) actúa como terminador TLS y proxy inverso directo hacia el gateway HTTP de Kubo:
.. code-block:: text
Petición DNF Upstream (Internet)
|
v
+---------------------------------------+
| Caddy / Nginx (mirrors.mx-os.mx:443) |
| Certificados Let's Encrypt / TLS 1.3 |
+---------------------------------------+
|
| proxy_pass http://127.0.0.1:8080/ipns/mirrors.mx-os.mx/
v
+---------------------------------------+
| Gateway HTTP de Kubo (IPFS Local) |
+---------------------------------------+
|
v
+---------------------------------------+
| Enjambre P2P de Nodos Guardianes |
+---------------------------------------+
Configuración de Ejemplo para Caddy
===================================
El servidor web delega la entrega de archivos estáticos al gateway local de IPFS:
.. code-block:: text
mirrors.mx-os.mx {
encode zstd gzip
# Proxy transparente hacia el gateway de IPFS
reverse_proxy http://127.0.0.1:8080 {
rewrite /ipns/mirrors.mx-os.mx{path}
header_up Host {upstream_hostport}
}
log {
output stdout
format filter {
wrap json
fields {
common_log delete
}
}
}
}
Beneficio Operativo
===================
Este desacoplamiento permite que los clientes externos utilicen el espejo como si fuera un servidor web convencional, mientras que por debajo, el servidor cabecera obtiene los bloques faltantes desde la red comunitaria de nodos guardianes, reduciendo drásticamente la carga de salida del nodo central.

View file

@ -0,0 +1,32 @@
================================
Resolución Inmutable con DNSLink
================================
Identificador Técnico: [TECH-003]
Fundamento
==========
El direccionamiento directo por CID (ejemplo: ``/ipfs/bafy...``) es inmutable; cualquier cambio en un paquete genera un nuevo CID raíz. Por su parte, el Sistema de Nombres Interplanetario tradicional (IPNS) basado en DHT experimenta una latencia de resolución prohibitiva para las consultas rápidas de metadatos de DNF.
Para solventar esta limitación, el proyecto utiliza **DNSLink**. DNSLink asocia un registro TXT en el sistema de nombres de dominio convencional con el CID raíz activo de IPFS.
Topología de Registros DNS
==========================
En los servidores de nombres autoritativos para el dominio ``mx-os.mx``, se definen los siguientes registros:
.. code-block:: zone
; Registro raíz del portal de espejos
_dnslink.mirrors.mx-os.mx. 300 IN TXT "dnslink=/ipfs/bafyrei..."
; Subdominios dedicados opcionales para granularidad independiente
_dnslink.fedora.mirrors.mx-os.mx. 300 IN TXT "dnslink=/ipfs/bafyfed..."
_dnslink.centos.mirrors.mx-os.mx. 300 IN TXT "dnslink=/ipfs/bafycen..."
Mecánica de Resolución en Kubo
==============================
1. Un cliente solicita un recurso bajo la ruta ``/ipns/mirrors.mx-os.mx/fedora/iso``.
2. Kubo extrae el nombre de dominio y consulta el registro TXT de ``_dnslink.mirrors.mx-os.mx`` utilizando DNS sobre HTTPS (DoH) o los resolutores del sistema local.
3. El registro TXT devuelve el prefijo ``dnslink=/ipfs/<CID_RAÍZ>``.
4. Kubo reemplaza internamente la ruta por ``/ipfs/<CID_RAÍZ>/fedora/iso`` y procede a recuperar los bloques vía Bitswap o desde la caché local.
5. El tiempo de vida (TTL) del registro se fija en 300 segundos (5 minutos) para permitir propagación rápida tras cada ciclo de sincronización.

25
etc/caddy/Caddyfile Normal file
View file

@ -0,0 +1,25 @@
# Configuración Caddy para mirrors.mx-os.mx
mirrors.mx-os.mx {
encode zstd gzip
# Proxy transparente hacia el gateway local de Kubo
reverse_proxy http://127.0.0.1:8080 {
rewrite /ipns/mirrors.mx-os.mx{path}
header_up Host {upstream_hostport}
transport http {
read_buffer 0
}
}
header {
Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
X-Content-Type-Options "nosniff"
X-Frame-Options "SAMEORIGIN"
Referrer-Policy "strict-origin-when-cross-origin"
}
log {
output stdout
format json
}
}

19
etc/mirrors.env Normal file
View file

@ -0,0 +1,19 @@
# Configuración de la Red de Espejos MxOS sobre IPFS
# Directorios de preparación y datos locales
MIRRORS_STAGING_DIR="${MIRRORS_STAGING_DIR:-$HOME/.local/share/mxos-mirrors/staging}"
MIRRORS_LOG_DIR="${MIRRORS_LOG_DIR:-$HOME/.local/share/mxos-mirrors/logs}"
# Configuración de IPFS
IPFS_PATH="${IPFS_PATH:-$HOME/.ipfs}"
IPFS_API_URL="${IPFS_API_URL:-/ip4/127.0.0.1/tcp/5001}"
IPFS_USE_NOCOPY="${IPFS_USE_NOCOPY:-false}"
# Dominios y DNSLink
CF_ZONE_ID="2bd35b00a854bc77cfd38009f977ea3c"
MIRRORS_DOMAIN="mirrors.mx-os.mx"
MIRRORS_DNSLINK_RECORD="_dnslink.mirrors.mx-os.mx"
# Espejos Upstream
FEDORA_UPSTREAM_RSYNC="rsync://dl.fedoraproject.org/pub/fedora/linux"
CENTOS_UPSTREAM_RSYNC="rsync://mirror.stream.centos.org/centos-stream"

View file

@ -0,0 +1,43 @@
# Configuración Nginx para mirrors.mx-os.mx como terminador TLS y proxy hacia Kubo
server {
listen 80;
listen [::]:80;
server_name mirrors.mx-os.mx;
# Redirección forzada hacia HTTPS
return 301 https://$host$request_uri;
}
server {
http2 on;
listen 443 ssl;
listen [::]:443 ssl;
server_name mirrors.mx-os.mx;
# Certificados SSL Let's Encrypt
ssl_certificate /etc/letsencrypt/live/mirrors.mx-os.mx/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/mirrors.mx-os.mx/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
# Encabezados de seguridad
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# Proxy inverso transparente hacia el gateway de Kubo
location / {
proxy_pass http://127.0.0.1:8080/ipns/mirrors.mx-os.mx/;
proxy_set_header Host 127.0.0.1:8080;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Deshabilitar buffering para flujo ágil de paquetes y artefactos de gran tamaño
proxy_buffering off;
proxy_read_timeout 300s;
proxy_connect_timeout 10s;
}
}

View file

@ -0,0 +1,15 @@
[Unit]
Description=Sincronización y publicación de la Red de Espejos MxOS sobre IPFS
Documentation=https://mirrors.mx-os.mx/README.rst
After=network-online.target ipfs.service
Wants=network-online.target
[Service]
Type=oneshot
WorkingDirectory=%h/Projects/mxos/mirrors
ExecStart=%h/Projects/mxos/mirrors/bin/mxos-mirror.bash run-all
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=default.target

11
systemd/mxos-mirror.timer Normal file
View file

@ -0,0 +1,11 @@
[Unit]
Description=Temporizador de sincronización periódica de espejos MxOS
Documentation=https://mirrors.mx-os.mx/README.rst
[Timer]
OnCalendar=*-*-* 04:00:00
RandomizedDelaySec=1800
Persistent=true
[Install]
WantedBy=timers.target