All Categories
  • 1st Steps
  • Authentication
  • Branding
  • Changelogs
  • Collaboration
  • Compliance
  • Customization
  • Desktop Client
  • External Storage
  • Frequently Asked Questions
  • Installation
  • Migrations
  • Mobile Clients
  • Nextcloud Context Chat
  • Nextcloud Flow (Windmill integration)
  • Nextcloud Talk
  • Operations
  • Partner Products
  • Roundcubemail
  • Scalability
  • Security
  • Setup Instructions for the Talk HPB

    This document contains instructions on how to install the different services for a Talk High Performance Backend.

    You can also find more information on the Nextcloud Portal at https://portal.nextcloud.com/categories/Partner-Products/Talk-High-Performance-Backend

    Installation

    Packages are provided for the following operating systems (64 bit):

    • Ubuntu Noble (24.04)
    • Ubuntu Jammy (22.04)
    • Ubuntu Focal (20.04)
    • Debian Trixie (13)
    • Debian Bookworm (12)
    • Debian Bullseye (11)
    • Red Hat Enterprise Linux 9
    • Red Hat Enterprise Linux 8
    • SUSE Linux Enterprise Server 16
    • SUSE Linux Enterprise Server 15

    Use online repository

    For customers there is an online repository that can be added to the local APT sources. Installing from there is recommended to automatically get new versions of the various components.

    Once you have received your unique customer id, open the repository website at https://packages.struktur.de/nextcloud/spreed/ to get the configuration for your system.

    Enter your customer id, select the distribution and follow the steps described on the website to activate the repository.

    Use tarball (Ubuntu / Debian only)

    To use the the release tarball, copy the repository folder to the server and create a file /etc/apt/sources.list.d/nextcloud-spreed-repository.list with the following contents:

    deb [arch=amd64, signed-by=/path/to/repository/struktur-ag-deb-sign-1.pub] file:///path/to/repository/ubuntu dist main
    

    Replace dist with focal, noble, trixie, etc. depending on the distribution you are using and update the path to the signing key and the repository.

    It's recommended to use the online repository instead as with the release tarball, all future updates must be uploaded and installed manually on the server.

    Install packages

    There are two deployment methods supported by the repository:

    • Run both the signaling server and the Janus WebRTC gateway on the same machine. This is recommended for small to medium sized setups. Install the meta-package nextcloud-spreed-services-full for this scenario.

    • Run the signaling server on one machine and the Janus WebRTC gateway on a different machine (or optionally on multiple machines). This is recommended for large setups. Install the meta-package nextcloud-spreed-services-signaling on the machine of the signaling server and the meta-package nextcloud-spreed-services-proxy on the machine(s) that will be running the Janus WebRTC gateway behind a signaling proxy.

    Refer to the configuration section for further details on the additional setup.

    The SIP bridge can be installed independently using the meta-package nextcloud-spreed-services-sipbridge. See below for information on setting up the SIP bridge.

    Package installation differs depending on the operating system.

    Debian / Ubuntu

    Make sure you have enabled the universe repository of your distribution or do so if not enabled yet:

    apt-add-repository universe
    

    Now the package lists can be updated and the packages installed:

    apt-get update
    apt-get install nextcloud-spreed-services-full
    

    Red Hat Enterprise Linux

    Make sure the EPEL repository is enabled.

    Afterwards install the packages:

    dnf install nextcloud-spreed-services-full
    

    On first installation, the package signing key must be confirmed if it was not installed manually before.

    SUSE Linux Enterprise Server

    Install the packages:

    zypper install nextcloud-spreed-services-full
    

    On first repository refresh, the package signing key must be confirmed if it was not installed before.

    Configuration

    Some services are automatically configured, others need additional manual configuration to run.

    Preliminaries

    Before starting to setup the services, the following must be available:

    • Nextcloud Talk must be installed with version 3.2.4 or newer.

    • An IP address that can be reached by all potential users of the service. If some participants will be connecting from the internet, this must be a public IP address.

    • A DNS server that can lookup external addresses (for STUN to work), including the address of the Nextcloud installation.

    • A valid webserver setup, including HTTPS on the server that will host the standalone signaling server, see section webserver certificate for further information.

    • Firewalls and routing must be configured so the services can connect to each other, see section network setup for further information.

    Network setup

    The various services must be able to communicate with each other, therefore some network configuration might need to be adjusted depending on the firewall or routing that is in use in the datacenter.

    Required connections:

    • From all potential users to the IP address of the server hosting the signaling server. This usually requires configuration on firewalls and routing in case the server is a virtual machine with an internal private IP.

    • From the server to the external hostname of the Nextcloud server. If the two installations are on different machines, this might require firewall and/or routing changes.

    • Outgoing STUN connections must be possible to stun.nextcloud.com port 3478 (both TCP and UDP). If possible, the connection should be allowed by hostname, not by IP address in case this changes in the future.

    In addition, the server must be able to resolve external hostnames (for STUN), including the hostname of the Nextcloud installation.

    Connection overview for cases where Nextcloud is running on the same machine:

                       ¦
          Internet ◄── ¦ ──► Server hosting Nextcloud and Talk services
                       ¦
                       ¦                                 (Nextcloud and the
                       ¦    ┌───────────┐                 signaling server connect
                       ¦    │ Nextcloud │ ◄────────────┐  through the frontend
                       ¦    └───────────┘              │  webserver with each other,
                       ¦          ▲                    │  i.e. their public URL)
                       ¦          │                    │
                       ¦          │                    ▼
    ┌─────────────┐    ¦    ┌───────────┐        ┌───────────┐
    │ Participant │ ───¦──► │ Webserver │ ─────► │ Signaling │
    │    (Web)    │    ¦    │   HTTPS   │        │ server    │
    └─────────────┘    ¦    └───────────┘        └───────────┘
           ▲           ¦                               │
           │           ¦                               │
           │           ¦    ┌───────────┐              │
           └───────────¦──► │  WebRTC   │ ◄────────────┘
                       ¦    │  Gateway  │
                       ¦    └───────────┘
                       ¦
    

    Connection overview for cases where Nextcloud is running on a separate machine:

                       ¦
          Internet ◄── ¦ ──► Server hosting Talk services
                       ¦
                       ¦
    ┌─────────────┐    ¦
    │  Nextcloud  │ ◄──¦──────────┐
    └─────────────┘    ¦          │
           ▲           ¦          │
           │           ¦          │
           │           ¦          ▼
    ┌─────────────┐    ¦    ┌───────────┐        ┌───────────┐
    │ Participant │ ───¦──► │ Webserver │ ◄────► │ Signaling │
    │    (Web)    │    ¦    │   HTTPS   │        │ server    │
    └─────────────┘    ¦    └───────────┘        └───────────┘
           ▲           ¦                               │
           │           ¦                               │
           │           ¦    ┌───────────┐              │
           └───────────¦──► │  WebRTC   │ ◄────────────┘
                       ¦    │  Gateway  │
                       ¦    └───────────┘
                       ¦
    

    The network setup can be verified by

    • pinging the hostname of the signaling server from external machines (simulating participants connecting to the server)
    • using curl to load the welcome page from the signaling server (see section frontend webserver for details)
    • resolving the hostname of Nextcloud from the server running the signaling server (e.g. host nextcloud.domain.invalid)
    • pinging the hostname of the Nextcloud installation from the machine running the signaling server
    • using curl to load a Nextcloud page from the machine running the signaling server (e.g. curl -i https://nextcloud.domain.invalid)

    Network setup with multiple WebRTC gateways

    If the Janus WebRTC gateway is hosted on one or multiple separate machines, the signaling server must be able to access these through a WebSocket connection on TCP port 443 (HTTPS).

    Connection overview for cases where multiple WebRTC gateways are used:

                       ¦                                       ¦
          Internet ◄── ¦ ──────►   Server hosting the  ◄────── ¦ ──► Server hosting
                       ¦            signaling server           ¦    a WebRTC gateway
                       ¦                                       ¦
                       ¦                                       ¦
    ┌─────────────┐    ¦                                       ¦
    │  Nextcloud  │ ◄──¦──────────┐                            ¦
    └─────────────┘    ¦          │                            ¦
           ▲           ¦          │                            ¦
           │           ¦          │                            ¦
           │           ¦          ▼                            ¦
    ┌─────────────┐    ¦    ┌───────────┐      ┌───────────┐   ¦
    │ Participant │ ───¦──► │ Webserver │ ◄──► │ Signaling │ ──¦──────────┐
    │    (Web)    │    ¦    │   HTTPS   │      │ server    │   ¦          │
    └─────────────┘    ¦    └───────────┘      └───────────┘   ¦          ▼
           ▲           ¦                                       ¦    ┌───────────┐
           │           ¦                                       ¦    │ Webserver │
           │           ¦                                       ¦    │   HTTPS   │
           │           ¦                                       ¦    └───────────┘
           │           ¦                                       ¦          │
           │           ¦                                       ¦          ▼
           │           ¦                                       ¦    ┌───────────┐
           │           ¦                                       ¦    │ Signaling │
           │           ¦                                       ¦    │   Proxy   │
           │           ¦                                       ¦    └───────────┘
           │           ¦                                       ¦          ▲
           │           ¦                                       ¦          │
           │           ¦                                       ¦          ▼
           │           ¦                                       ¦    ┌───────────┐
           └──────────────────────────────────────────────────────► │  WebRTC   │
                       ¦                                       ¦    │  Gateway  │
                       ¦                                       ¦    └───────────┘
                       ¦                                       ¦
    

    See above on how to verify the network setup. In addition, the server running the signaling proxy must be reachable by the server running the signaling server.

    Used ports / protocols:

    • The signaling server runs behind a webserver which performs SSL offloading. Clients (and Nextcloud itself) will connect using HTTPS (WebSocket / POST) on TCP port 443.
    • The signaling proxy runs behind a webserver which performs SSL offloading. The signaling server will connect using HTTPS (WebSocket) on TCP port 443.
    • The Janus WebRTC gateway will listen for connections from the signaling proxy on the local interface (WebSocket).
    • The clients will connect to the Janus WebRTC gateway using UDP on randomly negotiated ports as configured (see below). The packets will be encrypted using DTLS and SRTP.

    Janus WebRTC Gateway

    Janus will be preconfigured with the following settings:

    • Use a newly generated keypair and certificate for DTLS.
    • Listen only on the local interface on port 8188 for WebSocket connections.
    • Use ports 20000 to 40000 for RTP.
    • Ignore interfaces vmnet* and docker* when generating ICE candidates.
    • Use stun.nextcloud.com as STUN server.
    • All unnecessary plugins, transports and event handlers are disabled.

    Logs will be available through journalctl:

    journalctl --unit janus
    

    Only log messages since last reboot:

    journalctl --unit janus --boot
    

    Firewall

    Depending on the networking environment, the firewall may need additional configuration so the various services can reach each other and can be accessed by (external) users.

    • Nextcloud and the signaling server communicate using HTTPS (TCP on port 443). Connections are established in both directions (Nextcloud to the signaling server and the signaling server to Nextcloud) and are using the hostnames to reach each other.
    • External users connect to the signaling server using HTTPS (TCP on port 443). The HTTPS connection must be upgradable to a WebSocket connection. Depending on the setup this is either the same webserver as Nextcloud (if both are running on the same machine), or the webserver running on the dedicated machine for the signaling server and WebRTC gateway.
    • External users communicate with the WebRTC gateway using negotiated ports (TCP/UDP). Incoming connections (users -> gateway) are connecting to a port in the range of 20000-40000 for RTP (configurable, see above). Outgoing connections (gateway -> users) are using any port provided by the client of the user.
    • The signaling server and the WebRTC gateway are communicating through the local interface, so no configuration should be necessary to allow this.
    • The WebRTC gateway must be able to reach the STUN server stun.nextcloud.com through TCP/UDP on port 3478. This is used to get the external IP address.
    • All services must be able to resolve hostnames through the locally configured DNS server.
    • If a firewall is in front of Janus, it must be setup to do 1:1 NAT and the public address must be configured in Janus (see below).
    • If one or multiple signaling proxy servers are used, they must be reachable from the signaling server using HTTPS (TCP on port 443).
    • If a TURN server is set up, external users communicate with the TURN server using TURN (UDP and/or TCP on port 443, 3478 or other, depending on the configuration; for coTURN it can be specified using listening-port parameter). The TURN server acts as an external user towards the WebRTC gateway, so incoming connections (TURN server -> gateway) connect to a UDP port in the range 20000-40000 (configurable, see above), and outgoing connections (gateway -> TURN server) connect to a UDP port in the range 49152-65535 (configurable; for coTURN it can be specified using min-port and max-port parameters).

    Running Janus behind a 1:1 NAT

    If Janus is running behind a 1:1 NAT that maps all ports on the public address to the local address (e.g. Amazon EC2), the public address of the server must be configured in /etc/janus/janus.jcfg.

    Uncomment the line

    #nat_1_1_mapping = "1.2.3.4"
    

    to

    nat_1_1_mapping = "1.2.3.4"
    

    and replace 1.2.3.4 with the public address of the server.

    Make sure to restart janus afterwards:

    service janus restart
    

    Running Janus in a DMZ

    If Janus is running in a DMZ between two firewalls and with different external and internal IP addresses, you might need to setup two public addresses. Both firewalls must be configured to do 1:1 NAT (see above).

                    ┌──────────┐     ┌───────────┐     ┌──────────┐
     Internet  ◄──► │ External │ ◄─► │  WebRTC   │ ◄─► │ Internal │ ◄──► Intranet
    External IP     │ Firewall │     │  Gateway  │     │ Firewall │     Internal IP
                    └──────────┘     └───────────┘     └──────────┘
    

    Uncomment the line

    #nat_1_1_mapping = "1.2.3.4"
    

    to

    nat_1_1_mapping = "1.2.3.4,5.6.7.8"
    

    and replace 1.2.3.4 with the external address of the server and 5.6.7.8 with the internal address of the server. The parameter nat_1_1_mapping supports any number of (comma-separated) external addresses.

    Make sure to restart janus afterwards:

    service janus restart
    

    Standalone signaling service

    Make sure to restart the signaling server after settings have been modified:

    service nextcloud-spreed-signaling restart
    

    Logs will be available through journalctl:

    journalctl --unit nextcloud-spreed-signaling
    

    Only log messages since last reboot:

    journalctl --unit nextcloud-spreed-signaling --boot
    

    Common settings

    The standalone signaling service will be preconfigured with the following settings:

    • Listen only on the local interface on port 8088.
    • Connect to the Janus WebRTC Gateway on ws://localhost:8188.
    • A maximum bandwidth of 1 MBit/s is used for each audio/video stream and 2 MBit/s for screensharing streams.

    In addition to the automatic configuration, some manual settings are required to the file /etc/nextcloud-spreed-signaling/server.conf:

    • In section backend-1, the base URL that is running Nextcloud and where the signaling server is allowed to connect to must be entered as value for url.
    • Generate a random string (e.g. using openssl rand -hex 32) to be used as shared secret and enter as value for secret in section backend-1.
    • Multiple Nextcloud backends are supported by adding new sections [backend-X] with url and secret and listing the ids in the value backends of section backend above.
    • If a self-signed certificate is used on the Nextcloud backend, skipverify must be set to true.
    • The signaling server will be running behind a webserver like nginx or Apache, so the settings in section https do not need to be configured.

    Using an external Janus WebRTC gateway behind a signaling proxy service

    After installing the nextcloud-spreed-services-signaling package, the signaling server must be configured with information about the signaling proxy server(s) to connect to.

    A keypair is required for the signaling server to authenticate against the proxy server:

    $ openssl genrsa -out /etc/nextcloud-spreed-signaling/server.key 2048
    $ openssl rsa -in /etc/nextcloud-spreed-signaling/server.key \
        -pubout -out /etc/nextcloud-spreed-signaling/server.pub
    

    Ensure that the generated key is either owned by nextcloud-spreed-signaling or can be read by that user.

    Open the file /etc/nextcloud-spreed-signaling/server.conf and adjust the following settings in section [mcu]:

    • The type must be set to proxy.
    • The token_id must be set to a unique id for this signaling server.
    • The token_key must be set to the filename (including path) of the private key generated above.

    There are two ways to setup the list of proxy servers to use:

    • Configure static list of proxy server URLs in the signaling server.

      • Set urltype to static.
      • Set url to a space-separated list of proxy server URLs.
      • The service nextcloud-spreed-signaling supports reloading if the list of URLs has changed. This will dynamically add / remove proxy servers.
    • Dynamically fetch available proxy server URLs from an etcd cluster.

      • Set urltype to etcd.

      • Set keyprefix to the key prefix where server addresses are stored in the cluster.

      • Adjust the other etcd-related settings according to the etcd cluster. See the comments in the installed file for further information. Both a static list of endpoints and automatic detection through DNS SRV is supported. If TLS authentication should be used, the corresponding entries must be set.

      • The signaling server will watch the key prefix and add / remove proxy servers if entries are added / removed / changed in the etcd cluster.

      • New entries can be stored with etcdctl of etcd, e.g.:

        $ etcdctl put /signaling/proxy/server/proxy01 \
            '{"address":"https://proxy-01.domain.invalid/"}'
        

    When a user starts publishing, the signaling server selects a proxy server for the stream based on the geographic location of the user (if available) and the current number of streams on the different proxies. The proxy with the lowest number of currently active streams in the same country / continent will be used. If the location is unknown or no proxy exists in the same region as the user, the proxy with the lowest number of streams of all available proxies will be used. All subscribers of this publisher will use the same proxy to receive the stream. Different streams in a Nextcloud Talk room might end up on different proxy servers.

    See the configuration file for details on how to configure geo lookups.

    Signaling proxy server

    After installing the nextcloud-spreed-services-proxy package, the proxy server must be configured with information about the signaling servers that are allowed to connect.

    Changes must be done in the file /etc/nextcloud-spreed-signaling/proxy.conf.

    There are two ways to setup the allowed signaling servers:

    • Configure static list of tokens.

      • Set tokentype in section [app] to static.
      • Add entries in section [tokens] where the key is the token_id value of allowed signaling servers and the value the full path to the public key associated with the token_key setting of the signaling server.
      • Ensure the public key is readable by the service, e.g. has 644 rights.
      • The service nextcloud-spreed-signaling-proxy supports reloading if the list of tokens has changed. This will dynamically add / remove allowed servers (but not terminate existing connections).
    • Dynamically fetch tokens of allowed signaling servers from an etcd cluster.

      • Set tokentype in section [app] to etcd.

      • Set keyformat in section [tokens] to the key format where the public key associated with a token can be loaded from the etcd cluster. The variable %s will be replaced with the token_id sent by the signaling server.

      • Adjust the other etcd-related settings according to the etcd cluster. See the comments in the installed file for further information. Both a static list of endpoints and automatic detection through DNS SRV is supported. If TLS authentication should be used, the corresponding entries must be set.

      • New entries can be stored with etcdctl of etcd, e.g.:

        $ cat server.pub | etcdctl put /signaling/proxy/tokens/server1/public-key
        

    If geographic lookups should be used, the country of the proxy server must be configured as country in section [app].

    Clustering of multiple signaling servers

    The signaling server supports a clustering mode where multiple running servers can be interconnected to form a single "virtual" server. This can be used to increase the capacity of the signaling server or provide a failover setup.

    It is important that the backends are configured with the same id on every signaling server.

    backends = backend-1, backend-2
    
    [backend-1]
    ...
    
    [backend-2]
    ...
    

    If signaling proxies are used, their external URL must be configured on each signaling server (i.e. not using localhost / 127.0.0.1), even if they are running on the same machine as the signaling server. This is important so streams published to a signaling server through one proxy can be subscribed from another signaling server.

    Central NATS server for clustering

    For clustering mode, all signaling servers in the cluster must use a central NATS server. The server can be installed from the package gnatsd. The NATS server will asynchronously distribute events (e.g. sessions joining, leaving, etc.) between all servers in the cluster.

    By default, it is only listening on the local interface. Open /etc/default/gnatsd and change GNATSD_SERVICE_ARGS to listen on a public IP instead of the default 127.0.0.1. If the system is using systemd to run services, update the service definition in /lib/systemd/system/gnatsd.service accordingly.

    Make sure to restart the gnatsd service afterwards.

    Refer to the NATS documentation for further options of the NATS server.

    NATS clustering is documented at https://docs.nats.io/running-a-nats-service/configuration/clustering

    Setup of clustered signaling servers.

    After installing the nextcloud-spreed-services-signaling package, open the configuration file at /etc/nextcloud-spreed-signaling/server.conf and setup the URL to the NATS server in section [nats]:

    [nats]
    url = nats://192.168.0.1:4222
    

    The different signaling servers in the cluster communicate using GRPC, which also must be configured in the server.conf in section [grpc]. GRPC is used as protocol so signaling servers can (synchronously) query properties from and call methods on other servers in the cluster.

    Example (static list of nodes, no encryption):

    [grpc]
    listen = 0.0.0.0:7080
    
    # Cluster is using two nodes.
    targets = 192.168.1.1:7080, 192.168.1.2:7080
    

    Instead of having a hardcoded list of GRPC endpoints of signaling servers, DNS names can be configured which will be monitored and the list of resolved IPs will be used as cluster nodes. Connections are established / removed when the list of IPs changes in the DNS server.

    Example (dynamic list of nodes, authenticated and encrypted communication):

    [grpc]
    listen = 0.0.0.0:7080
    
    # GRPC server settings.
    servercertificate = /etc/nextcloud-spreed-signaling/grpc-server.crt
    serverkey = /etc/nextcloud-spreed-signaling/grpc-server.key
    clientca = /etc/nextcloud-spreed-signaling/grpc-client-ca.crt
    
    # GRPC client settings.
    clientcertificate = /etc/nextcloud-spreed-signaling/grpc-client.crt
    clientkey = /etc/nextcloud-spreed-signaling/grpc-client.key
    serverca = /etc/nextcloud-spreed-signaling/grpc-server-ca.crt
    
    # Cluster is using dynamic nodes.
    targets = signaling-nodes-dc1:7080, signaling-nodes-dc2:7080
    dnsdiscovery = true
    

    Refer to /usr/share/nextcloud-spreed-services-signaling/server.conf.spreed for all available options.

    Frontend webserver

    Usually the standalone signaling server is running behind a webserver that does the SSL protocol or acts as a load balancer for multiple signaling servers.

    The configuration examples below assume a pre-configured webserver (nginx or Apache) with a working HTTPS setup, that is listening on the external interface of the server hosting the standalone signaling server.

    After everything has been set up, the configuration can be tested using curl:

    $ curl -i https://myserver.domain.invalid/standalone-signaling/api/v1/welcome
    HTTP/1.1 200 OK
    Date: Thu, 05 Jul 2018 09:28:08 GMT
    Server: nextcloud-spreed-signaling/1.0.0
    Content-Type: application/json; charset=utf-8
    Content-Length: 59
    
    {"nextcloud-spreed-signaling":"Welcome","version":"1.0.0"}
    

    Webserver certificate

    If you don't have a certificate for your webserver running the signaling server yet, you can either create a (temporary) self-signed certificate, buy one from a CA or request one through Let's Encrypt.

    Generate a self-signed certificate (valid for one year):

    openssl req -x509 -nodes -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365
    

    Generate a certificate request to be signed by a CA (enter the hostname of the server as Common Name):

    openssl req -nodes -newkey rsa:4096 -keyout key.pem -out cert.csr
    

    The Let's Encrypt homepage has documentation on how to use and integrate it in different webservers. See https://letsencrypt.org/getting-started/ for further information.

    nginx

    Nginx can be used as frontend for the standalone signaling server without any additional requirements. If it's not available yet, it can be installed using apt install nginx.

    The backend should be configured separately so it can be changed in a single location and also to allow using multiple backends from a single frontend server.

    Assuming the standalone signaling server is running on the local interface on port 8088 below, add the following block to the nginx server definition in /etc/nginx/sites-enabled (just before the server definition):

    upstream signaling {
        server 127.0.0.1:8088;
    }
    

    To proxy all requests for the standalone signaling to the correct backend, the following location block must be added inside the server definition of the same file:

    location /standalone-signaling/ {
        proxy_pass http://signaling/;
        proxy_http_version 1.1;
        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 /standalone-signaling/spreed {
        proxy_pass http://signaling/spreed;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
    

    Example (e.g. /etc/nginx/sites-enabled/default):

    upstream signaling {
        server 127.0.0.1:8088;
    }
    
    server {
        listen 443 ssl http2;
        server_name myserver.domain.invalid;
    
        ssl_certificate /path/to/myserver.domain.invalid.crt;
        ssl_certificate_key /path/to/myserver.domain.invalid.key;
        ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384;
        ssl_protocols TLSv1.2;
        ssl_ecdh_curve secp384r1;
        ssl_prefer_server_ciphers on;
        ssl_session_cache shared:SSL:10m;
        ssl_session_timeout 10m;
        ssl_session_tickets off;
    
        # ... other existing configuration ...
    
        location /standalone-signaling/ {
            proxy_pass http://signaling/;
            proxy_http_version 1.1;
            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 /standalone-signaling/spreed {
            proxy_pass http://signaling/spreed;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "Upgrade";
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
    }
    

    For the signaling proxy server, the following settings can be used:

    upstream proxy {
        server 127.0.0.1:9088;
    }
    
    location /proxy {
        proxy_pass http://proxy;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
    

    See http://nginx.org/en/docs/http/configuring_https_servers.html for further information on setting up nginx with HTTPS.

    If you are running a SELinux enabled distribution, you might need to allow nginx to connect internally to the signaling server (nginx logs the error "(13: Permission denied) while connecting to upstream" otherwise):

    setsebool -P httpd_can_network_connect on
    

    Apache

    To configure the Apache webservice as frontend for the standalone signaling server, the modules mod_proxy_http and mod_proxy_wstunnel must be enabled so WebSocket and API backend requests can be proxied:

    a2enmod headers
    a2enmod proxy
    a2enmod proxy_http
    a2enmod proxy_wstunnel
    a2enmod rewrite
    a2enmod ssl
    

    Now the Apache VirtualHost configuration can be extended to forward requests to the standalone signaling server (assuming the server is running on the local interface on port 8088 below):

    <VirtualHost *:443>
        ServerName myserver.domain.invalid
    
        SSLEngine on
        SSLCertificateFile "/path/to/myserver.domain.invalid.crt"
        SSLCertificateKeyFile "/path/to/myserver.domain.invalid.key"
        SSLCipherSuite ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384
        SSLProtocol TLSv1.2
        SSLHonorCipherOrder on
    
        # ... other existing configuration ...
    
        # Enable proxying Websocket requests to the standalone signaling server.
        ProxyPass "/standalone-signaling/"  "ws://127.0.0.1:8088/"
    
        RequestHeader set X-Real-IP %{REMOTE_ADDR}s
    
        RewriteEngine On
        # Websocket connections from the clients.
        RewriteRule ^/standalone-signaling/spreed$ - [L]
        # Requests to fetch metrics.
        RewriteRule ^/standalone-signaling/metrics$ http://127.0.0.1:8088/metrics [L,P]
        # Backend connections from Nextcloud.
        RewriteRule ^/standalone-signaling/api/(.*) http://127.0.0.1:8088/api/$1 [L,P]
    
        # ... existing configuration ...
    
    </VirtualHost>
    

    See https://httpd.apache.org/docs/2.4/ssl/ssl_howto.html for further information on setting up Apache with HTTPS.

    Setup of Nextcloud Talk app

    Login to your Nextcloud as admin and open the additional settings page. Scroll down to the "Talk" section and enter the base URL of your standalone signaling server in the field "External signaling server". Please note that you have to use https if your Nextcloud is also running on https. Usually you should enter https://myhostname/standalone-signaling/ as URL.

    The value "Shared secret for external signaling server" must be the same as the property secret in section backend-1 of your server.conf configured above.

    If you are using a self-signed certificate for development, you need to uncheck the box Validate SSL certificate so backend requests from Nextcloud to the signaling server can be performed.

    SIP bridge

    The SIP bridge allows a user to dial-in with a regular phone into a room in Nextcloud Talk. An IVR workflow asks for meeting id and participant pin to check access to rooms.

    It's recommended to update to the latest point release of Nextcloud Talk and the also latest version of the signaling server before setting up the SIP bridge.

    Preliminaries

    A SIP gateway is necessary to perform the PSTN <-> SIP bridging. The SIP bridge software connects to the SIP gateway to receive incoming calls.

    Firewall / network setup

    The SIP bridge must be able to connect to the SIP gateway on UDP port 5060 for SIP and the range of ports used for RTP media depending on the setup of the SIP gateway. Also a connection must be possible to the Nextcloud backend and signaling server on TCP port 443 (HTTPS) and to the Janus WebRTC Gateway on the configured list of RTP ports (see above).

    Both the signaling server and the Janus WebRTC Gateway can run on different servers than the SIP bridge.

    The SIP bridge listens on UDP port 5060 for SIP and uses UDP ports 10000-30000 for RTP media (SIP and WebRTC), so these ports must be opened for incoming and outgoing packets.

    DTMF must be sent either as RFC 2833 packets or through SIP INFO. The SIP bridge is not doing inband DTMF detection.

    Connection overview::

                       ¦                                          ¦
          Internet ◄── ¦ ────► Server hosting Talk services ◄──── ¦ ───► SIP Bridge
                       ¦                                          ¦
    ┌─────────────┐    ¦                                          ¦
    │  Nextcloud  │ ◄──¦──────────────────────────────────────────¦────────────┐
    │             │ ◄──¦───────────────────────────────┐          ¦            │
    └─────────────┘    ¦                               │          ¦            │
           ▲           ¦          ┌────────────────────│──────────¦────────┐   │
           │           ¦          │                    │          ¦        │   │
           │           ¦          ▼                    ▼          ¦        │   │
    ┌─────────────┐    ¦    ┌───────────┐        ┌───────────┐    ¦    ┌───────────┐
    │ Participant │ ───¦──► │ Webserver │ ─────► │ Signaling │    ¦    │    SIP    │
    │    (Web)    │    ¦    │   HTTPS   │        │ server    │    ¦    │   Bridge  │
    └─────────────┘    ¦    └───────────┘        └───────────┘    ¦    └───────────┘
           ▲           ¦                               │          ¦        ▲   ▲
           │           ¦                               │          ¦        │   │
           │           ¦    ┌───────────┐              │          ¦        │   │
           └───────────¦──► │  WebRTC   │ ◄────────────┘          ¦        │   │
                       ¦    │  Gateway  │ ◄───────────────────────¦────────┘   │
                       ¦    └───────────┘                         ¦            │
                       ¦                                          ¦            ▼
                       ¦                                          ¦    ┌───────────┐
                       ¦                                          ¦    │    SIP    │
                       ¦                                          ¦    │  Gateway  │
                       ¦                                          ¦    └───────────┘
                       ¦                                          ¦
    

    Installation

    Install the SIP bridge through the package nextcloud-spreed-services-sipbridge which will also install all necessary dependencies including the IVR workflow and German / English voices.

    License generation

    A valid license is required to run the SIP bridge. Use the commandline tool spreed-license-keys to request a new license. Please note that licenses are bound to the hardware they were requested on, so make sure to run the command on the same server that will run the SIP bridge later.

    $ spreed-license-keys request
    spreed-license-keys
    Copyright (c) 2016-2020 struktur AG
    
    Generating license request
    Please enter your name (required):
    Please enter your company:
    Please enter your street (required):
    Please enter your zipcode and city (required):
    Please enter your two-letter country code (required):
    Please enter your phone number:
    Please enter your email address (required):
    
    This is your license request, please send it to sales@struktur.de:
    
    -----BEGIN LICENSE REQUEST-----
    ...some text...
    -----END LICENSE REQUEST-----
    
    The license request has also been saved as /tmp/license-request.txt
    

    Enter the information on the licensee, the license request will be printed (and saved to a file), send it to sales@struktur.de to get the license file.

    License files can be installed with the following command:

    sudo spreed-license-keys install /path/to/license-file.txt
    

    Depending on the installed license, the number of concurrent SIP calls is limited.

    Configuration

    General software configuration is in /etc/sipbridge/server.conf. This includes the list of SIP gateways to SIP REGISTER on. The SIP bridge can also run as SIP trunk and will accept any incoming SIP INVITE sent to it.

    In this file, the URL to the signaling server must be configured (in section nextcloud-spreed as endpoint) together with the internal secret from the signaling server configuration. Make sure to use the value internalsecret from the [clients] section. The URL must contain the complete path to the /spreed endpoint. If the SIP bridge and the signaling server are running on the same machine, you can use ws://localhost:8088/spreed if you are using the default configuration from above.

    By default the SIP bridge will listen on all interfaces, if this should be changed, a comma-separated list of IP addresses can be given in option listen-ips.

    If the SIP bridge runs behind an 1-1 NAT, the external IP can be configured through option external-ip.

    Workflow customizations (e.g. available languages) are available in the file /etc/sipbridge/workflow.conf. The URL to the Nextcloud backend must be configured as NEXTCLOUD_BACKEND_URL. The shared secret for requests between the SIP bridge and Nextcloud must be configured as TALK_SHARED_SECRET. Make sure to use the Shared secret from the SIP configuration section in the Talk admin settings, not the value from the High-performance backend section.

    See the comments in the file for additional information on available options.

    Restart the service spreed-sipbridge to activate any changes.

    Multiple backends for incoming calls

    Multiple Nextcloud backends can be configured in the workflow.conf in option NEXTCLOUD_BACKENDS which is a mapping between a number as sent by the PBX and the backend information to use for incoming calls to this number.

    Make sure to use the exact format that is sent in the username part of the To header for incoming calls. No canonicalization is done on the number before looking up an entry.

    Example:

    NEXTCLOUD_BACKENDS = {
      # All calls to "sip:12345678@sipgw.domain.invalid" will use this backend.
      "12345678": {
        "nextcloud-url": "https://nextcloud.domain.invalid",
        "talk-shared-secret": "sip-secret-from-talk-admin",
        "signaling-url": "wss://server.domain.invalid/signaling/spreed",
        "signaling-internal-secret": "the-random-internal-secret",
      },
    }
    

    If no matching entry is found in the mapping, the default backend will be used.

    Numbers in the mapping may also contain a trailing * wildcard which will match all numbers starting with the number prefix:

    NEXTCLOUD_BACKENDS = {
      # All incoming calls with a prefix of "234567" will use this backend,
      # i.e. calls to "sip:23456789@sipgw.domain.invalid",
      # "sip:23456765@sipgw.domain.invalid", etc.
      '234567*': {
        "nextcloud-url": "https://nextcloud.domain.invalid",
        "talk-shared-secret": "sip-secret-from-talk-admin",
        "signaling-url": "wss://server.domain.invalid/signaling/spreed",
        "signaling-internal-secret": "the-random-internal-secret",
      },
    }
    

    Restart the service spreed-sipbridge to activate any changes.

    SIP registration

    The SIP bridge can register at a SIP gateway to receive incoming calls.

    The endpoint configuration for this looks like the following:

    sip-endpoints:
      sip-provider1:
        hostname: "sipgw.domain.invalid"
        port: 5060
        username: "the-user"
        password: "verysecret"
        auth-username: "optional-different-user-for-register-auth"
    

    Any number of SIP gateways can be configured in the sip-endpoints. The port is optional and will default to 5060 if omitted.

    SIP trunk

    Instead of registering at a SIP gateway, the SIP bridge can act as trunk and will accept any calls that are sent to it through a SIP INVITE.

    The endpoint configuration for this looks like the following:

    sip-endpoints:
      sip-trunk:
        disable-registration: true
    

    If the trunk should also be used for dialing out, a hostname and optionally a port value is required. Other properties are optional, see below for details on dial-out.

    Please note that older versions of the SIP bridge required the hostname, username and password to be configured for trunk endpoints even if their values are not required in some cases. You need to configure dummy values for the service to start in these older versions.

    Dial-out

    Dial-out must be explicitly enabled on the endpoint that should take outgoing calls.

    sip-endpoints:
      dialout-provider:
        hostname: "sip.domain.invalid"
        port: 5060
        username: "the-user"
        password: "verysecret"
        from-username: "the-user-for-dialout"
        allow-dialout: true
        number-prefix: "00"
        replace-prefixes:
          0019876: ""
    

    Set allow-dialout to true (defaults to false). All numbers will be called in the E.164 form without the leading + by default. If this should be changed for a provider, the value number-prefix can be set to the digits to add as prefix. In the example above, +123456789 will be called as 00123456789.

    The configured username will be included in outgoing SIP INVITE requests, when using trunk mode (see above), a valid username might be required so the gateway will accept the outgoing call. A from-username can be configured if the PBX expects a different username for outgoing calls than what is used for registrations.

    To support multiple endpoints, the hostname can return different IP addresses on lookup. In this case, the SIP bridge will try them until an outgoing request could be sent successfully.

    The SIP bridge also supports looking up IP addresses based on DNS NAPTR / SRV records. For this, a hostname must be configured and the port must be set to 0. On outgoing call requests, a DNS NAPTR lookup will be performed and the SIP+D2U service (SIP over UDP) will be used. The service hostnames will be queried through DNS SRV and the SIP bridge will send the call request to the IP address of the received entries.

    If some numbers are connected directly to the SIP endpoint, they might be dialed directly using their extension. For this, replace-prefixes can be configured to strip (or replace) common prefixes of numbers. Please note that this will be evaluated after number-prefix. In the example above +198765432 will be called as 5432.

    Also the nextcloud-spreed configuration block must contain an entry backend with the base URL of Nextcloud.

    Example:

    nextcloud-spreed:
      # URL of signaling server the SIP bridge should connect to.
      endpoint: wss://server.domain.invalid/signaling/spreed
      # Base URL of Nextcloud to send in the signaling server connection request.
      backend: https://nextcloud.domain.invalid
      # Internal secret as configured in the signaling server.
      secret: the-random-internal-secret
    

    You can also configure multiple backends to use a single SIP bridge with different Nextcloud instances:

    nextcloud-spreed:
      - endpoint: wss://server.domain.invalid/signaling/spreed
        backend: https://nextcloud.domain.invalid
        secret: the-random-internal-secret
      - endpoint: wss://other-signaling.domain.invalid/signaling/spreed
        backend: https://other-nextcloud.domain.invalid
        secret: the-other-internal-secret
    

    To prevent abuse, number blocks can be blocked so they can not be dialed. For this, add a new section dialout and add a list of number prefixes as blacklist. The entries in the list will be matched against the unmodified E.164 number without the leading +.

    dialout:
      blacklist:
        - "12345"
        - "49180"
    

    Calling line presentation for outgoing calls (CLIP / CLIR)

    The SIP bridge supports triggering outgoing calls with transmitting a custom caller number (CLIP) or using private mode with anonymous calls (CLIR).

    If configured in Talk, the outgoing call will include the custom caller number assigned to the Nextcloud user in the From header and information on the (SIP) user triggering the call in the P-Asserted-Identity header.

    Anonymous calls are using "Anonymous" <sip:anonymous@anonymous.invalid> as fixed From header and set the Privacy header to id.

    Since version 0.1.13 of the sipbridge.workflow.nextcloud package, the format of the P-Asserted-Identity header can be customized through the setting ASSERTED_IDENTITY_FORMAT in the workflow.conf file:

    Set to None to use the default which uses the username and hostname of the SIP endpoint to dialout (see below).

    Can either be an empty string to omit the header, a fixed string or a string containing formatting placeholders. Please note that a valid header value must be generated, i.e. "Display Name" <sip:username@domain.tld>.

    Available variables for formatting:

    • number: The number to dial as submitted by the user.
    • dialout_number: The number to dial with applied replacements and prefix.
    • from_name: The caller information as submitted by the user (empty for CLIR).
    • sip.username: The username of the SIP endpoint used to dial out.
    • sip.hostname: The hostname of the SIP endpoint used to dial out.
    • sip.from_hostname: The from hostname of the SIP endpoint (if configured).
    • sip.port: The port of the SIP endpoint used to dial out.
    • sip.auth_username: The auth username of the SIP endpoint (if configured).
    • sip.from_username: The from username of the SIP endpoint (if configured).

    Example (default if None is configured):

    '"%(sip.username)s" <sip:%(sip.username)s@%(sip.hostname)s>'
    

    See https://docs.python.org/2.7/library/stdtypes.html#string-formatting for the syntax.

    SIP video

    If enabled on the SIP bridge license, SIP calls can contain video streams. Video of SIP participants will be published to the web room and they will see a video of the currently talking person. Once the speaker changes, the video will be switched accordingly.

    Supported SIP video codecs are H.264, VP8, VP9 and AV1. Publishing to the web may use VP8, VP9, AV1 or H.264. If end-to-end-encryption should be used, only VP8 and VP9 are supported for web videos.

    Video streams can be enabled by adding the following block to the server.conf of the SIP bridge:

    video:
      enabled: true
      framerate: 15
      bitrate: 150000
      web_codecs:
        - vp8
        - vp9
      phone_codecs:
        - h264
        - vp8
        - vp9
        - av1
    

    The parameters web_codecs and phone_codecs specify the codecs in the order to negotiate with the Janus WebRTC gateway or the SIP phones.

    framerate specifies the framerate and bitrate the number of bits per second of the video to generate for SIP users.

    Logging

    Logs will be written to /var/log/sipbridge and output of the workflow script is available through journalctl:

    journalctl --unit spreed-sipbridge
    

    Logging configuration is in /etc/spreed-sipbridge/server.conf:

    logging:
      level: 2
      filename: /var/log/sipbridge/sipbridge.log
    

    With loglevel set to 3 or higher, the SIP messages sent from and received by the SIP bridge are logged which often is helpful for debugging issues in communicating with the SIP gateway / provider.

    Upgrades

    Depending on how the services have been installed, the upgrade procedure is a bit different.

    Online repository installation

    If the services have been installed from the online repository. The packages get updated together with the other operating system packages.

    Tarball installation (Ubuntu / Debian only)

    When a new version of the additional services is released, the packages can be upgraded by copying the updated repository folder from the new tarball to the server and using apt to install the new packages:

    apt-get update
    apt-get dist-upgrade