apache2 Proxy mit Cache

apache2 Proxy mit Cache

apache

Ich nutze im ioBroker als Wetter Adapter Weather Undergound. Damit rasch das eigene Wetter abgefragt und in vis-2 mit Material-Design als HTML-Ausgabe dargestellt. Einfach, schlicht – tut es mir. Nur beziehe ich die Icons direkt von Weather Underground. Das muss doch auch anders gehen: Also hab ich mal eben einen apache2 Proxy davorgesetzt. Damit sind meine Zugriffe lokal und zusätzlich noch mit einem Cache. Es lohnt ja nicht jedes Bild immer und immer wieder zu laden – wenn man es doch in einem Cache ablegen könnte.

Bevor einer fragt: Ja, das ist sicherlich nicht sicher einfach so alles ohne irgendwelche Sicherheitsmaßnahmen umzusetzen. Das weiß ich auch. Zum einen läuft das bei mir nur intern und nicht öffentlich im Internet, zum anderen ging es mir um die Funktion. Ich wollte das einfach mal mit apache2 umgesetzt haben. Nicht mehr, nicht weniger 😉 Und betrachte dies als Beispiel: Bei mir war die Ausgangslage ioBroker. Wer weiß, was es bei Dir ist 😛

Das hier will ich haben:

Weather Underground im ioBroker

Das aktuelle Wetter inklusive Vorhersage 😉

Und so ist es gelöst – einfach folgenden HTML-Code in einem „Vis 2 Material-Widgets HTML-Vorlage“ einfügen:

<style>
.grid-container {
    display: grid;
    grid-template-columns: 64px auto;
    gap: 5px;
    padding: 5px;
    font-size: 0.8em;
}
.grid-container div {
    margin: auto 0;
}
.grid-container img {
    width: 64px;
    height: 64px;
}
</style>

<div class="grid-container">
    <div>
        <img src="{v:weatherunderground.0.forecast.0d.iconURL;alt:0_userdata.0.Wetter.Tagesvorhersage.VorhersageIcon;v?v:alt}">
    </div>
    <div>
        <span style="font-weight:bold;">Jetzt</span><br>
        {weatherunderground.0.forecast.current.temp} °C
    </div>

    <div>
        <img src="{v:weatherunderground.0.forecast.0d.iconURL;alt:0_userdata.0.Wetter.Tagesvorhersage.VorhersageIcon;v?v:alt}">
    </div>
    <div>
        <span style="font-weight:bold;">Heute: {weatherunderground.0.forecast.0d.date;date(DD.MM.YYYY)}</span>
        <br>
        {weatherunderground.0.forecast.0d.tempMin}
        -
        {weatherunderground.0.forecast.0d.tempMax} °C
        ({weatherunderground.0.forecast.0d.cloudCover} % Wolkendichte)
        <br>
        Regen: {weatherunderground.0.forecast.0d.precipitationChance} % ({weatherunderground.0.forecast.0d.precipitationAllDay} mm)
        <br>
        {weatherunderground.0.forecast.0d.state}
    </div>

    <div>
        <img src="{weatherunderground.0.forecast.1d.iconURL}">
    </div>
    <div>
        <span style="font-weight:bold;">{weatherunderground.0.forecast.1d.date;date(DD.MM.YYYY)}</span>
        <br>
        {weatherunderground.0.forecast.1d.tempMin}
        -
        {weatherunderground.0.forecast.1d.tempMax} °C
        ({weatherunderground.0.forecast.1d.cloudCover} % Wolkendichte)
        <br>
        Regen: {weatherunderground.0.forecast.1d.precipitationChance} % ({weatherunderground.0.forecast.1d.precipitationAllDay} mm)
        <br>
        {weatherunderground.0.forecast.1d.state}
    </div>

    <div>
        <img src="{weatherunderground.0.forecast.2d.iconURL}">
    </div>
    <div>
        <span style="font-weight:bold;">{weatherunderground.0.forecast.2d.date;date(DD.MM.YYYY)}</span>
        <br>
        {weatherunderground.0.forecast.2d.tempMin}
        -
        {weatherunderground.0.forecast.2d.tempMax} °C
        ({weatherunderground.0.forecast.2d.cloudCover} % Wolkendichte)
        <br>
        Regen: {weatherunderground.0.forecast.2d.precipitationChance} % ({weatherunderground.0.forecast.2d.precipitationAllDay} mm)
        <br>
        {weatherunderground.0.forecast.2d.state}
    </div>

    <div>
        <img src="{weatherunderground.0.forecast.3d.iconURL}">
    </div>
    <div>
        <span style="font-weight:bold;">{weatherunderground.0.forecast.3d.date;date(DD.MM.YYYY)}</span>
        <br>
        {weatherunderground.0.forecast.3d.tempMin}
        -
        {weatherunderground.0.forecast.3d.tempMax} °C
        ({weatherunderground.0.forecast.3d.cloudCover} % Wolkendichte)
        <br>
        Regen: {weatherunderground.0.forecast.3d.precipitationChance} % ({weatherunderground.0.forecast.3d.precipitationAllDay} mm)
        <br>
        {weatherunderground.0.forecast.3d.state}
    </div>

    <div>
        <img src="{weatherunderground.0.forecast.4d.iconURL}">
    </div>
    <div>
        <span style="font-weight:bold;">{weatherunderground.0.forecast.4d.date;date(DD.MM.YYYY)}</span>
        <br>
        {weatherunderground.0.forecast.4d.tempMin}
        -
        {weatherunderground.0.forecast.4d.tempMax} °C
        ({weatherunderground.0.forecast.4d.cloudCover} % Wolkendichte)
        <br>
        Regen: {weatherunderground.0.forecast.4d.precipitationChance} % ({weatherunderground.0.forecast.4d.precipitationAllDay} mm)
        <br>
        {weatherunderground.0.forecast.4d.state}
    </div>        

    <div>
        <img src="{weatherunderground.0.forecast.5d.iconURL}">
    </div>
    <div>
        <span style="font-weight:bold;">{weatherunderground.0.forecast.5d.date;date(DD.MM.YYYY)}</span>
        <br>
        {weatherunderground.0.forecast.5d.tempMin}
        -
        {weatherunderground.0.forecast.5d.tempMax} °C
        ({weatherunderground.0.forecast.5d.cloudCover} % Wolkendichte)
        <br>
        Regen: {weatherunderground.0.forecast.5d.precipitationChance} % ({weatherunderground.0.forecast.5d.precipitationAllDay} mm)
        <br>
        {weatherunderground.0.forecast.5d.state}
    </div>

