TCP permissions?

I’m not sure what category fits best so I figured config covers it…

I tried setting this up on a Pi3b with the main hassos image and it worked but I couldn’t get my serial to work. Everyone said I need a supervised install to make serial work so I put that aside and did a supervised install on a pi4/4g with raspbian buster and got serial working but now my command line switches died. I found that there are HUGE differences in how things work in hassos vs supervised within the config file!

I have SSH set up into the main host OS and I also added the SSH add-on so I have access to the HA environment through the web terminal. Both environments are very different in how they act. I have a relay board I need to send two numbers to. I can do it via command line or bash script from ssh into the main OS and it also works from the HA add-on ssh terminal environment, but fails when put into the yaml as a shell_command. I thought it was bash scripts in general but have realized that it is mainly ones that use tcp.

Just entering commands from command line or running as a script I was successful with:

1. Echo to nc 
2. Echo to /dev/tcp
3. Curl

But neither work from a shell_command within the system. I have basically the same script echo to /dev/ttyAMA0 for serial and the only difference here is the path that is echoed to so I assume the running Home Assistant has no access to /dev/tcp as a script. The fact nc doesn’t work from within a script proves that too. However, I have a tcp sensor set up to that ip and port that DOES work… so the Home Assistant environment has permission to use it, just not she’ll commands from within… so I don’t really know where to look to give scripts access to tcp functionality. I see tons of people running scripts echoing to /dev/tcp, netcat, AND curl so I know I must be missing something. Supervised runs as user root so it should be good AND I can’t do the “add user home assistant to dial out group” bc there is no user for that, only root.

Any ideas where to look to make these functions work? They were super easy in the hassos image (I used bash scripts with nc there) but I’m lost as to why it won’t work in supervised… I’m going on day three and I feel like it’s going to be something so obvious…

Hi,

Could you please show the code of the shell_commands you are using and the errors you’re receiving.

1 Like

OS: Raspbian Buster (Deb10)
HW: Raspberry Pi 4 - 4Gb

Errors would be amazing… I only get the log enters that the script failed. I can try to get some code up, but none are more than one or two lines, but essentially various versions of:

val=$(echo -n 23 | nc -w 2 10.0.0.2 6722)
r1="${val:0:1}"
echo -n $r1

OR

val=$(echo -n 23 > /dev/tcp/10.0.0.2/6722)
r1="${val:0:1}"
echo -n $r1

I say various versions bc I tried sending the same data via curl and /dev/tcp echo, both of which only change the first line. ALL three work from raspbian ssh cli AND the HA add-on ssh web terminal. NONE work from a script run from a commandline_switch. Eventually I found a “fix” (band-aid…) by making a symlink to netcat in my config folder and calling that (as you will see in code) and got it to work… I had the script returning true/false but cut all that to the basics. I also had tried full path for everything (ie: /bin/echo vs echo) and that made no difference. netcat in the HA terminal is /usr/bin/nc but that made no difference. I had added /dev/ to the allowed folders list but that made no difference.

Strange thing is my serial sensor is communicating via the /dev/ttyAMA0 so HA clearly HAS access to /dev/, just not TCP and you cannot link to tcp directly. the “null_state” functions were when I realized the TCP sensor works, which i use in the value template anyway so I do not actually NEED the “command_state” function, but it will not use the “value_template” if nothing is listed as a status command. I tried writing to a file in config (already created and existing) but that failed so I tried echo to /dev/null and that failed. Scripts run from within my HA fail. All of them. No matter what is in it. As in making a shell_command call “script.sh”, so I had to find a way to reduce them to single line and put the actual code in the shell_command. Now they function. Even putting code there any calls to /dev/ fail (except ttyAMA0), writing to config folder fails, doing almost anything fails… TOGGLE buttons will not work at all. If I set up a toggle and then set up two separate buttons for on/off that both call the same shell_command the toggle does nothing (but WILL update state when the other button is pressed) and the individual on/off buttons work fine…

The other issue is that everything is SLOW. Clicking a button works immediately, but status change occurs in 30-180 seconds. I went back to my pi3b to double check and those update within 2-4 seconds…

configuration.yaml:

switch:
  - platform: command_line
    switches:
      lanterncont:
        command_timeout: 2
        command_on: shell_command.lantern_on
        command_off: shell_command.lantern_off
        command_state: shell_command.lantern_state
        value_template: >
          {% if (states('sensor.lantern_stat_call')[0] == "0") -%}
            {{ true }}
          {%- else -%}
            {{ false }}
          {%- endif %}
        friendly_name: Lantern Control

scripts.yaml:

lantern_control:
  sequence:
  - service: shell_command.lantern_on
  - service: shell_command.lantern_off
  - service: shell_command.null_state
  - service: shell_command.null2_state
  - service: shell_command.lantern_state

shell.yaml:

  lantern_on: /bin/echo -n 21 | /config/nc -w 2 10.0.0.2 6722
  lantern_off: /bin/echo -n 11 | /config/nc -w 2 10.0.0.2 6722
  lantern_state: /bin/echo -n 23 | /config/nc -w 2 10.0.0.2 6722

So basically I got all of the things working that I wanted to, but it is horrible. It is patched together and VERY slow.

Why?
It’s /usr/bin/nc in a supervised docker of mine

Because it would fail any time I called it as /usr/bin/nc but creating a symlink in config (/usr/share/hassio/homeassistant) and calling that works.

I clearly have some kind of permission issue with the docker container or HA, and that’s what I’m trying to solve… but root is the only user that seems to be there… I’m new to docker so that may be why I’m struggling. The docs are all over the place too… I have found 5 walkthroughs from the last year on the home assistant site of how to install supervised and all are slightly different…

