Skip to content

Instantly share code, notes, and snippets.

@Zamana
Last active February 5, 2023 21:34
Show Gist options
  • Save Zamana/01ef240521f7b7c68baae10c57d89604 to your computer and use it in GitHub Desktop.
Save Zamana/01ef240521f7b7c68baae10c57d89604 to your computer and use it in GitHub Desktop.

verlihub

Verlihub NMDC server on FreeBSD/TrueNAS jail

First of all, make sure to refer and understand the general instructions from the official Verlihub documentation:

https://github.com/Verlihub/verlihub/wiki/Installation

What you'll find here are the specific instructions to compile Verlihub in a FreeBSD system, or in a TrueNAS jail. I'm considering that you already have a FreeBSD system or a jail ready to use. FreeBSD installation or jail creation will not be covered here.

This was originally tested in a TrueNAS-13.0-U3.1, which uses FreeBSD 13.1-RELEASE-p4 as base system.

1. Update your packages

Update your packages catalog and upgrade them, if necessary:

pkg update
pkg upgrade

2. Install packages

Install the packages necessary for the compilation process and execution:

pkg install \
gcc \
cmake \
mysql80-server \
openssl \
zlib-ng \
pcre \
icu \
libmaxminddb \
gettext \
lua54 \
python \
libgcrypt \
bash \
cdialog \
libysinfo

3. Get the source code and compile it

Get the latest sources from Verlihub project's github.

At this time the latest version is 1.4.0.0:

fetch https://github.com/Verlihub/verlihub/archive/refs/tags/1.4.0.0.tar.gz

Extract it:

tar xvfz 1.4.0.0.tar.gz

Note: instead of fetching the tarball, you can use git to clone the repository if you want; the final product will be the same. In order to use git, you'll need to install it first, if you don't have it yet, of course.

Now, enter in the folder where the package was extracted (or cloned) and execute:

cd verlihub-1.4.0.0
mkdir build
cd build
cmake ..

The ERROR regarding the PythonLibs will be addressed later. Move on for now...

and if everything ran fine, run:

make

Any error at these last two points will indicate an incomplete set of packages. Check what you have done.

If everything still ran fine, install the whole shebang:

make install

Following the FreeBSD structure, you'll find the "binaries" in /usr/local/share/verlihub and the configuration files in /usr/local/etc/verlihub.

4. Configuration

Before start the configuration process per se, it's necessary some adjustments.

Configure MySQL to run at the boot, and start the process:

sysrc mysql_server_enable=YES
service mysql-server start

Secure your MySQL installation by running mysql_secure_installation.

Regardless of your choices, you'll need to at least define the MySQL root password if you do not did it yet:

mysqladmin -u root password -p

IMPORTANT

  1. You can run Verlihub as root or as a regular user. If you decide to run as root (not recommended), you can configure the hub to listen at default port 411, but if you decide to use a regular user, you'll need to choose a port above 1024, like 4111, for example.

In this guide I'll follow the recommended way of using a regular user and port 4111. So...

  1. Verlihub allows the installation of several hub instances. In this guide I'm convering the installation of just one instance, in the "default" (by FreeBSD conventions) folder "/usr/local/<application>". If you want to have more than one instance, run each configuration session pointing to a different folder, and adapt the rc init script accordingly. You'll not find these details here, though.

Check Wiejak comments for more details


Create a user/group under which you want the Verlihub run. For example:

pw add user plex

Now run the installation and configure it as you like (follow Setup and Deploying a Hub for a reference), remembering to choose a port above 1024.

vh_gui --install

and give permissions for this user to the Verlihub configuration folder:

chown -R plex /usr/local/etc/verlihub

Now, in order to control the start/stop/status and configuration of Verlihub, you can use the ncurses/dialog interface:

To start:

su plex -c "vh_gui -r"

To get the status:

su plex -c "vh_gui -t"

To stop:

su plex -c "vh_gui -s"

or the command line interface:

To start:

su plex -c "vh -r /usr/local/etc/verlihub" 

To get the status:

su plex -c "vh -t /usr/local/etc/verlihub" 

To stop:

su plex -c "vh -s /usr/local/etc/verlihub" 

Again, refer to the official documentation about this.

IMPORTANT

In order to make your hub available externaly, you'll need to enable NAT and write firewall rules to allow incoming connections from internet to your local network. This configuration is beyond the scope of this article and will not be covered here. I'm sorry.

5. Starting Verlihub at boot

To start Verlihub at boot, create a file named /usr/local/etc/rc.d/verlihub with the following content:

#!/bin/sh

#
# Author: C. R. Zamana (czamana at gmail dot com)
#

#
# PROVIDE: verlihub
# REQUIRE: LOGIN network mysql
# KEYWORD: shutdown

. /etc/rc.subr

