bholland84
Posts: 10
Joined: Tue Mar 14, 2017 3:43 am

Using transmission over a VPN

Mon Mar 04, 2019 4:25 am

Hello all. I wanted to provide the means to use the raspberry pi 3 as a transmission server over a VPN. This includes a kill switch using ip tables. This is fairly complex so I included a markdown file describing exactly what I did to make using transmission to torrent over a VPN work.

Feel free to provide feedback for the document.

BTW, I have to give a huge shoutout and thank you to the kernel team. They made this very easy. I didn't have to recompile the kernel to get iptables to work, which was awesome. This will work with the latest build of Jessey.


Torrent Over a VPN on a Raspberry Pi 3

This document will describe how to safely torrent on a Rpi3 using a VPN and
kill switch. I would
like to especially thank the kernel team at the raspberry pi organization. The
Rpi3 kernel is spectacular and makes a lot of this possible, particularly with
the iptables mangling and routing. Having done something similar on another
platform, I can only express the sheer joy I have at making this work. Well
done.

Getting this to work is a tricky problem for a few reasons. The first is that
pi users will find that the 1GB ram limit is quite restrictive. The second is
that users will probably want to use a bare mettle solution rather than
something using and interpreter for speed improvements and ram limitations.
Lastly, the kernel setup for iptables is non-trivial. The RPi kernel team has
done an excellent job at making this as simple as possible.

This document is going to describe how to configure and set up a RPi 3 to run a
torrent server over a VPN from bare metal and go through each script in detail.
This might be a bit too advanced for some users but hopefully this is going to
demystify a lot of the difficulty.

Setup and Configuration

The configuration requires the following:

1. A VPN username and login. I prefer NordVPN. I tried others and they simply didn't work.
2. The transmission client
3. A kernel with iptables, the mangle operator, and routing
4. A VPN connection called NordVPN (anything really but this guide assumes a connection that you create in network manager called NordVPN).
This guide does not get into the specifics of how to configure and set it up but other guides do.

Transmission

This section will show you how to install and configure transmission. This is my
preferred torrent manager. It is very fast, lightweight, has a remote option,
comes with a web server, and is entirely written in C++ so it runs without an
interpreter.

What this does not do is run off of a single networking interface. For example,
something like Deluge can sort of run listen only to tun0, but it doesn't work
well and is very misleading.

This section will discuss the following:

1. Install transmission
2. Create a transmission user
3. Set up the startup scripts to run transmission as the user
4. Set up scripts to run before starting transmission

Install Transmission

This will install transmission.

Code: Select all

sudo apt install transmission-daemon
Create a transmission User
This will create a transmission user. Users must create a separate user to run
transmission. This is typically done for security reasons but also because
this user will have separate packet routing for the kill switch.

**NOTE: Make sure that the transmission user has full access to the transmission
download directory.**

Code: Select all

sudo adduser transmission
You do not have to call this user transmission but please note that whatever
name you chose will have to be the name that you use in each of the scripts.

Transmission Startup Scripts

The latest version of Ubuntu uses systemctl to manage all of the init scripts.
Many of the solutions that you will find online assume that it uses init.d or
even init. I believe Ubuntu 16.04 switched to systemctl but it probably happened
earlier.

Ubuntu places all of the systemctl scripts in /lib/systemd/system/. They are
called {Service Name}.service. The transmission startup script is:

emacs /lib/systemd/system/transmission-daemon.service

Open up this file and modify it so it looks like this.

Code: Select all

    [Unit]
    Description=Transmission BitTorrent Daemon
    After=network.target safe-transmission.service
    
    [Service]
    User=transmission
    Type=notify
    ExecStart=/usr/bin/transmission-daemon -f --log-error
    ExecStop=/bin/kill -s STOP $MAINPID
    ExecReload=/bin/kill -s HUP $MAINPID
    
    [Install]
    WantedBy=multi-user.target
    
The really important line here is to add `safe-transmission.service` in the
the `After=` line. The safe-transmission.service is a startup script that you
will create that will run before the transmission startup scripts.

The second really important line is that the service should run under the
transmission user. That is what the line `User=transmission` does.

Create the safe-transmission.service Startup Script

This service will run a bash script called `/usr/bin/safe_transmission.sh`
as root user.

