teldrive icon indicating copy to clipboard operation
teldrive copied to clipboard

Requiring authentication to log into web ui?

Open mkarimdev opened this issue 5 months ago • 11 comments

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.

mkarimdev avatar Jun 11 '25 11:06 mkarimdev

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.

puffious avatar Jun 11 '25 11:06 puffious

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.

iwconfig avatar Jun 11 '25 14:06 iwconfig

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.

mkarimdev avatar Jun 12 '25 15:06 mkarimdev

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

mkarimdev avatar Jun 12 '25 15:06 mkarimdev

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

iwconfig avatar Jun 12 '25 15:06 iwconfig

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 😄

mkarimdev avatar Jun 12 '25 22:06 mkarimdev

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]:9090 is accessible,
  • but [public_ip]:8080 is 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?

iwconfig avatar Jun 13 '25 09:06 iwconfig

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.

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!

mkarimdev avatar Jun 13 '25 13:06 mkarimdev

Great! Glad I could help.

I totally overlooked the external port binding in Docker.

Yeah, it's very common.

iwconfig avatar Jun 13 '25 14:06 iwconfig

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)

puffious avatar Jun 14 '25 10:06 puffious

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.

iwconfig avatar Jun 14 '25 11:06 iwconfig