Esto es una versión revisada de la guía original de Complication detallando el uso de Monotone en el desarrollo de I2P. Para obtener instrucciones básicas vea la guía rápida.

I2P usa un modelo distribuido de desarrollo. El código es replicado por administradores independientes en repositorios Monotone ("MTN"). Los desarrolladores con derechos para ello pueden subir sus cambios al repositorio (deben firmar un acuerdo de licencia antes de obtener estos derechos)

Algunas de las notables cualidades de Monotone son: control de versiones distribuido, autenticación con cifrados, acceso de control, su pequeño tamaño, tiene pocas dependencias, el almacenamiento de los proyectos usa una base de datos SQLite comprimida, y además tiene la capacidad de reanudar los intentos de sincronización interrumpidos.

Usando un cliente Monotone

Generando las claves de Monotone

Una clave de transporte le permite subir sus cambios al repositorio del servidor Monotone. Para poder subir código a Monotone (firmando su código), es necesaria una clave de subida. Ninguno de los servidores públicos de Monotone en I2P necesita claves para poder leer (o descargar) el código.

Sin una clave de transporte no se puede:

  • descargar el código de un servidor que no permita acceso global de lectura
  • subir código a cualquier servidor
  • ejecutar un servidor Monotone

Sin una clave de subida no se puede:

  • subir ningún código

So sólo desea obtener el código de MTN salte a la siguiente sección. Si desea generar las claves siga leyendo aquí.

Por convenio las claves son nombradas como una dirección de email, pero no es necesario que exista un email correspondiente. Por ejemplo, sus claves podrían llamarse:

  • yourname@mail.i2p
  • yourname-transport@mail.i2p

Monotone guarda las claves en $HOME/.monotone/keys en archivos de texto que se llaman exactamente igual que la clave. Por ejemplo:

  • /home/complication/.monotone/keys/complication@mail.i2p

Para generar las claves de transporte y subida ejecute los siguientes comandos en la terminal:

  • $ mtn genkey yourname-transport@someplace
  • $ mtn genkey yourname@someplace

Monotone le pedirá una contraseña para proteger sus claves. Se recomienda encarecidamente usar una contraseña para la clave de subida. Muchos usuarios dejan la contraseña de transporte en blanco, sobre todo los que ejecutan un servidor Monotone.

Confianza e iniciando su repositorio

El modelo de seguridad de Monotone ayuda a asegurar que nadie puede suplantar a un programador fácilmente si ser detectado. Ya que los programadores pueden cometer errores y pueden ser comprometidos, sólo una revisión manual puede asegurar la calidad del código. El modelo de confianza de Monotone se asegura de que usted sólo lea los cambios correctos. No reemplaza los cambios de lectura.

Un repositorio Monotono es un solo archivo (comprimido en una base de datos SQLite) que contiene todo el código del proyecto y su historial.

Después de importar las claves de los desarrolladores hacia Monotone y de Establecer enganches ('hooks') de evaluación de confianza, mediante esta monitorización Monotone evitará que cualquier código que no sea de confianza sea subido a su espacio de trabajo. Existen comandos disponibles para eliminar el código no confiable de su espacio de trabajo, pero en la práctica no se han necesitado debido a las políticas acceso a actualizaciones activas ('push') que se aplican.

Un repositorio puede almacenar muchas ramas. Por ejemplo, nuestro repositorio almacena las siguientes ramas principales:

  • i2p.i2p — El enrutador ('router') I2P y los programas asociados
  • i2p.www — El sitio web del proyecto I2P
  • i2p.syndie — Syndie, una herramienta de forums distribuídos.

Por convención, el repositorio de I2P Monotone se llama i2p.mtn. Antes de obtener código fuente desde los servidores, es necesario que sea inicializada una base de datos para su repositorio. Para inicializar su repositorio local vaya al directorio donde quiera que el fichero i2p.mtn y los subdirectorios sean guardados, y use el siguiente comando:

  • $ mtn --db="i2p.mtn" db init

Obteniendo y desplegando las claves de los desarrolladores

Las claves que los desarrolladores usan para consignar ('commit') código son esenciales para la evaluación de confianza en Monotone. Las otras claves de transporte de desarrolladores sólo son requeridas para operadores de servidor Monotone.

Las claves de consignación ('commit') de desarrolladores se proporcionan firmadas-con-GPG en otra página.

