IPTV Multicast IGMP configuration through VPN

Hello all. I have an openwrt Wireguard VPN setup and trying to run an IPTV receiver through that VPN. I have openwrt routers managing both ends of the VPN. The IPTV endpoint receiver device cannot receive the IPTV feed, I suspect from my research its related to multicast / IGMP support. I would appreciate some advice on how to get this up and running. I've installed IGMPproxy and enabled multicast on my Wireguard interfaces and haven't done any further changes yet as unsure of next steps.

My setup:

Site A:/etc/config/network

root@wg_site2site_a:~# cat /etc/config/network

config interface 'loopback'
        option device 'lo'
        option proto 'static'
        option ipaddr '127.0.0.1'
        option netmask '255.0.0.0'

config globals 'globals'
        option ula_prefix 'fdff:ffff:ffff::/48'

config device
        option name 'br-lan'
        option type 'bridge'
        list ports 'lan'
        option igmp_snooping '1'

config device
        option name 'lan'
        option macaddr 'xx'

config interface 'lan'
        option device 'br-lan'
        option proto 'static'
        option ipaddr '172.16.1.1'
        option netmask '255.255.255.0'

config device
        option name 'wan'
        option macaddr 'xx'

config interface 'wan'
        option device 'wan'
        option proto 'dhcp'
        option metric '1024'
        option peerdns '0'
        list dns '8.8.8.8'
        list dns '8.8.4.4'

config interface 'wan6'
        option device 'wan'
        option proto 'dhcpv6'
        option peerdns '0'
        list dns '2001:4860:4860::8888'
        list dns '2001:4860:4860::8844'

config interface 'wg_s2s_a'
        option proto 'wireguard'
        option private_key 'xx'
        option listen_port '51830'
        list addresses '10.0.1.1/24'

config wireguard_wg_s2s_a 's2s_vpn_site_b'
        option public_key 'xx'
        option preshared_key 'xx'
        option description 'Site B'
        option route_allowed_ips '1'
        option persistent_keepalive '25'
        list allowed_ips '172.16.2.0/24'
        list allowed_ips 'fdee:eeee:eeee::/48'
        list allowed_ips '10.0.1.2/32'
        option private_key 'xx'

config wireguard_wg_s2s_a 's2s_vpn_site_c'
        option description 'Site C'
        option public_key 'xx'
        option preshared_key 'xx'
        list allowed_ips '172.16.3.0/24'
        list allowed_ips 'fdee:ffff:ffff::/48'
        list allowed_ips '10.0.1.3/32'
        option private_key 'xx'
        option route_allowed_ips '1'
        option persistent_keepalive '25'

config device
        option name 'wg_s2s_a'
        option multicast '1'

Site B:/etc/config/network

root@wg_site2site_b:/etc/config# cat /etc/config/network

config interface 'loopback'
        option device 'lo'
        option proto 'static'
        option ipaddr '127.0.0.1'
        option netmask '255.0.0.0'

config globals 'globals'
        option ula_prefix 'fdee:eeee:eeee::/48'

config device
        option name 'br-lan'
        option type 'bridge'
        list ports 'lan'
        option igmp_snooping '1'

config device
        option name 'lan'
        option macaddr 'xx'

config interface 'lan'
        option device 'br-lan'
        option proto 'static'
        option ipaddr '172.16.2.1'
        option netmask '255.255.255.0'

config device
        option name 'wan'
        option macaddr 'xx'

config interface 'wan'
        option device 'wan'
        option proto 'dhcp'
        option metric '1024'
        option peerdns '0'
        list dns '8.8.8.8'
        list dns '8.8.4.4'

config interface 'wan6'
        option device 'wan'
        option proto 'dhcpv6'
        option peerdns '0'
        list dns '2001:4860:4860::8888'
        list dns '2001:4860:4860::8844'

config interface 'wg_s2s_b'
        option proto 'wireguard'
        option private_key 'xx'
        option listen_port '51830'
        list addresses '10.0.1.2/24'

config wireguard_wg_s2s_b 's2s_vpn_site_a'
        option public_key 'xx'
        option preshared_key 'xx'
        option description 'Site A'
        option route_allowed_ips '1'
        option persistent_keepalive '25'
        option endpoint_host 'xx'
        option endpoint_port '51830'
        list allowed_ips '172.16.1.0/24'
        list allowed_ips '10.0.1.1/32'
        list allowed_ips '0.0.0.0/0'

config device
        option name 'wg_s2s_b'
        option multicast '1'

Site A:/etc/config/igmpproxy

root@wg_site2site_a:~# cat /etc/config/igmpproxy
config igmpproxy
        option quickleave 1
#       option verbose [0-3](none, minimal[default], more, maximum)

config phyint
        option network wan
        option zone wan
        option direction upstream
#       list altnet 192.168.1.0/24
        list altnet 0.0.0.0/0

config phyint
        option network lan
        option zone lan
        option direction downstream

Site B:/etc/config/igmpproxy

root@wg_site2site_b:~# cat /etc/config/igmpproxy
config igmpproxy
        option quickleave 1
#       option verbose [0-3](none, minimal[default], more, maximum)

config phyint
        option network wan
        option zone wan
        option direction upstream
#       list altnet 192.168.1.0/24
        list altnet 0.0.0.0/0

config phyint
        option network lan
        option zone lan
        option direction downstream

Site A:/etc/config/firewall (only showing IGMP reference)

config rule
        option name 'Allow-IGMP'
        option src 'wan'
        option proto 'igmp'
        option family 'ipv4'
        option target 'ACCEPT'

Site B:/etc/config/firewall (only showing IGMP reference)

config rule
        option name 'Allow-IGMP'
        option src 'wan'
        option proto 'igmp'
        option family 'ipv4'
        option target 'ACCEPT'

basic question:
are the 224.0.0.0/4 mroutes configured on the wg interfaces?

Hi Nofan, I haven't done any changes yet. I've added my /etc/config/network for Site A above. Site B is similar. Can you suggest what lines to add to what config files to start? Thanks

I just wondered if

ip -4 route shows

224.0.0.0/4 destination on both sides via wg interfaces.

if so: OK ... if not one can add them with:

ip -4 route add 224.0.0.0/4 dev your-wg-interface

but how to do this in config I don't know,

Hi Nofan, I've added as you suggested to Site A:

root@wg_site2site_a:~# ip -4 route
default via 192.168.200.1 dev wan  src 192.168.200.10  metric 1024
10.0.1.0/24 dev wg_s2s_a scope link  src 10.0.1.1
10.0.1.2 dev wg_s2s_a scope link
10.0.1.3 dev wg_s2s_a scope link
172.16.1.0/24 dev br-lan scope link  src 172.16.1.1
172.16.2.0/24 dev wg_s2s_a scope link
172.16.3.0/24 dev wg_s2s_a scope link
192.168.200.0/24 dev wan scope link  metric 1024
224.0.0.0/4 dev wg_s2s_a scope link

and Site B:

root@wg_site2site_b:~# ip -4 route
default dev wg_s2s_b scope link
default via 10.0.0.1 dev wan  src 10.0.0.34  metric 1024
10.0.0.0/24 dev wan scope link  metric 1024
10.0.1.0/24 dev wg_s2s_b scope link  src 10.0.1.2
10.0.1.1 dev wg_s2s_b scope link
70.53.109.43 via 10.0.0.1 dev wan  metric 1024
172.16.1.0/24 dev wg_s2s_b scope link
172.16.2.0/24 dev br-lan scope link  src 172.16.2.1
224.0.0.0/4 dev wg_s2s_b scope link

@thema5on

Getting multicast v4 routes on both sides A&B right is first and often sufficient requirement.

Then, once mroutes are right, one could use tools as tcpdump and ping to inspect.

But ideally one would write a sender and receiver program or script for respective sides to test.

The IGMP receiver may be harder part. The sender part could be ping. I think there are igmp join programs too, but, again, they must be in opkg.

I used to do this on x86_64 Linux routers but crosscompiling for your openwrt arch might not be so easy, if not very tedious.

In /proc/net one can also find /proc/net/ip_mr_cache and /proc/net/ip_mr_vif but in general I am not so

Hi @NofanTasi. How do you suggest I troubleshoot? I have tcpdump installed at both ends.

Some output here:

root@wg_site2site_b:~# tcpdump -i br-lan udp and dst net 224.0.0.0/4
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on br-lan, link-type EN10MB (Ethernet), snapshot length 262144 bytes
22:58:22.818392 IP 172.16.2.163.1041 > 239.255.255.250.8082: UDP, length 459
22:58:25.819441 IP 172.16.2.163.1041 > 239.255.255.250.8082: UDP, length 459
22:58:28.820524 IP 172.16.2.163.1041 > 239.255.255.250.8082: UDP, length 459
22:58:31.821564 IP 172.16.2.163.1041 > 239.255.255.250.8082: UDP, length 459
22:58:34.822600 IP 172.16.2.163.1041 > 239.255.255.250.8082: UDP, length 459
22:58:37.823581 IP 172.16.2.163.1041 > 239.255.255.250.8082: UDP, length 459
22:58:40.824646 IP 172.16.2.163.1041 > 239.255.255.250.8082: UDP, length 459
...

@thema5on : I apoligize for not being able to help much.

Looking at some input you kindly provide I wonder if site a should perhaps have default route via its wg as well (as site b has) and I am a bit optimistic to see mcast packets arrive at site b albeit on br-lan.

Again, this is a bit wet finger sensing and I have no immediate further suggestions.

1 Like

Hi @NofanTasi

I've done concurrent captures on Site B, src 172.16.2.133 (endpoint tvip receiver), on the br-lan and wg interface. I see some traffic is not getting through. Perhaps that can indicate where I should troubleshoot if you can see a pattern?

See sample:

br-lan

root@wg_site2site_b:/etc/config# tcpdump -i br-lan src 172.16.2.163
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on br-lan, link-type EN10MB (Ethernet), snapshot length 262144 bytes
00:54:31.363524 IP 172.16.2.163.1041 > 239.255.255.250.8082: UDP, length 460
00:54:32.185270 IP 172.16.2.163.1025 > 10.2.89.110.43962: UDP, length 113
00:54:34.364558 IP 172.16.2.163.1041 > 239.255.255.250.8082: UDP, length 460
00:54:35.332895 IP 172.16.2.163 > 239.0.0.20: igmp v2 report 239.0.0.20
00:54:37.365584 IP 172.16.2.163.1041 > 239.255.255.250.8082: UDP, length 460
00:54:39.336959 IP 172.16.2.163 > 239.255.255.250: igmp v2 report 239.255.255.250
00:54:40.366657 IP 172.16.2.163.1041 > 239.255.255.250.8082: UDP, length 460
00:54:43.367697 IP 172.16.2.163.1041 > 239.255.255.250.8082: UDP, length 460
00:54:44.341024 IP 172.16.2.163 > 239.0.0.20: igmp v2 report 239.0.0.20
00:54:46.367645 IP 172.16.2.163.1041 > 239.255.255.250.8082: UDP, length 460
00:54:47.186134 IP 172.16.2.163.1025 > 10.2.89.109.43962: UDP, length 113
00:54:49.368696 IP 172.16.2.163.1041 > 239.255.255.250.8082: UDP, length 460
00:54:52.349150 IP 172.16.2.163 > 239.255.255.250: igmp v2 report 239.255.255.250
00:54:52.369740 IP 172.16.2.163.1041 > 239.255.255.250.8082: UDP, length 460
00:54:55.370784 IP 172.16.2.163.1041 > 239.255.255.250.8082: UDP, length 460
00:54:57.354247 IP 172.16.2.163 > 239.0.0.20: igmp v2 report 239.0.0.20
00:54:57.529270 IP 172.16.2.163.1028 > 10.2.89.34.123: NTPv4, Client, length 48
00:54:58.371860 IP 172.16.2.163.1041 > 239.255.255.250.8082: UDP, length 460
00:55:01.372982 IP 172.16.2.163.1041 > 239.255.255.250.8082: UDP, length 460
00:55:02.186840 IP 172.16.2.163.1025 > 10.2.89.110.43962: UDP, length 113
00:55:02.578164 ARP, Reply 172.16.2.163 is-at 10:56:11:fc:bb:31 (oui Unknown), length 46
^C

wg_s2s_b

root@wg_site2site_b:~# tcpdump -i wg_s2s_b src 172.16.2.163
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on wg_s2s_b, link-type RAW (Raw IP), snapshot length 262144 bytes
00:54:17.184148 IP 172.16.2.163.1025 > 10.2.89.109.43962: UDP, length 113
00:54:32.185374 IP 172.16.2.163.1025 > 10.2.89.110.43962: UDP, length 113
00:54:47.186247 IP 172.16.2.163.1025 > 10.2.89.109.43962: UDP, length 113
00:54:57.529402 IP 172.16.2.163.1028 > 10.2.89.34.123: NTPv4, Client, length 48
00:55:02.186943 IP 172.16.2.163.1025 > 10.2.89.110.43962: UDP, length 113
^C

239.0.0.20 is IGMP and 239.255.255.250 is SSDP both from receiver on side B.
But on sender side A, what are the multicast source and destination address? These are the ones to inspect on both sides to figure out where they go right or wrong.

Hi @NofanTasi

Thanks for your continued advice.

The Site B IPTV endpoint is 172.16.2.163, that's why it's isolated it in the tcpdump source -- it seems to not be forwarding to 239.255.255.255.250/UDP from Site B br-lan to the Site B wireguard interface from the captures below. I thought fix Site B interfaces first then troubleshoot Site A. What do you think?

2 Likes

I see ... it will perhaps also need to handle IGMP which can probably be done with igmpproxy. To forward non linklocal multicast from one interface to another on side B, maybe some "ip route" TYPE multicast command exists. And in /proc you may need to set mc_forwarding (if not set) on involved interfaces.

Hi @NofanTasi

Focusing just on IGMPproxy, I've updated my initial thread with the existing /etc/config/igmpproxy configuration. Can you (and the community) take a look and see if you have any suggestions? So far (Site B)..

  • br-lan has option igmp_snooping '1' in the network config
  • multicast is enabled on the wireguard interface in the network config
  • firewall rule wan interface has igmp allowed
  • ip4 routes added for 224.0.0.0/4 on the wireguard interface

.. yet 239.255.255.250 does not seem to be pass between interfaces from tcpdumps..
Site B wg_s2s_b interface tcpdump on src 172.16.2.163

root@wg_site2site_b:/etc/config# tcpdump -i wg_s2s_b src 172.16.2.163
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on wg_s2s_b, link-type RAW (Raw IP), snapshot length 262144 bytes
14:03:08.783035 IP 172.16.2.163.1028 > 10.2.89.4.123: NTPv4, Client, length 48
14:03:15.945867 IP 172.16.2.163.1025 > 10.2.89.110.43962: UDP, length 113
14:03:30.945978 IP 172.16.2.163.1025 > 10.2.89.109.43962: UDP, length 113
14:03:45.947219 IP 172.16.2.163.1025 > 10.2.89.110.43962: UDP, length 113
^C

Site B br-lan interface tcpdump on src 172.16.2.163 (concurrent with above)

root@wg_site2site_b:/sys/class/net# tcpdump -i br-lan src 172.16.2.163
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on br-lan, link-type EN10MB (Ethernet), snapshot length 262144 bytes
14:03:08.782898 IP 172.16.2.163.1028 > 10.2.89.4.123: NTPv4, Client, length 48
14:03:09.227952 IP 172.16.2.163 > 239.255.255.250: igmp v2 report 239.255.255.250
14:03:10.661629 IP 172.16.2.163.1046 > 239.255.255.250.8082: UDP, length 459
14:03:13.662806 IP 172.16.2.163.1046 > 239.255.255.250.8082: UDP, length 459
14:03:13.861892 ARP, Reply 172.16.2.163 is-at 10:56:11:fc:bb:31 (oui Unknown), length 46
14:03:15.945702 IP 172.16.2.163.1025 > 10.2.89.110.43962: UDP, length 113
14:03:16.664755 IP 172.16.2.163.1046 > 239.255.255.250.8082: UDP, length 459
14:03:17.244136 IP 172.16.2.163 > 239.255.255.250: igmp v2 report 239.255.255.250
14:03:19.665820 IP 172.16.2.163.1046 > 239.255.255.250.8082: UDP, length 459
14:03:21.252238 IP 172.16.2.163 > 239.0.0.20: igmp v2 report 239.0.0.20
14:03:22.666873 IP 172.16.2.163.1046 > 239.255.255.250.8082: UDP, length 459
14:03:25.667906 IP 172.16.2.163.1046 > 239.255.255.250.8082: UDP, length 459
14:03:28.668970 IP 172.16.2.163.1046 > 239.255.255.250.8082: UDP, length 459
14:03:30.945820 IP 172.16.2.163.1025 > 10.2.89.109.43962: UDP, length 113
14:03:31.669027 IP 172.16.2.163.1046 > 239.255.255.250.8082: UDP, length 459
14:03:31.772389 IP 172.16.2.163 > 239.255.255.250: igmp v2 report 239.255.255.250
14:03:34.670070 IP 172.16.2.163.1046 > 239.255.255.250.8082: UDP, length 459
14:03:35.780429 IP 172.16.2.163 > 239.0.0.20: igmp v2 report 239.0.0.20
14:03:37.671070 IP 172.16.2.163.1046 > 239.255.255.250.8082: UDP, length 459
14:03:39.788536 IP 172.16.2.163 > 239.0.0.20: igmp v2 report 239.0.0.20
14:03:39.788731 IP 172.16.2.163 > 239.255.255.250: igmp v2 report 239.255.255.250
14:03:40.672147 IP 172.16.2.163.1046 > 239.255.255.250.8082: UDP, length 459
14:03:42.234785 IP 172.16.2.163.1131 > wg_site2site_b.lan.53: 31367+ A? mdsfe001.iptv.bell.ca. (39)
14:03:43.673329 IP 172.16.2.163.1046 > 239.255.255.250.8082: UDP, length 459
14:03:45.947067 IP 172.16.2.163.1025 > 10.2.89.110.43962: UDP, length 113```

Thoughts?

Should on Site B upstream IGMP proxy not be network and zone corresponding to wireguard ?

on Site A it seems IGMP proxy upstream and downstream must be switched (if sender is on lan) and again network and zone wan should be corresponding to wireguard?

Hi @NofanTasi

Still focusing on Site B only for now, I've tried changing the igmpproxy and the firewall configuration to refer to the wireguard interface wg_s2s_b instead of the wan interface to no avail. I can see errors when trying to restart after the firewall configuration change so I think I have the syntax incorrect, which may mean the igmpproxy syntax is also wrong. See the error for firewall restart:

part of /etc/config/igmpproxy

config phyint
#       option network wan
#       option zone wan
        option network wg_s2s_b
        option zone wg_s2s_b

part of /etc/config/firewall

config rule
        option name 'Allow-IGMP'
#       option src 'wan'
        option src 'wg_s2s_b'
        option proto 'igmp'
        option family 'ipv4'
        option target 'ACCEPT'

Error on restarting firewall:

root@wg_site2site_b:/etc/config# /etc/init.d/igmpproxy restart
root@wg_site2site_b:/etc/config# /etc/init.d/firewall restart
Section @rule[2] (Allow-IGMP) option 'src' specifies invalid value 'wg_s2s_b'
Section @rule[2] (Allow-IGMP) skipped due to invalid options

For firewall I have input output forward ACCEPT configured in luci GUI between zones video and iptv corresponding to interfaces Video and TV.

The multicast video happens to come in on interface Video and IGMP from television on downstream interface TV needs to be proxy-ed to upstream interface Video

In the firewall config this looks symmetric like:

config zone
        option name 'video'
        option input 'ACCEPT'
        option output 'ACCEPT'
        option forward 'ACCEPT'
        list network 'Video'

config zone
        option name 'iptv'
        option input 'ACCEPT'
        option output 'ACCEPT'
        option forward 'ACCEPT'
        list network 'TV'

config forwarding
        option src 'iptv'
        option dest 'video'

config forwarding
        option src 'video'
        option dest 'iptv'

@NofanTasi Do you mind sharing the rest of your configuration so I can analyze and compare to my configuration? Do you have IPTV working over an openwrt VPN?

I have live multicast TV working from my provider using an OpenWRT router (which I replaced the provider router with). The setup requires igmpproxy (and a lot of dhcp parameters but that is to negotiate TV subscription). I have Wireguard server running as well on that OpenWRT router. But the TV is not going over the VPN. If I am abroad and connect to home via VPN, I do not need the TV content, I don't even think it would be possible to do this because the TV guide and channel zapping is to be done on provider TV box. The OpenWRT router is basically the gateway to the Internet and the IP TV content. I will contact you in PM to arrange for sharing my config.

Here is some output of mrouting berween incoming and outgoing.

root@router:~# cat /proc/net/ip_mr_vif
Interface      BytesIn  PktsIn  BytesOut PktsOut Flags Local    Remote
 0 eth1              0       0  28484746200 21006450 00000 0101A8C0 00000000
 1 eth2.30    28484746200 21006450         0       0 00000 AB965A0A 00000000

Thanks @NofanTasi .

I appear to have igmp working now across the VPN using the igmpproxy settings and tcpdump to monitor igmp traffic. I have configured the required DNS overrides for the IPTV provider. I am now troubleshooting UDP multicast. Do you have any advice on where to start? Thanks!

1 Like

@thema5on : Good progress ... as said igmpproxy on site A might need up/down stream reversed and also : down must be wireguard if up is lan. Apart from that I think having all multicast forwarding in interfaces and routes across interfaces somewhat right might help. Sorry to be vague. Also, I think tcpdump might have ways to just capture certain or all multicast. Then now on site A ... even if site B does not manage to declare its IGMP (v2 or v3) interest, perhaps locally (on site A) one can join some multicast G or (S,G) stream, and then see at least the content is there. To get it through the VPN tunnel, I guess the igmpproxy chain must be right. Now, all that said, this is all an enormous hack of static configurations. Real multicast (and unicast) is dynamic.