</div>

Im Objekt {weatherunderground.0.forecast.0d.iconURL} stehen URLs wie diese hier: https://www.wunderground.com/static/i/c/v4/28.svg. Und ich hätte gerne, dass daraus das hier wird: https://10.96.100.66:8082/proxy.0/img/https://www.wunderground.com/static/i/c/v4/28.svg. Damit vis-2 keinen externen Apache direkt aufruft, nutze ich den Proxy-Adapter. In diesem ist folgender Pfad gesetzt: aus /proxy.0/img/… mache https://10.96.100.66:4444/img/… wie in folgendem Screenshot gezeigt:

ioBroker Proxy-Adapter

ioBroker Proxy-Adapter Pfad-Einstellung

So wie ich vis-2 in meinem Webbrowser öffne und mir die Wettervorhersage anschaue, werden im Webbrowser die Bilder über die gleiche Adresse geladen, wie vis-2 selbst. Im Hintergrund setzt der Proxy-Adapter, wie oben gezeigt, die Anfragen auf den lokal installieren apache2 um – welcher die Proxy Anfragen an Port 4444 annimmt.

Dazu habe ich in der apache2 Konfig einen neuen vhost angelegt. Dieser lauscht auf Port 4444 und ist via https erreichbar. Als Cache nutze ich das apache2 Modul cache_disk. Damit das korrekt funktioniert, lasse ich die eventuell von der eigentlichen Anfrage gelieferten Header zum Caching durch meine eigenen überschreiben. Als nächstes wird die URL umgeschrieben. Aus https://<meine ioBroker>:4444/img/<https://das eigentliche Bild> soll einfach der Teil nach /img/ extrahiert und als eigentliche Bild-Quelle verwendet werden. Hier gibt es lediglich einen kleinen Haken: apache2 ersetzt // bei https:// durch einen /. Es wird aus der URL also http:/<wohin auch immer>. Deswegen wird die neue URL aus dem Protokoll, verbunden durch einen / und der eigentlichen Anfrage, zusammengesetzt. Sollte es zu einem Fehler kommen, lasse ich ein fallback.svg anzeigen. Und zuletzt lasse ich noch in die Standardlogdaten entsprechende Hinweise eintragen.

