SensorsIot / IOTstack

Docker stack for getting started on IOT on the Raspberry PI
GNU General Public License v3.0
1.45k stars 308 forks source link

Simple Samba share #548

Open Nurgak opened 2 years ago

Nurgak commented 2 years ago

I was looking around to share some media over Samba, but I could not find a good example on how to set it up.

With some effort I was able to achieve what I wanted: read-only shares with guest account for movies/series...

The goal was to stream movies to an Apple TV device. My method so far was to use the TV app on MacOS, which could only stream mp4 files and no subtitles to the Computers app on the Apple TV, very limited...

With Samba shares enabled and the VLC app installed on Apple TV any movie can be streamed and subtitles are an option as long as the subtitle file name is the same as the media file name.

Moreover, my media is stored on an external device, hosting IOTstack, inside the Nextcloud volume.

Here's my example.

version: '3.6'
services:
  samba:
    container_name: samba
    image: dperson/samba
    ports:
    - "139:139"
    - "445:445"
    read_only: true
    volumes:
    - type: bind
      source: /media/pi/storage/IOTstack/volumes/nextcloud/html/data/nurgak/files
      target: /share
      read_only: true
    restart: unless-stopped
    command: '-s "Movies;/share/Movies" -s "Series;/share/Series"'

Perhaps it could be interesting to integrate to IOTstack? I'm not sure what half of the options do...

ukkopahis commented 2 years ago

Samba is certainly useful in quite many scenarios. On the other hand it doesn't feel like an internet-of-things application. But that isn't really a strict requirement.

version: '3.6'
services:
  samba:
    container_name: samba
    image: ghcr.io/jtagcat/samba:samba
    ports:
      - "137:137/udp"
      - "138:138/udp"
      - "139:139/tcp"
      - "445:445/tcp"
    read_only: true
    tmpfs:
      - /tmp
    stdin_open: true
    tty: true
    volumes:
      - ./volumes/samba/share:/share:ro
    restart: unless-stopped
    command: '-s "share;/share"'
Nurgak commented 2 years ago

@ukkopahis See that's a very fortunate input that would be easily missed by an inexperienced person like me. I picked that image because it seemed straight forward, had lots of downloads on docker hub, and actually worked without too much effort... I did not even think about possible security issues with it.

I tried the image you suggested, but it did not work in my case, simply because it does not handle spaces in the share name. I tried escaping them (\) and replacing them with \040, but it did not work.

command: '-s "Movies;/share/Movies with a space" -s "Series;/share/Series with a space"'

ukkopahis commented 2 years ago

command: '-s "Movies;/share/Movies with a space" -s "Series;/share/Series with a space"'

Are you sure you don't have a typo somewhere? Check these folder exist in /share: docker-compose exec samba ls -la /share

Works for me (+also upgraded to use build from repository instead of relying on prebuilt images):

version: '3.6'
services:
  samba:
    container_name: samba
    build: https://github.com/jtagcat/samba.git#main:samba/
    ports:
      - "137:137/udp"
      - "138:138/udp"
      - "139:139/tcp"
      - "445:445/tcp"
    read_only: true
    tmpfs:
      - /tmp
    stdin_open: true
    tty: true
    volumes:
      - ./volumes/samba/share:/share:ro
    restart: unless-stopped
    command: '-s "share;/share/Kill Bill"'

Create and test:

