LG TV Block Mini-How-to

HOWTO: Locking LG out of a rooted webOS TV

So you have an LG TV and you want to use the “smart” features i.e. plug it into ethernet?

Our highest and best recommendation is to run the script to programmatically reject all agreements/EULAs and then just use it as a dumb display, but if you want to live dangerously.. this is a sort of mini how-to wiki.

This has also only been tested on the one target, but should be pretty readily adaptable to other models assuming something doesn’t work. If it gets complicated, I’m going to put the scripts attached here into a git repo.

Target: OLED65G5WUA, webOS 10.2.1 (starfish, build ponytail-paparoa), kernel
5.4.268-329.ptl4tv.2, LG1214 SoC, Homebrew Channel running (org.webosbrew.hbchannel.service), dropbear SSH :22 + telnetd :23,
dev mode enabled.

Audience: technically-savvy user with root SSH access to the TV.

The absolute best starting place is the Homebrew community for LG

https://www.webosbrew.org/ This is all old hat for them; been there; done that. Ironically, because I feel we cannot trust LG rooting your TV is the best way to ensure that you own the glass, not them.

Massive props, shout-out and thanks to the webOS Homebrew community. Hello and welcome!

Companion scripts: # scripts . Every script is idempotent,
POSIX /bin/sh, has a --dry-run mode, backs up before overwriting, and never
touches /var/lib/webosbrew/startup.sh or jumpstart.sh.

[!IMPORTANT]
Nothing in this document is applied automatically. You run these commands on your own rooted TV at your own risk. A factory reset wipes root, the Homebrew Channel, and every change below (This is your escape hatch at any time.)


The threat model (why layered)

LG’s TV firmware phones home through several independent channels, and no single
mechanism stops all of them:

Channel Process Endpoint
OS updates /usr/sbin/update snu/su/su-ssl/nsu.lge.com + hardcoded IP 156.147.69.32:8080
Telemetry /usr/sbin/sdx nextlgsdp.com, *.lgtvcommon.com, … (live: 54.186.247.229:443)
ACR /usr/sbin/acr2 (configured, currently inert)
Ads /usr/sbin/admanager info.lgsmartad.com (~every 60 s)
ThinQ/IoT iot-client, pushclient *.lgtviot.com, *.lgthinq.com, AWS IoT MQTT
LLM/AI com.webos.app.aiplatform ngfts.lge.com family
Crash/analytics uploadd, rdxd rdx2.nextlgsdp.com, rdl.lgtvcommon.com
Consents eula-service /var/luna/preferences/eula (accepted: Marketing, Privacy, Voice, ACR, IBA ads)