So sieht das ganze aus:

Listen 4444
<VirtualHost *:4444>
    ServerName imgprx.gehirn-mag.net.internal

    SSLEngine on
    SSLCertificateFile  /etc/apache2/ssl/fullchain.pem
    SSLCertificateKeyFile /etc/apache2/ssl/key.pem

    # --- Caching ---
    Header unset Cache-Control
    Header unset Pragma
    Header set Cache-Control "public, max-age=86400"
    CacheQuickHandler off
    CacheLock on
    CacheLockPath /tmp/mod_cache-lock
    CacheIgnoreHeaders Set-Cookie Cache-Control Pragma Expires
    CacheRoot /var/cache/apache2/mod_cache_disk
    CacheEnable disk /
    CacheDisable /fallback.svg
    CacheDefaultExpire 604800
    CacheMaxExpire 604800

    # --- URL Rewrite für /img/<https://asfasfdsa> ---
    # Apache macht aus https://bla... https:/bla... <-- Split in zwei Teile
    SSLProxyEngine On
    RewriteEngine On
    RewriteRule ^/img/(https?:)(.+)$ - [E=TARGET:$1/$2,E=TPROTO:$1,E=TURL:$2]
    RewriteCond %{ENV:TARGET} !=""
    RewriteRule ^(.*)$ %{ENV:TARGET} [P,L]

    # --- Fallback bei Fehlern ---
    ProxyErrorOverride On
    ErrorDocument 404 /fallback.svg
    ErrorDocument 500 /fallback.svg
    ErrorDocument 502 /fallback.svg
    ErrorDocument 503 /fallback.svg
    ErrorDocument 504 /fallback.svg
    Alias /fallback.svg /var/www/vhosts/proxy/fallback.svg

    # --- Log ---
    CustomLog /var/log/apache2/other_vhosts_access.log "%h %l %u %t \"%r\" %>s %b \"cache:%{cache-status}e\" \"target:%{TARGET}e\""
    ErrorLog  /var/log/apache2/error.log
</VirtualHost>

Im HTML-Vorlage Widget vom ioBroker habe ich die URLs nun wie folgen geändert: <img src=“/proxy.0/img/{weatherunderground.0.forecast.1d.iconURL}“>. Also lediglich ein /proxy.0/img vorangestellt. Bekommen habe ich also, dass im Webbrowser die externen Bilder ebenfalls über vis-2 geladen werden. Allerdings geht im Hintergrund ein apache2 ran, welcher die gewünschten Bilder aus dem Internet im Sinne eines Proxys lädt und diese sogar noch in einem Cache ablegt.

Und, nochmals erwähnt: Das läuft bei mir nur intern. Letztendlich lädt dieser Proxy alles aus dem Netz, was hinter /img/ steht. Sollte man das also wirklich ungeschützt ins Internet packen wollen, dann wären noch diverse weitere Einstellungen zum Thema Sicherheit sehr sinnvoll. Für meine Zwecke, wo ich im ersten Schritt nur wissen wollte, ob und wie man so etwas in apache2 lösen kann, tut es das mehr wie Dicke. Ich weiß, dass es geht – denn ich habe eine lauffähige Konfig 😀

by Mai 03, 2026 Keine Kommentare
stunnel: noch lange nicht ausgepopt

stunnel: noch lange nicht ausgepopt

Linux

Wer kennt das nicht? Irgendeine alte Software die betriebsnotwendig ist und schon seit geraumer Zeit keine Updates mehr bekommen hat. Und die dümpelt halt so vor sich hin. So lange alle Clients sich noch verbinden bzw. die Verbindungen zu anderen Servern aufgebaut werden können scheint ja alles wunderbar zu sein. Es scheint so. Bis irgendeiner meint seine TLS-Einstellungen zu aktualisieren… (mehr …)

by Jan. 21, 2020 Keine Kommentare