Skip to main content

Achter de Zyxel T-50 router van T-Mobile gebruik ik een ASUS RT-AC86U router (in DMZ), met daar weer een Raspberry Pi aan. Op die Pi wil ik een eenvoudige webhook server draaien. Dat lukt voor HTTP verkeer (DMZ op de de Zyxel, port forwarding op de ASUS), maar als ik HTTPS wil proberen faalt dit op het self-signed certificaat van de Zyxel router…

 

  1. Waarom speelt het certificaat van de Zyxel router een rol als de ASUS in de DMZ van die Zyxel router zit?
  2. Hoe los ik dit op?

 

(misschien gerelateerd, misschien ook niet: afgelopen zondag -nog voor mijn experimenten- meldde Shodan opeens dat er iets gevonden was op poort 443 van mijn WAN IP; heeft T-Mobile recent iets veranderd in de configuratie?)

PS: die server op de Pi gebruikt een Let’s Encrypt (wildcard) certificaat, dus dat is niet self-signed.

(kan het oorspronkelijke bericht niet meer bewerken)


 

En als je de server via het directe IP Adres bezoekt van de Pi werkt het wel?

Ik vermoed dat het komt door Nat-Loopback, misschien zou je eens kunnen kijken of je ook een foutmelding krijgt als je het publieke IP-Adres bezoekt via je smartphone (waarop Wi-Fi dan wel is uitgeschakeld).


@sublimerote Welke melding krijg je precies? Dat de site die je wil bezoeken onveilig is? Wat gebeurt er als je deze negeert? Dat kun je veilig doen. Krijg je dan wel de server die op de Pi draait of krijg je dan het inlogscherm van de router? Als dat laatste het geval is, wil je dan eens inloggen en kijken of er bij Onderhoud > Extern beheer geen vinkjes onder WAN staan?


Op mijn MacBook Pro (in het lokale netwerk): 

➜ curl -X POST https://server.domein.mijn:443/hook -H 'Content-Type: application/json' -d '{"a": "b"}'
curl: (60) SSL certificate problem: self signed certificate
More details here: https://curl.se/docs/sslcerts.html

curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.

➜ curl -X POST https://192.168.1.219:443/hook -H 'Content-Type: application/json' -d '{"a":"b"}'
curl: (7) Failed to connect to 192.168.1.219 port 443 after 9 ms: Connection refused

Op een andere poort (> 1024) dan 443 werkt het trouwens wel (bij gebruik van de domeinnaam; IP adres kan volgens mij ook niet werken, omdat het SSL certificaat voor een domein is; niet voor een IP adres), maar daar lijkt de third-party server die de webhooks genereert helaas niet mee overweg te kunnen (lijkt alleen poort 443 te ondersteunen?).

In Blink (SSH terminal voor iOS) op mijn iPhone over cellular (WiFi uit):

➜ curl -X POST https://server.domein.mijn:443/hook -H 'Content-Type: application/json' -d '{"a": "b"}'
curl: (35) Server aborted the SSL handshake

De vinkjes bij Extern Beheer staan uit voor WAN. Ze staan aan voor LAN/WLAN. Als ik die uitzet voor HTTPS krijg ik de foutmelding niet meer, maar lijken de calls te “hangen”. Ik zie ze niet binnenkomen op de server en er komt dan (uiteraard) ook geen antwoord terug.

De informatie die over de lijn gaat is niet heel erg gevoelig, dus als het echt niet anders kan zal ik terugvallen op HTTP, maar ik hoop met jullie hulp HTTPS werkend te krijgen.


Zucht. Weer wordt een vraag als “beantwoord” gemarkeerd (door wie?) zodra er iemand reageert, terwijl het probleem nog niet is opgelost…

Hoe werkt dat op dit forum?


@sublimerote Zou je screenshots kunnen delen van de relevante instellingen? Dat maakt het hopelijk wat makkelijker om een oorzaak te vinden. Misschien heeft iemand op basis daarvan nog een suggestie.


  • NAT

     

  • Extern Beheer

     