Create the service with:

Code: Select all

sudo emacs /lib/systemd/system/safe-transmission.service

and populate it with

Code: Select all

    [Unit]
    Description=Setup the VPN and routing for the transmission user
    Wants=network-online.target
    After=network.target network-online.target networking.service
    
    [Service]
    User=root
    Type=notify
    ExecStart=/usr/bin/safe_transmission.sh
    ExecReload=/bin/kill -s HUP $MAINPID
    
    [Install]
    WantedBy=multi-user.target
There are three important things to note here:

1. `User=root`: this will run the script as root user
2. `After=network.target network-online.target`
1. `network.target`: the very lowest level of networking that guarantees that networking is on but not up (eth0 probably doesn't exist)
2. `network-online.target`: ensures that networking is up and active
3. `networking.service`: probably not needed but doesn't hurt
3. `Wants=network-online.target`: this will make sure that the network is up and active

Initialize safe-transmission.sh

The next step is to make sure that systemctl knows to start the script. To do so

cd /lib/systemd/system/
sudo systemctl enable safe-transmission.service

**NOTE: I assume that you need to be in the /lib/systemd/system folder to run
the systemctl enable command but I am not entirely sure.**

Create the /usr/bin/safe_transmission.sh shell script

Remember that the safe-transmission.service simply calls the shell script. This
will get executed before the transmission-daemon service starts. The shell script
must exist within the /usr/bin directory due to how drives get mounted.

Code: Select all

emacs /usr/bin/safe_transmission.sh
and populate it with

Code: Select all

    #! /bin/bash
    if ! /sbin/ifconfig tun0 | grep -q "00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00"; then
        /usr/bin/nmcli con up NordVPN
    fi

    if /sbin/ifconfig tun0 | grep -q "00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00"; then
        VPNIF="tun0"
        VPNUSER="transmission"
        GATEWAYIP=`/sbin/ifconfig tun0 | /bin/egrep -o '([0-9]{1,3}.){3}[0-9]{1,3}' | /bin/egrep -v '-' | /bin/egrep -v ':' | /bin/egrep -v '255|(127.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3})' | /usr/bin/tail -n1`
        if [[ `/sbin/ip rule list | /bin/grep -c 0x1` == 0 ]]; then
              /sbin/ip rule add from all fwmark 0x1 lookup $VPNUSER
        fi

        /sbin/ip route replace default via $GATEWAYIP table $VPNUSER
        /sbin/ip route append default via 127.0.0.1 dev lo table $VPNUSER
        /sbin/ip route flush cache
    fi
    
then make it executable:

Code: Select all

sudo chmod 766 /usr/bin/safe_transmission.sh
Lets go through this one line at a time.

1. `#! /bin/bash`: start up a bash shell
2. `if ! /sbin/ifconfig tun0 | grep -q "00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00"; then`
1. run ifconfig tun0
2. if that returns something with "00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00" then do something
3. "00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00" is the mac address for tun0.
3. `/usr/bin/nmcli con up NordVPN`: this will turn on a connection called NordVPN. This is something you have to configure yourself.
4. `VPNIF="tun0"` and `VPNUSER="transmission"`: sets variables
5. The `GATEWAYIP=`: This should be the **ip address** that gets assigned via tun0. **This is required for the routing. If this is wrong, the default routing will be wrong and you will not be able to get online.**
1. `/sbin/ifconfig tun0`: run ifconfig over tun0. Run this on the command line for the output
2. `/bin/egrep -o '([0-9]{1,3}.){3}[0-9]{1,3}'`: run egrep to find anything that might look like an ip address
3. `/bin/egrep -v '-'`: The -v flag will select the inverse of the pipe. For this, there are a lot of ip's that looks like 00-00-... and we don't want to select it.
4. `/bin/egrep -v ':'`: Some of the ip's can be ipv6. We want to get rid of those too.
5. `/bin/egrep -v '255|(127.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3})'`: There will probably be a netmask. Ignore the netmasks.
6. `/usr/bin/tail -n1`: Multiple ip's might show up. Select the first one.
6. if `/sbin/ip rule list | /bin/grep -c 0x1` == 0 : This will make sure that the masking rule is not added twice
1. `/sbin/ip rule list`: list all of the ip routing rules
2. `/bin/grep -c 0x1`: find anything with the 0x1 bit set. This will come from the iptables mangling rules
3. ` == 0`: if this doesn't exist yet, create it
7. `/sbin/ip rule add from all fwmark 0x1 lookup $VPNUSER`: this will add a routing rule for the lookup table "transmission", which we will make in the next section
8. `/sbin/ip route replace default via $GATEWAYIP table $VPNUSER`: replace the default gateway for the tun0 ip address on the "transmission" ip routing table.
9. `/sbin/ip route append default via 127.0.0.1 dev lo table $VPNUSER`: add the localhost lookup to the "transmission" ip routing table.
10. `/sbin/ip route flush cache`" flush the cache. Do not forget to do this.

Add transmission to the Routing Table:

This is a very important step. Here, we need to create a new routing table for the transmission user. We will call this transmission.

Code: Select all

 sudo emacs /etc/iproute2/rt_tables

and make it look like

Code: Select all

#
    # reserved values
    #
    255     local
    254     main
    253     default
    0       unspec
    #
    # local
    #
    #1      inr.ruhep
    200     transmission
The only line that should change is that you need to add `200 transmission`. Make sure that this name matches the same name in the script above for the `$VPNUSER`.

Summary

We did the following in this section in this order:

1. Installed transmission
2. Edited /lib/systemd/system/transmission-daemon.service to start after safe-transmission.service
3. Created /lib/systemd/system/safe-transmission.service that will run safe_transmission.sh
4. Created /usr/bin/safe_transmission.sh
5. Make safe_transmission.sh into an executable
6. Add a new routing table called transmission

Configure Transmission

Remember, the transmission user will run transmission. There are many transmission configuration files around but:
**The transmission configuration file is /home/transmission/.config/transmission/settings.json**

Before editing the configuration file, make sure that transmission is off. Otherwise, your configuration
will get overwritten and will not save.

Code: Select all

sudo systemctl stop transmission-daemon
My configuration allows remote control over the 192.168.1.* network and has the default user "transmission"

Code: Select all

{
        "alt-speed-down": 50,
        "alt-speed-enabled": false,
        "alt-speed-time-begin": 540,
        "alt-speed-time-day": 127,
        "alt-speed-time-enabled": false,
        "alt-speed-time-end": 1020,
        "alt-speed-up": 50,
        "bind-address-ipv4": "0.0.0.0",
        "bind-address-ipv6": "::",
        "blocklist-enabled": true,
        "blocklist-url": "john.bitsurge.net/public/biglist.p2p.gz",
        "cache-size-mb": 4,
        "dht-enabled": true,
        "download-dir": "/external/downloads",
        "download-queue-enabled": true,
        "download-queue-size": 5,
        "encryption": 2,
        "idle-seeding-limit": 30,
        "idle-seeding-limit-enabled": false,
        "incomplete-dir": "/home/transmission/Downloads",
        "incomplete-dir-enabled": false,
        "lpd-enabled": false,
        "message-level": 1,
        "peer-congestion-algorithm": "",
        "peer-id-ttl-hours": 6,
        "peer-limit-global": 200,
        "peer-limit-per-torrent": 50,
        "peer-port": 51413,
        "peer-port-random-high": 65535,
        "peer-port-random-low": 49152,
        "peer-port-random-on-start": false,
        "peer-socket-tos": "default",
        "pex-enabled": true,
        "port-forwarding-enabled": true,
        "preallocation": 1,
        "prefetch-enabled": true,
        "queue-stalled-enabled": true,
        "queue-stalled-minutes": 30,
        "ratio-limit": 2,
        "ratio-limit-enabled": false,
        "rename-partial-files": true,
        "rpc-authentication-required": false,
        "rpc-bind-address": "0.0.0.0",
        "rpc-enabled": true,
        "rpc-host-whitelist": "",
        "rpc-host-whitelist-enabled": true,
        "rpc-password": "{375a6f9d15e71e5291f4522fcfd24c7805fbc0c5FFmKwW5a",
        "rpc-port": 9091,
        "rpc-url": "/transmission/",
        "rpc-username": "transmission",
        "rpc-whitelist": "127.0.0.1,192.168.1.*",
        "rpc-whitelist-enabled": true,
        "scrape-paused-torrents-enabled": true,
        "script-torrent-done-enabled": false,
        "script-torrent-done-filename": "",
        "seed-queue-enabled": false,
        "seed-queue-size": 10,
        "speed-limit-down": 100,
        "speed-limit-down-enabled": false,
        "speed-limit-up": 100,
        "speed-limit-up-enabled": false,
        "start-added-torrents": true,
        "trash-original-torrent-files": false,
        "umask": 18,
        "upload-slots-per-torrent": 14,
        "utp-enabled": true
    }
iptables Settings

This is the last part of this whole process. At this point, we have set up everything we need to
make all packets that are marked with a 0x1 flag to route through the transmission table, which
we then move only through the tun0 VPN connection.

In this step, we are going to mangle every package that comes from the transmission uesr, including
all of the packets that comes from the transmission application because the transmission-daemon
gets run under the transmission user.

Here is the script that will configure the iptables rules:

Code: Select all

#! /bin/bash

    export INTERFACE="tun0"
    export VPNUSER="transmission"
    export LANIP="192.168.1.0/24"
    export NETIF="eth0"

    iptables -F -t nat
    iptables -F -t mangle
    iptables -F -t filter

    # mark packets from $VPNUSER
    iptables -t mangle -A OUTPUT ! --dest $LANIP -m owner --uid-owner $VPNUSER -j MARK --set-mark 0x1
    iptables -t mangle -A OUTPUT --dest $LANIP -p udp --dport 53 -m owner --uid-owner $VPNUSER -j MARK --set-mark 0x1
    iptables -t mangle -A OUTPUT --dest $LANIP -p tcp --dport 53 -m owner --uid-owner $VPNUSER -j MARK --set-mark 0x1
    iptables -t mangle -A OUTPUT ! --src $LANIP -j MARK --set-mark 0x1

    # allow responses
    iptables -A INPUT -i $INTERFACE -m conntrack --ctstate ESTABLISHED -j ACCEPT

    # let $VPNUSER access lo and $INTERFACE
    iptables -A OUTPUT -o lo -m owner --uid-owner $VPNUSER -j ACCEPT
    
    # let all traffic out over the VPN
    iptables -A OUTPUT -o $INTERFACE -m owner --uid-owner $VPNUSER -j ACCEPT

    # all packets on $INTERFACE needs to be masqueraded
    iptables -t nat -A POSTROUTING -o $INTERFACE -j MASQUERADE

    #SSH - DO NOT REMOVE.
    iptables -A INPUT -p tcp --dport 22 -j ACCEPT
    iptables -A OUTPUT -p tcp --dport 22 -j ACCEPT

    # LAN
    iptables -A INPUT -s 192.168.0.0/16 -j ACCEPT
    iptables -A OUTPUT -s 192.168.0.0/16 -j ACCEPT

    iptables-save > /etc/iptables/rules.v4
    ip6tables-save > /etc/iptables/rules.v6
Details for this script

This section explains the details of the script.

1. `export INTERFACE="tun0"`: This sets your VPN interface. OpenVPN uses tun0. Set this as needed
2. `export VPNUSER="transmission"`: This sets the VPNUSER variable to transmission. Change this to whatever user will run the transmission-daemon application
3. `export LANIP="192.168.1.0/24"`: Set your lan network with associated netmask. Typical values are 192.168.1.0/24 and 192.168.0.0/24.
4. `export NETIF="eth0"`: set the interface to read and write to. f
5. `iptables -F -t nat`: flush all nat rules (delete them from the nat table)
6. `iptables -F -t mangle`: flush all mangle rules (delete from the mangle table)
7. `iptables -F -t filter`: flush all filter rules (delete from the filter table)
8. `iptables -t mangle -A OUTPUT ! --dest $LANIP -m owner --uid-owner $VPNUSER -j MARK --set-mark 0x1`
1. `iptables -t mangle`: use the mangle table
2. `-A OUTPUT`: for all outgoing packets
3. `! --dest $LANIP`: where the destination is **not (the !)** to any of the LAN ip addresses
4. `-m owner --uid-owner $VPNUSER`: where the owner is the the transmission user
5. `-j MARK --set-mark 0x1`: mark the packet with a 0x1
9. `iptables -t mangle -A OUTPUT --dest $LANIP -p udp --dport 53 -m owner --uid-owner $VPNUSER -j MARK --set-mark 0x1`
1. do the same thing but for the udp protocall over port 53 for DNS
10. `iptables -t mangle -A OUTPUT --dest $LANIP -p tcp --dport 53 -m owner --uid-owner $VPNUSER -j MARK --set-mark 0x1`: I do the same thing but for the tcp protocall over port 53 for DNS
11. `iptables -t mangle -A OUTPUT ! --src $LANIP -j MARK --set-mark 0x1`: I added this for testing. This will mark all packets for all users with a 0x1 mark.
12. `iptables -A INPUT -i $INTERFACE -m conntrack --ctstate ESTABLISHED -j ACCEPT`: If the connection is already established, then it is fine
13. `iptables -A OUTPUT -o lo -m owner --uid-owner $VPNUSER -j ACCEPT`: Allow the transmission user access to localhost
14. `iptables -A OUTPUT -o $INTERFACE -m owner --uid-owner $VPNUSER -j ACCEPT`: All all outbound traffic over the VPN
15. `iptables -t nat -A POSTROUTING -o $INTERFACE -j MASQUERADE`: I will be honest here, I don't know what this does but it is needed. I spent a long time trying to figure out what hte MASQUERADE option does and I couldn't figure it out.
16. `iptables -A INPUT -p tcp --dport 22 -j ACCEPT`: regardless of everything, allow ssh to recieve
17. `iptables -A OUTPUT -p tcp --dport 22 -j ACCEPT`: and send
18. `iptables -A INPUT -s 192.168.0.0/16 -j ACCEPT`: accept everything from the LAN
19. `iptables -A OUTPUT -s 192.168.0.0/16 -j ACCEPT`: accept everything from the LAN
20. `iptables-save > /etc/iptables/rules.v4`: save all of the rules to v4 so that they don't get deleted on reboot
21. `ip6tables-save > /etc/iptables/rules.v6`: save all of the rules to v6 so that they don't get deleted on reboot


Resources

This closely follows the document below but deviates in signifcant ways. Still
though, this is a very good start and helped me out a lot.

* https://www.niftiestsoftware.com/2011/0 ... interface/

A stack exchange talking about how to set up a service after networking is on and up

* https://unix.stackexchange.com/question ... as-started

madjo1983
Posts: 10
Joined: Sat Jan 20, 2018 12:39 pm

Re: Using transmission over a VPN

Thu Jul 04, 2019 2:43 pm

Hi,

Where sould the script

Code: Select all

#! /bin/bash

    export INTERFACE="tun0"
    export VPNUSER="transmission"
    export LANIP="192.168.1.0/24"
    export NETIF="eth0"

    iptables -F -t nat
    iptables -F -t mangle
    iptables -F -t filter

    # mark packets from $VPNUSER
    iptables -t mangle -A OUTPUT ! --dest $LANIP -m owner --uid-owner $VPNUSER -j MARK --set-mark 0x1
    iptables -t mangle -A OUTPUT --dest $LANIP -p udp --dport 53 -m owner --uid-owner $VPNUSER -j MARK --set-mark 0x1
    iptables -t mangle -A OUTPUT --dest $LANIP -p tcp --dport 53 -m owner --uid-owner $VPNUSER -j MARK --set-mark 0x1
    iptables -t mangle -A OUTPUT ! --src $LANIP -j MARK --set-mark 0x1

    # allow responses
    iptables -A INPUT -i $INTERFACE -m conntrack --ctstate ESTABLISHED -j ACCEPT

    # let $VPNUSER access lo and $INTERFACE
    iptables -A OUTPUT -o lo -m owner --uid-owner $VPNUSER -j ACCEPT
    
    # let all traffic out over the VPN
    iptables -A OUTPUT -o $INTERFACE -m owner --uid-owner $VPNUSER -j ACCEPT

    # all packets on $INTERFACE needs to be masqueraded
    iptables -t nat -A POSTROUTING -o $INTERFACE -j MASQUERADE

    #SSH - DO NOT REMOVE.
    iptables -A INPUT -p tcp --dport 22 -j ACCEPT
    iptables -A OUTPUT -p tcp --dport 22 -j ACCEPT

    # LAN
    iptables -A INPUT -s 192.168.0.0/16 -j ACCEPT
    iptables -A OUTPUT -s 192.168.0.0/16 -j ACCEPT

    iptables-save > /etc/iptables/rules.v4
    ip6tables-save > /etc/iptables/rules.v6
be written into ?
I'm not sure to understand this part of the tutorial.

Cheers,
O.

madjo1983
Posts: 10
Joined: Sat Jan 20, 2018 12:39 pm

Re: Using transmission over a VPN

Wed Jul 17, 2019 7:02 am

Gentle reminder.

Madaeng
Posts: 6
Joined: Tue Jun 11, 2019 6:15 pm
Location: Netherlands

Re: Using transmission over a VPN

Mon Jul 22, 2019 7:59 pm

madjo1983 wrote:
Thu Jul 04, 2019 2:43 pm
Hi,

Where sould the script

Code: Select all

#! /bin/bash

    export INTERFACE="tun0"
    export VPNUSER="transmission"
    export LANIP="192.168.1.0/24"
    export NETIF="eth0"

    iptables -F -t nat
    iptables -F -t mangle
    iptables -F -t filter

    # mark packets from $VPNUSER
    iptables -t mangle -A OUTPUT ! --dest $LANIP -m owner --uid-owner $VPNUSER -j MARK --set-mark 0x1
    iptables -t mangle -A OUTPUT --dest $LANIP -p udp --dport 53 -m owner --uid-owner $VPNUSER -j MARK --set-mark 0x1
    iptables -t mangle -A OUTPUT --dest $LANIP -p tcp --dport 53 -m owner --uid-owner $VPNUSER -j MARK --set-mark 0x1
    iptables -t mangle -A OUTPUT ! --src $LANIP -j MARK --set-mark 0x1

    # allow responses
    iptables -A INPUT -i $INTERFACE -m conntrack --ctstate ESTABLISHED -j ACCEPT

    # let $VPNUSER access lo and $INTERFACE
    iptables -A OUTPUT -o lo -m owner --uid-owner $VPNUSER -j ACCEPT
    
    # let all traffic out over the VPN
    iptables -A OUTPUT -o $INTERFACE -m owner --uid-owner $VPNUSER -j ACCEPT

    # all packets on $INTERFACE needs to be masqueraded
    iptables -t nat -A POSTROUTING -o $INTERFACE -j MASQUERADE

    #SSH - DO NOT REMOVE.
    iptables -A INPUT -p tcp --dport 22 -j ACCEPT
    iptables -A OUTPUT -p tcp --dport 22 -j ACCEPT

    # LAN
    iptables -A INPUT -s 192.168.0.0/16 -j ACCEPT
    iptables -A OUTPUT -s 192.168.0.0/16 -j ACCEPT

    iptables-save > /etc/iptables/rules.v4
    ip6tables-save > /etc/iptables/rules.v6
be written into ?
I'm not sure to understand this part of the tutorial.

Cheers,
O.
Same here. Everywhere TS indicates code, he also points out where to save it to, except for this one.

Zanstel
Posts: 30
Joined: Thu Jul 18, 2019 9:05 am

Re: Using transmission over a VPN

Mon Jul 22, 2019 8:26 pm

madjo1983 wrote:
Thu Jul 04, 2019 2:43 pm
be written into ?
I'm not sure to understand this part of the tutorial.

Cheers,
O.
If you notice, the end of the script creates the files /etc/iptables/rules.v4 and /etc/iptables/rules.v6

This files contains the rules to be restored by iptables-persistent

So I guess you need to install this package
sudo apt-get install iptables-persistent

And create this script and run as root one time.

I guess this is it.

Akopian
Posts: 1
Joined: Sat Sep 21, 2019 9:43 am

Re: Using transmission over a VPN

Sat Sep 21, 2019 9:48 am

Hi! Thanks for the tutorial. It was a bit hard to follow but I got it to work. One problem though. The Nordvpn server I chose has recently been removed and even though the "nmcli con up NordVPN" command fails, the transmission service starts normally. Is there an easy way to check that the connection has been established successfully before starting the service? Thanks.

Return to “Networking and servers”