Para importar claves de desarrollador tras verificar sus autenticidades, copie todas las claves en un nuevo fichero. Cree este fichero (ej. keys.txt) en el mismo directorio donde i2p.mtn resida. Luego importe las claves con el comando:

  • $ mtn --db="i2p.mtn" read < keys.txt

Nota: Nunca añada claves a $HOME/.monotone/keys manualmente.

Establecer enganches ('hooks') de evaluación de confianza

La política de confianza de monotone es demasiada relajada para nuestras necesidades: todos los colaboradores son de confianza por defecto. Esto no es aceptable para el desarrollo de I2P.

Vaya al directorio $HOME/.monotone y abra el fichero monotonerc con un editor de texto. Copie y pegue las dos siguientes funciones en este fichero:

-- This implements a list of trusted signers.
-- It is used on checkout and update.
-- It is not used for repo sync/push/pull.
-- If you do not include this function in ~/.monotone/monotonerc, the
-- default is to trust everybody, which is probably a bad thing
-- in an anonymous network.
-- Update the list below to reflect the signers YOU trust.
--
-- ref: http://www.monotone.ca/docs/Trust-Evaluation-Hooks.html
-- Modified to use key identities instead of key names, since
-- monotone allows duplicate key names, so any key-name-based
-- trust system is insecure.

--
--  Modified from intersection() to use key identities instead of key names, since
--  monotone allows duplicate key names.
--
--  a: table of ID structures (see above)
--  b: table of hex IDs
--
function keyintersection(a,b)
    local s={}
    local t={}
    for k,v in pairs(a) do s[v.id] = 1 end
    for k,v in pairs(b) do if s[v] ~= nil then table.insert(t,v) end end
    return t
end

--
-- from mtn source project.hh and lua_hooks.cc:
-- signers is a table of integers (starting with 1) to the following ID structure:
-- struct ID
-- {
--   id: (key_id in key_identity_info) hex of revision id hash;
--   given_name: (given_name in key_identity_info) // name given when creating the key
--   name: (official_name in key_identity_info) // name returned by hooks or (once implented) policy
-- };
-- id: hex of revision id hash;
-- name: cert_name
-- val: cert_value
--
function get_revision_cert_trust(signers, id, name, val)
   local trusted_signers = {
		"5bc185cfd680eb512fdb9626b9fb4298e136215e",	--  BlubMail@mail.i2p
		"f6706ac205e6b5d7a7e3ea4244ab0ef497f0a099",	--  cervantes@mail.i2p
		"690f278ff6c6157cbaf23b0d602b6d6dcf368313",	--  complication@mail.i2p
		"eb4ac08d5ddbb2bd73889f86c1211424025a6f07",	--  dev@robertfoss.se
		"aae785027c240ebbb0a883fd8ebcf8d6ecee4104",	--  dev@welterde.de
		"86478595288d1b96b58f0c8cd8a8971bc430f8fd",	--  dg2@mail.i2p
		-- completed dev agreement 2013-07 but never checked in anything
		--"5f75b8f0769770edc3267c21ddc9a00ddae31394",	--  digit@mail.i2p
		"4ebaace9973913416af92ee8d0fb93d64753df4c",	--  dream@mail.i2p
		"7e498ae94c9c322404adfc61b16bed388095906b",	--  duck@mail.i2p
		"6c728b0ffed3c2bf7fb0f3c583b30f966d9bacd5",	--  echelon2@mail.i2p
		"0e4e7ebebafbdf4cdacc45a47ba155b1215d8e8b",	--  forget@mail.i2p
		"f332b3d3b11b2efdae220cea75b9d5ba9ec3b52d",	--  hamada@mail.i2p
		"e246444b4fe69ba599e13403c4ab931066de902f",	--  hiddenz@mail.i2p
		"a61146ee69ddb9fcf3b82b19a62b8114b60d367e",	--  HungryHobo@mail.i2p
		"4844b1fd45f5a68744fa28d2f3e3b61a3cf83b95",	--  kytv@mail.i2p
		"6b2acfc9fe2f69b796631a514660fd7bdd237e2d",	--  laziestgravy@mail.i2p
		"c9b970f5e8917eada663d4c6b22096617021c95c",	--  m1xxy@mail.i2p
		"3be64909d6ab7c3d7afe16f20f24e672708b576b",	--  magma@mail.i2p
		"2977a6f4e11819a3f928783175caadc0071fc4de",	--  mathiasdm@mail.i2p
		"de9d196e8057e1629178edbfa1ed754c648d7340",	--  meeh@mail.i2p
		"2a0bba98558d7a9d7e4b1bd807789601252c0024",	--  mkvore-commit@mail.i2p
		"6ade4b7a9a6425194f482ab351950e4230dbbc85",	--  neutron@mail.i2p
		"bc74b49fd8a20513b2745a3d13414b7e9818dd18",	--  Oldaris@mail.i2p
		"3fb8d1ee1e82981a8076ddbcbf4d18f372b8bba7",	--  privateer@mail.i2p
		"e3815f0c985663182534fbd7d6a2bf93204a0bd0",	--  russiansponsor@mail.i2p
		"1092773c40f5813b9179d52a8ab7b499b9554da3",	--  sponge@mail.i2p
		"01265f0c817b24548478341fb75e672720a78b21",	--  str4d@mail.i2p
		"38fe2aa37e1eb9a300a2061ef153265c48031c6b",	--  walking@mail.i2p
		"a0eb78d437efad120dd9edcd776a327ec2c2adde",	--  zab@mail.i2p
		"2158706490e62a17c8140b6e9eabca965b681bc7",	--  zab2@mail.i2p
		"56810cd6434ab33593260e188b32bb83e4e9a139",	--  z3r0fox@mail.i2p
		"896e399990704373125f782ae2ee19b6611ac612"	--  zzz@mail.i2p
   }
   local t = keyintersection(signers, trusted_signers)
   if t == nil then return false end
   if #t>= 1 then return true end
   return false
