Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ rtmp_port: port to listen to incoming RTMP connection on (default 1935)
whip_port: port to listen to incoming WHIP calls on (default 8080)
http_relay_port: port used to relay data from the main service process to the per ingress handler process (default 9090)
rtc_config: configuration for ICE and other RTC related settings, same settings livekit-server RTC configuration. Used for WHIP.
enable_udp_url_pull: allow URL pull ingresses to pull from udp:// urls (default false, see the security note below)
multicast_interface: network interface to join multicast groups on for UDP url pull. Empty lets the OS decide

# cpu costs for various Ingress types with their default values
cpu_cost:
Expand All @@ -73,6 +75,21 @@ cpu_cost:

The config file can be added to a mounted volume with its location passed in the INGRESS_CONFIG_FILE env var, or its body can be passed in the INGRESS_CONFIG_BODY env var.

> **Security note on `enable_udp_url_pull`**
>
> Only enable UDP url pull if you trust both the callers allowed to create ingresses and the network the
> ingress handlers run on. Unlike `http://` and `srt://` urls, a `udp://` url doesn't make the handler
> connect out to the url host: the handler binds a local socket on the address and port taken from the
> url, and joins the multicast group if one is given. As a result, a caller creating a URL pull ingress
> can:
>
> - Choose which local port the handler binds, potentially colliding with other services on the host.
> - Have the handler ingest unauthenticated traffic. UDP is connectionless, so any host able to reach
> that port can inject media into the session, or spoof the sender address to disrupt a legitimate feed.
> - Have the handler join arbitrary multicast groups and republish whatever it receives into a LiveKit
> room, using the ingress as a relay for streams on the handler's local network that the caller has no
> direct access to.

In order for the LiveKit server to be able to create Ingress sessions, an `ingress` section must also be added to the livekit-server configuration:

```yaml
Expand Down
15 changes: 15 additions & 0 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,21 @@ type ServiceConfig struct {
Logging logger.Config `yaml:"logging"`
Development bool `yaml:"development"`
PSRPCSkipClaim bool `yaml:"psrpc_skip_claim,omitempty"` // Lets psrpc servers skip the claim handshake on queue rpcs
// Allow URL pull ingresses to pull from udp:// urls. Disabled by default, and should only be
// enabled on deployments where both the API callers and the network the handlers run on are trusted.
// Unlike the http and srt sources, udpsrc doesn't connect out to the url host: it binds a local
// socket on the address and port taken from the caller provided url, and joins the multicast group
// if one is given. This has a few consequences:
// - The caller controls which local port the handler binds, and can collide with other services
// running on the host.
// - UDP is connectionless and unauthenticated, so any host able to reach that port can inject
// media into the session, or spoof the sender address to disrupt a legitimate feed.
// - The caller can make the handler join arbitrary multicast groups and republish whatever
// traffic it receives into a LiveKit room, turning the ingress into a relay for streams on
// the handler's local network that the caller couldn't otherwise reach.
EnableUDPURLPull bool `yaml:"enable_udp_url_pull,omitempty"`
// Network interface to join multicast groups on for UDP url pull. Empty means let the OS decide.
MulticastInterface string `yaml:"multicast_interface,omitempty"`

// Used for WHIP transport
RTCConfig rtcconfig.RTCConfig `yaml:"rtc_config"`
Expand Down
21 changes: 20 additions & 1 deletion pkg/media/urlpull/source.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,10 @@ import (
"github.com/frostbyte73/core"
"github.com/go-gst/go-gst/gst"

"github.com/livekit/protocol/logger"

"github.com/livekit/ingress/pkg/errors"
"github.com/livekit/ingress/pkg/params"
"github.com/livekit/protocol/logger"
)

var (
Expand Down Expand Up @@ -85,6 +86,24 @@ func NewURLSource(_ context.Context, p *params.Params) (*URLSource, error) {
}
}
}
} else if p.EnableUDPURLPull && strings.HasPrefix(p.Url, "udp://") {
elem, err = gst.NewElement("udpsrc")
if err != nil {
return nil, err
}
err = elem.SetProperty("uri", p.Url)
Comment on lines +89 to +94

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

馃煡 UDP pull exposes internal networks

With UDP pulling enabled, udpsrc accepts any requested address. URL-ingress callers can bind internal ports or join arbitrary multicast groups.

Devin Review

Was this helpful? React with 馃憤 or 馃憥 to provide feedback.

if err != nil {
return nil, err
}

if p.MulticastInterface != "" {
err = elem.SetProperty("multicast-iface", p.MulticastInterface)
if err != nil {
return nil, err
}
}

// udpsrc doesn't expose a stats property, so leave printStats unset
} else {
return nil, errors.ErrUnsupportedURLFormat
}
Expand Down
Loading