Ich zeige hier mal anhand des in der EU nicht empfangbaren Senders RT deutsch, wie man Zensur oder Geoblocking umgeht.
Was man braucht:
- Rechentechnik (Odroid/RasPi/RockPi) mit Betriebssystem (CoreELEC/Ubuntu)
- einen ProtonVPN-Account: https://protonvpn.com
- SSH
- Docker
- TVHeadend-Server: https://hub.docker.com/r/linuxserver/tvheadend
- Streamlink: https://cgomesu.com/blog/Tvhlink/ und: https://streamlink.github.io/cli.html
- Privoxy: https://github.com/walterl/proton-privoxy und: https://www.privoxy.org/user-manual/
Auf die Installation von Betriebssystem, SSH und Docker gehe ich nicht ein.
Zunächst legt man, sofern nicht schon vorhanden, ein ProtonVPN-Konto an. Das darf ruhig zunächst ein Free-Account sein, bei dem Server in Japan, in den Niederlanden und in den USA verfügbar sind. Dort findet man unter https://account.protonvpn.com/account#openvpn die später benötigten OpenVPN-Zugangsdaten.
Dann gehts zu den Containern. Für TVH muß man zusätzlich zum /config- und zum /recordings-Verzeichnis das Verzeichnis /custom-cont-init.d mappen. Vorbereitend erstellt man also entsprechende Volumes:
Die Volumes befinden sich standardmäßig in Pfad /var/lib/docker/volumes
Im Volume "tvhcustom", also im Verzeichnis /var/lib/docker/volumes/tvhcustom/_data legt man die Datei streamlink_for_tvh_container.sh mit folgendem Inhalt an:
#!/usr/bin/env sh
###########################################################################################
# Script to install and upgrade Streamlink on the TVHeadend LinuxServer.io docker container
###########################################################################################
# How-To:
# 1. Copy 'streamlink_for_tvh_container.sh' to /custom-cont-init.d
# (see https://www.linuxserver.io/blog/2019-09-14-customizing-our-containers)
# 2. Start/Restart the tvheadend container
###########################################################################################
# Author: cgomesu
# Repo: https://github.com/cgomesu/tvhlink
###########################################################################################
# Notes
# - System-wide Python3 pkgs now managed by APK. 'testing' repo of the 'edge' branch seems
# to be pretty quick with release updates.
# - PEP 668 in Python 3.11 disables global pip3 install
# - Linuxserver.io changed location of custom scripts dir from /config/custom-cont-init.d
# to /custom-cont-init.d
# - Python 3.10.1 (edge branch) changes Python pkg directory
# - LinuxServer image comes with Python3 and the community repo source enabled
# - Streamlink 3.0.0 introduces lxml>=4.6.4 and <5.0 requirement
# - Streamlink 3.0.0 introduces pycountry and pycrypto dependencies
# - Keep this script POSIX sh compliant for compatibility
# - Use shellcheck
###########################################################################################
# Additional info
#
# Base image URL target:
# ghcr.io/linuxserver/tvheadend
#
# Script installs or upgrades the following pkg:
# python3, streamlink
#
# Tested images (tvheadend:latest):
# arm64:
# sha256:f14ee2a6c645286078c755a16a055f93860ceeb65d5e3f54ab61168e6b70b20b
###########################################################################################
# apk variables
APK_BRANCH='edge'
APK_MAIN="http://dl-cdn.alpinelinux.org/alpine/${APK_BRANCH:-edge}/main"
APK_COMMUNITY="http://dl-cdn.alpinelinux.org/alpine/${APK_BRANCH:-edge}/community"
APK_TESTING="http://dl-cdn.alpinelinux.org/alpine/${APK_BRANCH:-edge}/testing"
# takes msg ($1) and status ($2) as args
end () {
echo '***********************************************'
echo '* Finished Streamlink install/upgrade script'
echo "* Message: $1"
echo '***********************************************'
exit "$2"
}
# takes message ($1) and level ($2) as args
message () {
echo "[TVHlink] [$2] $1"
}
start () {
echo '***********************************************'
echo '****** Streamlink install/upgrade script ******'
echo '***********************************************'
echo 'Author: cgomesu'
echo 'Repo: https://github.com/cgomesu/tvhlink'
echo '***********************************************'
}
#takes a python3 pkg as argument ($1)
check_py3_pkg_exist () {
if python3 -c "import $1" > /dev/null 2>&1; then return 0; else return 1; fi
}
# checks user is root
check_root () {
if [ "$(id -u)" -eq 0 ]; then return 0; else return 1; fi
}
streamlink_apk () {
if ! apk add --upgrade -U -X "$APK_MAIN" -X "$APK_COMMUNITY" -X "$APK_TESTING" streamlink; then
end 'APK: Critical error. Unable install required packages. Check previous messages.' 1
fi
}
python3_remove_all () {
message 'APK: Python3 packages are now going to be managed by APK instead of PIP.' 'warning'
apk del --no-cache streamlink py3-lxml py3-requests py3-pip python3
}
############
# main logic
start
trap "end 'Received a signal to stop' 1" INT HUP TERM
if ! check_root; then end 'User is not root. This script needs root permission.' 1; fi
# for backward compatibility, let APK manage Python3 pkgs
# see https://github.com/cgomesu/tvhlink/issues/21
if check_py3_pkg_exist pip; then python3_remove_all; fi
message 'Installing/upgrading Streamlink...' 'info'
streamlink_apk
# EOF
message "Streamlink version: $(streamlink --version)." 'info'
end 'Reached EOF without critical errors.' 0
Alles anzeigen
Dieses Script ausführbar machen und den TVH-Container starten:
docker run -dit -p 9981:9981 -p 9982:9982 -h tvh --name tvh --restart unless-stopped -e PUID=1000 -e PGID=1000 -e TZ=Europe/Berlin -v tvhcustom:/custom-cont-init.d -v tvhconfig:/config -v tvhrecord:/recordings --network bridge linuxserver/tvheadend:latest
Danach startet man den VPN-Proxy:
docker run -d --device=/dev/net/tun --cap-add=NET_ADMIN -v /etc/localtime:/etc/localtime:ro -p 8888:8080 -e HOST_NETWORK="{DEINE_NETZWERKADRESSE}" -e PVPN_CMD_ARGS="connect --cc US" -e PVPN_TIER=0 -e PVPN_USERNAME={DEIN_PROTONVPN-USERNAME} -e PVPN_PASSWORD={DEIN_PROTONVPN-PASSWORT} --name privoxy-us walt3rl/proton-privoxy
{DEINE_NETZWERKADRESSE} ist z.B. 192.168.0.0/24 (wenn der Router unter 192.168.0.1 erreichbar ist)
Sollte es nicht notwendig sein, daß der Proxy aus dem gesamten LAN erreichbar ist, kann man die HOST_NETWORK-Variable weg lassen.
{DEIN_PROTONVPN-USERNAME} kopiert man von https://account.protonvpn.com/account#openvpn - z.B.: 1MdMap3saJKokA1nJ
{DEIN_PROTONVPN-PASSWORT} kopiert man von https://account.protonvpn.com/account#openvpn - z.B.: SkX3625DrEcKbve5WgjU9AXs8rhBpTab
Die Variable PVPN_CMD_ARGS in diesem Beispiel sorgt dafür, daß der Proxy eine Verbindung zu einem Server in den USA herstellt. Möglich mit einem Free-Account sind also auch "connect --cc NL" oder "connect --cc JP".
Die Variable PVPN_TIER enthält die Angabe, um welche Art von Konto es sich handelt (0=Free). Kann man alles auf https://github.com/walterl/proton-privoxy nachlesen.
Zuguterletzt wird die Playlist für TVH ergänzt oder angelegt. Der Eintrag für den o.g. Sender sieht z.B. so aus:
#EXTINF:-1 tvg-id="rt.de" tvg-name="RT deutsch" tvg-country="DE",RT deutsch
pipe:///usr/bin/streamlink --stdout --default-stream best --ringbuffer-size 32M --hls-audio-select "*" --http-proxy "http://192.168.0.26:8888" URL zur M3U8
IP-Adresse muß selbstverständlich angepaßt werden.
Man kann den VPN-Proxy-Container auch mehrmals (je nachdem wie viele unterschiedliche Serverman braucht) starten - dann mit anderem Namen (z.B. privoxy-nl), anderen Variablen (z.B. connect --cc NL), anderem Port-Mapping (z.B. -p 8887:8080).
Auf TVH gehe ich wie gesagt nicht ein. Läuft jedoch wie geschmiert!
Ich weise darauf hin, daß es sich hier lediglich um eine technische Anleitung handelt.
Niemand ist gezwungen oder aufgefordert, der Anleitung zu folgen, geschweige denn RT zu komsumieren.
Ich verwahre mich ausdrücklich vor Unterstellungen hinsichtlich meiner Sympathien und meines Weltbildes.