end

La primera función determina una intersección entre dos grupos, en nuestro caso los firmantes de la revisión y los firmantes de confianza.

La segunda función determina la confianza en una revisión dada, mediante una llamada a la primera con "signers" (firmantes) y "trusted" (confiables) como argumentos. Si la intersección de ambos es nula, no es confiable. Si la intersección no está vacía, la revisión es confiable. De otra manera, la revisión no es confiable.

Más información acerca de enganches ('hooks') de evaluación de confianza puede encontrarse documentación oficial de Monotone.

Descargar las ramas de i2p.i2p, i2p.www y i2p.syndie

I2P se entrega con un túnel preconfigurado apuntando al servidor del proyecto Monotone. Asegúrese de que el túnel ha sido iniciado dentro de I2PTunnel antes de intentar obtener (pull) el código fuente desde 127.0.0.1:8998

Entre en el directorio donde inicializó i2p.mtn. Dependiendo de si quiere sólo el código fuente de I2P, o también quiere el código del sitio web de I2P y Syndie, puede realizar pull (obtención) de diferentes maneras.

Si sólo quiere el código fuente de I2P:

  • $ mtn --db="i2p.mtn" -k "" pull "mtn://127.0.0.1:8998?i2p.i2p"

Si quiere todas las ramas de desarrollo (`branches`):

  • $ mtn --db="i2p.mtn" -k "" pull "mtn://127.0.0.1:8998?i2p.*"
Si la transferencia se interrumpe antes de completarse con éxito, simplemente repitiendo el comando pull se retomará la transferencia.

La obtención (`pulling`) en los ejemplos anteriores se realiza anónimamente especificando una clave de transporte vacía. Si todos realizaran obtenciones anónimas será más difícil para un atacante que gane control en el servidor, proporcionar datos falsos selectivamente a algunas personas.

Verificar que la evaluación de confianza funciona

Para verificar que la evaluación de confianza funciona:

  • Haga una copia de respaldo de su fichero monotonerc.
  • Modifique monotonerc estableciendo la variable trusted_signers (firmantes confiables) de la siguiente manera:
           local trusted_signers = {}
      
  • Con monotonerc configurado de la forma previa, Monotone no confiará en adelante en ninguno de los consignadores (`committers`). Confirme esto llendo al directorio donde i2p.mtn fue creado, e intente una revisión de la rama de I2P:
    • $ mtn --db="i2p.mtn" co --branch="i2p.i2p"

    Un directorio llamado i2p.i2p no debería aparecer. Debería encontrar muchos mensajes de error como:

        mtn: warning: trust function disliked 1 signers
        of branch cert on revision 523c15f6f50cad3bb002f830111fc189732f693b
        mtn: warning: trust function disliked 1 signers
        of branch cert on revision 8ac13edc2919dbd5bb596ed9f203aa780bf23ff0
        mtn: warning: trust function disliked 1 signers
        of branch cert on revision 8c4dd8ad4053baabb102a01cd3f91278142a2cd1
        mtn: misuse: branch 'i2p.i2p' is empty
      

    Si está satisfecho con el resultado, restaure monotonerc desde la copia de seguridad que fue creada antes. Si no creó una copia de seguridad como se le aconsejó, vuelva a leer Establecer enganches ('hooks') de evaluación de confianza (monitorización).

    Descargar una copia funcional de la última versión

    Si ya ha comprobado (`checkout`) un ramal de desarrollo (`branch`), pase a la siguiente sección.

    Cambie al directorio donde se emplace i2p.mtn. Allí ejecute:

    • $ mtn --db="i2p.mtn" co --branch="i2p.i2p"

    La comprobacion (`checkout`) debería completarse sin mensajes de error, y un directorio llamado i2p.i2p debería aparecer en el directorio actual. ¡Felicidades! Ha comprobado el último código fuente de I2P con éxito. está listo para ser compilado.

    Actualizar sus fuentes a la última versión

    Si no ha hecho esto ya, sincronice su repositorio local con código fresco desde el servidor. Para lograr esto, vaya al directorio donde se emplace i2p.mtn y ejecute:

    • $ mtn --db="i2p.mtn" -k "" pull "mtn://127.0.0.1:8998?i2p.i2p"

    Ahora vaya a su directorio i2p.i2p, y allí ejecute:

    • $ mtn update

    En tanto no haya errores…¡Felicidades! Ha realizado la actualización al último código fuente de I2P con éxito. Debe estar listo para compilar.

    Usando un servidor Monotone

    Obtención y despliegue de claves de transporte de desarrolladores

    Como operador de servidor, podría querer otorgar acceso a modificación (`push`) del código a ciertos desarrolladores.

    Obtener acceso para subir y descargar

    El servidor Monotone deniega todo acceso por defecto.

    Para garantizar acceso de sincronización local (`pull`) a todos los clientes, configure lo siguiente en $HOME/.monotone/read-permissions:

        pattern "*"
        allow "*"
    

    Nadie será capaz de modificar código en su servidor (`push`) sin serle otorgado permiso explícito. Para otorgar acceso de modificación:

    • Añada el nombre de la clave de transporte del usuario en $HOME/.monotone/write-permissions como
      zzz-transport@mail.i2p
      complication-transport@mail.i2p
      
      con una clave por línea.
    • Importe la(s) clave(s) de transporte a su base de datos. El procedimiento para importar claves de transporte es el mismo que para importar claves de consignación (`commit`), que se describe en la sección Obtención y despliegue de claves de transporte de desarrolladores.

    Ejecutar Monotone en modo servidor

    Se debe usar una base de datos aparte para su servidor Monotone porque Monotone bloqueará la base de datos mientras sea servida a otros. Haga una copia de su base de datos de desarrollo, y luego inicie el servidor con:

    • $ mtn serve --bind="127.0.0.1:8998" --db="i2p.mtn" --key "myserver-transport@mail.i2p"
    Si su clave está protegida con una frase-contraseña, Monotone puede requerir la frase-contraseña cuando conecte el primer cliente. Puede evitar esto realizando usted la primera conexión de cliente a su servidor (o eliminando la contraseña para su clave de transporte).

    Para que su servidor sea accesible para otros sobre I2P, tendrá que crear un túnel de servidor para él. Use el tipo de túnel "Standard" y el perfil "Bulk" (masivo).

    Diferencias en Debian GNU/Linux

    Debian (entre otras distribuciones) tiene integrado Monotone en sus estructuras demonios/servicios. Aunque los servidores Monotone aún se pueden ejecutar "de la forma corriente" en sistemas Debian, hacerlo "de la forma Debian" podría ser más apropiado.

    Los permisos se otorgan editando los ficheros /etc/monotone/read-permissions y /etc/monotone/write-permissions. También tendrá que editar /etc/default/monotone para hacer que Monotone se inicie en el arranque o para ajustar anfitrión (`host`), puerto, o emplazamiento de la base de datos.