name="verlihub"
rcvar="${name}_enable"
load_rc_config ${name}

: ${verlihub_enable:="NO"}
: ${verlihub_user:="root"}
: ${verlihub_bin:="/usr/local/bin/vh"}
: ${verlihub_conf:="/usr/local/etc/verlihub"}

PATH=$PATH:/usr/local/bin

procname=${verlihub_bin}

start_cmd=${name}_start
stop_cmd=${name}_stop
status_cmd=${name}_status

verlihub_start() {
        su ${verlihub_user} -c "${verlihub_bin} -r ${verlihub_conf}"
}

verlihub_stop() {
        su ${verlihub_user} -c "${verlihub_bin} -s ${verlihub_conf}"
}

verlihub_status() {
        su ${verlihub_user} -c "${verlihub_bin} -t ${verlihub_conf}"
}


run_rc_command "$1"

Set the execution permission to this file:

chmod +x /usr/local/etc/rc.d/verlihub

and configure it to run at boot under the user created previously:

sysrc verlihub_enable=YES
sysrc verlihub_user=plex

From now on you can manage Verlihub process with service verlihub start | stop | status.

6. Bonus

6.1. GeoIP database

If you want to use the GeoIP feature, install these packages:

pkg install  \
wget \
gtar \
geoipupdate

Change the tar symbolic link from bsdtar to gtar:

ln -sf /usr/local/bin/gtar /usr/bin/tar

NOTE: this is necessary because the tar command that FreeBSD provides natively doesn't handle wildcards...

Create an account at MAXMIND and put your license key in /usr/local/share/geoipupdate/GeoIP.conf:

mkdir /usr/local/share/geoipupdate
echo "<your license>" > /usr/local/share/geoipupdate/GeoIP.conf
chown -R plex /usr/local/share/geoipupdate

then run this command to update the database as root:

vh -g

and reload Verlihub as the regular user. For example:

su plex -c "vh -R"

You can also do this from your cliente, connected to your hub:

!reload

If you want to automate this process, the suggestion is to put these commands in a crontab, running once in a month. For example:

# update the geoip database
0 0 1 * * /usr/local/bin/vh --geoip >/dev/null

# and five minutes later, reload Verlihub
5 0 1 * * /usr/bin/su plex -c "/usr/local/bin/vh --reload" >/dev/null

6.2. TLS Proxy

A TLS proxy is a gateway for a Transport Layer Security (TLS) connection, which is a protocol that provides communications security over a computer network. A TLS proxy server protects against denial-of-service (DoS) attacks and other security threats.

Refer to TLS Proxy for more details.

For FreeBSD, things go like this...

Install the go language package:

pkg install go

Get the TLS proxy source code from the official repository.

At the time I'm writing, the latest version is 0.0.3.0:

fetch https://github.com/Verlihub/tls-proxy/archive/refs/tags/0.0.3.0.tar.gz

As usual, you can also get the source code by cloning the repository with git.

Extract the package if you get it with fetch, and enter in the folder just created:

cd tls-proxy-0.0.3.0

Then, compile it:

set CGO_ENABLED=0 && go build -ldflags "-libgcc=none" -tags netgo proxy.go

If everything ran fine, you'll find a proxy binary in the folder. Success!

Copy proxy to /usr/local/bin:

cp proxy /usr/local/bin

Generate a self signed certificate:

openssl req -new -newkey rsa:4096 -x509 -sha256 -days 365 -nodes -out "hub.crt" -keyout "hub.key"

and decide where to put the files hub.crt and hub.key. I suggest to put them inside the Verlihub configuration folder, but that's your call.

Create a file /usr/local/etc/rc.d/proxy to get it running at boot:

#!/bin/sh

#
# Author: C. R. Zamana (czamana at gmail dot com)
#

#
# PROVIDE: proxy
# REQUIRE: LOGIN network
# KEYWORD: shutdown

. /etc/rc.subr

name="proxy"
rcvar="${name}_enable"
load_rc_config ${name}

: ${proxy_enable:="NO"}
: ${proxy_bin:="/usr/local/bin/proxy"}
: ${proxy_cert:="/usr/local/etc/verlihub/hub.crt"}
: ${proxy_key:="/usr/local/etc/verlihub/hub.key"}
: ${proxy_host:="0.0.0.0:4111"}
: ${proxy_hub:="127.0.0.1:4111"}

pidfile=/var/run/${name}

procname=${proxy_bin}

command="/usr/sbin/daemon"
command_args="-f -p ${pidfile} ${procname} -cert=${proxy_cert} --key=${proxy_key} --host=${proxy_host} --hub=${proxy_hub}"

run_rc_command "$1"

Now, there are some variables that you should configure before you can run this script. You can follow what is suggested by default in the script, but at the minimum least you'll need to define the IPs and ports where you want to run the proxy and the hub.

