Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Push image not working with SSL cert/key active on HA #81

Open
htvekov opened this issue Dec 4, 2021 · 18 comments
Open

Push image not working with SSL cert/key active on HA #81

htvekov opened this issue Dec 4, 2021 · 18 comments

Comments

@htvekov
Copy link

htvekov commented Dec 4, 2021

openHASP 0.6.3 - HA supervised core-2021.10.5

HA Configuration

homeassistant:
  allowlist_external_dirs:
    - /config
    - /share
    - /tmp
  
  allowlist_external_urls:
    - "https://www.life360.com/img/user_images/"

  internal_url: http://192.X.X.X:8123
  external_url: https://my_personal.duckdns.org

http:
  ssl_certificate: /ssl/fullchain.pem
  ssl_key: /ssl/privkey.pem

HA direct service call used to test

service: openhasp.push_image
data:
  image: https://my_personal.duckdns.org/local/Mikkel.png
  obj: p5b40
  width: 50
  height: 50
target:
  entity_id: openhasp.wt32_01

Describe the bug

Using duckdns to gain access to HA from external network, causes issues with paths/permissions using openhasp.push_image
Using SSL on HA will also disable the possibility to gain local access to HA via http://local_ip_address:port. Only access via https://local_ip_address:port is possible with the expected insecure browser warning.
Installing reverse proxy will solve the local access issue with url's, but not necessarily issue with permission/access rights to HA's folders.

Seems like converted image is never recieved. Test picture is tested to be accessible via browser using same url
Most likely permission issues with the api/openhasp/serve path. Can't add that specific path to HA's allowlist_external_dirs, as it's not exposed to HA.
Also noted that URL pushed to openhasp device is the internal_url from HA configuration. Could also be an issue, as device only will be able to access HA via https URL's (alternatively external duckdns url)

Note: If SSL is deactivated in HA, everything works perfectly without issues at all.

Debug log

2021-12-04 21:20:30 DEBUG (SyncWorker_3) [custom_components.openhasp.image] image_to_rgb565 out_image: /tmp/tmpdghbzkiu
2021-12-04 21:20:30 DEBUG (MainThread) [custom_components.openhasp] Push hasp/wt32_01/command/p5b40.src with http://my.local.ip.address:port/api/openhasp/serve/4ab482c80ba29d55629f5a44f9e1e0f7


wt32-sc01 device log:

21:19:59.876 -> 0KPrompt > MQTT RCV: hasp/wt32_01/command/p5b40.src = http://my.local.ip.address:port/api/openhasp/serve/4ab482c80ba29d55629f5a44f9e1e0f7
21:20:30.415 -> 0KPrompt > ATTR: HTTP result -5



@kquinsland
Copy link

I am not sure if HTTPs is supported.
Can you repeat this with HTTP only?

A quick google and I think i found the -5 code: https://github.com/espressif/arduino-esp32/blob/master/libraries/HTTPClient/src/HTTPClient.h#L44

@fvanroie
Copy link
Collaborator

I pushed an update to 0.7-dev that allows for https in img.src urls.
Previously only http:// was accepted and https:// was silently dropped.

Some testing is still required... so feel free to try the latest dev build of the firmware.

@htvekov
Copy link
Author

htvekov commented Jan 20, 2022

Thanks, @fvanroie

I've tested latest build and got it to work... partially.
The plate side is ok now, but some work has to be done in the CC HA environment (path/folders) or the CC code itself.

HA configuration:

homeassistant:
  allowlist_external_dirs:
    - /config
    - /share
    - /tmp
  
  internal_url: https://XXX.XXX.X.XX:8123
  external_url: https://mypersonalduck.duckdns.org
http:
  ssl_certificate: /ssl/fullchain.pem
  ssl_key: /ssl/privkey.pem

Notice that I've changed HA's internal_url configuration as well to https. So path in mqtt message is absolutely correct (Checked with MQTT Explorer). But plate reports a 404 response though. Also get a 404 response in browser on my local PC as well (unfortunately expected).

