From 99e2eb323d754d15a75ba7ed66f8dff2cc846242 Mon Sep 17 00:00:00 2001 From: Chris Varenhorst Date: Sun, 6 Apr 2025 17:30:01 -0700 Subject: [PATCH 1/8] Add secure remote setup instructions to protect against arbitrary command execution --- README.md | 37 ++++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index fe218f8..2005dc3 100644 --- a/README.md +++ b/README.md @@ -32,29 +32,48 @@ Restart Home Assistant and enjoy! #### Remote mpv -It is also possible to connect to a remove mpv instance over the network. First, ensure that `socat` is installed, and -create a script that runs socat to expose the mpv socket on a network port (2352 in the following example). It is -important that this script has the extension `.run`, and is executable (run `chmod +x socat.run`): +It is also possible to connect to a remote mpv instance over the network. For security reasons, it's strongly recommended to use SSH tunneling to create an encrypted connection rather than exposing the socket directly over the network. Directly exposing the mpv control socket is a security risk, as it would allow anybody with access to the port to execute arbitrary commands via mpv's `run` command. + +First, ensure that `socat` is installed. Then create a script that: +1. Starts a local TCP listener that connects to the mpv socket +2. Creates an SSH tunnel to securely expose this listener to your Home Assistant machine + +Example secure connection script (save as `secure-mpv-tunnel.sh` and make executable with `chmod +x`): ```sh -#!/bin/sh -exec socat TCP-LISTEN:2352,fork UNIX-CONNECT:/path/to/mpv-socket +#!/bin/bash +# Replace these values with your actual settings +MPV_SOCKET="/path/to/mpv-socket" +LOCAL_PORT="2352" +REMOTE_HOST="homeassistant.local" # Your Home Assistant machine +REMOTE_USER="user" # SSH user on your Home Assistant machine + +# Kill all background processes when script terminates +trap "kill 0" SIGINT SIGTERM EXIT + +# Create local TCP listener that connects to mpv socket +socat TCP-LISTEN:${LOCAL_PORT},reuseaddr,fork UNIX-CONNECT:${MPV_SOCKET} & + +# Create secure SSH tunnel +ssh -N -R ${LOCAL_PORT}:localhost:${LOCAL_PORT} ${REMOTE_USER}@${REMOTE_HOST} ``` -Start mpv with using the `--script` option to have it run the script on startup: +Start mpv with the `--script` option to run the script on startup: ```sh -mpv --input-ipc-server=/path/to/mpv-socket --script=/path/to/socat.run +mpv --input-ipc-server=/path/to/mpv-socket --script=/path/to/secure-mpv-tunnel.sh ``` -Finaly, configure the integration to connect over the network: +Finally, configure the integration to connect to the local end of the tunnel: ```yaml media_player: - platform: mpv name: "MPV Player" server: - host: 192.168.1.100 + host: localhost port: 2352 ``` +This approach ensures all communication between Home Assistant and mpv is encrypted through SSH, preventing unauthorized access to your mpv instance. + #### Other useful mpv options You can additionally use the `--idle` mpv option to have it remain alive if no media is playing. From 278dd6ed6979fab3ecfc785475595566a5477c70 Mon Sep 17 00:00:00 2001 From: Chris Varenhorst Date: Sun, 6 Apr 2025 17:58:23 -0700 Subject: [PATCH 2/8] Make example script shorter and match original better --- README.md | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 2005dc3..de0c874 100644 --- a/README.md +++ b/README.md @@ -34,11 +34,7 @@ Restart Home Assistant and enjoy! It is also possible to connect to a remote mpv instance over the network. For security reasons, it's strongly recommended to use SSH tunneling to create an encrypted connection rather than exposing the socket directly over the network. Directly exposing the mpv control socket is a security risk, as it would allow anybody with access to the port to execute arbitrary commands via mpv's `run` command. -First, ensure that `socat` is installed. Then create a script that: -1. Starts a local TCP listener that connects to the mpv socket -2. Creates an SSH tunnel to securely expose this listener to your Home Assistant machine - -Example secure connection script (save as `secure-mpv-tunnel.sh` and make executable with `chmod +x`): +First, ensure that `socat` is installed, and create a script that runs socat with an SSH tunnel to securely expose the mpv socket (port 2352 in the following example). It is important that this script has the extension `.run`, and is executable (run `chmod +x secure-tunnel.run`): ```sh #!/bin/bash # Replace these values with your actual settings @@ -47,9 +43,6 @@ LOCAL_PORT="2352" REMOTE_HOST="homeassistant.local" # Your Home Assistant machine REMOTE_USER="user" # SSH user on your Home Assistant machine -# Kill all background processes when script terminates -trap "kill 0" SIGINT SIGTERM EXIT - # Create local TCP listener that connects to mpv socket socat TCP-LISTEN:${LOCAL_PORT},reuseaddr,fork UNIX-CONNECT:${MPV_SOCKET} & @@ -59,7 +52,7 @@ ssh -N -R ${LOCAL_PORT}:localhost:${LOCAL_PORT} ${REMOTE_USER}@${REMOTE_HOST} Start mpv with the `--script` option to run the script on startup: ```sh -mpv --input-ipc-server=/path/to/mpv-socket --script=/path/to/secure-mpv-tunnel.sh +mpv --input-ipc-server=/path/to/mpv-socket --script=/path/to/secure-tunnel.run ``` Finally, configure the integration to connect to the local end of the tunnel: From 9e0e84928a1489fcae6e3d561fc565c29b984eea Mon Sep 17 00:00:00 2001 From: Chris Varenhorst Date: Sun, 6 Apr 2025 18:00:38 -0700 Subject: [PATCH 3/8] Make script filename better --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index de0c874..239b316 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ Restart Home Assistant and enjoy! It is also possible to connect to a remote mpv instance over the network. For security reasons, it's strongly recommended to use SSH tunneling to create an encrypted connection rather than exposing the socket directly over the network. Directly exposing the mpv control socket is a security risk, as it would allow anybody with access to the port to execute arbitrary commands via mpv's `run` command. -First, ensure that `socat` is installed, and create a script that runs socat with an SSH tunnel to securely expose the mpv socket (port 2352 in the following example). It is important that this script has the extension `.run`, and is executable (run `chmod +x secure-tunnel.run`): +First, ensure that `socat` is installed, and create a script that runs socat with an SSH tunnel to securely expose the mpv socket (port 2352 in the following example). It is important that this script has the extension `.run`, and is executable (run `chmod +x secure-mpv-tunnel.run`): ```sh #!/bin/bash # Replace these values with your actual settings @@ -52,7 +52,7 @@ ssh -N -R ${LOCAL_PORT}:localhost:${LOCAL_PORT} ${REMOTE_USER}@${REMOTE_HOST} Start mpv with the `--script` option to run the script on startup: ```sh -mpv --input-ipc-server=/path/to/mpv-socket --script=/path/to/secure-tunnel.run +mpv --input-ipc-server=/path/to/mpv-socket --script=/path/to/secure-mpv-tunnel.run ``` Finally, configure the integration to connect to the local end of the tunnel: From 984b3805f124c9b78d403ec4506d395b235fcc96 Mon Sep 17 00:00:00 2001 From: Chris Varenhorst Date: Sun, 6 Apr 2025 18:03:33 -0700 Subject: [PATCH 4/8] Use more descriptive variable names --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 239b316..6bf7ca0 100644 --- a/README.md +++ b/README.md @@ -40,14 +40,14 @@ First, ensure that `socat` is installed, and create a script that runs socat wit # Replace these values with your actual settings MPV_SOCKET="/path/to/mpv-socket" LOCAL_PORT="2352" -REMOTE_HOST="homeassistant.local" # Your Home Assistant machine -REMOTE_USER="user" # SSH user on your Home Assistant machine +HA_HOST="homeassistant.local" # Your Home Assistant machine +HA_USER="user" # SSH user on your Home Assistant machine # Create local TCP listener that connects to mpv socket socat TCP-LISTEN:${LOCAL_PORT},reuseaddr,fork UNIX-CONNECT:${MPV_SOCKET} & # Create secure SSH tunnel -ssh -N -R ${LOCAL_PORT}:localhost:${LOCAL_PORT} ${REMOTE_USER}@${REMOTE_HOST} +ssh -N -R ${LOCAL_PORT}:localhost:${LOCAL_PORT} ${HA_USER}@${HA_HOST} ``` Start mpv with the `--script` option to run the script on startup: From e270598a0e84c6d1e1edfb5501b09c4e814f117a Mon Sep 17 00:00:00 2001 From: Chris Varenhorst Date: Sun, 6 Apr 2025 18:10:01 -0700 Subject: [PATCH 5/8] Add note about HA SSH addon configuration --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 6bf7ca0..6a30d03 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,8 @@ socat TCP-LISTEN:${LOCAL_PORT},reuseaddr,fork UNIX-CONNECT:${MPV_SOCKET} & ssh -N -R ${LOCAL_PORT}:localhost:${LOCAL_PORT} ${HA_USER}@${HA_HOST} ``` +> **Note:** If using the [Home Assistant SSH addon](https://github.com/hassio-addons/addon-ssh), you'll need to enable `allow_remote_port_forwarding: true` in its configuration. + Start mpv with the `--script` option to run the script on startup: ```sh mpv --input-ipc-server=/path/to/mpv-socket --script=/path/to/secure-mpv-tunnel.run From b1c7212965851746d76ccd9a637c2188cf5fb1c8 Mon Sep 17 00:00:00 2001 From: Chris Varenhorst Date: Sun, 6 Apr 2025 18:17:52 -0700 Subject: [PATCH 6/8] Clarify SSH requirements in remote setup --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6a30d03..c1fe58a 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,7 @@ socat TCP-LISTEN:${LOCAL_PORT},reuseaddr,fork UNIX-CONNECT:${MPV_SOCKET} & ssh -N -R ${LOCAL_PORT}:localhost:${LOCAL_PORT} ${HA_USER}@${HA_HOST} ``` -> **Note:** If using the [Home Assistant SSH addon](https://github.com/hassio-addons/addon-ssh), you'll need to enable `allow_remote_port_forwarding: true` in its configuration. +> **Note:** This method requires SSH access to your Home Assistant instance. If using the popular [Home Assistant SSH addon](https://github.com/hassio-addons/addon-ssh), you'll need to enable `allow_remote_port_forwarding: true` in its configuration for the reverse tunnel to work. Start mpv with the `--script` option to run the script on startup: ```sh From 700303d52aea5b573d374adc7c63b1b02184ddcd Mon Sep 17 00:00:00 2001 From: Chris Varenhorst Date: Sun, 6 Apr 2025 18:25:21 -0700 Subject: [PATCH 7/8] lol, forgot to ensure socat exposed it on a local port only, which would have negated this entire approach --- README.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index c1fe58a..d64c136 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,11 @@ Restart Home Assistant and enjoy! It is also possible to connect to a remote mpv instance over the network. For security reasons, it's strongly recommended to use SSH tunneling to create an encrypted connection rather than exposing the socket directly over the network. Directly exposing the mpv control socket is a security risk, as it would allow anybody with access to the port to execute arbitrary commands via mpv's `run` command. -First, ensure that `socat` is installed, and create a script that runs socat with an SSH tunnel to securely expose the mpv socket (port 2352 in the following example). It is important that this script has the extension `.run`, and is executable (run `chmod +x secure-mpv-tunnel.run`): +First, ensure that `socat` is installed, and create a script that: +1. Uses socat to bridge the mpv Unix socket to a localhost-only port on your machine +2. Creates an SSH reverse tunnel to securely forward that port to your Home Assistant server + +The script must have the `.run` extension and be executable (run `chmod +x secure-mpv-tunnel.run`): ```sh #!/bin/bash # Replace these values with your actual settings @@ -43,8 +47,8 @@ LOCAL_PORT="2352" HA_HOST="homeassistant.local" # Your Home Assistant machine HA_USER="user" # SSH user on your Home Assistant machine -# Create local TCP listener that connects to mpv socket -socat TCP-LISTEN:${LOCAL_PORT},reuseaddr,fork UNIX-CONNECT:${MPV_SOCKET} & +# Create localhost-only TCP listener that connects to mpv socket +socat TCP-LISTEN:${LOCAL_PORT},bind=127.0.0.1,reuseaddr,fork UNIX-CONNECT:${MPV_SOCKET} & # Create secure SSH tunnel ssh -N -R ${LOCAL_PORT}:localhost:${LOCAL_PORT} ${HA_USER}@${HA_HOST} From 5d067024a37a58d6fed8a942fe2cc592faf8b164 Mon Sep 17 00:00:00 2001 From: Chris Varenhorst Date: Sun, 6 Apr 2025 18:39:11 -0700 Subject: [PATCH 8/8] Add port check to prevent duplicate script execution --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index d64c136..b147431 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,12 @@ LOCAL_PORT="2352" HA_HOST="homeassistant.local" # Your Home Assistant machine HA_USER="user" # SSH user on your Home Assistant machine +# Exit if port already in use (script likely already running) +if nc -z 127.0.0.1 ${LOCAL_PORT} 2>/dev/null; then + echo "Port ${LOCAL_PORT} already in use, assuming secure-mpv-tunnel script is already running" + exit 0 +fi + # Create localhost-only TCP listener that connects to mpv socket socat TCP-LISTEN:${LOCAL_PORT},bind=127.0.0.1,reuseaddr,fork UNIX-CONNECT:${MPV_SOCKET} &