teldrive
teldrive copied to clipboard
Requiring authentication to log into web ui?
I have just figured out that anybody can log into the WebUI and use his telegram account to upload through my container... couldn't find any password setting or something. I've already added password for the webdav page with rclone, but still the frontend is missing authentication. I'm not sure if I'm 100% correct, but any help is appreciated... as I need to expose the port but also can't leave it un-protected. Thanks for great work.
you can whitelist the telegram accounts which can use log-in to your teldrive instance by adding usernames in config.toml under jwt-allowed-users.
Whitelist or not, if your instance is public facing, it is strongly recommended to put it behind a reverse proxy regardless.
Caddy + basic_auth with a random string as username is enough imo. Even better with a whitelist, but not necessary, imo.
This is in my Caddyfile for my containerized caddy instance:
teldrive.example.com {
tls internal
basic_auth /* {
some-random-string-as-username some-hashed-random-password
}
reverse_proxy teldrive:8080
# etc
}
Same goes for Rclone.
you can whitelist the telegram accounts which can use log-in to your teldrive instance by adding usernames in config.toml under jwt-allowed-users.
just figured out it's already in my config.toml, but have you tried logging with a non-whitelisted account? because i tried a random phone number and it continued to otp step.. not sure what will happen next as it was random.
Whitelist or not, if your instance is public facing, it is strongly recommended to put it behind a reverse proxy regardless.
Caddy + basic_auth with a random string as username is enough imo. Even better with a whitelist, but not necessary, imo.
This is in my Caddyfile for my containerized caddy instance:
teldrive.example.com {
tls internal basic_auth /* { some-random-string-as-username some-hashed-random-password } reverse_proxy teldrive:8080 # etc } Same goes for Rclone.
thanks for the info, i already use caddy for all my containers, adding a basic auth with is a good idea. but that keeps the source ip-address:port without auth .. which may not be very secret :" i think whitelisting a telegram account is the most secure option now
but that keeps the source ip-address:port without auth
I don't understand what you're saying. Your instance is already behind a reverse proxy and won't be accessible to anyone other than your docker host and the container itself. If you're worried about someone gaining ssh access: if that happens you're in much bigger trouble anyway, and you're probably doing something wrong elsewhere.
i think whitelisting a telegram account is the most secure option now
Sure, i never said not to use it. If anything you should use it in addition to basic auth
I don't understand what you're saying. Your instance is already behind a reverse proxy and won't be accessible to anyone other than your docker host and the container itself. If you're worried about someone gaining ssh access: if that happens you're in much bigger trouble anyway, and you're probably doing something wrong elsewhere.
"That's not quite what I meant. Even with those Caddy settings, your instance is still exposed publicly without authentication if someone accesses it directly through your public IP and port, instead of going through the reverse proxy. It's really not that hard for someone to find your IP and scan for open ports.
The real solution is to configure the network your container is on so you can close off that external port. Then, in your Caddyfile, you'd point to 127.0.0.1:port instead. This keeps direct access completely locked down.
It would've been easier if a basic authentication has been added to the core app tho 😄
Well, you must be doing something wrong, because the whole point of a reverse proxy IS exactly that; to not expose the instance directly. You do that by NOT opening the port that your instance is bound to.
A common mistake is exposing the port with docker, because it handles iptables for you automatically. It means that it is very easy to have open ports with docker compose without knowing or thinking about it.
By doing
services:
some-service:
image: ...
ports:
- 9090:8080
# etc
you would bind your instance to all network interfaces (0.0.0.0) on port 9090, thus exposing the instance to the public.
[public_ip]:9090is accessible,- but
[public_ip]:8080is not and never will be (by this container).
You could do
services:
some-service:
image: ...
ports:
- 127.0.0.1:9090:8080
# etc
to expose your instance to your docker host only, by simply binding to localhost specifically.
But with containerized caddy, it is very easy to just omit exposing any port at all. Simply remove the ports section and make sure to share a network between your instances.
You can either define a caddy instance within the same compose file:
services:
my-teldrive-service:
image: ...
# etc
my-caddy-service:
image: ...
# etc
Or separate them, and either use the default network of the teldrive container (which docker compose creates automatically), or create your own custom network.
networks:
my-teldrive-service_default:
external: true
services:
my-caddy-service:
image: ...
networks:
- my-teldrive-service_default
# etc
And in the Caddyfile, you use the use reverse_proxy my-teldrive-service:[my-internal-teldrive-port]
You can even share the same network stack of Caddy with Teldrive, or vice versa, so that both of their containers, or any number of containers, use the same subnet (e.g. 172.21.0.0/16) instead of each getting its own (e.g. 172.21.0.0/16 and 172.22.0.0/16). They simply share the same network interfaces with each other.
services:
my-teldrive-service:
image: ...
network_mode: service:my-caddy-service
# network_mode: container:the-container-name-of-my-caddy-service
# etc
Or even better, don't make your instances public at all and use wireguard instead. That way you can close all your ports except your wireguard port. You can also use Tailscale or Zerotier.
services:
my-teldrive-service:
image: ...
# etc
my-wireguard-service:
image: lscr.io/linuxserver/wireguard:latest
container_name: wireguard
# etc
or if separate (and this is what i do):
services:
my-teldrive-service:
image: ...
network_mode: container:wireguard
# network_mode: service:my-wireguard-service
# etc
Connect your PC to your VPS via wireguard and then access your teldrive with e.g. http://10.13.13.2:[my-internal-teldrive-port].
And creating a split tunnel you don't route all your internet traffic via your wireguard VPN. That way your PC's IP is from your ISP but you can still access e.g. http://10.13.13.2:[my-internal-teldrive-port]. If you want https, you can reverse proxy to port 443, or (i believe) use tailscale or zerotier, which is simpler to use but not as private as using wireguard directly.
The simplest solution, if you need to make it public (reverse proxied), is to omit the ports section. And all this stuff, regardless if it's reverse proxied or tucked behind a VPN, has nothing to do with basic auth.
It would've been easier if a basic authentication has been added to the core app tho
Now, with what i've just explained to you, what you're proposing is not really that much easier. If anything, it would be less secure. With Caddy, you have the security in a much more maintained software with security in mind! Additionally, if you use basic auth (or some other authentication method) + Caddy, or any other reverse proxy solution, you get two layers of security. How, you ask? Because Teldrive already provide some security! You authenticate with your Telegram account, don't you? And, in addition to that, you can even ban anyone but yourself to be able to log in (i.e. the whitelist).
Even in the unlikely event that someone actually gets access to your instance, it's not like they get a hold of your files anyway. If they do, you simply nuke their shit because you control your database. With encryption, file chunking, and randomized filenames, it’s much more of a hassle for them than it is for you - and they'd be the idiot, not you.
You catch my drift?
Well, you must be doing something wrong, because the whole point of a reverse proxy IS exactly that; to not expose the instance directly. You do that by NOT opening the port that your instance is bound to.
A common mistake is exposing the port with
docker, because it handlesiptablesfor you automatically. It means that it is very easy to have open ports with docker compose without knowing or thinking about it.
Thanks a lot for the detailed breakdown really appreciate you taking the time to explain it so clearly.
Though I got a B+ in my computer networks course last semester, I totally overlooked the external port binding in Docker. I had used 8090:8090 instead of binding it to 127.0.0.1:8090:8090, which basically exposed the port to the world with and without realizing it :""
Your point about using internal networking and omitting the ports: section entirely when behind a reverse proxy like Caddy makes total sense now. Definitely tightening things up on my setup. lesson learned!
Thanks again!
Great! Glad I could help.
I totally overlooked the external port binding in Docker.
Yeah, it's very common.
you can whitelist the telegram accounts which can use log-in to your teldrive instance by adding usernames in config.toml under jwt-allowed-users.
just figured out it's already in my config.toml, but have you tried logging with a non-whitelisted account? because i tried a random phone number and it continued to otp step.. not sure what will happen next as it was random.
after verifying the otp, teldrive will through an error like "user not allowed" (similar to how it would show Internal Server Error when adding bots)
you can whitelist the telegram accounts which can use log-in to your teldrive instance by adding usernames in config.toml under jwt-allowed-users.
just figured out it's already in my config.toml, but have you tried logging with a non-whitelisted account? because i tried a random phone number and it continued to otp step.. not sure what will happen next as it was random.
after verifying the otp, teldrive will through an error like "user not allowed" (similar to how it would show Internal Server Error when adding bots)
Teldrive has to know the username before it can grant access or not. To get the username (or any other user info) you need to login to the Telegram API client first.