I have an LG TV that, by my own choice, does not have Internet access.
It is not disconnected from my network. It is connected to the LAN, uses my DNS server, and can communicate with whatever I decide to allow. I simply have a firewall rule preventing it from accessing the Internet.
My home infrastructure uses shadowcat4 as the router/firewall, a fanless mini PC with an Intel N95 and four Intel I226-V 2.5 Gb Ethernet interfaces. It runs Slackware-current and replaced my old shadowcat3 router.
The Internet connection comes through FTTH with the ONT in bridge mode. Shadowcat4 establishes the PPPoE connection directly and also runs nftables, OpenVPN, dnsmasq, dnscrypt-proxy, and a few other things.
The LAN is 192.168.111.0/24, shadowcat4 is 192.168.111.14, and the LG TV is 192.168.111.191.
The problem appeared because of a rather silly characteristic of the TV: if it completely loses electrical power, it loses its date and time. When power comes back, it may boot believing that it is sometime in 2022.
That by itself would not be a major problem, except that I use the TV's automatic power-on feature. I want it to turn itself on at 06:00, and obviously it needs to know what time it is for that to work.
With Internet access enabled, it recovered the correct time automatically. With Internet access blocked, it did not.
So the question became quite specific:
What is the absolute minimum Internet access the TV needs solely to recover its date and time?
First suspect: NTP
The first thing I thought of, and the first thing I discussed with ChatGPT during the troubleshooting process, was the obvious candidate: NTP.
If a device needs to know the time, one would expect UDP traffic to port 123.
Shadowcat4 already uses NTP and, in fact, during the tests another interesting problem showed up: NTP queries leaving through my PPPoE connection were receiving replies very inconsistently. We captured traffic on ppp0, verified the outgoing queries, and compared the results with another machine using a different ISP.
From that other connection, the same NTP servers responded quickly and consistently.
Everything pointed toward some behavior involving the ISP or the network path used by shadowcat4.
Interesting, but ultimately a false lead for the TV problem.
Capturing the LG's traffic after a cold boot revealed something much more important:
the TV was not attempting to use UDP/123 at all.
No NTP.
Instead, it was repeatedly trying to establish TCP connections to port 443.
Opening HTTPS as a test
The firewall uses nftables with a DROP policy. The LG was given a specific rule before the general LAN access rules:
ip saddr 192.168.111.191 oifname "ppp*" drop
As a test, we temporarily inserted an exception before that DROP rule allowing the TV to connect to any destination over TCP/443.
Then I performed a real cold boot: unplugged the TV from power, waited, and plugged it back in.
It started without the correct time.
With HTTPS allowed, it recovered the correct date and time.
That completely changed the direction of the investigation. We were no longer looking for an NTP server. Some LG service accessible over HTTPS was involved in recovering the time.
Using DNS as a guide
The TV uses dnsmasq on shadowcat4 as its DNS server, so I started logging its queries.
Several domains appeared:
lgtvonline.lge.com
BR7.nextlgsdp.com
AIC.tv.wiselg.com
aic-gfts.nextlgsdp.com
qt2-kic.lgtviot.com
aic.lgtviot.com
BR7.info.lgsmartad.com
The last one was particularly amusing because my HaGeZi blocklist causes:
BR7.info.lgsmartad.com
to return NXDOMAIN.
The TV recovered its time perfectly anyway.
So advertising was out of the picture.
The domain that started looking particularly interesting was:
BR7.nextlgsdp.com
dnsmasq was returning a set of addresses such as:
54.200.71.5
54.186.200.227
32.189.217.166
16.146.234.1
32.188.96.203
52.41.138.142
52.35.116.50
16.147.145.11
The set is not permanent: the addresses rotate and change over time.
Capturing the exact moment
For most of the testing I used tcpdump.
I recorded a complete capture:
tcpdump -ni eth0 -s0 -w /tmp/tv-br7.pcap host 192.168.111.191
Before opening the firewall, there was a succession of SYN packets from the TV toward HTTPS servers, but no replies because nftables was dropping them.
After enabling the exception, the first SYN/ACK appeared:
13:47:57.785790
52.35.116.50:443 -> 192.168.111.191
Flags [S.]
A few seconds later, connections started appearing from:
52.41.138.142:443
Both addresses were part of the set DNS had just returned for BR7.nextlgsdp.com.
The correlation was very strong, but it was still a correlation.
I wanted to prove that those HTTPS connections were actually intended for that hostname.
Enter tshark
Until this point, I did not have tshark installed on shadowcat4.
I installed Wireshark 4.6.8 using the SlackBuild available from SlackBuilds.org. I did not really need the Wireshark graphical interface; I only wanted tshark to analyze the pcap file I had already generated with tcpdump.
The useful part is that, although HTTPS encrypts the application data, the TLS ClientHello can contain the SNI identifying the server name the client wants to reach.
I ran:
tshark -r /tmp/tv-br7.pcap \
-Y 'ip.src==192.168.111.191 && tls.handshake.extensions_server_name' \
-T fields \
-e frame.time \
-e ip.dst \
-e tls.handshake.extensions_server_name
And there it was:
2026-09-16T13:47:57.800548000-0300 52.35.116.50 br7.nextlgsdp.com
2026-09-16T13:48:02.134213000-0300 52.41.138.142 br7.nextlgsdp.com
2026-09-16T13:48:05.790571000-0300 52.41.138.142 br7.nextlgsdp.com
...
Case closed.
We no longer merely knew that those IP addresses had been returned by DNS for BR7.nextlgsdp.com: we now had the TV's own TLS ClientHello declaring through SNI that it wanted to talk to:
br7.nextlgsdp.com
The definitive test
We then performed the test that actually mattered.
The firewall was configured to block all Internet access from the TV except TCP/443 toward the eight addresses that BR7.nextlgsdp.com resolved to at that moment.
Then I performed another real cold boot by physically removing power from the TV.
The LG recovered the correct date and time.
During that test it had no access to the other services it had queried through DNS. It also could not access the advertising service blocked by HaGeZi.
So, for my practical purposes, the result was demonstrated:
the TV can remain without general Internet access and only needs HTTPS access to BR7.nextlgsdp.com to recover its date and time.
I am not claiming that TLS itself is being used as a time synchronization protocol. TLS does not normally provide system time that way. Some response or part of the LG service available over HTTPS is apparently what allows the TV to obtain the information it needs.
For my firewall, that distinction does not matter. I now know which traffic needs to be allowed.
The resulting nftables configuration
The important part of the forward chain now conceptually looks like this:
TV -> current BR7.nextlgsdp.com IPs:443 ACCEPT
TV -> Internet DROP
established,related ACCEPT
LAN -> Internet ACCEPT
In /etc/nftables.conf I have:
ip saddr 192.168.111.191 \
ip daddr { 54.200.71.5, 54.186.200.227, 32.189.217.166, 16.146.234.1, \
32.188.96.203, 52.41.138.142, 52.35.116.50, 16.147.145.11 } \
oifname "ppp*" tcp dport 443 accept
ip saddr 192.168.111.191 oifname "ppp*" drop
The ordering is deliberate.
The exception must come before the TV's DROP rule, and both must come before established,related and the general LAN-to-PPPoE rule.
That way, even an already-established connection from the TV cannot bypass its specific policy.
The dynamic IP problem
Naturally, one final detail remained: those eight addresses are not permanent.
My dnsmasq is version 2.93, as packaged by Slackware-current:
Dnsmasq version 2.93
Interestingly, it recognizes the --nftset option, but the official binary was compiled with:
ipset no-nftset
I could rebuild dnsmasq with nftset support and create an elegant integration between DNS and a named nftables set.
But by this point I was thinking something along the lines of: one more spot isn't going to matter to the tiger.
Updating eight IP addresses once a day does not need to become an engineering project.
So, with ChatGPT's help, I created:
/root/bin/update-lg-tv.sh
The script:
queries the current A records for
BR7.nextlgsdp.comusingdig;extracts the IP addresses currently allowed for
192.168.111.191:443from nftables;sorts both sets so DNS response ordering does not matter;
exits without doing anything if they match;
if they differ, updates the corresponding rule in
/etc/nftables.conf;validates the new configuration with
nft -c;saves a backup;
loads the new ruleset;
records what happened using
logger.
There is also one important safety precaution: if dig returns no IPv4 addresses, the script changes nothing. A temporary DNS failure cannot cause a perfectly good whitelist to be replaced by an empty one.
Its first execution was exactly as boring as an administration script should be:
# /root/bin/update-lg-tv.sh
# echo $?
0
The DNS addresses matched the firewall addresses, so it did nothing.
The script can now simply be run once a day from cron. I do not need to chase DNS changes in real time: the only purpose of this exception is to let the TV recover its clock after completely losing electrical power.
As for organization, I prefer administration scripts to remain readable. If this logic grows, instead of accumulating embedded awk, sed, and subsidiary logic inside one large shell script, I will split it into small scripts under a directory such as:
/root/bin/lg-tv/
update.sh
get-dns-ips.sh
get-nft-ips.sh
update-nft-conf.sh
Not because Bash cannot do everything in one file, but because six months from now I want to be able to look at a script and immediately understand what it does.
What I liked about this experiment
The most interesting part of the whole exercise was the method.
We started with a perfectly reasonable hypothesis:
the TV needs NTP.
The evidence said otherwise.
Then we saw HTTPS.
We allowed only port 443 and verified that the TV recovered its clock.
We logged DNS queries to identify candidate services.
We reduced firewall access exclusively to the addresses belonging to one domain.
We repeated the cold boot.
It worked.
Finally, we used tshark on the packet capture to extract the TLS SNI and confirm that the connections actually getting through the firewall were going to br7.nextlgsdp.com.
The interaction with ChatGPT was particularly useful during this process, not because it could tell me in advance that "LG gets its time from this particular server," but precisely because it could not. We built hypotheses, designed tests to eliminate them, and looked at actual evidence coming from my own network.
Some paths led nowhere — the initial NTP investigation being the obvious example — but they were still useful because they eliminated possible explanations.
In the end, there was no need to trust LG documentation, Internet blocklists, or assumptions about what a Smart TV should be doing.
We watched its packets and proved what it was actually doing.
And shadowcat4 continues doing exactly what I wanted from the beginning:
the TV is connected to my network, but that does not mean it has permission to freely talk to the Internet.
No comments:
Post a Comment