Skip the TLS SNI check when request hostname has a literal IP address

This commit is contained in:
Jaakko Keränen 2024-04-13 14:27:37 +03:00
parent d1905e688c
commit a9923d43fc
No known key found for this signature in database
GPG Key ID: BACCFCFB98DB2EDC
2 changed files with 19 additions and 9 deletions

View File

@ -59,6 +59,7 @@ v0.6.1:
v0.6.2:
* Skip the TLS SNI check when request hostname has a literal IP address. (SNI is not supposed to be used with literal addresses.)
* Respond with status 53 if an unknown hostname is requested. This helps reveal configuration errors where the correct hostnames are not specified.
### v0.5

View File

@ -7,6 +7,7 @@ import importlib
import os.path
import select
import socket
import ipaddress
import multiprocessing as mp
import subprocess
import threading
@ -381,15 +382,23 @@ def handle_gemini_or_titan_request(request_data):
report_error(stream, 59, "Invalid port number")
return
if not stream.get_servername():
# Server name indication is required.
report_error(stream, 59, "Missing TLS server name indication")
return
if stream.get_servername().decode() != hostname:
report_error(stream, 53, "Proxy request refused")
return
if stream.get_servername().decode() not in worker.cfg.hostnames():
report_error(stream, 53, f"Proxy request refused ({stream.get_servername().decode()})")
return
# The hostname may be a literal IPv4/IPv6 address.
try:
ipaddress.ip_address(hostname)
# No error during parsing, looks like a literal address.
except ValueError:
# Server name indication is required.
report_error(stream, 59, "Missing TLS server name indication")
return
else:
sni_name = stream.get_servername().decode()
if sni_name != hostname:
# SNI servername does not match the hostname in the URL. Misbehaving client?
report_error(stream, 53, "Proxy request refused")
return
if sni_name not in worker.cfg.hostnames():
report_error(stream, 53, f"Proxy request refused (domain \"{sni_name}\")")
return
try:
status, meta, body, from_cache = worker.context.call_entrypoint(Request(