Mocht het relevant zijn; dit was de melding die Shodan vorige week gaf:

// Trigger: new_service
// Port: 443 / tcp
// Hostname(s): <mijn-IP-adres>.ftth.glasoperator.nl

Ik heb de datum en tijd even weggelaten, maar het was op een tijdstip dat ik niet eens thuis was…

Aangezien ik Extern Beheer via WAN heb uitstaan (zie screenshots) is het waarschijnlijk geen wijziging van mij die dit alert triggerde?


En dit lijkt aan te geven dat de Zyxel inderdaad “in de weg zit” bij gebruik van de standaard HTTPS poort (443):

➜ wget https://mijn.domein
--2022-08-21 23:26:37-- https://mijn.domein/
Resolving mijn.domein (mijn.domein)... <mijn IP adres>
Connecting to mijn.domein (mijn.domein)|<mijn IP adres>|:443... connected.
ERROR: cannot verify mijn.domein's certificate, issued by ‘CN=ZyXELcert,OU=ZyXELcert,O=ZyXEL,ST=TWN,C=TW’:
Self-signed certificate encountered.
ERROR: certificate common name ‘ZyXELcert’ doesn't match requested host name ‘mijn.domein’.
To connect to mijn.domein insecurely, use `--no-check-certificate'.

en (poort expliciet):

➜ wget https://mijn.domein:443
--2022-08-21 23:28:12-- https://mijn.domein/
Resolving mijn.domein (mijn.domein)... <mijn IP adres>
Connecting to mijn.domein (mijn.domein)|<mijn IP adres>|:443... connected.
ERROR: cannot verify mijn.domein's certificate, issued by ‘CN=ZyXELcert,OU=ZyXELcert,O=ZyXEL,ST=TWN,C=TW’:
Self-signed certificate encountered.
ERROR: certificate common name ‘ZyXELcert’ doesn't match requested host name ‘mijn.domein’.
To connect to mijn.domein insecurely, use `--no-check-certificate'.

 


Hi @sublimerote, merci voor de aanvullingen! Super dat er al zo met jou mee is gedacht. Ik wil heel graag @Gerrit078@TMTV en @Hidden.nld vragen of jullie hier nog een tip/advies voor hebben? Ik had je heel graag het antwoord willen geven, maar dit gaat mijn pet te boven. Excuses! 


En dit lijkt aan te geven dat de Zyxel inderdaad “in de weg zit” bij gebruik van de standaard HTTPS poort (443):

➜ wget https://mijn.domein
--2022-08-21 23:26:37-- https://mijn.domein/
Resolving mijn.domein (mijn.domein)... <mijn IP adres>
Connecting to mijn.domein (mijn.domein)|<mijn IP adres>|:443... connected.
ERROR: cannot verify mijn.domein's certificate, issued by ‘CN=ZyXELcert,OU=ZyXELcert,O=ZyXEL,ST=TWN,C=TW’:
Self-signed certificate encountered.
ERROR: certificate common name ‘ZyXELcert’ doesn't match requested host name ‘mijn.domein’.
To connect to mijn.domein insecurely, use `--no-check-certificate'.

en (poort expliciet):

➜ wget https://mijn.domein:443
--2022-08-21 23:28:12-- https://mijn.domein/
Resolving mijn.domein (mijn.domein)... <mijn IP adres>
Connecting to mijn.domein (mijn.domein)|<mijn IP adres>|:443... connected.
ERROR: cannot verify mijn.domein's certificate, issued by ‘CN=ZyXELcert,OU=ZyXELcert,O=ZyXEL,ST=TWN,C=TW’:
Self-signed certificate encountered.
ERROR: certificate common name ‘ZyXELcert’ doesn't match requested host name ‘mijn.domein’.
To connect to mijn.domein insecurely, use `--no-check-certificate'.

 