By default, the hub should be listening on localhost only, and the proxy should be listening on all or at least the public interface of your system, so it can be reached from outside the host itself.

Anyway, here is an example of how you can configure these variables:

sysrc proxy_enable=YES
sysrc proxy_cert="/usr/local/etc/verlihub/hub.crt"
sysrc proxy_key="/usr/local/etc/verlihub/hub.key"
sysrc proxy_host="192.168.0.119:4111"
sysrc proxy_hub="127.0.0.1:4111"

Explaining:

  • proxy_cert should point to where you decided to save the hub.crt file;
  • proxy_key should point to where you decided to save the hub.key file;
  • proxy_host should point to the IP:PORT of your public (non-loopback) interface
  • proxy_hub should point to the loopback:PORT where Verlihub will listen

Use this as a reference and feel free to change the paths/IPs/ports as you like.

Now... if the hub is already running and listening on the non-loopback interface, you need to make the change to the loopback interface first:

So, at your client, run:

!set listen_ip 127.0.0.1
!set listen_port 4111
!set tls_proxy_ip 127.0.0.1

Do this, restart the hub and start the proxy:

service verlihub restart
service proxy start

If everything ran fine, you should see something like this after login into the hub:

(...)
[*] Hub TLS: 1.3
(...)

6.3. Ledokol

Regarding Ledokol, refer to the Ledokol Wiki for more references.

Here is the way to implement it.

First, download the Ledokol plugin from the official Github repository, extract its contents, and copy the files ledo_en.lang and ledoko.lua to the Verlihub's scripts folder. In our example here it would be something like this:

cp ledo_en.lang ledokol.lua /usr/local/etc/verlihub/scripts
chown plex /usr/local/etc/verlihub/scripts/*

Just after installing Verlihub, you'll realize that Plugman (the "plugin manager") is the only plugin loaded. You can check this by:

su plex -c "vh -a"

or executing !pluglist in your DC++ client.

In order to use Ledokol (or any other Lua plugin), you need to load it first. In order to load the plugin at the start of Verlihub, you can use:

su plex -c "vh -n"

and choose the Lua plugin.

Once it's done, restart the Verlihub process:

service verlihub restart

Now, connect to your hub and run !pluglist. You'll see that now you have the Lua plugin listed. And you can check that Ledokol is loaded by using the client command !lualist.

In order to effectively use Ledokol, refer to its documentation.

7. Plugins and the case of Python 2 and 3

At the cmake .. phase you must have realized that the Python plugin wasn't compiled because the system was unable to find the PythonLibs:

(...)
-- Could NOT find PythonLibs (missing: PYTHON_LIBRARIES PYTHON_INCLUDE_DIRS) (Required is at least version "2.7")
-- [ ER ] Not building python plugin due to unsatisfied dependencies
(...)

This issue regarding the PythonLibs can be circumvented if you "help" cmake to find them, this way:

cmake .. \
-DPYTHON_INCLUDE_DIR=$(python -c "from distutils.sysconfig import get_python_inc; print(get_python_inc())") \ 
-DPYTHON_LIBRARY=$(python -c "import distutils.sysconfig as sysconfig; print(sysconfig.get_config_var('LIBDIR'))")

Or, if you want to be more elegant, you can use a script, like this:

#!/bin/sh

include_dir=$(python -c "from distutils.sysconfig import get_python_inc; print(get_python_inc())")
library_dir=$(python -c "import distutils.sysconfig as sysconfig; print(sysconfig.get_config_var('LIBDIR'))")

cmake .. -DPYTHON_INCLUDE_DIR=$include_dir -DPYTHON_LIBRARY=$library_dir

and the result will be:

(...)
-- Found PythonLibs: /usr/local/lib (found suitable version "3.9.16", minimum required is "2.7")
-- [ OK ] Building python plugin
(...)

Unfortunately, even elegantly helping cmake to find the libraries and include folders will not be enough, because the plugins were written using some functions from Python 2.x era that are now deprecated.

Unfortunately, again, I don't have the technical knowledge to port the code, but if you have this knowledge and want to help the community, this of course would be very much appreciated. If you want, do this workaround and try to compile Verlihub again: you'll see some warnings and errors that will prevent the system to be compiled.

Anyway, the Python plugin isn't necessary to run the hub; it is only used for some specific scripting and you can live without it.

8. Conclusion

I hope that this guide will help someone, not only to get the Verlihub running, but also to spread the FreeBSD use and knowledge.

I'm open to criticisms and suggestions in order to improve this article, including grammar and spelling errors.

Happy Verlihubing!

@Zamana
Copy link
Author

Zamana commented Feb 5, 2023

@Zamana , FreeBSD have limitations that lock non-root user starting ports lower or equal to 1024 like modern debian linux does?

Yes. There are ways to circumvent this, but it is not recommended.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment