diff --git a/README.md b/README.md index 8f35331..315d656 100644 --- a/README.md +++ b/README.md @@ -44,15 +44,16 @@ The following are the known available endpoints: ### MQTT Broker -| CMD param | ENV variable | Description | -|---------------------|------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| -m or --mqtt-uri | MQTT_URI | URI to the MQTT Server. TCP: tcp://mqtt.eclipseprojects.io:1883, WebSocket: ws://mqtt.eclipseprojects.io:9001 or TLS: tls://mqtt.eclipseprojects.io:8883 - Leave it empty to disable MQTT connection | -| --mqtt-server-cert | MQTT_SERVER_CERT | Path to the server certificate authority file in PEM format is required for TLS | -| --mqtt-user | MQTT_USER | MQTT user name | -| --mqtt-password | MQTT_PASSWORD | MQTT password | -| --mqtt-client-id | MQTT_CLIENT_ID | MQTT Client Identifier. Defaults to saic-python-mqtt-gateway. | -| --mqtt-topic-prefix | MQTT_TOPIC | Provide a custom MQTT prefix to replace the default: saic | -| | MQTT_LOG_LEVEL | Log level of the MQTT Client: INFO (default), use DEBUG for detailed output, use CRITICAL for no output, [more info](https://docs.python.org/3/library/logging.html#levels) | +| CMD param | ENV variable | Description | +|-----------------------------------|---------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| -m or --mqtt-uri | MQTT_URI | URI to the MQTT Server. TCP: tcp://mqtt.eclipseprojects.io:1883, WebSocket: ws://mqtt.eclipseprojects.io:9001 or TLS: tls://mqtt.eclipseprojects.io:8883 - Leave it empty to disable MQTT connection | +| --mqtt-server-cert | MQTT_SERVER_CERT | Path to the server certificate authority file in PEM format is required for TLS | +| --mqtt-server-cert-check-hostname | MQTT_SERVER_CERT_CHECK_HOSTNAME | Enable or disable TLS certificate hostname checking when using a custom certificate. Enabled (True) by default. Set to False when using a self-signed certificate without a matching hostname. This option might be insecure. | +| --mqtt-user | MQTT_USER | MQTT user name | +| --mqtt-password | MQTT_PASSWORD | MQTT password | +| --mqtt-client-id | MQTT_CLIENT_ID | MQTT Client Identifier. Defaults to saic-python-mqtt-gateway. | +| --mqtt-topic-prefix | MQTT_TOPIC | Provide a custom MQTT prefix to replace the default: saic | +| | MQTT_LOG_LEVEL | Log level of the MQTT Client: INFO (default), use DEBUG for detailed output, use CRITICAL for no output, [more info](https://docs.python.org/3/library/logging.html#levels) | ### Home Assistant Integration diff --git a/src/configuration/__init__.py b/src/configuration/__init__.py index e4c050f..de30dad 100644 --- a/src/configuration/__init__.py +++ b/src/configuration/__init__.py @@ -32,6 +32,7 @@ def __init__(self) -> None: self.mqtt_port: int = 1883 self.mqtt_transport_protocol: TransportProtocol = TransportProtocol.TCP self.tls_server_cert_path: str | None = None + self.tls_server_cert_check_hostname: bool = True self.mqtt_user: str | None = None self.mqtt_password: str | None = None self.mqtt_client_id: str = "saic-python-mqtt-gateway" diff --git a/src/configuration/parser.py b/src/configuration/parser.py index c7b97f5..1b9d065 100644 --- a/src/configuration/parser.py +++ b/src/configuration/parser.py @@ -97,6 +97,9 @@ def __parse_mqtt_transport(args: Namespace, config: Configuration) -> None: config.mqtt_transport_protocol = TransportProtocol.TLS if args.tls_server_cert_path: config.tls_server_cert_path = args.tls_server_cert_path + config.tls_server_cert_check_hostname = ( + args.tls_server_cert_check_hostname + ) else: msg = f"Invalid MQTT URI scheme: {parse_result.scheme}, use tcp or ws" raise SystemExit(msg) @@ -156,7 +159,7 @@ def __setup_osmand(args: Namespace, config: Configuration) -> None: def __setup_parser() -> argparse.ArgumentParser: - parser = argparse.ArgumentParser(prog="MQTT Gateway") + parser = argparse.ArgumentParser(prog="MQTT Gateway", add_help=True) parser.add_argument( "-m", "--mqtt-uri", @@ -462,6 +465,20 @@ def __setup_parser() -> argparse.ArgumentParser: default=False, type=check_bool, ) + parser.add_argument( + "--mqtt-server-cert-check-hostname", + help="Enable or disable TLS certificate hostname checking when using custom certificate." + "Enabled (True) by default" + "Set to (False) when using self-signed certificate without a matching hostname." + "This option might be insecure." + "Environment Variable: MQTT_SERVER_CERT_CHECK_HOSTNAME", + dest="tls_server_cert_check_hostname", + required=False, + action=EnvDefault, + envvar="MQTT_SERVER_CERT_CHECK_HOSTNAME", + default=True, + type=check_bool, + ) return parser diff --git a/src/publisher/mqtt_publisher.py b/src/publisher/mqtt_publisher.py index 8d80bb6..cb2809a 100644 --- a/src/publisher/mqtt_publisher.py +++ b/src/publisher/mqtt_publisher.py @@ -58,7 +58,11 @@ async def connect(self) -> None: if cert_uri: LOG.debug(f"Using custom CA file {cert_uri}") ssl_context.load_verify_locations(cafile=cert_uri) - ssl_context.check_hostname = False + if not self.configuration.tls_server_cert_check_hostname: + LOG.warning( + f"Skipping hostname check for TLS connection to {self.host}" + ) + ssl_context.check_hostname = False else: ssl_context = None await self.client.connect(