-
Notifications
You must be signed in to change notification settings - Fork 42
Podcast RSS Feeds
Note
The below steps may not be required depending on your podcast app. If your podcast app doesn't rely on 3rd party servers for its core functionality, you might be able to use a VPN instead. If a VPN works for you, skip to the Putting it all together
section below
RSS Feeds can be used to bring your content from Pinchflat into your favourite podcast app/RSS reader, but it takes a little setup to do so securely:
- Your Pinchflat instance is accessible outside your network via an unchanging domain. I'm leaving this as an exercise to the reader
- It works best to use a reverse proxy or similar - I use NGINX Proxy Manager on UnRAID
- You can probably use a CF Tunnel but you will be streaming media which is against CF's ToS. Do what you will, but don't say I didn't tell ya'!
- You may need to serve the site over
https
(but you really should, anyway)
Since your Pinchflat instance will need to be accessible from the outside world, it's essential that you add some level of authentication. Seriously, it'd be silly to not secure the app. To do so, add both the BASIC_AUTH_USERNAME
and BASIC_AUTH_PASSWORD
environment variables to your docker run
command or Docker container manager.
For example:
docker run
-p 8945:8945 \
-v /host/path/to/config:/config \
-v /host/path/to/downloads:/downloads \
-e BASIC_AUTH_USERNAME=admin \
-e BASIC_AUTH_PASSWORD=CHANGEME \
ghcr.io/kieraneglin/pinchflat:latest
It's recommended to use the app-provided authentication rather than any authentication provided by your reverse proxy unless you know what you're doing. See the next step for the reason why.
Important
Test that opening the app makes you enter these credentials before moving on.
"Wait! I can't serve content to my podcast app now!", you're saying. And you're right!
A requirement of working with your podcast app is that the endpoints for reading the XML feed, getting the feed assets (like cover image), and streaming media are accessible via an unchanging URL that requires no configuration. Essentially, these routes need to live 100% outside of the app's authentication. All routes are protected by default, but if you want to exclude these routes from authentication simply set the EXPOSE_FEED_ENDPOINTS
env var to any value. Here's an example of what we have so far:
docker run
-p 8945:8945 \
-v /host/path/to/config:/config \
-v /host/path/to/downloads:/downloads \
-e BASIC_AUTH_USERNAME=admin \
-e BASIC_AUTH_PASSWORD=CHANGEME \
-e EXPOSE_FEED_ENDPOINTS=yes \
ghcr.io/kieraneglin/pinchflat:latest
If you're doing it this way, I'm going to assume you're pretty technical so this will be extremely high level.
Essentially, you need to add authentication to all routes except the "feed" endpoints. These endpoints handle serving XML, images, media. You can find those routes in the router by searching for pipe_through :feeds
.
Here's an example NGINX location
block that works at the time of this writing:
location ~* (^/sources/[^/]+/feed(_image)?|^/media/[^/]+/(stream|episode_image))(\.[a-zA-Z0-9]+)?$ {
# You may want to add more here depending on your setup
proxy_pass $forward_scheme://$server:$port;
}
This is a technical digression that doesn't impact setup, but it's good to be aware of the security implications of what you're doing.
Internally the app uses numeric IDs to reference resources (eg: in the route sources/59/media/660
I'm talking about the 59
and the 660
). If this is how we served data to the RSS feed, it would be trivially easy for an attacker to use an enumeration/forced browsing approach to start looking through the content you've downloaded. After all, they'd just need to try swapping 660
for 661
then 662
, etc. This application is fairly low-stakes, but I'd rather not invite that possibility in the first place.
To mitigate this, any external URLs reference media via a universally unique identifier (UUID). This isn't perfect security since anyone who knows the URL for media can access it, but it makes it essentially impossible to guess a URL in the first place.
By now you should have done the following:
- Set up a reverse proxy (or similar) so you can access Pinchflat from the internet via your custom domain
- Added authentication via HTTP Basic auth
- Excluded the RSS/streaming-related endpoints from authentication so your podcast app can access the data
Almost done! Now, you just need to add your RSS feed to your podcast app:
⚠️ Visit Pinchflat from your custom domain or VPN when performing the next steps⚠️ - Create a new source and download some content
- When viewing the source, click "Actions" along the top then "Copy RSS Feed"
- Enter that feed URL into your podcast app
- That's it!
Well done! Like I said, this is a beta feature and RSS/XML can be very finicky. Please let me know if you encounter any problem by creating a GitHub issue!