Skip to content

Instantly share code, notes, and snippets.

@Zamana
Last active March 19, 2025 13:49
Show Gist options
  • Save Zamana/4b8021d79f626d5cf656926aa465a652 to your computer and use it in GitHub Desktop.
Save Zamana/4b8021d79f626d5cf656926aa465a652 to your computer and use it in GitHub Desktop.
AirDC++ WebClient in FreeBSD/FreeNAS jail

Compiling and installing AirDC++ on FreeBSD/TrueNAS jail

First of all, make sure to refer and understand the general instructions in the official AirDC++ site:

https://airdcpp-web.github.io/docs/installation/compiling.html

http://airdcpp.net/docs/compiling/compiling.html

What you'll find here are the specific instructions to compile airdcppd on a FreeBSD system, or on a TrueNAS jail.

This was originally tested in a FreeNAS-11.3-U4.1, which uses FreeBSD 11.3-RELEASE-p11 as base system.

UPDATE: it was retested in TrueNAS CORE 12.0-U5.1 and it is working fine.

UPDATE 2022/11: it was retested in TrueNAS-13.0-U3.1 and it is working fine!

UPDATE 2024/02: our friend Freeben666 used this guide in a 13.2-p10 jail and it's still working fine!

1. Update your packages:

pkg update
pkg upgrade

2. Install the dependencies and tools:

pkg install git cmake libmaxminddb miniupnpc pkgconf libnatpmp leveldb websocketpp boost-all python npm

Note: from version 3 onwards, you'll also need the nlohmann-json package:

pkg install nlohmann-json

Thank you marius137!

3. Clone the repository:

git clone https://github.com/airdcpp-web/airdcpp-webclient.git

4. Enter in the source-code folder and compile it:

cd airdcpp-webclient
cmake .
make -j2

Tip

In the command above, "-j2" refers to the number of threads that you want to use to compile the source code. If you have more vCPUs (cores), you can increase this number accordingly, like "-j4" or "-j8" etc.

If everything ran fine, you'll find the airdcppd binary in the airdcppd folder. So it's time to install the whole shebang:

make install

5. Init script to start airdcppd automagically at system/jail boot

Here is my script:

#!/bin/sh

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

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

. /etc/rc.subr

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

: ${airdcppd_enable:="NO"}
: ${airdcppd_user:="root"}
: ${airdcppd_group:="root"}

pidfile="/var/run/airdcppd/airdcppd.pid"

command="/usr/local/bin/airdcppd"
command_args="-d -c=/home/${airdcppd_user}/.airdc++ -p=${pidfile}"

run_rc_command "$1"

Save it under the name airdcppd and copy to /usr/local/etc/rc.d with 755 permissions.

6. Service configuration

1. Decide and create the user/group under which the service will run. In my specific case:

pw group add plex -g 118
pw user add plex -u 111
pw user mod plex -m /home/plex

2. Create the folder to store the PID file, with the appropriate permissions:

mkdir /var/run/airdcppd
chown plex:plex /var/run/airdcppd

3. Configure the service to run automagically at system/jail boot, according with your setup. In my specific case:

sysrc airdcppd_enable=YES
sysrc airdcppd_user=plex
sysrc airdcppd_group=plex

7. First run: configuration

Now, refer back to the original documentation, and look for "Configure and run". You'll need to run the program once via command line with the "--configure" switch in order to set up ports and user accounts.

su plex
airdcppd --configure
exit

And at this point you should be able to control the service with:

service airdcppd start | stop | status | restart

And finally, decide and configure the folders you'll want to share and download the files. This is important if you are using jails, because in this case you'll need to configure the bindings (mounting points). Refer to the FreeNAS documentation regarding this.

Now the service should be accessible through:

http://<jail|freebsd IP>:5600

8. Bonus: reverse proxy

If you want to avoid the ":5600" in the URL, you can use a reverse proxy.

Here is my specific configuration for nginx, using http://airdc.lan as address. As I have an internal DNS (unbound), I prefer to have an URL for each application. Feel free to adapt to your scenario:

server {
        listen       80;
        server_name  airdc.lan;

        location / {
                proxy_pass http://<IP_ADDR>:5600;
                gzip_types text/plain application/javascript;
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "upgrade";
                proxy_set_header Authorization "";
                proxy_redirect off;
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP       $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        }

        location /api/v1 {
                proxy_pass http://<IP_ADDR>:5600/api/v1;
                gzip_types text/plain application/javascript;
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "upgrade";
                proxy_set_header Authorization "";
                proxy_redirect off;
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP       $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }

    }

Note: change the <IP_ADDR> with your actual IP address.

Now you can point your DNS (or hosts file) to the IP of your reverse proxy server (or directly to the IP of you Airdc++ installation if you decided to install the reverse proxy in the same environament) and point your browser to http://airdc.lan (or to the address you chose).


Feel free to point out any mistakes I made, including misspellings, typos and grammar errors.

Happy AirDC++ing.

@Freeben666
Copy link

Hi !

Thanks a lot for this guide.

