zreptil / nightscout-reporter

a web app to create PDF documents from nightscout data
https://nightscout-reporter.zreptil.de/
BSD 3-Clause "New" or "Revised" License
59 stars 47 forks source link

URL hinter Cloudflare-Proxy nicht erreichbar #70

Closed opal06 closed 1 year ago

opal06 commented 1 year ago

Ich hoste Nightscout auf einer Domain von Cloudflare. Traffic wird über Cloudflares Proxy geleitet. In diesem Szenario meldet Nightscout-Reporter direkt eine unerreichbare URL, obwohl die Domain erreichbar ist (auch über den Button im Reporter selbst neben dem URL-Eingabefeld; der Token ist also korrekt). CORS ist ebenfalls aktiviert (siehe status.json). Mit deaktiviertem Proxy (Cloudflare nur als DNS-Provider für die Domain) ist die Nightscout-URL für den Reporter erreichbar. Sobald die URL einmal gespeichert und "gefunden" wurde, funktioniert die Datenabfrage dann aber auch über den Cloudflare-Proxy. Insofern scheint es ein konkretes Problem bei der ersten Überprüfung der URL zu sein.

Ich füge hier den Output der status.json-Datei an sowie den HTTP-Response-Header mit und ohne Cloudflare-Proxy:

status.json:

{
  "status": "ok",
  "name": "nightscout",
  "version": "14.2.6",
  "serverTime": "2023-02-25T16:22:41.546Z",
  "serverTimeEpoch": 1677342161546,
  "apiEnabled": true,
  "careportalEnabled": true,
  "boluscalcEnabled": true,
  "settings": {
    "units": "mg/dl",
    "timeFormat": 24,
    "dayStart": 7,
    "dayEnd": 21,
    "nightMode": false,
    "editMode": true,
    "showRawbg": "never",
    "customTitle": "Nightscout",
    "theme": "colors",
    "alarmUrgentHigh": false,
    "alarmUrgentHighMins": [
      30,
      60,
      90,
      120
    ],
    "alarmHigh": false,
    "alarmHighMins": [
      30,
      60,
      90,
      120
    ],
    "alarmLow": false,
    "alarmLowMins": [
      15,
      30,
      45,
      60
    ],
    "alarmUrgentLow": false,
    "alarmUrgentLowMins": [
      15,
      30,
      45
    ],
    "alarmUrgentMins": [
      30,
      60,
      90,
      120
    ],
    "alarmWarnMins": [
      30,
      60,
      90,
      120
    ],
    "alarmTimeagoWarn": false,
    "alarmTimeagoWarnMins": "15",
    "alarmTimeagoUrgent": false,
    "alarmTimeagoUrgentMins": "30",
    "alarmPumpBatteryLow": false,
    "language": "en",
    "scaleY": "log",
    "showPlugins": "dbsize delta direction upbat",
    "showForecast": "openaps",
    "focusHours": 3,
    "heartbeat": 60,
    "baseURL": "https://nightscout.flserver.net",
    "authDefaultRoles": "denied",
    "thresholds": {
      "bgHigh": 180,
      "bgTargetTop": 160,
      "bgTargetBottom": 70,
      "bgLow": 69
    },
    "insecureUseHttp": false,
    "secureHstsHeader": false,
    "secureHstsHeaderIncludeSubdomains": false,
    "secureHstsHeaderPreload": false,
    "secureCsp": false,
    "deNormalizeDates": false,
    "showClockDelta": false,
    "showClockLastTime": false,
    "frameUrl1": "",
    "frameUrl2": "",
    "frameUrl3": "",
    "frameUrl4": "",
    "frameUrl5": "",
    "frameUrl6": "",
    "frameUrl7": "",
    "frameUrl8": "",
    "frameName1": "",
    "frameName2": "",
    "frameName3": "",
    "frameName4": "",
    "frameName5": "",
    "frameName6": "",
    "frameName7": "",
    "frameName8": "",
    "authFailDelay": 5000,
    "adminNotifiesEnabled": true,
    "DEFAULT_FEATURES": [
      "bgnow",
      "delta",
      "direction",
      "timeago",
      "devicestatus",
      "upbat",
      "errorcodes",
      "profile",
      "bolus",
      "dbsize",
      "runtimestate",
      "basal",
      "careportal"
    ],
    "alarmTypes": [
      "simple"
    ],
    "enable": [
      "careportal",
      "boluscalc",
      "food",
      "basal",
      "bwp",
      "iob",
      "cob",
      "cage",
      "sage",
      "iage",
      "ar2",
      "azurepush",
      "rawbg",
      "pushover",
      "bgi",
      "pump",
      "openaps",
      "cors",
      "treatmentnotify",
      "bgnow",
      "delta",
      "direction",
      "timeago",
      "devicestatus",
      "upbat",
      "errorcodes",
      "profile",
      "bolus",
      "dbsize",
      "runtimestate",
      "simplealarms"
    ]
  },
  "extendedSettings": {
    "dbsize": {
      "inMib": true,
      "max": 2048
    },
    "devicestatus": {
      "advanced": true,
      "days": 1
    }
  },
  "authorized": {
    "token": "$token",        // Aus Sicherheitsgründen entfernt 
    "sub": "Nightscout-Reporter",
    "permissionGroups": [
      [
        "*:*:read"
      ],
      []
    ],
    "iat": 1677342161,
    "exp": 1677370961
  },
  "runtimeState": "loaded"
}

