IPFS sin dolor (aunque no es seguro)

IPFS sin dolor (aunque no es seguro)

A pesar de que ya había más de un artículo sobre IPFS en Habr.

Aclaro de inmediato que no soy un experto en este campo, pero he mostrado interés por esta tecnología en varias ocasiones, aunque mis intentos de experimentar con ella a menudo me han causado algún dolor. Hoy he vuelto a experimentar y he obtenido algunos resultados que me gustaría compartir. En resumen, describiré el proceso de instalación de IPFS y algunas características (todo se hará en Ubuntu, no he probado en otras plataformas).

Si te perdiste qué es IPFS, está bastante detallado aquí: habr.com/ru/post/314768

Instalación

Para la pureza del experimento, sugiero instalarlo en un servidor externo, ya que consideraremos algunas complicaciones al trabajar en modo local y remoto. Luego, si lo deseas, se puede desinstalar fácilmente, no ocupa mucho espacio.

Instalamos Go

Documentación oficial
Consulta la versión actual en golang.org/dl

Nota: es mejor instalar IPFS como el usuario que se usará con más frecuencia. Esto se debe a que a continuación veremos una opción de montaje a través de FUSE y ahí hay ciertos matices.

cd ~
curl -O https://dl.google.com/go/go1.12.9.linux-amd64.tar.gz
tar xvf go1.12.9.linux-amd64.tar.gz
sudo chown -R root:root ./go
sudo mv go /usr/local
rm go1.12.9.linux-amd64.tar.gz