Guess HA doesn't really don't want to share that 'internal' non-exposed path via https. Path is not configurable by user and cannot be whitelisted AFAIK. I've not enough knowledge about the topic to come up with a clever solution. Could be that running HA supervised gives extra challenges with the allowed/whitelisted paths ?

But via https i can easily gain browser access eg. to an image stored in a HA whitelisted path/folder.
Eg. https://192.xxx.xxx.xxx:8123/local/test_image.jpg

Finalized my tests pushing an already converted image from a whitelisted folder (config/www or local) to plate via HA services:

service: mqtt.publish
data:
  topic: hasp/plates/command/p2b40.src
  payload_template: >
    https://192.XXX.XXX.XXX:8123/local/3c2a249c29fdcde2de1c74d3ad38ac73.dib

With above, image appears on plate 😀 So issue is about the access rights at HA's end to certain non whitelisted paths/folders. Perhaps the solution is to revise CC a bit and use 'public' HA folders for the final image ?
Unless there's a http/ssl/HA folders expert guru here with the perfect solution ? 😆🙋‍♂️

@exotsk
Copy link

exotsk commented Jan 20, 2023

Hi, i have tried install last (and not last) firmware, addon and home assistant, many combinations. but i catch this error alltime. from 192.168.1.1 (router?)
which way do I move to solve this problem? HA Supervised with SSL.

