From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: mail.toke.dk; spf=pass (mailfrom) smtp.mailfrom=webweaving.org (client-ip=148.251.234.232; helo=weser.webweaving.org; envelope-from=dirkx@webweaving.org; receiver=) Authentication-Results: mail.toke.dk; dkim=pass (1024-bit key; unprotected) header.d=webweaving.org header.i=@webweaving.org header.a=rsa-sha256 header.s=shared header.b=T9gD6Hzv Received: from weser.webweaving.org (weser.webweaving.org [148.251.234.232]) by mail.toke.dk (Postfix) with ESMTPS id 9B499B02E16 for ; Sat, 22 Mar 2025 21:37:43 +0100 (CET) Received: from smtpclient.apple (fiber.static.cbizz.nl [185.142.248.117] (may be forged)) (authenticated bits=0) by weser.webweaving.org (8.18.1/8.18.1) with ESMTPSA id 52MKXqDS017684 (version=TLSv1.2 cipher=ECDHE-ECDSA-AES256-GCM-SHA384 bits=256 verify=NO); Sat, 22 Mar 2025 21:33:55 +0100 (CET) (envelope-from dirkx@webweaving.org) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=webweaving.org; s=shared; t=1742675635; bh=CEPCNju29A+k/UaWlno7C4ERjBSPEOEek4Hlcd8hrbw=; h=From:Subject:Date:In-Reply-To:Cc:To:References; b=T9gD6HzvlcA6vaKV9eKHN23/ls+tPuZLUkb1REIP64WAR1MOqtVQSxVBGMbBysNW6 BupjsJ6xdr7V/hAklAe8F9zECRA++7iolJYbLKxNPhNZmGgpnjeVVZ+AZ9WsxRYRdx WoLGX7terFIqKCzuGajBj4iddeSOXkcEsYsqAPdo= X-Authentication-Warning: weser.webweaving.org: Host fiber.static.cbizz.nl [185.142.248.117] (may be forged) claimed to be smtpclient.apple From: Dirk-Willem van Gulik Message-Id: <91DBD932-2B0A-43D4-8905-EC2886ACA2F4@webweaving.org> Content-Type: multipart/alternative; boundary="Apple-Mail=_861C455B-0FA2-4AC2-862B-5182B5F64922" Mime-Version: 1.0 (Mac OS X Mail 16.0 \(3826.400.131.1.6\)) Date: Sat, 22 Mar 2025 21:32:52 +0100 In-Reply-To: <87v7s0or61.wl-jch@irif.fr> To: Juliusz Chroboczek References: <87v7s0or61.wl-jch@irif.fr> X-Mailer: Apple Mail (2.3826.400.131.1.6) X-Greylist: Sender succeeded SMTP AUTH, not delayed by milter-greylist-4.6.4 (weser.webweaving.org [148.251.234.232]); Sat, 22 Mar 2025 21:33:55 +0100 (CET) Message-ID-Hash: SLWDPDVE7ZNFDRBJDWOOU2JXNWHHFAKY X-Message-ID-Hash: SLWDPDVE7ZNFDRBJDWOOU2JXNWHHFAKY X-MailFrom: dirkx@webweaving.org X-Mailman-Rule-Hits: member-moderation X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency CC: galene@lists.galene.org X-Mailman-Version: 3.3.10 Precedence: list Subject: [Galene] Re: About UDP multiplexing List-Id: =?utf-8?q?Gal=C3=A8ne_videoconferencing_server_discussion_list?= Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: --Apple-Mail=_861C455B-0FA2-4AC2-862B-5182B5F64922 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=utf-8 On 22 Mar 2025, at 19:29, Juliusz Chroboczek wrote: > By default, Galene will use random UDP ports for media traffic. If = the > high ports are inaccessible for some reason (say, because there is > a firewall in the way), it will fall back to routing through the = built-in > TURN server. While this is the right approach, it makes Galene > challenging to install for people who wish to put it behind a = firewall. >=20 > There is another approach, which is to put all the UDP traffic on a = single > port; this is called UDP multiplexing. I tried it a couple of years = ago, > and it did not work well, apparently Pion (our WebRTC library) had = some > issues with double-stack hosts when multiplexing. It appears to work = now, > and I've implemented it in the branch "udpmux". >=20 > UDP muxing is very simple to use: just add the option "-udp 10000", = where > 10000 is the port that you wish to use for UDP traffic. Works most splendidly.=20 I am wondering if the config could be simpler; e.g we now have -udp-range 10000:20000 Which clashes (obviously) with this new -udp 100000 So perhaps it would be nice to simplify this in one option to: -udp-range 10000-20000 -udp-range 10000 Or - when nothing is specified =E2=80=94 just use any port above 1024. > There are some caveats: >=20 > - there is a slight performance penalty, but it should be negligible; >=20 > - if the server is renumbered (its IP address changes), you will need > to restart Galene. >=20 > The code is live on galene.org, and it seems to work fine. I've > reimplemented it just today, so if you did test before, please test = again. >=20 > Note that UDP muxing, in its current state, does not solve the NAT > problem: if your server is behind NAT, Galene will still fallback to = TURN, > even if the mux port is forwarded on the NAT. I'll see if I can = implement > something, but please don't hold your breath, I'm not really = interested in > working around NAT issues. For what it is worth this works fairly ok with NAT now in a somewhat = neutered FreeBSD jail; config below through NAT. Install is `stock=E2=80=99 freebsd from ports; with just the galene = binary swapped for the one from the usbmux branch. Which comes very close to what is ideal to deploy in a more = controlled/enterprise/defence-in-depth sort of setting. So that is most lovely ! Dw. Jail - minimal jail with just =E2=80=98pkg install galena=E2=80=99 and: /etc/rc.conf galene_enable=3Dyes galene_http=3D127.0.2.1:8888 galene_args=3D" -turn $EXT_VISIBLE_IP:1195 -http 127.0.2.1:8888 = -insecure -udp 10000 " Reverse proxy on the outside via apache or nginx (both work): =20 location /ws { proxy_pass http://127.0.2.1:8888/ws; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } location / { proxy_pass http://127.0.2.1:8888; } =20 And tied in to normal certificate mngt, logging, etc done entirely = outside galene. If needed - intercepting the web furniture. With as the firewall setting nothing more than: /etc/rc.conf: pf_enable=3D"YES" pf_rules=3D"/etc/pf.conf" /etc/pfc.conf: =09 ext_if=3D=E2=80=9Cvtnet0" set skip on lo scrub in all turn_range=3D"10000" jails=3D"{ 127.0.2.0/24 }" galene_jail_ip=3D127.0.2.1 # Jails allowed to do any outbound (via NAT) jails_outbound=3D"{ $galene_jail_ip }" nat pass on $ext_if from $jails_outbound to any -> $ext_vis_ip = static-port rdr pass on $ext_if proto {udp,tcp} from any to $ext_jail_ip = port 1195 -> $galene_jail_ip rdr pass on $ext_if proto {udp,tcp} from any to $ext_jail_ip = port $turn_range -> $galene_jail_ip =E2=80=A6. pass in on $ext_if proto tcp to { $ext_vis_ip } port { = http, https } keep state # HTTP reverse proxy (ngix) pass in on $ext_if proto { tcp, udp } to { $ext_vis_ip } port = 1195 keep state # Turn pass in on $ext_if proto { udp, tcp } to { $ext_vis_ip } port = $turn_range keep state # RTP --Apple-Mail=_861C455B-0FA2-4AC2-862B-5182B5F64922 Content-Transfer-Encoding: quoted-printable Content-Type: text/html; charset=utf-8 On 22 Mar = 2025, at 19:29, Juliusz Chroboczek <jch@irif.fr> = wrote:

By default, Galene will use = random UDP ports for media traffic.  If the
high ports = are inaccessible for some reason (say, because there is
a firewall in = the way), it will fall back to routing through the built-in
TURN = server.  While this is the right approach, it makes = Galene
challenging to install for people who wish to put it behind a = firewall.

There is another approach, which is to put all the UDP = traffic on a single
port; this is called UDP multiplexing.  I = tried it a couple of years ago,
and it did not work well, apparently = Pion (our WebRTC library) had some
issues with double-stack hosts = when multiplexing.  It appears to work now,
and I've implemented = it in the branch "udpmux".

UDP muxing is very simple to use: just = add the option "-udp 10000", where
10000 is the port that you wish to = use for UDP traffic.

Works = most splendidly. 

I am wondering if the = config could be simpler; e.g we now have

= -udp-range 10000:20000

Which clashes = (obviously) with this new

-udp = 100000

So perhaps it would be nice to simplify = this in one option to:

= -udp-range 10000-20000
-udp-range 10000

Or - when = nothing is specified =E2=80=94  just use any port above = 1024.

There = are some caveats:

 - there is a slight performance penalty, = but it should be negligible;

 - if the server is renumbered = (its IP address changes), you will need
   to restart = Galene.

The code is live on galene.org, and it seems to work = fine.  I've
reimplemented it just today, so if you did test = before, please test again.

Note that UDP muxing, in its current = state, does not solve the NAT
problem: if your server is behind NAT, = Galene will still fallback to TURN,
even if the mux port is forwarded = on the NAT.  I'll see if I can implement
something, but please = don't hold your breath, I'm not really interested in
working around = NAT issues.

For what it is = worth this works fairly ok with NAT now in a somewhat neutered FreeBSD = jail; config below through NAT.

Install is = `stock=E2=80=99 freebsd from ports; with just the galene binary swapped = for the one from the usbmux branch.

Which comes = very close to what is ideal to deploy in a more = controlled/enterprise/defence-in-depth sort of = setting.

So that is most lovely = !

Dw.



Jail - minimal jail with just =E2=80=98pkg = install galena=E2=80=99 and:

/etc/rc.conf

= galene_enable=3Dyes

= galene_http=3D127.0.2.1:8888

= galene_args=3D" -turn $EXT_VISIBLE_IP:1195 -http 127.0.2.1:8888 = -insecure -udp 10000 "


Reverse proxy on the outside = via apache or nginx (both work):

    =     

    =     location /ws {

    =         proxy_pass = http://127.0.2.1:8888/ws;

    =         proxy_set_header Upgrade = $http_upgrade;

    =         proxy_set_header Connection = "upgrade";

    =     }

    =     location  / { proxy_pass http://127.0.2.1:8888; = }

  =   


And tied in to normal = certificate mngt, logging, etc done entirely outside galene.  If = needed - intercepting the web furniture.

With = as the firewall setting nothing more = than:

/etc/rc.conf:

= pf_enable=3D"YES"

= pf_rules=3D"/etc/pf.conf"


/etc/pfc.conf:

=

= ext_if=3D=E2=80=9Cvtnet0"

set skip = on lo

scrub in = all


= turn_range=3D"10000"


jails=3D"{ = 127.0.2.0/24 }"

        = galene_jail_ip=3D127.0.2.1


# Jails = allowed to do any outbound (via NAT)

= jails_outbound=3D"{ $galene_jail_ip }"


nat pass = on $ext_if from $jails_outbound to any -> $ext_vis_ip static-port


rdr pass = on $ext_if proto {udp,tcp} from any to $ext_jail_ip port 1195  =       -> $galene_jail_ip

rdr pass = on $ext_if proto {udp,tcp} from any to $ext_jail_ip port $turn_range = -> $galene_jail_ip


=E2=80=A6.<= /p>

pass in = on $ext_if proto tcp          to { = $ext_vis_ip } port { http, https } keep state # HTTP reverse proxy = (ngix)

pass in = on $ext_if proto { tcp, udp } to { $ext_vis_ip } port 1195 keep = state = # Turn

pass in = on $ext_if proto { udp, tcp } to { $ext_vis_ip } port $turn_range = keep state = # RTP






<= /body>= --Apple-Mail=_861C455B-0FA2-4AC2-862B-5182B5F64922--