Luego, es necesario actualizar el entorno (más detalles aquí: golang.org/doc/code.html#GOPATH).

echo 'export GOPATH=$HOME/work' >> ~/.bashrc
echo 'export PATH=$PATH:/usr/local/go/bin:$GOPATH/bin' >> ~/.bashrc
source ~/.bashrc

Verificamos que Go se haya instalado

go version

Instalamos IPFS

Me gustó más el método de instalación a través de ipfs-update.

Lo instalamos con el siguiente comando

go get -v -u github.com/ipfs/ipfs-update

Después de esto, se pueden ejecutar los siguientes comandos:

ipfs-update versions — para ver todas las versiones disponibles para descargar.
ipfs-update version — para ver la versión instalada actualmente (como aún no hemos instalado IPFS, mostrará none).
ipfs-update install latest — instalar la última versión de IPFS. En lugar de latest, se puede especificar cualquier versión deseada de la lista disponible.

Instalamos IPFS

ipfs-update install latest

Verificamos.

ipfs --version

La instalación en general es así.

Ejecutando IPFS

Inicialización

Para empezar, hay que realizar la inicialización.

ipfs init

En respuesta, recibirás algo como esto:

 ipfs init
initializing IPFS node at /home/USERNAME/.ipfs
generating 2048-bit RSA keypair...done
peer identity: QmeCWX1DD7HnXXXXXXXXXXXXXXXXXXXXXXXXxxx
to get started, enter:
	ipfs cat /ipfs/QmS4ustL54uo8FzR9455qaxZwuMiUhyvMcX9Ba8nUH4uVv/readme

Puedes ejecutar el comando sugerido

ipfs cat /ipfs/QmS4ustL54uo8FzR9455qaxZwuMiUhyvMcX9Ba8nUH4uVv/readme

Resultado

¡Hola y bienvenido a IPFS!

██╗██████╗ ███████╗███████╗
██║██╔══██╗██╔════╝██╔════╝
██║██████╔╝█████╗  ███████╗
██║██╔═══╝ ██╔══╝  ╚════██║
██║██║     ██║     ███████║
╚═╝╚═╝     ╚═╝     ╚══════╝

Si estás viendo esto, has instalado exitosamente
IPFS y ahora estás interfiriendo con el ipfs merkledag!

 -------------------------------------------------------
| Advertencia:                                         |
|   Este es software en versión alpha. ¡Úsalo a tu propio riesgo! |
|   Falta mucho o no está pulido. Hay errores.        |
|   Aún no es seguro. Lee las notas de seguridad para más información.   |
 -------------------------------------------------------

Echa un vistazo a algunos de los otros archivos en este directorio:

  .\/about
  .\/help
  .\/quick-start     <-- ejemplos de uso
  .\/readme          <-- este archivo
  .\/security-notes

Aquí es donde, en mi opinión, comienza lo interesante. Los chicos ya empiezan a usar sus tecnologías incluso en la fase de instalación. El hash ofrecido QmS4ustL54uo8FzR9455qaxZwuMiUhyvMcX9Ba8nUH4uVv — no fue generado especialmente para ti, sino que está incrustado en la versión de lanzamiento. Es decir, antes del lanzamiento prepararon el texto de bienvenida, lo lanzaron en IPFS y añadieron la dirección al instalador. Me parece que eso es muy genial. Y este archivo (en realidad, toda la carpeta) ahora se puede ver no solo localmente, sino también en la puerta de enlace oficial. ipfs.io/ipfs/QmS4ustL54uo8FzR9455qaxZwuMiUhyvMcX9Ba8nUH4uVv. En este caso se puede estar seguro de que el contenido de la carpeta no ha cambiado, ya que si hubiera cambiado, el hash también habría cambiado.

A propósito, en este caso IPFS tiene cierta similitud con un servidor de control de versiones. Si se hacen cambios en los archivos de origen de la carpeta y se vuelve a lanzar la carpeta en IPFS, obtendrá una nueva dirección. Sin embargo, la carpeta antigua no desaparece y estará disponible en su dirección original.

Inicio del Daemon

ipfs daemon

Deberías recibir una respuesta como esta:

ipfs daemon
Inicializando daemon...
versión de go-ipfs: 0.4.22-
versión del repositorio: 7
versión del sistema: amd64/linux
versión de Golang: go1.12.7
Swarm escuchando en /ip4/x.x.x.x/tcp/4001
Swarm escuchando en /ip4/127.0.0.1/tcp/4001
Swarm escuchando en /ip6/::1/tcp/4001
Swarm escuchando en /p2p-circuit
Swarm anunciando /ip4/127.0.0.1/tcp/4001
Swarm anunciando /ip6/::1/tcp/4001
El servidor API escuchando en /ip4/127.0.0.1/tcp/5001
WebUI: http://127.0.0.1:5001/webui
Servidor Gateway (solo lectura) escuchando en /ip4/127.0.0.1/tcp/8080
Daemon listo

Abriendo puertas al Internet

Presta atención a estas dos líneas:

WebUI: http://127.0.0.1:5001/webui
Servidor Gateway (solo lectura) escuchando en /ip4/127.0.0.1/tcp/8080

Si has instalado IPFS localmente, podrás acceder a las interfaces de IPFS a través de direcciones locales y tendrás todo disponible (Por ejemplo, localhost:5001/webui/). Sin embargo, al instalar en un servidor externo, por defecto los gateways están cerrados para internet. Hay dos gateways:

  1. Panel de administración webui (github) en el puerto 5001.
  2. API externo en el puerto 8080 (solo lectura).

Por ahora, para experimentos, se pueden abrir ambos puertos (5001 y 8080), pero en un servidor de producción, por supuesto, se debería cerrar el puerto 5001 con un firewall. También hay un puerto 4001, que es necesario para que otros peers puedan encontrarte. Este debe permanecer abierto para solicitudes externas.

Abrimos para editar ~/.ipfs/config y buscamos estas líneas:

"Addresses": {
  "Swarm": [
    "/ip4/0.0.0.0/tcp/4001",
    "/ip6/::/tcp/4001"
  ],
  "Announce": [],
  "NoAnnounce": [],
  "API": "/ip4/127.0.0.1/tcp/5001",
  "Gateway": "/ip4/127.0.0.1/tcp/8080"
}

Cambiamos 127.0.0.1 por la IP de su servidor y guardamos el archivo, después reiniciamos IPFS (detenemos la ejecución con Ctrl+C y luego volvemos a iniciarlo).

Deberíamos obtener

...
WebUI: http://ip_su_servidor:5001/webui
Servidor Gateway (solo lectura) escuchando en /ip4/ip_su_servidor/tcp/8080

Ahora las interfaces externas deberían estar disponibles.

Verifique

http://dominio_o_ip_del_servidor:8080/ipfs/QmS4ustL54uo8FzR9455qaxZwuMiUhyvMcX9Ba8nUH4uVv/readme

Debería abrirse el archivo readme mencionado anteriormente.

http://dominio_o_ip_del_servidor:5001/webui/

Debería abrirse la interfaz web.

Si su webui está funcionando, puede cambiar la configuración de IPFS directamente en ella, incluyendo la visualización de estadísticas, pero a continuación consideraré las opciones de configuración directamente a través del archivo de configuración, lo cual no es crítico en general. Simplemente es mejor recordar dónde se encuentra el config y qué hacer con él, ya que si la interfaz web no funciona, será más complicado.

Configurando la interfaz web para trabajar con su servidor

Aquí hay una primera trampa, en la que tardé unas tres horas.

Si usted instaló IPFS en un servidor externo, pero no instaló ni ejecutó IPFS localmente, al ingresar a /webui en la interfaz web debería ver un error de conexión:

IPFS sin dolor (aunque no es seguro)

El problema es que, en mi opinión, webui funciona de manera bastante ambigua. Primero intenta conectarse al API del servidor donde está abierta la interfaz (por supuesto, basado en la dirección en el navegador). Si no puede allí, intenta conectarse al gateway local. Y si tiene IPFS ejecutándose localmente, su webui funcionará normalmente, solo que estará interactuando con un IPFS local y no uno externo, aunque haya abierto la webui en un servidor externo. Luego sube archivos, pero por alguna razón no los ve de forma directa en el servidor externo...

Y si no está ejecutado localmente, obtendremos un error de conexión. En nuestro caso, el error es probablemente debido a CORS, como también indica webui, sugiriendo agregar la configuración.

ipfs config --json API.HTTPHeaders.Access-Control-Allow-Origin '["http://ip_de_tu_servidor:5001", "http://127.0.0.1:5001", "https://webui.ipfs.io"]'
ipfs config --json API.HTTPHeaders.Access-Control-Allow-Methods '["PUT", "GET", "POST"]'

Yo simplemente escribí un wildcard.

ipfs config --json API.HTTPHeaders.Access-Control-Allow-Origin '["*"]'

Los encabezados agregados se pueden encontrar todos en el mismo ~/.ipfs/config. En mi caso es

  "API": {
    "HTTPHeaders": {
      "Access-Control-Allow-Origin": [
        "*"
      ]
    }
  },

Reiniciamos ipfs y vemos que webui se ha conectado exitosamente (al menos debería, si has abierto los gateways para solicitudes externas, como se describió anteriormente).

Ahora se pueden subir carpetas y archivos directamente a través de la interfaz web, así como crear tus propias carpetas.

Montaje del sistema de archivos FUSE.

Esto es una característica bastante interesante.

Los archivos (al igual que las carpetas) se pueden agregar no solo a través de la interfaz web, sino también directamente en la terminal, por ejemplo:

ipfs add test -r
added QmfYuz2gegRZNkDUDVLNa5DXzKmxxxxxxxxxx test/test.txt
added QmbnzgRVAP4fL814h5mQttyqk1aURxxxxxxxxxxxx test

El último hash es el hash de la carpeta raíz.

Con este hash podemos abrir la carpeta en cualquier nodo ipfs (que pueda encontrar nuestro nodo y obtener contenido), podemos en la interfaz web en el puerto 5001 o 8080, o localmente a través de ipfs.

ipfs ls QmbnzgRVAP4fL814h5mQttyqk1aUxxxxxxxxxxxxx
QmfYuz2gegRZNkDUDVLNa5DXzKmKVxxxxxxxxxxxxxx 10 test.txt

Pero también se puede abrir como una carpeta normal.

Crearemos dos carpetas en la raíz y otorgaremos derechos a nuestro usuario.

sudo mkdir /ipfs /ipns
sudo chown USERNAME /ipfs /ipns

y reiniciaremos ipfs con la bandera --mount.

ipfs daemon --mount

Se pueden crear carpetas en otros lugares y especificar la ruta a ellas a través de los parámetros ipfs daemon --mount --mount-ipfs /ruta_ipfs --mount-ipns /ruta_ipns

Ahora leer de esta carpeta es un poco inusual.

ls -la /ipfs
ls: reading directory '/ipfs': Operation not permitted
total 0

Es decir, no hay acceso directo a la raíz de esta carpeta. Pero aún se puede obtener contenido, sabiendo el hash.

ls -la /ipfs/QmbnzgRVAP4fL814h5mQttyqxxxxxxxxxxxxxxxxx
total 0
-r--r--r-- 1 root root 10 Aug 31 07:03 test.txt

cat /ipfs/QmbnzgRVAP4fL814h5mQttyqxxxxxxxxxxxxxxxxx/test.txt 
test
test

Dentro de la carpeta, incluso la autocompletación funciona al especificar la ruta.

Como mencioné anteriormente, con este tipo de montaje hay particularidades: por defecto, las carpetas montadas con FUSE solo son accesibles para el usuario actual (incluso root no podrá leer de dicha carpeta, y mucho menos otros usuarios en el sistema). Si quieres hacer que estas carpetas sean accesibles para otros usuarios, hay que cambiar en la configuración «FuseAllowOther»: false a «FuseAllowOther»: true. Pero eso no es todo. Si estás ejecutando IPFS como root, todo está bien. Y si lo haces como un usuario normal (aunque sea con sudo), entonces recibirás un error.

error del helper de montaje: fusermount: la opción allow_other solo está permitida si 'user_allow_other' está configurado en /etc/fuse.conf

En este caso, hay que modificar /etc/fuse.conf, descomentando la línea #user_allow_other.

Después de eso, reiniciamos ipfs.

Problemas conocidos con FUSE

Se ha observado repetidamente que después de reiniciar ipfs con montaje (o tal vez en otros casos), los puntos de montaje /ipfs y /ipns se vuelven inaccesibles. No hay acceso a ellos, y ls -la /ipfs muestra ???? en la lista de permisos.

Encontré esta solución:

fusermount -z -u /ipfs
fusermount -z -u /ipns

Después de eso, reiniciamos ipfs.

Agregamos el servicio

Por supuesto, ejecutar en la terminal es solo para pruebas iniciales. En producción, el demonio debe iniciarse automáticamente al iniciar el sistema.

Desde sudo creamos el archivo /etc/systemd/system/ipfs.service y escribimos en él:

[Unit]
Description=Daemon de IPFS
After=syslog.target network.target remote-fs.target nss-lookup.target

[Service]
Type=simple
ExecStart=/home/USERNAME/work/bin/ipfs daemon --mount
User=USERNAME
Restart=always

[Install]
WantedBy=multi-user.target

Por supuesto, USERNAME debe ser reemplazado por tu usuario (y posiblemente la ruta completa al programa ipfs será diferente en tu caso (se debe indicar la ruta completa).

Activamos el servicio.

sudo systemctl enable ipfs.service

Iniciamos el servicio.

sudo service ipfs start

Verificamos el estado del servicio.

sudo service ipfs status

Para la limpieza del experimento, en el futuro se puede reiniciar el servidor para verificar que ipfs se inicie automáticamente.

Agregamos los pares que conocemos.

Consideremos la situación en la que tenemos nodos IPFS instalados tanto en un servidor externo como localmente. En el servidor externo, añadimos un archivo y tratamos de acceder a él a través de IPFS localmente usando su CID. ¿Qué sucederá? Por supuesto, el servidor local probablemente no tiene información sobre nuestro servidor externo y simplemente intentará encontrar el archivo a través del CID "preguntando" a todos los pares IPFS disponibles que ya ha "conocido". Estos, a su vez, preguntarán a otros. Y así sucesivamente, hasta que se encuentre el archivo. Lo mismo ocurre cuando intentamos acceder al archivo a través de la puerta de enlace oficial. ipfs.io. Si tenemos suerte, el archivo se encontrará en cuestión de segundos. Pero si no, puede tardar varios minutos en ser encontrado, lo que impacta enormemente en la comodidad del trabajo. Pero nosotros sabemos dónde aparecerá primero ese archivo. Entonces, ¿por qué no decirle a nuestro servidor local desde el principio "busca allí primero"? Al parecer, esto se puede hacer.

1. Ingrese al servidor remoto y en el archivo de configuración ~/.ipfs/config busque

"Identity": {
    "PeerID": "QmeCWX1DD7HnPSuMHZSh6tFuxxxxxxxxxxxxxxxx",

2. Ejecute sudo service ipfs status y busque en él las entradas Swarm, por ejemplo:

Swarm announcing /ip4/ip_de_tu_servidor/tcp/4001

3. Construya una dirección completa en el formato "/ip4/ip_de_tu_servidor/tcp/4001/ipfs/$PeerID".

4. Para mayor seguridad, intentemos agregar esta dirección a los pares a través de nuestra interfaz web local.

IPFS sin dolor (aunque no es seguro)

5. Si todo está OK, abrimos el archivo de configuración local ~/.ipfs/config, encontramos "Bootstrap": […
y añadimos la dirección obtenida como el primer elemento en el array.

Reiniciamos IPFS.

Ahora añadimos un archivo en el servidor externo y tratamos de solicitarlo en el local. Debería llegar rápidamente.

Pero esta funcionalidad aún es inestable. Según entiendo, incluso si especificamos la dirección del par en Bootstrap, durante el funcionamiento, IPFS cambia la lista de conexiones activas con los pares. En cualquier caso, se está discutiendo esto y se tienen deseos sobre la posibilidad de especificar pares permanentes. aquí Y parece que se presume se va a añadir cierta funcionalidad en ipfs@5.0+.

La lista de pares actuales se puede ver tanto en la interfaz web como en la terminal.

ipfs swarm peers

En ambos casos, se puede añadir manualmente su propio par.

ipfs swarm connect "/ip4/ip_de_tu_servidor/tcp/4001/ipfs/$PeerID"

Hasta que mejoren esta funcionalidad, se puede escribir una herramienta que verifique la conexión con el par deseado y, si no hay conexión, que la agregue.

Reflexiones

Entre aquellos que ya están familiarizados con IPFS, hay tanto argumentos a favor como en contra de IPFS. En principio, hace dos días la discusión me motivó a investigar IPFS una vez más. Y en cuanto a la discusión mencionada: no puedo decir que esté muy en contra de alguno de los argumentos expresados (solo no estoy de acuerdo con que un programador y medio utiliza IPFS). En general, ambos lados tienen algo de razón (especialmente el comentario sobre los cheques lo cual invita a la reflexión). Pero si dejamos de lado la evaluación ética y legal, ¿quién puede dar una evaluación técnica de esta tecnología? Personalmente tengo una sensación interna de que 'esto es definitivamente necesario, tiene ciertas perspectivas'. Pero la razón exacta no está claramente formulada. Es decir, si observamos los medios centralizados existentes, en muchos parámetros están mucho más avanzados (estabilidad del funcionamiento, velocidad, manejabilidad, etc.). No obstante, tengo una idea que parece tener sentido y que difícilmente podría realizarse sin estos sistemas descentralizados. Claro, estoy siendo un poco ambicioso, pero la formularía así: el principio de la difusión de la información en Internet debe cambiar.

Lo explico. Si lo pensamos bien, actualmente nuestra información se difunde bajo el principio de 'Espero que aquel a quien se la entregué la proteja y no se pierda ni sea recibida por quienes no estaba destinada'. Para poner un ejemplo, es fácil considerar diferentes servicios de correo, almacenamiento en la nube, etc. ¿Y qué tenemos al final? En Habr, la plataforma Seguridad de la información está en la primera posición y prácticamente todos los días recibimos noticias sobre otra filtración global. En principio, todo lo interesante está enumerado en <ironía>maravilloso<\/ironía> artículo El verano casi ha terminado. Casi no quedan datos no filtrados. Es decir, los gigantes de Internet se están volviendo cada vez más grandes, acumulan cada vez más información y tales filtraciones son una especie de explosiones informativas. Nunca había pasado algo así, y aquí estamos de nuevo. Sin embargo, aunque muchos entienden que hay riesgos, seguirán confiando sus datos a empresas externas. Primero, no hay muchas alternativas, y segundo, estas prometen que han tapado todos los agujeros y que esto nunca volverá a repetirse.

¿Qué opción veo? Creo que los datos deberían distribuirse abiertamente desde el principio. Pero la apertura en este caso no significa que todo deba ser fácilmente legible. Me refiero a la apertura en el almacenamiento y distribución, pero no a una apertura total en la lectura. Supongo que la información debería distribuirse con claves abiertas. El principio de claves abiertas/cerradas ya es antiguo, prácticamente tan antiguo como Internet. Si la información no es confidencial y está destinada a un amplio público, se publica inmediatamente con una clave abierta (pero sigue estando encriptada, simplemente cualquiera puede descifrarla con la clave disponible). Y si no, se publica sin clave abierta, y la clave se entrega a quien debe tener acceso a esa información. Al mismo tiempo, quien debe leerla solo debe tener la clave, y no debería preocuparse demasiado por dónde obtener esa información: simplemente la descarga de la red (este es el nuevo principio de distribución por contenido y no por dirección).

Por lo tanto, los atacantes necesitarían obtener una gran cantidad de claves privadas para un ataque masivo, y es poco probable que puedan hacerlo en un solo lugar. Esta tarea, en mi opinión, es más complicada que hackear un servicio específico.

Y aquí se cierra otro problema: la verificación de la autoría. Ahora en Internet se pueden encontrar muchas citas escritas por nuestros conocidos. Pero, ¿dónde está la garantía de que realmente las escribieron? Si cada uno de estos registros estuviera acompañado de una firma digital, sería mucho más fácil. Y no importa dónde se almacene esta información, lo importante es la firma, que es difícil de falsificar.

Y lo interesante aquí es que IPFS ya incorpora medios de cifrado (está construido sobre tecnología blockchain). En la configuración se indica de inmediato la clave privada.

  "Identity": {
    "PeerID": "QmeCWX1DD7HnPSuMHZSh6tFuMxxxxxxxxxxxxxx",
    "PrivKey": "CAASqAkwggSkAgEAAoIBAQClZedVmj8JkPvT92sGrNIQmofVF3ne8xSWZIGqkm+t9IHNN+\/NDI51jA0MRzpBviM3o\/c\/Nuz30wo95vWToNyWzJlyAISXnUHxnVhvpeJAbaeggQRcFxO9ujO9DH61aqgN1m+JoEplHjtc4KS5
pUEDqamve+xAJO8BWt\/LgeRKA70JN4hlsRSghRqNFFwjeuBkT1kB6tZsG3YmvAXJ0o2uye+y+7LMS7jKpwJNJBiFAa\/Kuyu3W6PrdOe7SqrXfjOLHQ0uX1oYfcqFIKQsBNj\/Fb+GJMiciJUZaAjgHoaZrrf2b\/Eii3z0i+QIVG7OypXT3Z9JUS60
KKLfjtJ0nVLjAgMBAAECggEAZqSR5sbdffNSxN2TtsXDa3hq+WwjPp\/908M10QQleH\/3mcKv98FmGz65zjfZyHjV5C7GPp24e6elgHr3RhGbM55vT5dQscJu7SGng0of2bnzQCEw8nGD18dZWmYJsE4rUsMT3wXxhUU4s8\/Zijgq27oLyxKNr9T7
2gxqPCI06VTfMiCL1wBBUP1wHdFmD\/YLJwOjV\/sVzbsl9HxqzgzlDtfMn\/bJodcURFI1sf1e6WO+MyTc3.................

No soy un experto en seguridad y no puedo saber con certeza cómo utilizar esto correctamente, pero me parece que a nivel de intercambio entre nodos IPFS se utilizan estas claves. Además, js-ipfs y proyectos de ejemplo como orbit-db, que es en lo que opera orbit.chat. Es decir, teóricamente, cada dispositivo (móvil y no solo) podría estar fácilmente equipado con sus propias máquinas de cifrado y descifrado. En tal caso, solo quedaría que cada uno se encargara de mantener sus claves privadas y cada uno sería responsable de su propia seguridad, en lugar de ser un rehén de algún factor humano en algún gigante de internet superpopular.

Solo los usuarios registrados pueden participar en la encuesta. Inicie sesión, por favor.

¿Has oído hablar de IPFS antes?

  • Nunca he oído sobre IPFS, pero suena interesante

  • No he oído y no quiero oír

  • He oído, pero no me interesó

  • He oído, pero no entendí; ahora parece interesante

  • Hace tiempo que uso IPFS activamente

69 usuarios votaron. 13 usuarios se abstuvieron.

Fuente: habr.com

Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS 🔥 Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS | ProHoster