pi@raspberrypi:~/samba-test $ docker-compose build --pull && docker-compose up -d 
...
pi@raspberrypi:~/samba-test $ ls -l volumes/samba/share/Kill\ Bill/*
-rw-r--r-- 1 pi pi 0 Apr 23 22:17 'volumes/samba/share/Kill Bill/1.avi'
pi@raspberrypi:~/samba-test $ docker-compose exec samba smbclient -N -m SMB2 '\\localhost\share'
Try "help" to get a list of possible commands.
smb: \> ls
  .                                   D        0  Sat Apr 23 19:17:52 2022
  ..                                  D        0  Sat Apr 23 15:47:47 2022
  1.avi                               N        0  Sat Apr 23 19:17:52 2022

        61097724 blocks of size 1024. 46326780 blocks available

But took a while to figure that out you need the -m SMB2 flag for some reason.

Paraphraser commented 2 years ago

@ukkopahis - going back to your "is this IoT?" I'd vote "yes". As soon as I saw the first post I thought it sounded like a perfect fit. The AppleTV is an appliance with no useful storage of its own. Any local media needs to go "somewhere" and this is "somewhere". I actually see little difference between the problem of hosting media somewhere for serving to devices that play that media, and hosting sensor data in Influx+Grafana for display on devices.

I think this whole idea is far more intriguing than, say, Flex.

@Nurgak - on the topic of:

command: '-s "Movies;/share/Movies space" -s "Series;/share/Series space"'

did you also happen to try:

command: '-s "Movies;\"/share/Movies space\"" -s "Series;\"/share/Series space\""'

If wrapping in escaped quotes doesn't solve it either then the next step might be to open an issue on GitHub because embedded spaces has got to be a fairly common use-case. It might also be worth checking non-ASCII/UTF8 characters in names. Or even possessive apostrophes "Hogan's Heroes" - those sometimes confuse brain-dead pathname parsing algorithms.

Nurgak commented 2 years ago

@ukkopahis @Paraphraser It turns out I also had issues with the mounting point, solving that allowed me to predictably mount the external drive where my stuff is and the shares were created successfully, even with spaces in the path. My bad.

However, I'm not successful in accessing them the same way as with the dperson/samba image (from a computer or Apple TV), the guest account does not seem to be allowed, maybe that's related to the -m SMB2 flag... how would one integrate that to the docker-compose file?

Perhaps the dperson/samba image, or forks thereof, is not the best option for this, but I would not know which one would be...

ukkopahis commented 2 years ago

Would this help and allow your computer and Apple to connect? It fixes the smbclient flag requirement. I suspect the newer samba versions in this image tries to use a too new protocol version.

    command: '-g "server max protocol = SMB2" -s "share;/share"'

or the same, but using YAML block style to improve readability when there are lots of parameters:

    command: >-
        -g "server max protocol = SMB2"
        -s "share;/share"
Nurgak commented 2 years ago

@ukkopahis Unfortunately no luck. The added option does have an effect, but when I want to browse as a guest I get rejected. Screenshot 2022-04-24 at 18 04 44 I tried with a user and it worked (-u "test;test"), but I'd like to have the guest account enabled to avoid having to enter credentials. Perhaps having guest access might be bad practice, but I don't care about that for read-only shares.

ukkopahis commented 2 years ago

This configuration problem should be solved using the new image, as the old has the CVE-2021-44142 (RCE) vulnerability. Can't add such security holes to IOTstack. I don't have a AppleTV/mac to test with, so somebody who has one has to do the legwork to get an example public share to work.

ukkopahis commented 2 years ago

I guess you could make one last try using:

    command: >-
        -u "nobody;" -g "guest account = nobody"
        -S -g "server max protocol = SMB2"
        -n
        -s "share;/share"
Nurgak commented 2 years ago

@ukkopahis Unfortunately still no luck.

I noticed that the jtagcat image tends to create an enormous amount of volumes (seen from Portainer), such as /var/lib/docker/volumes/c4ef02605ee7f001d42e5b13ab3da4bd055e383a75eecf5c049c28652b702fca/_data. Perhaps related to the fact that I test with many different settings, but they remain abandoned and new ones are created.

I will look for another image...

ukkopahis commented 2 years ago

enormous amount of volumes

docker system prune

I will look for another image...

Probably won't help much. The jtagcat image is just stock alpine using an up-to-date Samba. Any other image using the same Samba version will work the same way, it's all in the configuration.

Nurgak commented 2 years ago

Probably won't help much. The jtagcat image is just stock alpine using an up-to-date Samba. Any other image using the same Samba version will work the same way, it's all in the configuration.

That's good to know...

I would be nice to have logs that would help debugging the issue. I feels not matter what combination of settings, I'm not accessing the files over the guest account.