HTTP-Response-Header mit Cloudflare:

HTTP/2 200 
date: Sat, 25 Feb 2023 16:37:12 GMT
content-type: text/html; charset=utf-8
access-control-allow-origin: *
access-control-allow-methods: GET,PUT,POST,DELETE,OPTIONS
access-control-allow-headers: Content-Type, Authorization, Content-Length, X-Requested-With
vary: Accept-Encoding
strict-transport-security: max-age=15552000; includeSubDomains; preload
content-security-policy: upgrade-insecure-requests; frame-ancestors 'self'
referrer-policy: same-origin
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
x-xss-protection: 1; mode=block
x-robots-tag: noindex, nofollow, nosnippet, noarchive
cf-cache-status: DYNAMIC
server-timing: cf-q-config;dur=7.9999954323284e-06
report-to: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v3?s=xxx"}],"group":"cf-nel","max_age":604800}
nel: {"success_fraction":0,"report_to":"cf-nel","max_age":604800}
server: cloudflare
cf-ray: 79f1dd3d6dca0f82-MXP

HTTP-Response-Header ohne Cloudflare:

HTTP/2 200 
server: nginx
date: Sat, 25 Feb 2023 16:39:10 GMT
content-type: text/html; charset=utf-8
content-length: 42973
x-powered-by: Express
access-control-allow-origin: *
access-control-allow-methods: GET,PUT,POST,DELETE,OPTIONS
access-control-allow-headers: Content-Type, Authorization, Content-Length, X-Requested-With
etag: W/"a7dd-KqgKA0V+WV9SiSTc6X0GMAUJD18"
vary: Accept-Encoding
strict-transport-security: max-age=15552000; includeSubDomains; preload
content-security-policy: upgrade-insecure-requests; frame-ancestors 'self'
referrer-policy: same-origin
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
x-xss-protection: 1; mode=block
x-robots-tag: noindex, nofollow, nosnippet, noarchive
zreptil commented 1 year ago

Die Überprüfung der URL geschieht immer auf die gleiche Art, auf die später auf die URL zugegriffen wird. Alles andere würde auch keinen Sinn machen. Schliesslich soll die Überprüfung ja testen, ob Nightscout Reporter die URL verwenden kann. So wie es aussieht, ist die Seite durch Authentifizierung geschützt, weshalb dort ein Token gesetzt werden muss. Du kannst sowas eigentlich nur dann zuverlässig testen, wenn Du auf Deinen Server von ausserhalb Deines Netzwerkes zugreifst, wie das auch Nightscout Reporter macht.

In Deinem Fall sollte das dann über https://nightscout.flserver.net/api/v1/status.json?token=xxx geschehen, wobei xxx das Token ist. Du hast das zwar aus dem Listing oben entfernt, aber die Authentication Antwort vom Cloudflare Server inklusive der Autorisierungsantwort steht drin. Keine Ahnung, ob ein Hacker was damit anfangen kann (ich bin keiner), aber die Info würde ich an Deiner Stelle auch nicht so öffentlich verteilen. Da wäre das Token schon etwas weniger sicherheitsrelevant, denke ich.

opal06 commented 1 year ago

Zur Authentifizierung verwende ich einen in Nightscout generierten Token mit den Berechtigungen ::read, was auch erfolgreich funktioniert, nachdem ich die erste Einrichtung des Reporters ohne Cloudflare-Proxy vorgenommen habe. Es scheint nur bei der erstmaligen Einrichtung auf einem neuen Gerät (oder nach Löschen der Websiten-Daten) nicht zu funktionieren. Den Token zu entfernen war in der Tat vlt. etwas übereifrig. Jedenfalls kann ich bestätigen, dass ich von außerhalb meines Heimnetzes mit diesem Token die status.json-Datei aus meinem ersten Post abrufen konnte. Du kannst es gerne selbst überprüfen, hier wäre die URL, diesmal mit Token: https://nightscout.flserver.net/api/v1/status.json?token=nightscout-4616e25f9249f0e3

Ich bin mir aber auch bewusst, dass es vlt. ein edge-case ist, der nicht unbedingt gefixt werden muss. Es gibt ja immerhin einen Workaround...

Was Cloudflare angeht, danke für den Hinweis. Habe den jetzt sicherheitshalber entfernt, wobei ich nicht sicher bin, auch wenn das nur mit Cloudflares Network Error Reporting zu tun haben sollte.