Fishy Words


Urbit on NixOS

Urbit is a experimental networked operating system. It’s currently built in layers of C, Nock, then Hoon.

These aren’t the most secure languages, and the project is still in development. So you should be careful that the urbit server could be hacked.

Here’s the setup I’m using to ensure a compromised urbit server is contained using both low privilege user and a systemd container.

[user@nixos:~]$ tree /srv/urbit/
/srv/urbit/
├── someship-faster/ # ship folder
└── urbit-binary/
    └── .run

2 directories, 1 file

Ensure the folder is read/writable and the binary is executable by the urbit group.

# local service
systemd.services."urbit-run" = {
  enable = true;
  description = "local urbit instance";
  unitConfig = { Type = "forking"; };
  wantedBy = [ "multi-user.target" ];
  wants = [ "network-online.target" ];
  after = [ "network-online.target" ];
  serviceConfig = {
      ExecStart = "/srv/urbit/my-ship/.run --ames-port 4050 --http-port 6060 --https-port 5050 --no-tty --quiet";
      ExecStop  = "/srv/urbit/my-ship/.run --no-tty --exit";
      User = "urbit"; Group = "urbit";

      # limited access to files
      ReadWritePaths = "/srv/urbit/";
      ReadOnlyPaths = [ "/etc/hosts" "/etc/resolv.conf" ];

      # prevent other access to system
      DeviceAllow = []; NoNewPrivileges = "true"; ProtectControlGroups = "true";
      ProtectClock = "true"; PrivateDevices = "true"; PrivateUsers = "true";
      ProtectHome = "true"; ProtectHostname = "true"; ProtectKernelLogs = "true";
      ProtectKernelModules = "true"; ProtectKernelTunables = "true";
      ProtectProc = "invisible"; RemoveIPC = "true"; RestrictSUIDSGID = "true";
      RestrictRealtime = "true";
  };
};


# reverse proxy
services.nginx.virtualHosts."someship.website.com" = {
  http2 = false; forceSSL = true; enableACME = true;
  locations."/" = {
    proxyWebsockets = true;
    proxyPass = "http://127.0.0.1:6060";
    extraConfig = ''
        proxy_set_header Host $host;
        proxy_set_header Forwarded for=$remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        chunked_transfer_encoding off;
        proxy_buffering off;
        proxy_cache off;
        proxy_redirect default;
        proxy_redirect http://127.0.0.1:6060 https://someship.website.com;
      '' + "proxy_set_header Connection '';";
  };
};

# users and groups
users.groups.urbit = {};
users.users.urbit = { isSystemUser = true; group = "urbit"; };

External References