Doe je deze test van een machine in je eigen netwerk? Direct aan de Zyxel of aan de Asus? Als je buiten de Asus om met de Zyxel verbindt zal het verkeer in de Zyxel aankomen als LOKAAL verkeer en krijg je toegang tot de lokale web server/ beheersomgeving van de Zyxel. In dat geval zou het wel kunnen werken als je dat van buiten je eigen netwerk (bijv vanaf een mobiele telefoon die niet aan je WIFI verbonden is) verbinding maakt.  Ik durf niet te zeggen wat de Zyxel doet met verkeer naar 443 VANUIT de DMZ (Asus). Het kan zomaar zijn dat dat ook naar de beheersomgeving van de Zyxel gaat.

Test eens vanaf een mobiele telefoon zonder WIFI?


En dit lijkt aan te geven dat de Zyxel inderdaad “in de weg zit” bij gebruik van de standaard HTTPS poort (443):

➜ wget https://mijn.domein
--2022-08-21 23:26:37-- https://mijn.domein/
Resolving mijn.domein (mijn.domein)... <mijn IP adres>
Connecting to mijn.domein (mijn.domein)|<mijn IP adres>|:443... connected.
ERROR: cannot verify mijn.domein's certificate, issued by ‘CN=ZyXELcert,OU=ZyXELcert,O=ZyXEL,ST=TWN,C=TW’:
Self-signed certificate encountered.
ERROR: certificate common name ‘ZyXELcert’ doesn't match requested host name ‘mijn.domein’.
To connect to mijn.domein insecurely, use `--no-check-certificate'.

en (poort expliciet):

➜ wget https://mijn.domein:443
--2022-08-21 23:28:12-- https://mijn.domein/
Resolving mijn.domein (mijn.domein)... <mijn IP adres>
Connecting to mijn.domein (mijn.domein)|<mijn IP adres>|:443... connected.
ERROR: cannot verify mijn.domein's certificate, issued by ‘CN=ZyXELcert,OU=ZyXELcert,O=ZyXEL,ST=TWN,C=TW’:
Self-signed certificate encountered.
ERROR: certificate common name ‘ZyXELcert’ doesn't match requested host name ‘mijn.domein’.
To connect to mijn.domein insecurely, use `--no-check-certificate'.

 

Naar welk A-Record verwijst mijn.domein.ext ?

Bezoek je mijn.domein.ext vanuit je eigen lokale netwerk of via een externe verbinding?

Als je deze tests uitvoert vanaf je eigen verbinding komt het echt door NAT loopback, wat gebeurt er als je dezelfde test doet naar het IP-Adres van je Pi?


Doe je deze test van een machine in je eigen netwerk? Direct aan de Zyxel of aan de Asus?

Zowel binnen mijn netwerk (aan de Asus; nooit direct aan de Zyxel) als buiten mijn netwerk (iPhone op cellular, met een ander IP adres dan mijn publieke/WAN IP adres bij T-Mobile Thuis). In beide gevallen hetzelfde resultaat (foutmelding over self-signed ZyXELcert certificaat).

Naar welk A-Record verwijst mijn.domein.ext ?

Bezoek je mijn.domein.ext vanuit je eigen lokale netwerk of via een externe verbinding?

Als je deze tests uitvoert vanaf je eigen verbinding komt het echt door NAT loopback, wat gebeurt er als je dezelfde test doet naar het IP-Adres van je Pi?

Het A record van dat domein verwijst naar mijn publieke/WAN IP adres bij T-Mobile Thuis (`dig mijn.domein +short` levert hetzelfde IP adres op als `curl -s -X GET https://checkip.amazonaws.com` op een Mac in mijn eigen lokale netwerk).

(zie boven voor antwoord op 2e vraag)

Zoals ik al eerder aangaf is mijn Let’s Encrypt certificaat een wildcard certificaat voor mijn domein, maar niet voor mijn publieke/WAN IP adres bij T-Mobile Thuis. Een test met het lokale IP adres faalt dus ook, maar anders en verwacht:

