OpenHAB auf einer Kodi Box als Docker Service installieren
Nachdem ich ja, vor ein paar Tagen schon, ein PI-hole auf meine Kodi box installiert hatte, habe ich nun für die Home-Automatisierung auch noch ein openHAB mit einer influxdb2 eingerichtet um damit Licht, Thermostate und Multimedia zu steuern. Hier nun in groben schritten meine Lösung
Installation
Dockerd installieren
Wir brauchen das Kodi addon Docker in Dienste, wenn wir ein minimal System nutzen um einen dockerd zu haben.
Install xbmc.service Docker
systemd
Die service files speichere unter '/storage/.config/system.d/'
Filename: openhab.docker.service
[Unit]
Description=%p container
Requires=service.system.docker.service
Requires=network-online.service
After=network-online.service
After=pi-hole.docker.service
[Service]
Restart=always
RestartSec=10s
TimeoutStartSec=0
ExecStartPre=-/bin/sh -c "mkdir -p /storage/dockerdata/%p/data/openhab/conf /storage/dockerdata/%p/data/openhab/addons /storage/dockerdata/%p/data/openhab/userdata"
ExecStartPre=-/bin/sh -c "/storage/.kodi/addons/service.system.docker/bin/docker rm %p"
ExecStart=/storage/.kodi/addons/service.system.docker/bin/docker run \
--rm \
--name %p \
-e TZ="Europe/Berlin" \
--network=host \
--hostname %p \
-v "/storage/dockerdata/%p/data/openhab/conf:/openhab/conf" \
-v "/storage/dockerdata/%p/data/openhab/addons:/openhab/addons" \
-v "/storage/dockerdata/%p/data/openhab/userdata:/openhab/userdata" \
-v "/etc/localtime:/etc/localtime:ro" \
-v "/storage/.cache/timezone:/etc/timezone:ro" \
-e OPENHAB_HTTP_PORT=8090 \
-e OPENHAB_HTTPS_PORT=8094 \
-e CRYPTO_POLICY="unlimited" \
-e EXTRA_JAVA_OPTS="-Duser.timezone=Europe/Berlin" \
openhab/openhab:3.4.1
# https://hub.docker.com/r/openhab/openhab/tags
# docker pull openhab/openhab:latest
ExecStop=/storage/.kodi/addons/service.system.docker/bin/docker stop %p
[Install]
WantedBy=multi-user.target
Filename: influxdb.docker.service
[Unit]
Description=%p container
Requires=service.system.docker.service
Requires=network-online.service
After=network-online.service
After=pi-hole.docker.service
Before=openhab.docker.service
[Service]
Restart=always
RestartSec=10s
TimeoutStartSec=0
ExecStartPre=-/bin/sh -c "mkdir -p /storage/dockerdata/%p/data/etc /storage/dockerdata/%p/data/influxdb"
ExecStartPre=-/bin/sh -c "/storage/.kodi/addons/service.system.docker/bin/docker rm %p"
ExecStart=/storage/.kodi/addons/service.system.docker/bin/docker run \
--rm \
--name %p \
-p 8086:8086 \
# ip-hole is not bound on host localhost only inside the bridge
--dns=172.17.0.1 \
--add-host host.docker.internal:host-gateway \
#--network=host \
--hostname %p \
-v "/storage/dockerdata/%p/data/etc:/etc/influxdb2" \
-v "/storage/dockerdata/%p/data/influxdb:/var/lib/influxdb2" \
-e DOCKER_INFLUXDB_INIT_MODE="setup" \
-e DOCKER_INFLUXDB_INIT_USERNAME="admin" \
-e DOCKER_INFLUXDB_INIT_PASSWORD="admin1234" \
-e DOCKER_INFLUXDB_INIT_ORG="myorg" \
-e DOCKER_INFLUXDB_INIT_BUCKET="openhab" \
-e DOCKER_INFLUXDB_INIT_ADMIN_TOKEN="extremtopsecrettoken1234" \
-e INFLUXD_LOG_LEVEL="warn" \
-e TZ="Europe/Berlin" \
# docker wand pull a arm/v7 image wat not exist for influxdb2
--platform linux/arm64 \
influxdb:2.6
# https://hub.docker.com/_/influxdb/tags
ExecStop=/storage/.kodi/addons/service.system.docker/bin/docker stop %p
[Install]
WantedBy=multi-user.target
Steuerung des Services mit Systemd
Systemd Konfiguration neu einlesen.
systemctl daemon-reload
Service starten
systemctl start influxdb.docker.service
systemctl start openhab.docker.service
Service status
systemctl influxdb.docker.service
systemctl status openhab.docker.service
Start Service on reboot
systemctl enable openhab.docker.service
systemctl enable influxdb.docker.service
Service stoppen
systemctl stop openhab.docker.service
systemctl stop influxdb.docker.service
Logs lesen
journalctl -u openhab.docker.service
journalctl -u influxdb.docker.service
tail -f /storage/dockerdata/openhab.docker/data/openhab/userdata/logs/*.log
Bash im laufendem Docker öffnen
docker exec -it openhab.docker /bin/bash
Influxdb
Set New influxdb admin pw
Aus der infuxdb doku 'User passwords cannot be updated in the InfluxDB UI.'
Wir müssen als das pw mit der Shell ändern und das geht mit dem init token welsches bei dem ersten Start eingerichtet wird.
docker exec -it influxdb.docker influx user password -n admin -t extremtopsecrettoken1234
- go to Load Data->API Tokens
- Gerate API Token...
- Alte Admin token in der Liste löschen
Influxdb als persistent storage in openHAB einrichten
Als erstes muss man sich in openHAB einloggen und dort in die Settings gehen und bei den Add-ons das addon "InfluxDB Persistence" suchen und installieren.
Nach der Installation hat man nun in den Settings bei 'Other Services' die Einstellungen 'InfluxDB Persistence Service' wo man seine InfluxDB verbinden kann. Hier reichen wenige Optionen.
- Database URL: http://127.0.0.1:8086
- Database Version: InfluxDB 2
- Authentication Token: ein neues auth token generieren wie schon bei dem Admin pw ändern beschreiben und einfügen.
- Database/Organization: myorg
- Retention Policy / Bucket: openhab
Ich habe dann noch die 3 folgenden Schalter an gemacht 'Add Category Tag', 'Add Type Tag', 'Add Label Tag' um es eventuell später in Grafana als Selektor nutzten zu können.
Nun können wir die influxdb als Persistence storage auswählen. Dafür gehen wir wieder in den Settings zu den 'System Services' in die 'Persistence' Option und wählen 'InfluxDB persistence layer'.
Für die Persistence Config gibt es jetzt noch ein File was wir anlegen müssen und wofür es leider keine UI Config gibt.
Dafür legen wir das folgende File an
Filename: /storage/dockerdata/openhab.docker/data/openhab/conf/persistence/influxdb.persist
Strategies {
default = everyChange, restoreOnStartup
}
Items {
// persist all items on every change and restore them from the db at startup
* : strategy = everyChange, restoreOnStartup
}
Und nun sollten, sobald wir thinks haben Daten in der InfluxDB zu finden sein :)
Das war es schon, wie man nun ein paar Sachen in openHAB einbaut und benutzt werde ich in einem weiteren Artikel beschreiben.
Viel Spaß beim Nachbauen
Links
PI-hole auf einer Kodi Box als docker Service installieren
Ich habe mir vor einiger Zeit eine recht leistungsstarke und mit genug Ressourcen ausgestattete Kodi Box zugelegt die ich nun zum Testen mit ein paar Service auf Docker Basis nutzten wollte um nicht noch einen Server betreiben zu müssen bzw. die Existierenden Ressourcen einfach zu nutzten. Die Basis auf Docker hat hier 2. gründe. erstens Benutzte ich CoreELEC als Distribution, weswegen ich nur ein sehr minimales Linux System habe wo ich nicht einfach Pakete installieren kann und zweitens, ich mit einem fertigen Docker alles Nötige ohne Große spielen, in einem packet habe, welsches von dem restlichen System gut genug getrennt ist.
Installation
Dockerd installieren
Wir brauchen das Kodi addon docker in Dienste wenn wir ein minimal System nutzen um einen dockerd zu haben.
Install xbmc.service Docker
systemd
Das service file speichere ich in '/storage/.config/system.d/pi-hole.docker.service'
[Unit]
Description=%p container
Requires=service.system.docker.service
Requires=network-online.service
After=service.system.docker.service
After=network-online.service
Befora=kodi.service
[Service]
[Unit]
Description=%p container
Requires=service.system.docker.service
Requires=network-online.service
After=service.system.docker.service
After=network-online.service
Before=kodi.service
[Service]
Restart=always
RestartSec=10s
TimeoutStartSec=0
ExecStartPre=-/bin/sh -c "mkdir -p /storage/dockerdata/%p/config/etc-pihole /storage/dockerdata/%p/config/dnsmasq"
ExecStartPre=-/bin/sh -c "/storage/.kodi/addons/service.system.docker/bin/docker rm %p"
ExecStartPre=-/bin/sh -c "ntpd -d -n -q -p 157.90.24.29"
ExecStart=/storage/.kodi/addons/service.system.docker/bin/docker run \
--rm \
--name %p \
-p 53:53/tcp -p 53:53/udp \
-p 8053:80 \
-e TZ="Europe/Berlin" \
#-e # WEBPASSWORD: 'set a secure password here or it will be random' \
-v "/storage/dockerdata/%p/config/etc-pihole:/etc/pihole" \
-v "/storage/dockerdata/%p/config/dnsmasq:/etc/dnsmasq.d" \
--dns=192.168.1.1 --dns=192.168.8.1 \
#--restart=unless-stopped \
--hostname coreelec \
-e VIRTUAL_HOST="coreelec" \
-e FTLCONF_LOCAL_IPV4="192.168.8.190" \
pihole/pihole:latest
# before set a new docker have u to pull it manual
# docker pull pihole/pihole:latest
# ohne dns kein pull ohne pull kein docker :)
ExecStop=/storage/.kodi/addons/service.system.docker/bin/docker stop %p
[Install]
WantedBy=multi-user.target
Steuerung des Services mit systemd
Systemd Konfiguration neu einlesen.
systemctl daemon-reload
Service starten
systemctl start pi-hole.docker.service
Service status
systemctl status pi-hole.docker.service
Start Service on reboot
systemctl enable pi-hole.docker.service
Service stoppen
systemctl stop pi-hole.docker.service
Logs lesen
journalctl -u pi-hole.docker.service
Password für die Web-UI von Pi-hole
Wenn man ein Pi Hole das erste Mal aufsetzt, muss man ein neues Password setzten. Dafür gibt es 2 Wege.
-
Im dem Service File WEBPASSWORD setzten.
-
Neu setzten des Web-Passwords in dem Docker selbst mit dem Befehl
docker exec pi-hole.docker pihole -a -p
Zeit stellen
Meine Kodi Box hat keine Akku gepufferte Uhr weswegen ich nach jedem Reboot die Zeit neu stellen muss, das habe ich auch in dem Service Init eingebaut weil ohne richtige Zeit viele Probleme mit z.B. SSL auftreten und so Downloads fehlschlagen könnten oder diverse Crypto nicht richtig funktioniert.
Ermittel eine $IP aus pool.ntp.org
ntpd -d -n -q -p $IP
Der Grund für die ip ist, ohne DNS Server keine DNS Auflösung und man startet den Service ja erst :)
IP-Hole über DHCP als Primären DNS auf einen OpenWRT Router einrichten
Router via ssh Verbinden und dann die DHCP-Konfiguration anpassen.
/etc/config/dhcp
und yourDNSIP mit der ip vom IP-Hole ersetzten
config 'dhcp' 'lan'
...
list 'dhcp_option' '6,yourDNSIP'
So hat jeder Client den PI-hole als DNS Server und nicht den Router, so kann man in PI-hole genau sehen welscher Client welsche anfrage gemacht hat.
HDMI Suspend verhindern
Die Kodi Box ging bisher immer in den Suspend Modus, wenn der Fernseher ausgeschaltet wurde. Das ist aber jetzt nicht mehr gewollt, wenn wichtige Dienste auf der Box Parallel Laufen. Deswegen schalte ich aus, dass die Box auf das HDMI-Signal reagieren soll und verhindere so das Ungewollte einschlafen.
# HDMI CEC Control
# Setup custom options by enable these flags:
#
# Function bit
# CEC_FUNC_MASK 0
# ONE_TOUCH_PLAY_MASK 1
# ONE_TOUCH_STANDBY_MASK 2
# AUTO_POWER_ON_MASK 3
# STREAMPATH_POWER_ON_MASK 4
# CEC_INPUT_MASK 5
# ACTIVE_SOURCE_MASK 6
#
# default: cec_func_config=7f
Wir wollen kein ONE_TOUCH_STANDBY_MASK also das 2. Bit auf 0, ich setzte cec_func_config also auf 0b1101111 = 0x6F. zum Hinzufügen von cec_func_config=6f muss man mit ssh auf die Box und den /flash Mount Point auf Beschreibbar umstellen und die config anpassen.
ssh to CE
mount -o rw,remount /flash
nano /flash/config.ini
mount -o ro,remount /flash
Blocklisten
Pi-hole bringt zwar eine Block Liste mit, aber es gibt weit mehr nützliche listen, um sein internetleben Freier zu verbringen :)
Viel Spaß beim Nachbauen
Links
Lazy Loading ist nun im Blog komplett implementiert
Lazy Load ist eine Technik, Content erst zu laden, wenn er auch tatsächlich vom User betrachtet wird und Content der außerhalb des angezeigten Bereiches erst einmal nicht vom Browser laden zu lassen um Traffic und CPU/GPU Ressourcen zu sparen. Es ist besonders bei Bilderblogs sehr wirksam da dort besonders viel Traffic entsteht und es das Seitenladen sehr beschleunigt.
Lazy load für Bilder
Für Bilder habe ich vanilla-lazyload eingebaut, um auf der Index Seite bei vielen Bildern einen Geminderten Load zu erreichen. Das hat sehr gut funktioniert und das Bilder Blog in der Ladezeit beschleunigt.
Die Implementierung war sehr einfach man muss eigentlich nur die JS Lib laden und den IMG Tag etwas anders schreiben.
Beispiel
Im Header habe ich aus den Beispielen ein paar Sachen übernommen, mit ein wenig Logging Feedback in der Konsole. Ich habe dann noch ein myLazyLoad.update() hinzugefügt welsches nach dem fertigen laden der Seite nochmal alle Bilder indexiert, weil das normale laden der Lib wohl ein Limit hat und nicht alle Bilder gefunden hatte.
<style>
img:not([src]) {
visibility: hidden;
}
/* Fixes Firefox anomaly during image load */
@-moz-document url-prefix() {
img:-moz-loading {
visibility: hidden;
}
}
</style>
<script>
function logElementEvent(eventName, element) {
console.log(Date.now(), eventName, element.getAttribute("data-src"));
}
var callback_enter = function (element) {
logElementEvent("🔑 ENTERED", element);
};
var callback_exit = function (element) {
logElementEvent("🚪 EXITED", element);
};
var callback_loading = function (element) {
logElementEvent("⌚ LOADING", element);
};
var callback_loaded = function (element) {
logElementEvent("👍 LOADED", element);
};
var callback_error = function (element) {
logElementEvent("💀 ERROR", element);
element.src =
"https://via.placeholder.com/440x560/?text=Error+Placeholder";
};
var callback_finish = function () {
logElementEvent("✔️ FINISHED", document.documentElement);
};
var callback_cancel = function (element) {
logElementEvent("🔥 CANCEL", element);
};
window.lazyLoadOptions = {
threshold: 0,
// Assign the callbacks defined above
callback_enter: callback_enter,
callback_exit: callback_exit,
callback_cancel: callback_cancel,
callback_loading: callback_loading,
callback_loaded: callback_loaded,
callback_error: callback_error,
callback_finish: callback_finish,
elements_selector: ".img-zoomable"
};
window.addEventListener(
"LazyLoad::Initialized",
function (e) {
console.log(e.detail.instance);
},
false
);
document.addEventListener('DOMContentLoaded', function () {
var myLazyLoad = new LazyLoad(window.lazyLoadOptions);
myLazyLoad.update();
});
</script>
<script async type="text/javascript" src="{{ rootUrl }}/js/lazyload.min.js"></script>
Die IMG Tags haben nun kein src Attribut mehr sondern ein data-src Attribut welsches die Bild URL beinhaltet was bei sichtbar werden des Bildes geladen werden soll.
<a href="ORGIMGURL" target="_blank">
<img data-src="LAZYLOARDIMGURL" alt="image" />
</a>
Das funktioniert bei meinem Bilder Blog, auf dem teils mehrere 100 Bilder auf der Startseite zu sehen sind sehr gut und mit allen getesteten Browsern und Mobilgeräten.
Lazy load für krpano
Bei krpano hatte ich das Problem das Handys teils Probleme hatten, mehr als 4 Panoramen auf einer Seite darzustellen, was dann dazu geführt hatte das kein Panorama mehr funktionierte. Das Problem habe ich mit einen Lazyloader mit Hilfe von IntersectionObserver() lösen können und die Ladezeit des Blogs noch mehr Verbessert.
Beispiel
Im Header habe ich einen krpanoobserver() erzeugt der die Sichtbarkeit der registrierten Elemente Überwach und bei Sichtbarkeit das Panorama Lädt und beim weiter scrollen das Panorama wieder Löscht um WebGl Ressourcen Frei zu machen.
<script type="text/javascript" src="{{ rootUrl }}/js/krpano/krpano.js"></script>
<script>
var krpanolist = ["dummy"];
var krpanoobserver = new IntersectionObserver(function(entries) {
if(entries[0]['isIntersecting'] === true) {
//console.log('Target is visible in the screen');
for (let i = 0; i < krpanolist.length; i++) {
if (krpanolist[i] == entries[0].target.id) {
return;
}
}
console.log('add krpano ' + entries[0].target.id );
krpanolist.push( entries[0].target.id )
embedpano({xml:entries[0].target.attributes.xml.nodeValue, target:entries[0].target.id, id:'krpanoSWFObject'+entries[0].target.id , html5:"only", mobilescale:1.0, passQueryParameters:"startscene,startlookat"});
}
else {
console.log('remove krpano ' + entries[0].target.id);
removepano( 'krpanoSWFObject'+entries[0].target.id );
krpanolist = krpanolist.filter(item => item !== entries[0].target.id)
}
}, { threshold: [0, 0.01, 1] });
</script>
Im Artikel lade ich jetzt nicht mehr das Panorama sondern konfiguriere mit dem krpanoobserver() das Laden des Panoramas und gebe ihm die #ID mit, in dem das Panorama Geladen werden soll bzw. welsches HTML Element observiert werden soll und mit dem xml Attribut gebe ich ihn die url zum pano.xml File welsches geladen werden soll.
<div id="pano_BFUbPBDC" class="pano-image" xml="PANORAMAURL/pano.xml">
<script>
krpanoobserver.observe(document.querySelector("#pano_BFUbPBDC"));
</script>
</div>
Lazy load für openlayer
OpenLayers Benutzte ich um GPX Tracks oder Kartenpunkte im Blog Darzustellen. OpenLayers scheint aber lade Probleme zu bekommen wenn zu viele Karten auf der selben Seite geladen werden, weswegen ich auch für OpenLayers ein Lazy Loading in Blog eingebaut habe um die Karten erst zu laden wenn sie Angezeigt werden soll.
Beispiel
Im Header habe ich einen olmapobserver() Gebaut der bei der ersten Sichtbarkeit der Karte diese lädt und sie dann ignoriert.
<script src="{{ rootUrl }}/js/ol/ol.js"></script>
<script src="{{ rootUrl }}/js/openlayer_init.js"></script>
<link rel="stylesheet" media="screen" href="{{ rootUrl }}/js/ol/ol.css">
<script>
// LazyLoad for openlayer map
var olmaps = {};
var olmapobserver = new IntersectionObserver(function(entries) {
mymapID = entries[0].target.id.split("_")[1];
if(entries[0]['isIntersecting'] === true) {
if(olmaps[mymapID].getTarget() == null) {
console.log('add ol map ' + entries[0].target.id);
olmaps[mymapID].setTarget( entries[0].target.id );
}
}
}, { threshold: [0, 0.01, 1] });
</script>
Im Artikel habe ich die Map soweit vorbereitet und alle Maps in olmaps[] fertig konfiguriert gespeichert. Danach werden sie im Observer mit olmaps[mymapID].setTarget( entries[0].target.id ); ihrem Target zugewiesen, womit sie dann endgültig geladen wird.
<div id="olmap_mapSFDXPwaB" class="olmap">
<select id="tilesource_mapSFDXPwaB" class="tilesource">
<option value="oSTREETm" selected="selected">OpenStreetMap.org</option>
<option value="OSMDE" >OpenStreetMap.de</option>
<option value="4UMAPS" >4UMaps.eu</option>
<option value="CYCLOSM" >CyclOSM</option>
<option value="OPENTOPOMAP" >OpenTopoMap</option>
<option value="TOPPLUS" >TOP PLUS</option>
<option value="ArcGIS">Satellite</option>
</select>
</div>
<script>
olmaps.mapSFDXPwaB = new ol.Map({
controls: ol.control.defaults.defaults().extend([
new ol.control.FullScreen(),
new ol.control.OverviewMap({
layers: [
new ol.layer.Tile({
source: tileSource_oSTREETm,
}),
],
})
]),
target: null, // 'olmap_mapSFDXPwaB'
layers: [],
view: new ol.View({
center: [0, 0],
zoom: 0
})
});
olmaps.mapSFDXPwaB.addLayer(new ol.layer.Tile({
source: tileSource_OSMDE
}));
var vectorSource_mapSFDXPwaB = new ol.source.Vector({
url: 'URLZUMGPXTRACK.gpx',
format: new ol.format.GPX()
});
var vectorStyle = new ol.style.Style({
stroke: new ol.style.Stroke({
color: 'red',
width: 3,
opacity: 0.5
})
});
olmaps.mapSFDXPwaB.addLayer(new ol.layer.Vector({
source: vectorSource_mapSFDXPwaB,
style: vectorStyle
}));
var layers_mapSFDXPwaB = olmaps.mapSFDXPwaB.getLayers().getArray();
vectorSource_mapSFDXPwaB.once('change',function(e){
if(vectorSource_mapSFDXPwaB.getState() === 'ready') {
if(layers_mapSFDXPwaB[1].getSource().getFeatures().length > 0) {
olmaps.mapSFDXPwaB.getView().fit(vectorSource_mapSFDXPwaB.getExtent());
}
}
});
var select_mapSFDXPwaB = document.getElementById('tilesource_mapSFDXPwaB');
function onChange_mapSFDXPwaB() {
var newMap = select_mapSFDXPwaB.value;
if(newMap) {
var tileSource ='tileSource_' + newMap;
var mapSource = eval(tileSource);
var mapLayer0 = layers_mapSFDXPwaB[0];
mapLayer0.setSource(mapSource);
}
}
select_mapSFDXPwaB.addEventListener('change', onChange_mapSFDXPwaB);
olmapobserver.observe(document.querySelector("#olmap_mapSFDXPwaB"));
</script>
Viel Spaß beim Nachbauen
Links
Steam Deck zum Desktop Rechner machen
Das Steam-Deck ist nicht nur eine tolle lösung um überall Spielen zu können sondern auch ein brauchbarer Linux Linux Desktop auf Basis von Arch Linux.
es ist auch sehr einfach selbe Software zu installieren.
Zum Desktop Modus wechseln
- geh in das Steam Menü
- Betätige die Ein/Aus Schaltfläche
- geh auf „Zum Desktop wechseln“
Nun lädt ein eigener KDE Desktop den man, mit einem angeschlossenen Monitor, super Konfigurieren kann.
User Passwort Setzen
Um was als root auf des Steam-Deck machen zu können, muss man sich erst ein User pw geben für sudo.
- Aus dem Startmenü die Konsole öffnen
- Das Kommando 'passwd' eingeben
- Sein neues Password setzten
Nun kann man mit sudo arbeiten.
Lese-Schreib Modus Einschalten
Wenn man aber nun eigene Pakete installieren möchte muss man die Steam-Deck aus ihren Sicherheit‘s Read-Only Modus befreien.
Dafür muss man wieder auf die Konsole gehen und folgendes nach einander eingeben.
sudo steamos-readonly disable
sudo pacman-key --init
sudo pacman-key --populate archlinux
sudo pacman -Syu
Software Suchen
Pakete kann man mit pacman finden.
pacman -Ss "^mc"
als Beispiel und installieren geht dann mit
pacman -S mc
Links
Externe ports in das interne Netz Portforwarden
In Speziellen Fällen braucht man eine Portweiterleitung in das eigene Netzwerk, in meinem Fall verhindert eine VPN den externen Zugriff auf port 22, also hole ich mir den port auf meinem OpenWrt Router.
-
edit /etc/config/firewall
nano /etc/config/firewall
-
add follow lines
config redirect option name 'blog.medi.li ssh' option src 'lan' option proto 'tcpudp' option src_dport '5555' option dest_ip '$ServerIP' option dest_port '22' option target 'DNAT' option dest 'wan' option gl '1'
-
reload rules
/etc/init.d/firewall reload
Und connecte mich local gegen meinen Router auf port 5555, der mich dann zu meinem Server weiter leitet.
Die Latenz is echt klein und nicht bemerkbar und es ist schneller als ein SSH Tunnel auf einem 2. Gerät :)
bleibt neugierig