Quick note though: pw user mod -m /home/plex should be pw user mod plex -m /home/plex

Regards

@Zamana
Copy link
Author

Zamana commented Feb 16, 2022

Fixed!

Thank you!

@kuzmos
Copy link

kuzmos commented Aug 29, 2022

Kudos for this. Tested on TrueNAS-13.0-U1.1 and all works flawlessly.

@Freeben666
Copy link

I used this again to do an upgrade of my Airdcpp-web running in a 13.2-p10 jail, worked without a hitch 👌

@Zamana
Copy link
Author

Zamana commented Feb 25, 2024

Hello!

Thank you very much for the feedback. It's very much appreciated.

Regards.

@Freeben666
Copy link

Freeben666 commented Feb 25, 2024

Hello!

Thank you very much for the feedback. It's very much appreciated.

Regards.

You're welcome. You went through the trouble of publishing this guide, least I can do is give some feedback ;-)

One thing I'd improve : in step 4 I'd advise people to adjust the number of threads used by the compiler. The command you give is set for 2 threads (make -j2). In my case, having 16 vCPU for my TrueNAS VM, I used make -j16 and it is much faster.

Regards

@Zamana
Copy link
Author

Zamana commented Feb 25, 2024

Done!

Thanks again.

@Freeben666
Copy link

Hello !

I'm having a hard time compiling v2.12.2 inside a 13.3-p4 jail. Anyone also having trouble ?

@Freeben666
Copy link

If anyone had some trouble with 13.3, the bug has been fixed (only in the develop branch at the moment)

airdcpp-web/airdcpp-webclient#478

@marius137
Copy link

nlohmann-json is missing from install dependencies

@Zamana
Copy link
Author

Zamana commented Oct 1, 2024

nlohmann-json is missing from install dependencies

Hi!

Indeed:

Build: the nlohmann JSON library is no longer included with the source (new build dependency)

Source

@gunnarrt
Copy link

gunnarrt commented Dec 7, 2024

Compiled the newest 2.13.2 master with thread fix on 13.3 followed this guide. Missing dependencies now are

Missing dependencies: openssl

@darkstar
Copy link

darkstar commented Mar 19, 2025

trying to compile this in 13.5 gives an error:

/root/airdcpp-webclient/airdcpp-core/airdcpp/core/crypto/CryptoManager.cpp:514:14: error: no matching function for call to 'X509_STORE_CTX_get_current_cert'
  514 |         if ((cert = X509_STORE_CTX_get_current_cert(ctx)) != NULL) {
      |                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/openssl/x509_vfy.h:497:7: note: candidate function not viable: 1st argument ('const X509_STORE_CTX *' (aka 'const x509_store_ctx_st *')) would lose const qualifier
  497 | X509 *X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx);
      |       ^                               ~~~~~~~~~~~~~~~~~~~
1 error generated.
--- airdcpp-core/CMakeFiles/airdcpp.dir/airdcpp/core/crypto/CryptoManager.cpp.o ---
*** [airdcpp-core/CMakeFiles/airdcpp.dir/airdcpp/core/crypto/CryptoManager.cpp.o] Error code 1

make[2]: stopped in /root/airdcpp-webclient/build
1 error

seems it needs this patch:

iff --git a/airdcpp-core/airdcpp/core/crypto/CryptoManager.cpp b/airdcpp-core/airdcpp/core/crypto/CryptoManager.cpp
index e38df313..f8bae4ae 100644
--- a/airdcpp-core/airdcpp/core/crypto/CryptoManager.cpp
+++ b/airdcpp-core/airdcpp/core/crypto/CryptoManager.cpp
@@ -509,7 +509,7 @@ int CryptoManager::verify_callback(int preverify_ok, X509_STORE_CTX *ctx) {

 }

-string CryptoManager::formatError(const X509_STORE_CTX *ctx, const string& message) {
+string CryptoManager::formatError(X509_STORE_CTX *ctx, const string& message) {
        X509* cert = NULL;
        if ((cert = X509_STORE_CTX_get_current_cert(ctx)) != NULL) {
                X509_NAME* subject = X509_get_subject_name(cert);
diff --git a/airdcpp-core/airdcpp/core/crypto/CryptoManager.h b/airdcpp-core/airdcpp/core/crypto/CryptoManager.h
index 1568e596..58665d48 100644
--- a/airdcpp-core/airdcpp/core/crypto/CryptoManager.h
+++ b/airdcpp-core/airdcpp/core/crypto/CryptoManager.h
@@ -101,7 +101,7 @@ private:
                return (b == 0 || b==5 || b==124 || b==96 || b==126 || b==36);
        }

-       static string formatError(const X509_STORE_CTX *ctx, const string& message);
+       static string formatError(X509_STORE_CTX *ctx, const string& message);
        static string getNameEntryByNID(X509_NAME* name, int nid) noexcept;

        void loadKeyprint(const string& file) noexcept;

It also needs to be configured with -DIconv_IS_BUILT_IN:BOOL=OFF, i.e.

cmake ..  -DIconv_IS_BUILT_IN:BOOL=OFF

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