➜ wget https://192.168.1.12:443
--2022-08-22 20:24:58-- https://192.168.1.12:443/
Connecting to 192.168.1.12:443... failed: Connection refused.

 


Ik geloof dat ik zelf een workaround heb gevonden…

Als ik de poort voor de HTTPS service bij Extern Beheer op iets anders dan 443 zet (bijvoorbeeld 9443) dan kan ik wel succesvol met de server op de Pi communiceren (remote en lokaal)!

Helaas werken de webhooks dan nog steeds niet (wel via HTTP), maar dat is waarschijnlijk een probleem van de partij die de webhooks genereert, dus ik ga daar verder kijken.

Bedankt voor het meedenken! En als jullie nog tips hebben zijn die nog steeds welkom.


Als ik de poort voor de HTTPS service bij Extern Beheer op iets anders dan 443 zet (bijvoorbeeld 9443) dan kan ik wel succesvol met de server op de Pi communiceren (remote en lokaal)!

Dat is bijzonder, maar wel goed om te weten voor wie hier in de toekomst nog tegenaan zullen lopen. Maak je gebruik van DDNS en zo ja, heb je die ingesteld op de Zyxel of op de Asus? Als je screenshots plaatst van de instellingen in de Asus kan dat misschien iemand op een idee brengen.


Als ik de poort voor de HTTPS service bij Extern Beheer op iets anders dan 443 zet (bijvoorbeeld 9443) dan kan ik wel succesvol met de server op de Pi communiceren (remote en lokaal)!

Dat is bijzonder, maar wel goed om te weten voor wie hier in de toekomst nog tegenaan zullen lopen. Maak je gebruik van DDNS en zo ja, heb je die ingesteld op de Zyxel of op de Asus? Als je screenshots plaatst van de instellingen in de Asus kan dat misschien iemand op een idee brengen.

Nee, dit is heel logisch. Verkeer naar het je public IP adress wordt gerouteerd naar de router, of dat van buiten komt of van binnen je netwerk maakt niet uit. Port translation kan dan dat IP pakket doorsturen naar een interne adres/port combinatie. Hairpin NAT zorgt ervoor dat dat ook werkt van binnen je eigen netwerk. 

Maar voordat port translation gebeurt kijkt de router eerst of er voor de interface waarop het pakket binnenkomt een dienst in de router is die op die port luistert (beheer). Voor verkeer van buiten zet je dat aan/uit met de boven beschreven instellingen. Voor IP-verkeer van binnen je eigen netwerk staat beheer altijd aan (anders zou je jezelf buiten kunnen sluiten). Een vraag naar  <je publieke IP>:443 kan dus voor verkeer uit je eigen netwerk door de router afgehandeld worden (beheer luister op die port) terwijl voor verkeer uit het internet beheer uitstaat bij de port translation uitkomt en netjes naar de webserver in je netwerk wordt gestuurd.

Door de port waarop beheer luistert te veranderen maak je de port 443 vrij en werkt hairpin NAT zoals gewenst: verkeer uit je eigen netwerk naar je publieke IP adres port 443 wordt netjes vertaald naar je interne host port 443.

In plaats van porttranslation kun je dus ook de DMZ functionaliteit gebruiken die de port mapping voor alle poorten doet,

DDNS kun je normaal gesproken vanaf je router of eender welke host achter de router doen zo lang de DDNS server  slim genoeg is je publieke IP uit de update request te halen. Dat is niet zo spannend.


Bedankt voor jullie aanvullingen. Ik weet niet zeker of ik ze helemaal begrijp. Dat Extern Beheer op poort 443 in de weg zit bij lokaal verkeer begrijp ik, maar ik snap nog steeds niet waarom dat voor extern verkeer ook zo is. Is dat niet gewoon een bug in de T-Mobile/Zyxel firmware?

Ik gebruik mijn eigen domeinnaam (via een A record) om de server op de Pi te benaderen. Strikt genomen is dat geen DDNS, maar ik heb op mijn Asus router wel een (Inadyn) script draaien dat dit DNS record aanpast als mijn publieke/WAN IP adres van T-Mobile Thuis verandert (maar tot nog toe is dat adres behoorlijk stabiel). Dit script “kan er tegen” dat de ASUS router achter de T-Mobile router hangt (het IP adres “klopt”).