I did see that raspbian is not actually approved a s a “supported” OS… maybe I will start over (again…) with true Debian10 and see if that helps… nothing that worked in the HASSOS install works here and nothing that works here works in the HASSOS install.

Sorry. I have a tendency to read diagonally when there is too much text :wink:

You can enter your container with docker exec -it homeassistant /bin/bash from the OS.
You’ll get a shell under root. HA also runs under root in the container so you’d have a smilar environment.

Now, you might be able to debug more easily your issue.

Note that you don’t have a full bash. Just busybox. So that could limit the capabilities of your scripts
Nevermind. Seems a full bash. I’m not sure wthether shell commands run under bash or plain sh though, which is busybox, not bash. That might explain…

EDIT2: Setting the HA log level to debug would show the commands stdout/stderr, according to the doc

EDIT3: Again from the doc, the proper way to execute a script would be bash /config/shell/script.sh

All good, I have a tendency to use too many words to get my point across… lol

I will try that… but I did see that the add-on web ssh terminal is busybox which is why I tested there assuming if it works in that limited environment it should within HA. Also paths and env are different there so I used that to make sure all was good. I wonder if that provides yet another env…?

Had logs at debug but didn’t get more info from the error. I love errors, they tell you exactly how to fix the issue! I would kill to get some detailed errors! Lol

As for /config/shell/script.sh Is that needed? That folder doesn’t exist, though I have a folder I put those scripts in but the name was different. Is there something that allows for permissions for a folder with that name? I saw multiple people say on threads that they must be in the main config folder so I moved them there instead of the sub folder I had within config

Replace that with the path to your actual bash script, obviously :wink:

Oh, ok. I had them in /config/dd/ (with proper path) and they did not work so I moved them to /config/ and they didnt work. I was not sure if you were saying that /config/shell/ had special permissions within the HA environment… All my scripts have been in /config/ or a folder within.

Just connected with this technique and all scripts function properly with nc (actual /usr/bin/nc, not my symlink) OR curl OR echo to /dev/tcp/10.0.0.2/6722

They also all work from the busybox terminal in the add-on and the OS env… There are definately different permissions in the HA running environment than in any of these other three options. I also can write to files and /dev/null from any of those places but not from within HA…

Ah, not sure how you installed HA, but there is apparmor involved, which might limit what you can do under HA.
I had it disabled everywhere so cannot really help, there.

Now we are getting somewhere… lol!
I remember seeing an error or message about apparmor. I believe I was going through the info screen trying to make everything “approved” and it was not there so I added it… but now I cannot find that. I did not know what it was so I added it thinking it was required (again, never used docker before so a LOT of new things thrown at me)

How did you disable it?

I installed standard raspbian, then I did:

sudo apt autoremove
curl -fsSL get.docker.com -o get-docker.sh && sh get-docker.sh
sudo systemctl enable docker
sudo systemctl start docker
sudo usermod -aG docker pi
sudo apt-get install jq apparmor-utils socat network-manager
sudo reboot now
sudo apt-get purge modemmanager

I was “strongly suggested” to enable it there:

I guess doing the inverse would disable it?

I stopped the service and now I can run nc without the symlink! What I am noticing though is when I create a switch like this:

switch:
  - platform: command_line
    switches:
      lanterncont:
        command_timeout: 2
        command_on: shell_command.lantern_on
        command_off: shell_command.lantern_off
        command_state: shell_command.lantern_state
        value_template: >
          {% if (value[0] == "0") -%}
            {{ '0' }}
          {%- else -%}
            {{ '-1' }}
          {%- endif %}
        friendly_name: Lantern Control

and I have

shell_command:
  lantern_on: echo -n 21 | nc -w 2 10.0.0.2 6722
  lantern_off: echo -n 11 | nc -w 2 10.0.0.2 6722
  lantern_state: echo -n 23 | nc -w 2 10.0.0.2 6722

Creating a basic button and setting ‘tap_action’ to toggle, I get errors of script failed for the scripts in command_on, command_off, and command_status… which are calling my commands as shown (ie: command_on: shell_command.lantern_on) but if I do ‘tap_action’ of ‘call-service’ and call service shell_command.lantern_on it works with no errors… So this issue seems to now be in the toggle functionality… How can it work when triggered by a call-service but not when triggered by a toggle?!? The toggle function updates so fast on my other install but using call-service I need two buttons and have to process the status myself which is only when that tcp sensor updates which takes forever.

Got the time down to 5-10s…
By making the call-service button entity the tcp sensor rather than the switch.

Now if I can get it to use shell commands from a script file instead of “inline” commands in the yaml I should be good! The app-armor was definitely blocking the inline scripts but I can’t make it run .sh files still.

Using the bash /config/<myscript.sh> way?

nope. And all I get in the log is this:

2021-06-28 13:53:51 INFO (SyncWorker_1) [homeassistant.components.command_line.switch] Running state value command: shell_command.lantern_state
2021-06-28 13:53:51 ERROR (SyncWorker_1) [homeassistant.components.command_line] Command failed: shell_command.lantern_state

But triggering shell_command.lantern_state from a button with:

          tap_action:
            action: call-service
            service: shell_command.lantern_state
            service_data: {}
            target: {}

Works every time

I ran into permission problems similar to this and IIRC I had to install the community version of web terminal in order to get elevated permissions. Which version of ssh did you install, there are 2.

I installed “Terminal & SSH” at “Current version: 9.1.3”