jellyfin-srfPlay/NETWORK_ROUTING_GUIDE.md
Duncan Tourolle ac6a3842dd
Some checks failed
🏗️ Build Plugin / call (push) Failing after 0s
📝 Create/Update Release Draft & Release Bump PR / call (push) Failing after 0s
🧪 Test Plugin / call (push) Failing after 0s
🔬 Run CodeQL / call (push) Failing after 0s
first commit
2025-11-12 22:05:36 +01:00

6.3 KiB

Network-Level Gateway Routing for SRF Content

This guide explains how to configure network-level routing to direct all SRF-related traffic (including video streams) through your Swiss gateway/proxy at 192.168.1.37.

Overview

Instead of configuring proxy support at the application level, this approach uses Linux policy-based routing to redirect traffic destined for SRF domains through an alternate gateway. This ensures:

  • API requests to il.srgssr.ch go through the gateway
  • Video stream requests to srf-vod-amd.akamaized.net (and other CDNs) go through the gateway
  • ffprobe and ffmpeg automatically use the gateway
  • No application configuration needed - transparent to Jellyfin

Prerequisites

  • Root access to the Jellyfin server (192.168.1.4)
  • Gateway at 192.168.1.37 with IPv4 forwarding enabled
  • Both machines on the same network segment

Installation on Jellyfin Server

Step 1: Copy Scripts to Jellyfin Server

From your development machine:

# Copy the routing scripts to Jellyfin server
scp setup-gateway-routing.sh cleanup-gateway-routing.sh user@192.168.1.4:~

Step 2: SSH to Jellyfin Server

ssh user@192.168.1.4

Step 3: Make Scripts Executable

chmod +x setup-gateway-routing.sh cleanup-gateway-routing.sh

Step 4: Run Setup Script

sudo ./setup-gateway-routing.sh

When prompted:

  • Gateway IP: 192.168.1.37
  • Network interface: Find your interface name first with ip -br link show (common names: eth0, ens18, enp0s3)

The script will:

  1. Create a custom routing table named srf_gateway
  2. Resolve IP addresses for all SRF domains
  3. Add routes through your gateway (192.168.1.37)
  4. Create routing rules for policy-based routing
  5. Set up a systemd service for persistence across reboots

Step 5: Verify Routing

Check that routes are configured:

# Show the custom routing table
ip route show table srf_gateway

# Show routing rules
ip rule show | grep srf_gateway

# Test routing for Integration Layer API
ip route get $(dig +short il.srgssr.ch | head -1)

# Test routing for video CDN
ip route get $(dig +short srf-vod-amd.akamaized.net | head -1)

Step 6: Test from Jellyfin Server

Test that the routing is working:

# Test API access
curl -v "https://il.srgssr.ch/integrationlayer/2.0/mediaComposition/byUrn/urn:srf:video:b84713f0-f81b-460f-9b0f-d0517310fb4f.json" 2>&1 | grep -E "(x-location|HTTP/)"

# Should show: x-location: CH

Step 7: Restart Jellyfin

sudo systemctl restart jellyfin

What Gets Routed

The following domains are routed through the gateway:

  • il.srgssr.ch - Integration Layer API (metadata)
  • www.srf.ch - Main SRF site
  • www.rts.ch - RTS (Radio Télévision Suisse)
  • www.rsi.ch - RSI (Radiotelevisione svizzera)
  • www.rtr.ch - RTR (Radiotelevisiun Svizra Rumantscha)
  • www.swi.ch - SWI (swissinfo)
  • srf-vod-amd.akamaized.net - SRF video CDN
  • rts-vod-amd.akamaized.net - RTS video CDN
  • rsi-vod-amd.akamaized.net - RSI video CDN
  • play-web.srf.ch - Play web interface
  • il-stage.srgssr.ch - Staging environment

How It Works

  1. DNS Resolution: Domains are resolved to IP addresses
  2. Routing Table: A custom routing table (srf_gateway) is created with routes through the gateway
  3. Policy Routing: Rules direct traffic to specific IPs to use the custom routing table
  4. Persistence: A systemd service ensures routes survive reboots

Disabling Plugin Proxy Configuration

Once network-level routing is working, you can disable the proxy configuration in the plugin:

  1. Go to Jellyfin Dashboard → Plugins → SRF Play
  2. Uncheck "Use Proxy"
  3. Save configuration
  4. Restart Jellyfin

The plugin will use direct HTTP requests, but the network layer will transparently route them through the gateway.

Troubleshooting

Routes Not Working

Check if gateway is reachable:

ping 192.168.1.37
nc -zv 192.168.1.37 3128

Check routing table:

ip route show table srf_gateway

DNS Changes

If SRF changes their IP addresses, you may need to re-run the setup script:

sudo ./cleanup-gateway-routing.sh
sudo ./setup-gateway-routing.sh

Verify Traffic Path

Use traceroute to see the path:

traceroute $(dig +short il.srgssr.ch | head -1)
# Should show 192.168.1.37 as first hop

Check Systemd Service

systemctl status srf-gateway-routing.service
journalctl -u srf-gateway-routing.service

Removing the Configuration

To completely remove the routing configuration:

sudo ./cleanup-gateway-routing.sh

This will:

  • Remove all routing rules
  • Flush the custom routing table
  • Disable and remove the systemd service

Advantages of This Approach

  1. Transparent: No application changes needed
  2. Complete Coverage: All network traffic to SRF domains uses gateway
  3. Persistent: Survives reboots
  4. Centralized: Managed at network level
  5. Debug-Friendly: Can verify with standard network tools

Disadvantages

  1. DNS Changes: If SRF changes IPs, routing must be updated
  2. New Domains: New CDN domains require script update
  3. Static IPs Only: Doesn't work with wildcard domains

Gateway Configuration

Ensure your gateway (192.168.1.37) has:

  1. IPv4 Forwarding Enabled:

    # On the gateway (192.168.1.37)
    sudo sysctl net.ipv4.ip_forward=1
    
    # Make permanent
    echo "net.ipv4.ip_forward=1" | sudo tee -a /etc/sysctl.conf
    
  2. Firewall Rules (if using iptables):

    # On the gateway (192.168.1.37)
    sudo iptables -A FORWARD -s 192.168.1.4 -j ACCEPT
    sudo iptables -A FORWARD -d 192.168.1.4 -m state --state RELATED,ESTABLISHED -j ACCEPT
    sudo iptables -t nat -A POSTROUTING -s 192.168.1.4 -o <outbound-interface> -j MASQUERADE
    
  3. Squid Proxy (if using proxy mode):

    • Already configured and accessible at port 3128
    • Note: With network-level routing, traffic goes through the gateway's routing, not necessarily the Squid proxy

Testing Complete Data Chain

After setup, test the complete flow:

  1. Metadata API: Browse shows in Jellyfin - should work
  2. Video Playback: Try playing a video - should work
  3. Thumbnails: Images should load

All traffic should be routed through 192.168.1.37, giving you the Swiss location needed to access geo-blocked content.