2023-01-20 20:27:10.809 ERROR (MainThread) [homeassistant.components.websocket_api.http.connection] [140344930660704] Error handling message: Unknown error (unknown_error) from 192.168.1.1 (Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWe
bKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36)
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/components/websocket_api/decorators.py", line 27, in _handle_async_response
await func(hass, connection, msg)
File "/usr/src/homeassistant/homeassistant/components/websocket_api/commands.py", line 646, in handle_execute_script
await script_obj.async_run(msg.get("variables"), context=context)
File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 1524, in async_run
await asyncio.shield(run.async_run())
File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 409, in async_run
await self._async_step(log_exceptions=False)
File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 453, in _async_step
self._handle_exception(
File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 476, in _handle_exception
raise exception
File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 451, in _async_step
await getattr(self, handler)()
File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 684, in _async_call_service_step
await service_task
File "/usr/src/homeassistant/homeassistant/core.py", line 1755, in async_call
task.result()
File "/usr/src/homeassistant/homeassistant/core.py", line 1792, in _execute_service
await cast(Callable[[ServiceCall], Awaitable[None]], handler.job.target)(
File "/usr/src/homeassistant/homeassistant/helpers/entity_component.py", line 213, in handle_service
await service.entity_service_call(
File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 678, in entity_service_call
future.result() # pop exception if have
File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 958, in async_request_call
await coro
File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 715, in _handle_entity_call
await result
File "/config/custom_components/openhasp/init.py", line 616, in async_push_image
f"{get_url(self.hass, allow_external=False)}/api/openhasp/serve/{image_id}"
File "/usr/src/homeassistant/homeassistant/helpers/network.py", line 201, in get_url
raise NoURLAvailableError
homeassistant.helpers.network.NoURLAvailableError

@htvekov
Copy link
Author

htvekov commented Jan 22, 2023

Haven't really tested lately whether or not openHASP accepts images via https.
Have you tested if everything works as expected using http and disabling ssl in HA ?

@exotsk
Copy link

exotsk commented Jan 24, 2023

In browser all pic is available. i am used ha/local/pic.jpg link, also tried any image from internet (from example for example),
had tried use local network http server, with local adress. I have one result. my network have letsencrypt ssl, dynamic ip with DDNS desec.io.
for understading situation i had tried to use HassWP (HA for windows) and there i have other error with example data

2023-01-24 14:56:21,579.579 INFO (MainThread) [homeassistant.helpers.script.websocket_api_script] websocket_api script: Running websocket_api script
2023-01-24 14:56:21,579.579 INFO (MainThread) [homeassistant.helpers.script.websocket_api_script] websocket_api script: Executing step call service
2023-01-24 14:56:23,321.321 ERROR (MainThread) [aiohttp.server] Unhandled exception
Traceback (most recent call last):
File "D:\HassWP\python-3.9.10.amd64\lib\site-packages\aiohttp\web_protocol.py", line 514, in start
resp, reset = await task
File "D:\HassWP\python-3.9.10.amd64\lib\site-packages\aiohttp\web_protocol.py", line 460, in _handle_request
reset = await self.finish_response(request, resp, start_time)
File "D:\HassWP\python-3.9.10.amd64\lib\site-packages\aiohttp\web_protocol.py", line 613, in finish_response
await prepare_meth(request)
File "D:\HassWP\python-3.9.10.amd64\lib\site-packages\aiohttp\web_fileresponse.py", line 279, in prepare
fobj = await loop.run_in_executor(None, filepath.open, "rb")
File "D:\HassWP\python-3.9.10.amd64\lib\concurrent\futures\thread.py", line 58, in run
result = self.fn(*self.args, **self.kwargs)
File "D:\HassWP\python-3.9.10.amd64\lib\pathlib.py", line 1252, in open
return io.open(self, mode, buffering, encoding, errors, newline,
File "D:\HassWP\python-3.9.10.amd64\lib\pathlib.py", line 1120, in _opener
return self._accessor.open(self, flags, mode)
PermissionError: [Errno 13] Permission denied: 'C:\Users\name\AppData\Local\Temp\tmp1wukuwzu'

this feature very important for use, especially on big screens, and i hope,
can make it work

@exotsk
Copy link

exotsk commented Jan 30, 2023

Unknown error disappeared with ssl turned off, but I get the following.
2023-01-30 11:49:29.809 ERROR (MainThread) [aiohttp.server] Error handling request
Traceback (most recent call last):
File "/usr/local/lib/python3.10/site-packages/aiohttp/web_protocol.py", line 334, in data_received
messages, upgraded, tail = self._request_parser.feed_data(data)
File "aiohttp/_http_parser.pyx", line 551, in aiohttp._http_parser.HttpParser.feed_data
aiohttp.http_exceptions.BadStatusLine: 400, message="Bad status line 'Invalid method encountered'"
2023-01-30 11:49:34.925 ERROR (MainThread) [aiohttp.server] Error handling request
Traceback (most recent call last):
File "/usr/local/lib/python3.10/site-packages/aiohttp/web_protocol.py", line 334, in data_received
messages, upgraded, tail = self._request_parser.feed_data(data)
File "aiohttp/_http_parser.pyx", line 551, in aiohttp._http_parser.HttpParser.feed_data
aiohttp.http_exceptions.BadStatusLine: 400, message="Bad status line 'Invalid method encountered'"

if ssl is enabled and configured as here.
I get an error from 192.168.1.1 if I work on the XA external link, and from the local machine 192.168.1.99 if I work on the XA internal link https ://192.168.1.110: 8123 at this log location.
2023-01-20 20:27:10.809

MainThread [homeassistant.components.websocket_api.http.connection] [140344930660704] Error Message: Unknown Error (unknown_error) from 192.168.1.1

When i give URL from local http server with jpg image by command through MQTT (src), I receive NoData in place of the picture, in other cases it does not change in any way.
image
image

@exotsk
Copy link

exotsk commented Jan 30, 2023

This error log is caught by XA for windows initially without ssl. Errors with access rights from temp directory are visible here.

2023-01-30 12:11:37,728.728 INFO (MainThread) [homeassistant.helpers.script.websocket_api_script] websocket_api script: Running websocket_api script
2023-01-30 12:11:37,728.728 INFO (MainThread) [homeassistant.helpers.script.websocket_api_script] websocket_api script: Executing step call service
2023-01-30 12:11:53,318.318 INFO (MainThread) [homeassistant.helpers.script.websocket_api_script] websocket_api script: Running websocket_api script
2023-01-30 12:11:53,318.318 INFO (MainThread) [homeassistant.helpers.script.websocket_api_script] websocket_api script: Executing step call service
2023-01-30 12:11:53,404.404 ERROR (MainThread) [aiohttp.server] Unhandled exception
Traceback (most recent call last):
File "D:\HassWP\python-3.9.10.amd64\lib\site-packages\aiohttp\web_protocol.py", line 514, in start
resp, reset = await task
File "D:\HassWP\python-3.9.10.amd64\lib\site-packages\aiohttp\web_protocol.py", line 460, in _handle_request
reset = await self.finish_response(request, resp, start_time)
File "D:\HassWP\python-3.9.10.amd64\lib\site-packages\aiohttp\web_protocol.py", line 613, in finish_response
await prepare_meth(request)
File "D:\HassWP\python-3.9.10.amd64\lib\site-packages\aiohttp\web_fileresponse.py", line 279, in prepare
fobj = await loop.run_in_executor(None, filepath.open, "rb")
File "D:\HassWP\python-3.9.10.amd64\lib\concurrent\futures\thread.py", line 58, in run
result = self.fn(*self.args, **self.kwargs)
File "D:\HassWP\python-3.9.10.amd64\lib\pathlib.py", line 1252, in open
return io.open(self, mode, buffering, encoding, errors, newline,
File "D:\HassWP\python-3.9.10.amd64\lib\pathlib.py", line 1120, in _opener
return self._accessor.open(self, flags, mode)
PermissionError: [Errno 13] Permission denied: 'C:\Users\exo\AppData\Local\Temp\tmpxtu63qje'

@dgomes
Copy link
Collaborator

dgomes commented Jan 30, 2023

Well this is not going to work properly on windows because we use UNIX temporary files to generate the images.

@htvekov when using SSL there are 2 possible configuration (SSL handled by HA or SSL handled by a Reverse Proxy). That means that you must tell HA your configuration setup using internal_url and external_url in order for CC to known which is what. For security reasons CC always prefers internal_url paths...

@htvekov
Copy link
Author

htvekov commented Jan 30, 2023

I did some quick SSL tests last night, when I was playing with image config anyway 😉

Didn't save any logs, but I can redo test later if needed.
I use DuckDNS only (no reverse proxy). As far as I understood from last time we talked about this SSL issue, it all boils down to HA not accepting DuckDNS access as the cert is not valid. I get cert warnings in the HA log.

If adding https address or my DuckDNS path in HA's internal_url outbound mqtt message to plate is correct, but plate is not allowed/can't find the file and returns a 404 HTTP error.

Using a browser I can access the file entering the exact same path (copy/paste from openHASP log)

openHASP fw still accepts inbound https messages. I've retested with a dib file i had stored locally and i can without issues push that direct src mqtt message

@dgomes
Copy link
Collaborator

dgomes commented Jan 30, 2023

If HA is configured to handle SSL (https://www.home-assistant.io/integrations/http/#ssl_certificate) then you must have httpS in the internal_url address.

Please activate CC debug mode and provide logs

@htvekov
Copy link
Author

htvekov commented Jan 30, 2023

If HA is configured to handle SSL (https://www.home-assistant.io/integrations/http/#ssl_certificate) then you must have httpS in the internal_url address.

Please activate CC debug mode and provide logs

I went through various scenarios and actually got SSL working with one specific configuration 🎉🙂

For SSL to work here using 'standard' DuckDNS following settings must be done:

Image path for push_image service MUST start with:
image: https://myduckdns.duckdns.org.....

internal_url setting in HA MUST be the duckDNS url:

internal_url: https://myduckdns.duckdns.org
external_url: https://myduckdns.duckdns.org

I guess that using above will direct all traffic between HA and external components through DuckDNS (not really the best solution)

Debug log clips from CC in HA + openHASP logs attached.
Four different scenarios tested.

HA has some SSL protocol issues if two images are send within a few seconds (in my case images are identical)

ssl_openhasp_log.txt

@dgomes
Copy link
Collaborator

dgomes commented Jan 30, 2023

1st snippet:

CC can't access media_player content (CC validated the SSL certificate and did not match IP/hostname)

2nd snippet:

CC did get the image and made available... then something wrong with your automation...

3rd snippet:

Likely trying to serve http over https...

4th snippet:

Again... SSL mismatch.

Conclusions: you are running SSL in HA and therefore you get all sorts of SSL mismatches...
My advise: move SSL out of HA and leave http:// as internal_url

@htvekov
Copy link
Author

htvekov commented Jan 30, 2023

Well, I guess you're absolutely right that SSL in HA is not an ideal solution.
Either have SSL outside of HA or use HA Companion app if you just want access to HA from outside your own network.
Thank you for your input on this 👍

Anyway, both CC and openHASP fw supports SSL. I've just confirmed that with my tests.
Don't know if you got the snippets mixed up or I just misunderstood what 3rd snippet is, as the 3rd snippet actually is the working solution 😉😁

@dgomes
Copy link
Collaborator

dgomes commented Jan 30, 2023

In the 3rd snippet you are not making use of internal_url... It's working, but all your internal traffic is going around the internet... (not a good idea)

@htvekov
Copy link
Author

htvekov commented Jan 30, 2023

In the 3rd snippet you are not making use of internal_url... It's working, but all your internal traffic is going around the internet... (not a good idea)

Ok. Then I understood what you meant 🙂
Yep. I fully agree. Even though it's working, it's not a viable solution.

I guess a reverse proxy configuration (nginx or similar) would work as expected.
But I have close to zero network knowledge. So I won't spend time going down that path.
I'll support the HA community instead and go with the Companion app.

@exotsk
Copy link

exotsk commented Jan 31, 2023

Please tell me if I use the local http server and use the src command via mqtt (it is used by the push image service from ha?) How to send an image to the board correctly? are there size or format restrictions?
I don't use duckdns if it's important to work over ssl.

@jazzmonger
Copy link

Does this lend any clues?

Logger: homeassistant.components.automation.openhasp_push_image_to_plate
Source: helpers/script.py:468
Integration: Automation ([documentation](https://www.home-assistant.io/integrations/automation), [issues](https://github.com/home-assistant/core/issues?q=is%3Aissue+is%3Aopen+label%3A%22integration%3A+automation%22))
First occurred: 9:00:54 AM (2 occurrences)
Last logged: 9:02:35 AM

HASP push Media image to Kitchen plate: Error executing script. Unexpected error for call_service at pos 1: module 'PIL.Image' has no attribute 'ANTIALIAS'
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 468, in _async_step
    await getattr(self, handler)()
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 704, in _async_call_service_step
    response_data = await self._async_run_long_action(
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 666, in _async_run_long_action
    return long_task.result()
           ^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/core.py", line 2035, in async_call
    response_data = await coro
                    ^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/core.py", line 2072, in _execute_service
    return await target(service_call)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/entity_component.py", line 235, in handle_service
    return await service.entity_service_call(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 876, in entity_service_call
    response_data = await _handle_entity_call(
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 948, in _handle_entity_call
    result = await task
             ^^^^^^^^^^
  File "/config/custom_components/openhasp/__init__.py", line 607, in async_push_image
    rgb_image = await self.hass.async_add_executor_job(
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/concurrent/futures/thread.py", line 58, in run
    result = self.fn(*self.args, **self.kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/openhasp/image.py", line 35, in image_to_rgb565
    im.thumbnail((height, width), Image.ANTIALIAS)
                                  ^^^^^^^^^^^^^^^
AttributeError: module 'PIL.Image' has no attribute 'ANTIALIAS'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants