? Editing: Post:21.body Save Delete Cancel
Content changed Sign & Publish new content

Skw's Blog

Some notes on Linux and functional programming

Follow in NewsfeedFollowing

Latest comments:

Enabling Native OpenSSL in ZeroNet on NixOS

on Mar 08, 2019

Since my last post, the ZeroNet devs have added support for checking the LD_LIBRARY_PATH environment variable. This means we can add the location of our native OpenSSL library to it to achieve optimal performance.

Setting it is pretty easy; all we need to do is override the postFixup phase of the zeronet package, which is where the shell wrapper is created:

postFixup = ''
  makeWrapper "$out/share/zeronet.py" "$out/bin/zeronet" \
    --set PYTHONPATH "$PYTHONPATH" \
    --set PATH ${pkgs.python2Packages.python}/bin \
    --set LD_LIBRARY_PATH ${pkgs.openssl_1_0_2.out}/lib
'';

The only difference between ours and the normal one is that we added that LD_LIBRARY_PATH line, and we prefixed the variable referenced in PATH with pkgs. since we're not inside nixpkgs.

All together, with the current commit info, our override looks like this:

nixpkgs.config.packageOverrides = pkgs: rec {
  zeronet = pkgs.lib.overrideDerivation pkgs.zeronet (attrs: rec {
    buildInputs = with pkgs; [ openssl_1_0_2 ] ++ attrs.buildInputs;
    version = "0.6.5-git";
    src = pkgs.fetchFromGitHub {
      owner = "HelloZeroNet";
      repo = "ZeroNet";
      rev = "1ad44ace0ad178b3f5c514774441f6c3e20eb795";
      sha256 = "02qkj3ilmxvls4c9wxcpf55psnbm1mfjczgg2mxcv42yyz6c1zgc";
    };
    postFixup = ''
      makeWrapper "$out/share/zeronet.py" "$out/bin/zeronet" \
        --set PYTHONPATH "$PYTHONPATH" \
        --set PATH ${pkgs.python2Packages.python}/bin \
        --set LD_LIBRARY_PATH ${pkgs.openssl_1_0_2.out}/lib
    '';
  });
};

Now, when you go to the benchmark page, you should see something like

- openssl verify x 100..........0.053s [x6.97: Insane!!]

instead of