Key platform facts that shape the design (all verified on this TV):

  • /etc/hosts is on a read-only overlay (You cannot edit it in place.) The
    only way to change it is a bind-mount of a modified copy (this is exactly
    what Homebrew Channel’s own startup.sh does).
  • iptables exists but there are no netfilter kernel modules So firewall
    rules fail. Null routes are kernel state and vanish on reboot. Neither is a
    viable on-TV mechanism.
  • The persistence mechanism is /var/lib/webosbrew/init.d/* So executable
    scripts (no dots in the filename) run as root every boot by Homebrew Channel’s
    startup.sh via run-parts. This survives reboots (not factory reset).
  • The only thing that survives a factory reset is blocking done outside
    the TV: at the router.

Hence the layered design: router layer (survives everything, catches
hardcoded-IP fallbacks) + on-TV layers (official HBChannel blockers + custom
init.d hosts bind-mount + consent decline).


Layer 0: Preflight

Goal: confirm the TV is in the expected state and take backups before changing
anything.

0.1 Confirm root + Homebrew Channel

ssh root@(ip of your TV)
# expect: root@LGwebOSTV, alpine
ls -la /var/lib/webosbrew/
# expect: startup.sh, sshd/, and an (empty) init.d/
ls /media/developer/apps/usr/palm/services/ | grep hbchannel
# expect: org.webosbrew.hbchannel.service

RATIONALE: every later layer depends on the Homebrew Channel’s startup.sh
running our init.d hooks as root at boot. If the TV is not rooted or HBChannel
is not running, init.d never executes and Layers 2–5 silently do nothing. The
empty init.d/ on this TV is a clean hook point so there isn’t anything to conflict with.

0.2 Back up the files we will modify

mkdir -p /tmp/lg-lockout-backup
cp -a /etc/hosts /tmp/lg-lockout-backup/hosts
cp -a /var/luna/preferences/eula /tmp/lg-lockout-backup/eula
cp -a /var/luna/preferences/option /tmp/lg-lockout-backup/option
cp -a /var/luna/preferences/general /tmp/lg-lockout-backup/general
cp -a /mnt/lg/cmn_data/sdp/sdx/server_addr_version.conf /tmp/lg-lockout-backup/

RATIONALE: the consent files are JSON and the eula file is the one place a mistake is hard to undo by eye. A timestamped copy costs nothing and gives you a clean restore path. (The scripts also make their own .bak.* copies before every overwrite. The aim is best-practices and a little bit paranoia if you come back here to ask for help. )

0.3 Know the escape hatch

Factory reset (Settings > General >Reset, or the physical reset procedure)
wipes /var and /media: root, Homebrew Channel, dev mode, and every lockout
change are gone; the TV returns to stock LG firmware with all consents accepted.

RATIONALE: documenting this up front removes the fear factor; nothing you do
here should be irreversible. It also sets the expectation that the durable layer is
the router one (Layer 1), because only that one survives a reset.


Layer 1: Router / DHCP DNS blocking (survives everything)

Goal: make the TV unable to resolve or reach LG endpoints at the network
level, independent of anything on the TV.

1.1 Block LG domains in your DNS resolver (Pi-hole / dnsmasq)

# dnsmasq.conf (or Pi-hole Local DNS → DNS records, or AdGuard Home)
address=/nextlgsdp.com/0.0.0.0
address=/lgtvcommon.com/0.0.0.0
address=/lgsmartad.com/0.0.0.0
address=/lgtviot.com/0.0.0.0
address=/lgthinq.com/0.0.0.0
address=/snu.lge.com/0.0.0.0
address=/su.lge.com/0.0.0.0
address=/su-ssl.lge.com/0.0.0.0
address=/nsu.lge.com/0.0.0.0
address=/snu-dev.lge.com/0.0.0.0
address=/su-dev.lge.com/0.0.0.0
address=/ngfts.lge.com/0.0.0.0
# address=/lgsmartweb.com/0.0.0.0  # breaks voice search
# optional tradeoffs (see #BLOCKLIST section):
# address=/lgtvsdp.com/0.0.0.0     # breaks Content Store
# address=/lgappstv.com/0.0.0.0    # breaks Content Store

The TV’s resolver is the local connmand proxy on 127.0.0.1:53, which forwards
to your DHCP-provided upstream DNS (on this network: 10.200.0.3/.4/.5).
Blocking at the upstream resolver covers the TV with zero TV-side changes.

RATIONALE: this is the most robust layer because it’s outside the TV, it’ll survive every TV reboot, every TV factory reset, and even a re-root. It is the only layer that can catch
the hardcoded OTA fallback IP (see 1.3) and the only layer that stops the boot-time update check, which runs before startup.sh and therefore before any hosts bind-mount exists. If you skip this layer, a factory reset silently re-arms all LG phone-home with no on-TV defense left. This should also stop the forced “hey we changed the EULA don’t not not don’t do anything to confirm changes” they have lately started doing with the forced EULA popups…

1.2 Block outbound DNS to anything but your resolver

# firewall (OpenWrt / pfSense / your router):
# reject outbound :53 from the TV's subnet to any IP except your resolver

RATIONALE: some webOS firmwares bypass DHCP DNS and hardcode 8.8.8.8 (or
similar) as the resolver. If the TV can reach a public resolver, Layer 1.1 is
trivially bypassed and the TV resolves LG domains again. Blocking outbound :53
forces the TV to use only your resolver.

1.3 Block LG’s hardcoded IPs at the firewall

# reject outbound from the TV to:
#   156.147.69.32:8080   (hardcoded OTA fallback on the TV from Steve's video; domain blocks MISS this)
#   54.186.247.229:443   (observed live sdx telemetry endpoint, AWS)

RATIONALE: /usr/sbin/update contains a hardcoded IP fallback
(http://156.147.69.32:8080/CheckSWAutoUpdate.laf) used when DNS fails, which is exactly
the situation our DNS blocks create. Hosts files and DNS can never block an IP;
only a firewall can. 54.186.247.229 was the live sdx telemetry destination at
recon time; AWS endpoints can move, so this is something we should make a note to watch in the future.

Do you have Pi-hole? If you have pi-hole on your network you can watch a lot of this DNS traffic via pi-hole. But it doesn’t work for these hard-coded fallbacks.


Layer 2: Built-in Homebrew Channel blockers

Goal: enable the official, zero-maintenance blockers that ship with Homebrew
Channel.

2.1 Enable the block-updates flag

ssh root@(your tv ip)
touch /var/luna/preferences/webosbrew_block_updates

On every boot, startup.sh then:

  • bind-mounts a hosts file with snu.lge.com su-dev.lge.com su.lge.com su-ssl.lge.com
    pointed at 127.0.0.1 + ::1 (the core OTA domains), and
  • read-only bind-mounts a stub over /tmp/rdxd, /tmp/uploadd,
    /var/spool/rdxd, /var/spool/uploadd/{pending,uploaded} the telemetry
    spool directories so uploadd/rdxd cannot write crash/analytics data.

RATIONALE: this is the official mechanism maintained upstream by the
Homebrew Channel project, zero maintenance, and it exercises the exact
bind-mount technique our custom Layer 3 script reuses. Enable it first because
it is the most likely to keep working across Homebrew Channel updates. It only
covers the 4 core OTA domains, which is why Layer 3 adds even more stuff.


Layer 3 — Custom init.d hosts blocklist (10-block-lg-telemetry)

Goal: bind-mount a comprehensive hosts blocklist on every boot.

3.1 Install the script

# from your machine:
scp -r lg-lockout root@(your tv IP):/tmp/
ssh root@(your tv IP)
mkdir -p /var/lib/webosbrew/init.d
cp /tmp/lg-lockout/scripts/10-block-lg-telemetry /var/lib/webosbrew/init.d/
chmod 755 /var/lib/webosbrew/init.d/10-block-lg-telemetry

RATIONALE: run-parts executes every executable file in init.d/ so we name our file 10-block-lg-telemetry (the 10- prefix also orders it before any later hooks). chmod 755 is required or run-parts skips it. The script itself:

  • copies /etc/hosts to /tmp, appends 0.0.0.0 <domain> + ::1 <domain> for
    every domain in its block list, then mount --binds the copy over /etc/hosts
    — the only way to change hosts on the RO overlay;
  • is idempotent (re-running refreshes the file, never duplicates entries);
  • self-heals on reboot (the bind mount is not persistent; a fresh copy is made
    every boot);
  • has an opt-out flag (/var/luna/preferences/webosbrew_block_updates_extra_off)
    so you can drop the long-tail list without uninstalling.

RATIONALE (why bind-mount and not echo >> /etc/hosts): /etc/hosts is on
the read-only overlay because direct writes fail or are silently lost. The bind-mount
is the verified technique used by Homebrew Channel itself. Why not iptables or
null routes?
iptables has no netfilter kernel modules on this TV (rules fail),
and null routes are kernel state wiped on reboot. Hosts bind-mount is the only
working on-TV mechanism.

3.2 Apply now (no reboot required)

sh /var/lib/webosbrew/init.d/10-block-lg-telemetry
cat /etc/hosts          # confirm the block entries are visible

RATIONALE: the init.d hook only fires at next boot. Running it once by hand
applies the block immediately, so you can verify before rebooting.

3.3 What the block list covers

Full list with sources in BLOCKLIST Section. Summary: OTA (snu/su/su-ssl/nsu/ snu-dev/su-dev.lge.com), SDX telemetry (nextlgsdp.com family + all
*.lgtvcommon.com services + lggalleryplus.com + tv.wiselg.com), ads
(lgsmartad.com), ThinQ/IoT (*.lgtviot.com, *.lgthinq.com), LLM/AI
(ngfts.lge.com family), crash/analytics (rdx2.nextlgsdp.com,
rdl.lgtvcommon.com). Content Store (lgtvsdp.com, lgappstv.com) and voice
search (lgsmartweb.com) are commented out which are opt-in tradeoffs.

RATIONALE: every domain in the list was observed live on this TV (from the
sdx server_addr_version.conf map, binary strings, and live egress) or is
sourced from the community blocklists cited in the BLOCKLIST Section. Keeping the
tradeoff domains commented out means the default install never breaks Content
Store or voice search without an explicit choice. You should block the voice search, though.


Layer 4: Decline all LG ToS / consents (decline-tos.sh)

Goal: programmatically decline every LG consent at the source, so LG’s
services have no permission to collect.

4.1 Run the decline script

ssh [email protected]
sh /var/lib/webosbrew/lg-lockout/decline-tos.sh          # after install.sh
# or, to preview first:
sh /var/lib/webosbrew/lg-lockout/decline-tos.sh --dry-run

What it does:

  1. /var/luna/preferences/eula This sets every eulaStatus.*Allowed key to
    false (false = declined) and every per-document accepted flag in
    eulaInfo/eulaInfoNetwork to false, marking them updated so the UI
    re-reads them. On this TV that declines the currently-accepted S_MKT
    Marketing, S_PRG Privacy, S_VNG Voice, S_ADG ACR&Viewing, S_TAG IBA ads
    .
  2. /var/luna/preferences/option This sets voiceAllowed=false,
    voice2Allowed=false, watchedListCollection=off, usageCare=false,
    dbgLogUpload=false, faultLogUpload=false, thirdPartyCookie=off.
  3. /var/luna/preferences/general This sets aiNudge=off, screenSaverAd=off,
    homePromotion=off, launchEulaByHome=false.
  4. ACR opt-out marker This creates
    /mnt/lg/cmn_data/acr/data/eula_disallowed_rebooted and removes
    eula_allowed.
  5. Restarts eula-service (and acr2 if present) so the daemons re-read the
    files.

RATIONALE: this is the “we own the glass” consent grab declined at the
source
. LG’s eula-service daemon exposes no public accept/decline API —
only start/requestEulaDownload/getEulaDownloadStatus/cancelEulaDownload/ resetEula Soooo… with root we write the state files directly. Declining at the
source matters because several services key off these flags independently of
network blocking: ACR (acr.xml is ACR_On=true but the consent gate and the
opt-out marker are what actually stop it), voice data collection, and the
diagnostic/usage uploads. If you only block the network, LG’s services still
believe they have consent; declining the consent removes the authorization too. NOTE: We have observed some “interesting stuff” with how this has changed across webOS versions. More on that may appear in a future video; this was against webOS 25.

[!NOTE]
eulaStatus write shape is high-confidence from the live file; the setSystemSettings Luna command (luna://com.webos.settingsservice/ setSystemSettings, category option) is a documented alternative but the eula write shape is medium-confidence and the script backs up first for exactly this reason. There is probably no need to touch configd feature flags tv.conti.supportAcr / supportViewingInfoCollection since those seem to gate features, not consent. Significant reverse-engineering was required here and I feel LG may be deliberately obfuscating how it works from the end-user.


Layer 5: App-update gate bypass (clear-app-update-gate.sh, optional)

Goal: stop the Content Store’s “update available” nag without blocking the
Content Store itself.

5.1 Run the clear script

ssh root@(your TV IP)
sh /var/lib/webosbrew/lg-lockout/clear-app-update-gate.sh

It moves aside (with a .bak.* backup) the app store’s cached update state:

/mnt/lg/cmn_data/var/palm/data/com.webos.appInstallService/updateInfo
/mnt/lg/cmn_data/var/palm/data/com.webos.appInstallService/updateDependencyInfo

and leaves empty replacements, so the store sees “no pending updates”.

RATIONALE: adapted from dr0dr1dr2dr3/lgappupdateblocker, which blocks the
app-update gate via 172× 0.0.0.0 *.lgtvsdp.com hosts entries plus the
updateInfo wipe. We deliberately do not copy its hosts trick (it writes
/etc/hosts directly, which fails on the RO overlay; our Layer 3 covers hosts
via bind-mount) and we also wipe updateDependencyInfo, which the original
misses. This layer is optional: if you don’t care about app-update popups,
skip it.

[!WARNING]
updateInfo can be re-created by the app store after a reboot (upstream issue #2). The durable fix is the hosts/DNS layers stopping the store from reaching lgtvsdp.com in the first place but that breaks the Content Store (see caveats). This script is the no-tradeoff middle ground; run it after boot if you want it automatic.


Layer 6: Verification

Goal: confirm every layer is actually in place.

6.1 Run the verifier

ssh root@(your TV ip)
sh /var/lib/webosbrew/lg-lockout/verify-lockout.sh

It checks, and reports PASS/FAIL per item:

  1. hosts Check every expected block domain present; hosts is a bind mount.
  2. processes Check whether sdx/uploadd/rdxd/admanager are running (they
    may still run but fail to phone home — that’s the goal) .
  3. consents Check networkAllowed, acrAllowed, voiceAllowed all false in
    eula; option keys declined; ACR opt-out marker present.
  4. egress Check netstat scan for established/close-wait connections to LG
    domains.
  5. resolver Check resolv.conf points at the local connman proxy (so upstream
    blocking is what matters).
  6. app-update gate Check updateInfo absent or empty.

6.2 Manual spot-checks

# hosts block active?
cat /etc/hosts | grep -c '^0\.0\.0\.0'          # expect ~50+
# can the TV still resolve LG domains? (should FAIL)
getent hosts snu.lge.com || echo "BLOCKED"
# consent state?
grep -E 'networkAllowed|acrAllowed|voiceAllowed' /var/luna/preferences/eula
# live egress (should show nothing to LG)
netstat -tn | grep -E ':(443|80|5100)' | grep -E 'lge\.com|lgsdp|lgsmartad|lgappstv|lgtviot|lgtvcommon|lgthinq|nextlgsdp|wiselg'

RATIONALE: a lockout you can’t verify is a lockout you can’t trust. The
failure modes are silent (services that keep running but fail quietly, hosts
mounts that didn’t take, consents that got re-accepted by a UI prompt). The
verifier turns “is it working?” into a 30-second checklist. The screenshot note:
capture the verifier output for your records.


What survives reboot vs factory reset

Layer Survives reboot Survives factory reset
1 Router DNS + firewall :white_check_mark: :white_check_mark:
2 HBChannel built-in blockers :white_check_mark: :cross_mark:
3 init.d hosts bind-mount :white_check_mark: :cross_mark:
4 Consent decline :white_check_mark: :cross_mark:
5 App-update gate wipe :warning: (state may return) :cross_mark:
Root + Homebrew Channel :white_check_mark: :cross_mark:

Caveats

  1. Content Store tradeoff. lgtvsdp.com + lgappstv.com are needed for the Content Store to work. They are commented out of the default block list; the community blocklists (and lgappupdateblocker) block them, which kills the Content Store. Homebrew Channel installs via the local com.webos.appInstallService/dev/install path and keeps working either way.
  2. Voice search breaks if you block lgsmartweb.com. The voice stack (voiceinput*, trigger_thinq, trigger_alexa, wake word hiLG) is local, but the NLP/search backends are remote (nextlgsdp.com sdp_nlp, lgsmartweb.com). Local voice commands survive; voice search needs the remote backend. lgsmartweb.com is commented out by default. It isn’t clear what your exposure here is in terms of privacy. I’d recommend not using local voice services.
  3. Never accept an OS update once rooted. The update check runs before startup.sh at boot, so hosts blocking is best-effort for OTA (but the router layer is the real OTA defense). Root persistence across OS updates is not guaranteed (webOS 26 exists for 2026 models). If an update ever slips through, expect to re-root and re-apply everything.
  4. Push notifications via AWS IoT MQTT use a per-device broker certificate (/mnt/lg/cmn_data/.pushclient/push.cert.pem) with a device-specific *.amazonaws.com host; do not hosts-blockable. DNS-block *.amazonaws.com only if you accept collateral damage.
  5. Failsafe mode skips everything. Homebrew Channel has a failsafe flag (/var/luna/preferences/webosbrew_failsafe) that bypasses startup.sh and while it’s set, Layers 2–5 are inert. Only the router layer still protects you.
  6. Do not block .lge.com wholesale. It kills the Content Store and other legitimate services. Only the specific *.lge.com subdomains listed in BLOCKLIST Section are blocked.
  7. acr2 is currently inert on the test TV (empty solution lib, zeroed DB), so
    ACR blocking is preventive, not a fix for an active leak. If you want ACR fully dead, the consent decline + opt-out marker in Layer 4 is how you do that.

Uninstall / rollback

ssh root@(your tv IP) 
rm /var/lib/webosbrew/init.d/10-block-lg-telemetry
rm -rf /var/lib/webosbrew/lg-lockout
rm /var/luna/preferences/webosbrew_block_updates
# restore backups from Layer 0.2 if you want the original consents back
cp /tmp/lg-lockout-backup/eula /var/luna/preferences/eula
cp /tmp/lg-lockout-backup/option /var/luna/preferences/option
reboot   # clears the hosts bind mount

Or just factory reset and then everything is gone, including root.

WE NOT RESPONSIBLE IF THIS GOES SIDEWAYS. Perform modifications at your own risk.

#BLOCKLIST Section

LG webOS TV — Lockout Blocklist

Target: OLED65G5WUA, webOS 10.2.1 (starfish, build ponytail-paparoa), IP (your TV IP).
All domains below were observed live on this TV on 2026-08-24 (read-only recon) unless
marked community (taken from the cited blocklists, not re-verified on this unit).

Hosts-file entries block exact hostnames only as there are no wildcards in /etc/hosts.
Every subdomain a service uses must be listed individually. For DNS-layer blocking (Pi-hole /
dnsmasq) you may use wildcards where your resolver supports them (marked *).


1. OTA / OS updates

Domain What it is What breaks if blocked
snu.lge.com OTA check/feedback (CheckSWAutoUpdate.laf, DownLoadFeedback.laf, …) OS auto-update (desired)
su.lge.com OTA download (HTTP) OS auto-update (desired)
su-ssl.lge.com OTA download (HTTPS) OS auto-update (desired)
nsu.lge.com OTA (port 5100) OS auto-update (desired)
snu-dev.lge.com OTA dev endpoint nothing (dev)
su-dev.lge.com OTA dev endpoint nothing (dev)
IP 156.147.69.32:8080 Hardcoded OTA fallback IP The domain blocks MISS this nothing: must be blocked at router/firewall, hosts cannot block an IP

Source: on-device /usr/sbin/update binary strings + throwaway96/webosbrew (webosbrew.org)
and Informatic/RootMyTV (https://github.com/Informatic/rootmy.tv).

2. SDX telemetry (primary phone-home, /usr/sbin/sdx)

Endpoint map from /mnt/lg/cmn_data/sdp/sdx/server_addr_version.conf (v1.5).

2a. nextlgsdp.com family

Domain sdx service
nextlgsdp.com sdp_auth, sdp_init, sdp_common, sdp_logging, sdp_home, sdp_nlp, sdp_onnow, sdp_search, sdp_apps, sdp_apps_resource, sdp_airplay, sdp_nais
ibs.nextlgsdp.com ibis_secure
ibsstat.nextlgsdp.com ibis_stat_secure
rdx2.nextlgsdp.com rdx_secure (also used by uploadd)

2b. lgtvcommon.com family (* = wildcard-safe in DNS blockers)

Domain Service
lgtvcommon.com * base
netflixvoice.lgtvcommon.com voice proxy
nudge.lgtvcommon.com nudge (promo notifications)
homeprv.lgtvcommon.com home provisioning
wiseconfig.lgtvcommon.com smart config
pnv.lgtvcommon.com CPV
recommend.lgtvcommon.com recommendations
cdpsvc.lgtvcommon.com CDP
cpauth.lgtvcommon.com CDP auth
cdpbeacon.lgtvcommon.com CDP beacon
rdl.lgtvcommon.com rdxd crash/analytics upload
wiseresource.lgtvcommon.com wise resource
qcardservice.lgtvcommon.com qcard
qt2-kic.lab.lgtvcommon.com ThinQ AI lab endpoint

2c. Other SDX endpoints

Domain Service
lgshopsvc.lgappstv.com LG Shop
lggalleryplus.com Gallery+
tv.wiselg.com wise account / buddy

Live observation: sdx held an outbound HTTPS connection to 54.186.247.229:443 (AWS) at recon time and block that IP at the router as well (it may resolve to other IPs over time, but that’d probably require a firmware update on the TV to reconcile…)

3. ACR (Automatic Content Recognition)

Domain What it is What breaks
(none currently) acr2 (/usr/sbin/acr2) is configured (acr.xml ACR_On="true", Alphonso, dsnoop:0,12, client token LG-webOS25-X-54eGHhzNbjzrzgcM) but not running so check the solution lib dir is empty, DB zeroed ACR (desired)

Blocking is not the primary defense for ACR: decline the S_ADG consent and create the
opt-out marker (see decline-tos.sh). If ACR ever starts phoning home it will use the
SDX/nextlgsdp.com path already covered above.

4. Ads

Domain What it is What breaks
lgsmartad.com * ad server (base) ads (desired)
info.lgsmartad.com admanager polls this every ~60s (com.webos.service.admanager) ads (desired)

5. ThinQ / IoT

Domain What it is What breaks
lgtviot.com * base ThinQ app / IoT
api.lgtviot.com iot-client / sdx iot ThinQ app
commonpush.lgtviot.com iot push ThinQ push
sports.lgtviot.com iot sports sports alerts
ocp.lgtviot.com ocpservice OCP
push.lgtviot.com sportsalarm push sports alerts
buddy.lgtviot.com buddyconnector buddy
lgthinq.com * base ThinQ app
common.lgthinq.com ThinQ common ThinQ app
connect-client.lgthinq.com ThinQ connect ThinQ app

Push notifications (com.webos.service.pushclient) use AWS IoT MQTT with a per-device
certificate
(/mnt/lg/cmn_data/.pushclient/push.cert.pem) And the broker hostname is
device-specific (*.iot.<region>.amazonaws.com) and it seems LG has taken steps to ignore the local /etc/hosts for DNS-block. *.amazonaws.com only if you are willing to lose other AWS-reachable features, or use your firewall to suss out what your TV is connecting to at amazonaws.com and then block that.

6. LLM / AI platform (com.webos.app.aiplatform)

Domain What it is What breaks
ngfts.lge.com AI platform AI features (desired)
qt2-ngfts.lge.com AI platform AI features
kic-ngfts.lge.com AI platform AI features
kic-qt2-ngfts.lge.com AI platform AI features

profile.json on this TV has "llm": {"support": true} so the AI/LLM stack is enabled and
needs these endpoints. Or you can just block them if you don’t want it.

7. Crash / analytics upload

Domain What it is What breaks
rdx2.nextlgsdp.com uploadd crash upload nothing
rdl.lgtvcommon.com rdxd analytics upload (/etc/rdxd.conf AutoUpload=true) nothing

Both uploadd and rdxd were running on this TV. The built-in HBChannel “telemetry neuter”
(read-only bind-mounts over /tmp/rdxd, /tmp/uploadd, /var/spool/rdxd,
/var/spool/uploadd/{pending,uploaded}) stops them from writing – see Layer 2.

8. Voice stack

Domain What it is What breaks
nextlgsdp.com (sdp_nlp) voice NLP backend voice search / assistant
lgsmartweb.com LG web search backend voice search results

The voice stack itself (voiceinput*, trigger_thinq, trigger_alexa, voiceconductor,
performer, wake word hiLG) is local; only the NLP/search backends are remote. Blocking
them breaks voice search but not local voice commands. Optional and there are caveats.

9. Content Store / app store – There is a TRADEOFF (optional)

Domain What it is What breaks if blocked
lgtvsdp.com * Content Store / app update gate Content Store breaks; also the mechanism lgappupdateblocker uses to block app-update popups
lgappstv.com * app store / LG Shop Content Store + app installs break
lgshopsvc.lgappstv.com LG Shop service LG Shop

lgtvsdp.com + lgappstv.com are needed for the Content Store to work. Homebrew
Channel installs via com.webos.appInstallService/dev/install (local, no LG network), so
homebrew keeps working regardless. Block these only if you accept losing the Content Store.


Community blocklist sources

These folks are the real MVPs here. Huge Kudos!

Source URL Notes
TheShawnMiranda/LG-TV-Ad-Block GitHub - TheShawnMiranda/LG-TV-Ad-Block: Raw Adblock List for blocking ads on LG's WebOS. Tested on LG C2 in North America. · GitHub list + fullblock variants
hugobatista/lg-tv-ad-block GitHub - hugobatista/lg-tv-ad-block: A curated hosts list to block advertisements and tracking domains on LG Smart TVs. · GitHub
AMV007/lg_tv_blocklist GitHub - AMV007/lg_tv_blocklist: hosts for block at lg tv for not listen your in background · GitHub
kkl1974/LG-WebOS-AdGuard-blocklist GitHub - kkl1974/LG-WebOS-AdGuard-blocklist · GitHub AdGuard format
athimannil/webos-pihole-blocklists GitHub - athimannil/webos-pihole-blocklists · GitHub Pi-hole format
samsapti/LG-webOS-Blocklist GitHub - samsapti/LG-webOS-Blocklist: A non-breaking DNS blocklist that blocks ads, tracking and recommendations on LG webOS TVs · GitHub
throwaway96/webosbrew GitHub - webosbrew/webos-homebrew-channel: Unofficial webOS TV homebrew store and root-related tooling · GitHub core OTA domains (snu/su/su-ssl/snu-dev/su-dev/nsu.lge.com)
Informatic/RootMyTV https://github.com/Informatic/rootmy.tv telemetry wildcards (.lgtvsdp.com .lgsmartad.com .lgappstv.com .lgtviot.com .lgtvcommon.com)
dr0dr1dr2dr3/lgappupdateblocker GitHub - dr0dr1dr2dr3/lgappupdateblocker · GitHub app-update-gate blocker (172× 0.0.0.0 *.lgtvsdp.com + updateInfo wipe)

Wildcard guidance for DNS-layer blockers

Safe to wildcard: *.nextlgsdp.com, *.lgtvcommon.com, *.lgsmartad.com, *.lgtviot.com,
*.lgthinq.com, *.lgtvsdp.com (tradeoff), *.lgappstv.com (tradeoff).

Do NOT block .lge.com wholesale because it kills the Content Store and other legitimate services. I was surprised in my research how many LG “fans” want to keep using built-in functionality of the TV. Only block the specific *.lge.com subdomains listed above (snu/su/nsu/ngfts).

Remember to rename the files to remove the .txt extension!

10-block-lg-telemetry.txt (5.2 KB)
clear-app-update-gate.sh.txt (1.9 KB)
decline-tos.sh.txt (6.6 KB)
install.sh.txt (4.1 KB)
verify-lockout.sh.txt (4.8 KB)

33 Likes

Interesting, even if I don’t have that TV*. But publishing this will spark an “arms race“ with LG that will push an update to their units soon that makes this guide useless. :face_with_symbols_on_mouth:

*I have a 32” Philips “smart“ TV that I was gifted by my new ISP when I upgraded my internet to Gbit fibre, about 2 yrs ago.

It’s still in the unopened box :stuck_out_tongue: My other TV’s, also not in use but still working, predate the emergence of the IoT hype by at least a decade :+1:

It’s kind of amazing one has to jump through this many hoops to mitigate spyware in a TV.

1984 was supposed to be a fiction…

5 Likes

… not an instruction manual.

7 Likes

It is, isn’t it :roll_eyes:

A “quick ‘n dirty“ method, provided you don’t have a Netflix account (or similar) is to put the TV on an air-gapped LAN with your own DNS and DHCP servers, so any request to LG’s IP addresses gets automagically ignored, or perhaps redirected/forwarded to Voyager 2 or Starship Enterprise even? :wink: If you put your Plex or Jellyfin server on the same LAN you’d still be able to stream content to the TV.

Theoretically, if said server has 2 physically separate ports (absolute requirement!!), one could serve as the Intranet (with TV), while the other could accept normal traffic. Just make sure there’s no bridge configured between the two. This trick won’t work if the server has only one physical port.

1 Like

I like the idea of root tv, run programmatic “NO MEANS NO LG” eula reject script and then airgap, lol

5 Likes

Could we instead create a botnet of reformed LG TVs that turn on their master?

8 Likes

I wonder if there is anything covering feeding in low quality audio generation of gibberish from a tiny model 24/7/365. Would probably need to occasionally change it up so as to not to make it too easy to filter out.

1 Like

I wonder if you could tailor the gibberish to something silly & see if they implement it. “For some reason our users really want the tvs to come with cat ears, our listening devices are reporting it world wide”.

6 Likes

it’s disgusting to see how far these companies are willing to go for surveilance and spying. this behavior is nothing else than a criminal act and it’s terrible to see that there will be no fines for them. What companies/brands are also affected ? LG is selling their panels (including the electronics) to a lot of other companies and these displays are sold under various brands. are these brands also affected ?

1 Like

I imagine the TV would take a long time to start due to timeout trying to load the trash in the dashboard so ideally if you want to air gap make sure to use REJECT instead of DROP firewall rules. DROP is default for firewall.

My IOT vlan where I dump all the trash such as tvs, roombas, and video game consoles has no access to the internet by default with an allow list for exceptions.

3 Likes

this is great however everytime i go and check if i can root my tv (the terminology isn’t a natural one in australian english btw) there have been new exploits but also they have been patched out - i guess the difference now is i can just get hermes to check for me periodically :+1: thanks for the reminder

1 Like

I am still following this guide for my LG G5 55”, but I noticed that the 10-block-lg-telemetry script did not affect my /etc/hosts. It was saying the mount was already in place, so it would refresh the hosts file, but nothing changed and I only saw the existing homebrew channel /etc/hosts. The mount | grep -q check in it just checks for any mount over /etc/hosts, not taking into account whether it is this script’s mount or homebrew channel’s mount.

I made this change to fix it:

root@lg-g5:/var/lib/webosbrew/init.d# diff 10-block-lg-telemetry.bak 10-block-lg-telemetry
--- 10-block-lg-telemetry.bak
+++ 10-block-lg-telemetry
@@ -115,7 +115,7 @@
 HOSTS_FILTERED=$(printf '%s\n' "$BLOCK_HOSTS" | sed 's/[[:space:]]*#.*$//' | sed '/^[[:space:]]*$/d')
 
 # Idempotence: if our bind mount is already in place, just refresh the file.
-if mount | grep -q " on $MOUNT_POINT "; then
+if findmnt -n -o source "$MOUNT_POINT" | grep -q "tmpfs\[/${HOSTS_TMP#/tmp/}\]"; then
     log "bind mount already active; refreshing block file"
     # /etc/hosts currently IS our block list — rebuild from the pristine copy
     # taken on first run so we never duplicate entries.
root@lg-g5:/var/lib/webosbrew/init.d# 

Haven’t fully thought through how robust this is to changes in HOSTS_TMP locations and it won’t correct the order of the bind mounts if something else is on top of the script’s, but probably neither of those is likely.

4 Likes

now can you PLEASE do one of these for Samsung TV’s as well…these pieces of garbage are just as guilty at stealing all your personal data.

3 Likes

and these are everywhere too, and in a lot of boardrooms and medical offices

I have a samsung spyware TV and it sits on my home network which goes through my openwrt router which has a permanent wireguard outbound vpn connection, has adblock running as a service and also forwards to controld as the advertised DNS instead of the upstream DNS provided by my ISP. I read here ( Samsung & LG Smart TV DoH IP & Domain Blocklist Matrix | Privacy Smart Home ) that these tv’s use encrypted dns over google and cloudflare’s dns services to phone home if their default telemetry addresses are blocked, so it may be a good plan to avoid using google and cloudflare dns services on these tv’s if you are trying to block them at the network level.

edited to include the vpn and fixed some verbage.

2 Likes

It’s nice, although personally I’ll never give any TV internet access… perhaps limited LAN access if I have to.

I’m waiting for the day when corporations are willing to accept the cost of adding a modem and e-SIM to every device, or some other effective form of standalone internet access. Only then will the nightmare of blocking this mess begin. :slight_smile:

If only they did it properly, so that it can’t be disabled by software manipulation or by desoldering a component from the PCB without damaging and disrupting the device. In other words, an absolutely irremovable connection to the mothership. And the era will come when we’ll have to jam signals within our own lair. Dark times… it gives me chills.

2 Likes

hello @HamSandwich ,

your solution needs deeper knowledge about networking that the main mass of users haven’t. another problem is that the companies are clever. “owing the glass” is based under the terms and conditions the buyer of a smart-tv have to agree if they want to use the device.

I see a future market for Faraday cage TV enclosures.

2 Likes

fyi, if anyone else have problems with content store. Probably vary between different countries.

If I block nextlgsdp_com it disables content store on my C5 and C1. It need to reach “countrycode”_nextlgsdp_com to be exact. underscore = .

1 Like