What is lokinet?

Like the tor project, lokinet is a decentralized onion router that routes (all) traffic through multiple other servers. The nice thing about it is, that it runs on a lower network layer than tor. This makes lokinet able to route traffic using any network protocol, instead of sending everything over TCP. A good example of this is SSH. If a lokinet server is hosting an SSH or VPN service, it can be accessed without the need for port forwarding.

Goal

The goal of this project is to host a website (SNApp) on lokinet using a docker image. This project keeps it simple, using only a webserver. However, anything that can be hosted, can be hosted on lokinet.

Previous work

This blogpost is based on another post in which docker and docker-compose are explained.

Building a lokinet server container

Below is a Dockerfile that creates a container with lokinet inside.
The goal of this container is to provide a lokinet service with a permanent .loki address.

FROM ubuntu:latest
RUN apt update
RUN apt upgrade
RUN echo "resolvconf resolvconf/linkify-resolvconf boolean false" | debconf-set-selections
RUN apt install curl lsb-release resolvconf dnsutils --yes
RUN curl -so /etc/apt/trusted.gpg.d/oxen.gpg https://deb.oxen.io/pub.gpg
RUN echo "deb https://deb.oxen.io `lsb_release -sc` main" > /etc/apt/sources.list.d/oxen.list
RUN apt update
RUN apt install lokinet --yes
RUN chown _lokinet:_loki /etc/loki -R
RUN /usr/bin/lokinet -g
RUN lokinet-bootstrap
RUN chown _lokinet:_loki /etc/loki -R
RUN echo "#!/bin/bash" > /get_loki_address.sh
RUN echo "host -t cname localhost.loki 127.3.2.1" >> /get_loki_address.sh
RUN chmod +x /get_loki_address.sh
RUN cp /etc/loki/lokinet.ini /
RUN echo "#!/bin/bash" > /start.sh
RUN echo "cp -n /lokinet.ini /etc/loki/" >> /start.sh
RUN echo "cp -n /lokinet.ini /var/lib/lokinet/" >> /start.sh
RUN echo "/usr/bin/lokinet -g" >> /start.sh
RUN echo "sed -ie 's|#keyfile=|keyfile=/var/lib/lokinet/snappkey.private|g' /etc/loki/lokinet.ini" >> /start.sh
RUN echo "sed -ie 's|#keyfile=|keyfile=/var/lib/lokinet/snappkey.private|g' /var/lib/lokinet/lokinet.ini" >> /start.sh
RUN echo "rm -rf /var/lib/lokinet/nodedb/" >> start.sh
RUN echo "rm -rf /var/lib/lokinet/profiles.dat" >> start.sh
RUN echo "/usr/bin/lokinet" >> /start.sh
RUN chmod +x /start.sh
ENTRYPOINT ["/start.sh"]

Configuring docker-compose

Below is a docker-compose.yml file that configures 3 services:

  • lokinet: Using the above Dockerfile, a lokinet service will allow access to the .loki address.
  • tiredofit/nginx-php-fpm: to run a webserver, which can host a simple website.
  • containrrr/watchtower: to automatically keep all containers up to date.
version: "3.3"
services:
  lokinet:
    build: lokinet
    restart: always
    privileged: true
    tty: true
    network_mode: host
    tmpfs:
      - /run
      - /tmp
    volumes:
      - "./lokinet/var_lib_lokinet:/var/lib/lokinet"
      - "./lokinet/etc_loki:/etc/loki"
  php-nginx:
    container_name: php-nginx
    image: tiredofit/nginx-php-fpm
    restart: always
    ports:
      - "80:80"
    volumes:
      - "./webroot:/www/html"
  watchtower:
    image: containrrr/watchtower
    container_name: watchtower
    restart: always
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    command: lokinet php-nginx

In the docker-compose.yml file, the network_mode for the lokinet container is set to host. This will cause lokinet to have direct access to the host OS’s network. Now lokinet can talk to all other containers, as if it was running directly on the host OS.

Running the containers

When running the command docker-compose up --build, all the configured containers will start running.

Getting the loki address

The lokinet container contains a script that can give the current .loki address. First, access the container using the following command:

docker exec -it <container id> /bin/bash

Then, from inside the container, execute the script:

/get_loki_address.sh

Now the .loki address will be shown. If a client connects to this .loki address, the website will be shown.

Debugging

If the .loki address cannot be reached after a few minutes, try removing the ./lokinet/var_lib_lokinet/nodedb directory and the ./lokinet/var_lib_lokinet/profiles.dat and restart the container(s).

Conclusion

It is possible to host a website on lokinet using docker. A Dockerfile and docker-compose.yml were the only configuration files needed. To host other kinds of services on lokinet, just add another container in the docker-compose.yml file and it will be hosted on lokinet.