- openssl verify x 100...not avalible :(
Read more

Zeronet over Tor on NixOS

on Feb 23, 2019

NixOS

For those who don't know, NixOS (warning: clearnet link) is a GNU/Linux distro with a pretty radical twist:
the package manager is declarative rather than imperative.

The implications of this might not be immediately obvious, so I'll quickly break them down here:

  • The entire system is managed by a single tool, using a pure-functional language. Even the installer is controlled by it.
  • The configuration of a system (and the binaries on the system!) can be versioned, so rolling back to a previous version is trivial.
  • Configuration versioning also means you can create a new version without switching to it. This is super useful for testing new settings.
  • Upgrades are atomic, meaning the whole upgrade is completed without ever entering an inconsistent state, so failed upgrades are always safe.
  • Packages can be installed per-user, so multiuser systems are both more convenient and safer than on traditional GNU/Linux systems.

So you can see NixOS's approach is very powerful. However, this power doesn't come for free. One major downside to this model is in how it has to be implemented: NixOS cannot use standardized paths for many files. This has performance implications for ZeroNet discussed in the known issues below.

Configuring Tor

In NixOS, packages can define services which can be enabled by the user. These services can in turn define options to modify the behavior of the service. The package for Tor defines a pretty powerful set of options we can use to set it up securely:

{ config, pkgs, ... }:
{
  services.tor = {
    enable = true;
    client = {
      enable = true;
      socksIsolationOptions = [
        "IsolateClientAddr" "IsolateSOCKSAuth"
        "IsolateClientProtocol" "IsolateDestPort"
        "IsolateDestAddr"
      ];
      socksPolicy = "accept 127.0.0.0/24";
    };
    controlSocket = {
      enable = true;
    };
  };
}

This enables the tor service, then enables the tor.client with extensive connection isolation, and a socksPolicy that only allows connections from local IPs (I have a virtual machine on my box, which is why it's not just 127.0.0.1/32). This connection is used by the Tor Browser Bundle when connecting to non-zeronet resources.
Next, we enable the tor.controlSocket, which used by ZeroNet to connect to the Tor network.

It's that simple! Just save configuration.nix and run nixos-rebuild switch, and Nix takes care of everything for us.

Configuring ZeroNet

ZeroNet is slighty more complex to get going, since the package hosted in nixpkgs tends to lag behind live by a fair bit.

The first thing we need to do is override the version of ZeroNet in nixpkgs so we can pull from the repo ourselves, without waiting for nixpkgs to catch up.

There are 2 ways to do this: the safe, manual way, and the unsafe, automatic way.

The safe way first:

{ config, pkgs, ... }:
{
  nixpkgs.config.packageOverrides = pkgs: rec {
    zeronet = pkgs.lib.overrideDerivation pkgs.zeronet (attrs: rec {
      buildInputs = with pkgs; [ openssl_1_0_2 ];
      version = "0.6.5-git";
      src = pkgs.fetchFromGitHub {
        owner = "HelloZeroNet";
        repo = "ZeroNet";
        rev = "174e8d3c19e4dbe53bdab95db0aa3de416249df3";
        sha256 = "0bbmjbz36nlf7il0ph2i7s32jnlxq2v0wc8nxi4aaqxns8qy2jkf";
      };
    });
  };
}

The downside of this is that we need to monitor the ZeroNet repo for changes, and calculate update the rev and hash manually. the upside is that it lets us verify that the version we're updating to is safe before running the update.

Now, the unsafe way:

{ config, pkgs, ... }:
{
  nixpkgs.config.packageOverrides = pkgs: rec {
    zeronet = pkgs.lib.overrideDerivation pkgs.zeronet (attrs: rec {
      buildInputs = with pkgs; [ openssl_1_0_2 ];
      version = "git-master";
      src = fetchGit {
        url = "https://github.com/HelloZeroNet/ZeroNet";
      };
    });
  };
}

This way is unsafe for 2 reasons:

  1. It uses the undocumented fetchGit builtin without specifying an expected hash or revision. This means we cannot verify that sources were downloaded correctly when updating. Additionally, Nix will upgrade ZeroNet even when we do not pass --upgrade to nixos-rebuild, so we have no control over the version being used.
  2. It does not allow us to verify the code is safe before updating.

The advantage is that it's a set and forget solution.

Now that we've told NixOS to grab the correct version of ZeroNet, we need to enable and configure the service:

{ config, pkgs, ... }:
{
  services.zeronet = {
    enable = true;
    tor = true;
    torAlways = true;
    port = 43110;
  };
}

This tells ZeroNet to run on localhost:43110, and to always use Tor. It turns out that we don't need to do any further configuration here, since the default settings are pretty sane.

Now we just run nixos-rebuild switch, and ZeroNet should become available on localhost:43110. Easy!

Known Issues

In order to achieve versioning and atomic upgrades, the Nix package manager uses a "store" to hold all the installed files. Each package, configuration file, service, etc. gets its own folder in the store, prefixed by a hash. Since these paths are unpredictable from a program's point of view, there's no way to find things like dependencies. Fortunately, Nix provides us with a fix for most cases: the installer will automatically patch binaries using patchelf so they reference the correct libraries. Unfortunately, this doesn't work in every case: non-binary files (like python scripts) are not handled automatically by the installer. Since ZeroNet uses the system OpenSSL, it will fail to find it and fall back to a slower pure-python implementation of openssl verify.

This can be confirmed by navigating to the benchmark page:

CryptBitcoin:
- hdPrivatekey x 10..........0.091s [x7.72: Insane!!]
- sign x 10..........0.177s [x1.98: Fast]
- openssl verify x 100...not avalible :(
- pure-python verify x 10..........0.129s [x12.36: Insane!!]

This issue is being tracked here (warning: clearnet link).

Read more
Add new post

Title

21 hours ago · 2 min read ·
3 comments
Body
Read more

Not found

Title

21 hours ago · 2 min read

0 Comments:

user_name1 day ago
Reply
Body
This page is a snapshot of ZeroNet. Start your own ZeroNet for complete experience. Learn More