(Ik heb weliswaar de DDNS service van Asus zelf ook aan staan, maar dat is alleen als backup en die gebruik ik eigenlijk niet.)


Bedankt voor jullie aanvullingen. Ik weet niet zeker of ik ze helemaal begrijp. Dat Extern Beheer op poort 443 in de weg zit bij lokaal verkeer begrijp ik, maar ik snap nog steeds niet waarom dat voor extern verkeer ook zo is. Is dat niet gewoon een bug in de T-Mobile/Zyxel firmware?

Wat is voor jou extern verkeer? Verkeer vanuit jouw netwerk ook al is dat naar het externe IP-adres is lokaal verkeer: het stopt op de grens tussen je lokaal netwerk en het internet (je router).

Als het vanaf het internet (bijv. een mobiel met WIFI uit maar met mobiele data) inderdaad op de beheersomgeving uitkomt, ja dan heb je een bug in de Zyxel te pakken. Maar ik kan me niet voorstellen dat het geval is.


Wat is voor jou extern verkeer?

Een iPhone waarvan WiFi uit staat.

Ik dacht dat ik eerder (met poort 443) ook foutmeldingen in dit scenario kreeg, maar ik zie nu met poort 9443 inderdaad dat er intern een foutmelding over het self-signed certificaat verschijnt, maar extern het curl verzoek blijft hangen (geen response, geen foutmelding).

Dat heb ik dus mogelijk verkeerd onthouden…


Als je extern beheer op de WAN aan hebt staan, snap ik dat de Zyxel dan het verkeer van buiten dat bestemd is voor poort 443 op een LAN-apparaat afvangt. De Zyxel heeft dan hogere prioriteit dan port forwarding. Maar dan blijft het vreemd dat als je dit uit hebt staan poort 443 toch gereserveerd blijft. Dat zou een bug kunnen zijn. Daar heb ik overigens geen last van. Ik heb extern beheer op de WAN uit staan (LAN staat wel aan), poort 443 ingevuld en toch kan ik mijn NAS op poort 443 bereiken, zowel binnen het netwerk als op 4G.

@sublimerote Dat was inderdaad de reden dat ik naar DDNS vroeg, maar zo te lezen werkt het zoals het hoort.


Ik probeerde (HTTPS over) poort 443 omdat ik bij een andere poort dan 443 een foutmelding kreeg van de dienst die de webhooks genereert. Zoals eerder vermeld werkt dat nu met poort 443 helaas ook niet.

Inmiddels achter ben ik er achter welke (beginners?) fout ik had gemaakt: in de NodeJS/Express server op de Pi gebruikte ik cert.pem i.p.v fullchain.pem (chain.pem is ook niet voldoende) zoals die door certbot van Let’s Encrypt zijn gegenereerd… Daar kwam ik achter door mijn certificaat/chain op deze site te controleren: https://whatsmychaincert.com. Na die wijziging werkt HTTPS communicatie wel; ook over een andere poort dan 443!

Ik kan dus eventueel weer poort 443 gebruiken voor “Extern” Beheer (ik heb het alleen aanstaan voor “LAN/WLAN”, maar niet voor “WAN”).

Nu is mijn probleem echt opgelost. Dank voor alle hulp!


 

En omdat ik dit (per ongeluk) als beste antwoord heb gemarkeerd (en niet meer kan aanpassen?) nog even de relevante lessen voor mij als concreter antwoord op de oorspronkelijke vragen (dankzij de antwoorden van anderen hier):

  1. Let op dat je echt extern test (bv. cellular netwerk van iPhone met WiFi uit)
  2. Verander poort 443 voor HTTPS bij “Extern Beheer” evt. in een andere random poort (maar dit zou niet nodig moeten zijn als je echt extern test)