LFS Pure SSH implementation uses ROOT_URL instead of LOCAL_ROOT_URL #14237

Closed
opened 2025-11-02 11:07:12 -06:00 by GiteaMirror · 8 comments
Owner

Originally created by @florolf on GitHub (Mar 9, 2025).

Description

When using the LFS Pure SSH protocol, the "download" links in the batch responses are generated using setting.AppURL (aka ROOT_URL). While this makes sense for the classic hybrid transport mode where the LFS client needs to connect to the externally facing API URLs to download objects, in the SSH protocol case, subsequent LFS download requests are being originated from the SSH server node.

This causes a number of problems:

  • One major reason to use the SSH protocol in the first place is to avoid having to publicly expose the HTTP LFS endpoints in the first place. However, as implemented, the server side SSH protocol implementation will still try to access the public endpoints (unlike other code which needs to talk to the main Gitea service, which will use LOCAL_ROOT_URL, which can bypass a reverse proxy in front if Gitea.
  • ROOT_URL might not be even accessible from the SSH server node, which will cause obscure failures when cloning a repository (LFS: got status 500 when fetching OID)

Gitea Version

1.23.5

Can you reproduce the bug on the Gitea demo site?

No

Log Gist

No response

Screenshots

No response

Git Version

No response

Operating System

No response

How are you running Gitea?

Self-hosted setup running behind a HTTPS reverse proxy and using OpenSSH for SSH. Both SSH, the reverse proxy and Gitea are running on the same machine, but because of some unrelated peculiar network configuration, the external URL (ROOT_URL) is not accessible locally.

Database

SQLite

Originally created by @florolf on GitHub (Mar 9, 2025). ### Description When using the LFS Pure SSH protocol, the `"download"` links in the `batch` responses are generated using `setting.AppURL` (aka `ROOT_URL`). While this makes sense for the classic hybrid transport mode where the LFS client needs to connect to the externally facing API URLs to download objects, in the SSH protocol case, subsequent LFS `download` requests are being originated from the SSH server node. This causes a number of problems: - One major reason to use the SSH protocol in the first place is to avoid having to publicly expose the HTTP LFS endpoints in the first place. However, as implemented, the server side SSH protocol implementation will still try to access the public endpoints (unlike other code which needs to talk to the main Gitea service, which will use `LOCAL_ROOT_URL`, which can bypass a reverse proxy in front if Gitea. - `ROOT_URL` might not be even accessible from the SSH server node, which will cause obscure failures when cloning a repository (`LFS: got status 500 when fetching OID`) ### Gitea Version 1.23.5 ### Can you reproduce the bug on the Gitea demo site? No ### Log Gist _No response_ ### Screenshots _No response_ ### Git Version _No response_ ### Operating System _No response_ ### How are you running Gitea? Self-hosted setup running behind a HTTPS reverse proxy and using OpenSSH for SSH. Both SSH, the reverse proxy and Gitea are running on the same machine, but because of some unrelated peculiar network configuration, the external URL (`ROOT_URL`) is not accessible locally. ### Database SQLite
GiteaMirror added the type/bug label 2025-11-02 11:07:13 -06:00
Author
Owner

@wxiaoguang commented on GitHub (Mar 9, 2025):

I don't know why people insist to play with LOCAL_ROOT_URL .... see this for explanation: https://github.com/go-gitea/gitea/issues/32554#issuecomment-2484498386 and https://github.com/go-gitea/gitea/issues/32554#issuecomment-2484514616 . The document also says that "you do not need to change the default value" https://github.com/go-gitea/gitea/blob/main/custom/conf/app.example.ini#L128-L136

In short: forget it, it is not for end users.

@wxiaoguang commented on GitHub (Mar 9, 2025): I don't know why people insist to play with `LOCAL_ROOT_URL` .... see this for explanation: https://github.com/go-gitea/gitea/issues/32554#issuecomment-2484498386 and https://github.com/go-gitea/gitea/issues/32554#issuecomment-2484514616 . The document also says that "you do not need to change the default value" https://github.com/go-gitea/gitea/blob/main/custom/conf/app.example.ini#L128-L136 In short: forget it, it is not for end users.
Author
Owner

@wxiaoguang commented on GitHub (Mar 9, 2025):

but because of some unrelated peculiar network configuration, the external URL (ROOT_URL) is not accessible locally.

TBH, ROOT_URL should always be accessible and be used when you need to access to Gitea.

The "peculiar network configuration" should be fixed or use some workaround to make ROOT_URL work.

@wxiaoguang commented on GitHub (Mar 9, 2025): > but because of some unrelated peculiar network configuration, the external URL (`ROOT_URL`) is not accessible locally. TBH, `ROOT_URL` should always be accessible and be used when you need to access to Gitea. The "peculiar network configuration" should be fixed or use some workaround to make `ROOT_URL` work.
Author
Owner

@florolf commented on GitHub (Mar 9, 2025):

I don't know why people insist to play with LOCAL_ROOT_URL

I'm not insisting on playing with it, I'm merely pointing out that there is an inconsistency in how the lfstransfer module handles it. Because of 7290bfaccb/modules/lfstransfer/backend/backend.go (L45) it uses LOCAL_ROOT_URL for all the requests where it constructs the request URL itself, but Download (via 7290bfaccb/modules/lfstransfer/backend/backend.go (L182)) uses whatever the previous batch request has returned, which uses ROOT_URL.

This means that this code will break in any configuration where there is a meaningful distinction between ROOT_URL and LOCAL_ROOT_URL.

The "peculiar network configuration" should be fixed or use some workaround to make ROOT_URL work.

I could work around the network issue but my main motivation for wanting to use the SSH LFS transport is avoiding having to expose the HTTP LFS endpoint publicly in the first place, so this wouldn't help.

@florolf commented on GitHub (Mar 9, 2025): > I don't know why people insist to play with `LOCAL_ROOT_URL` I'm not insisting on playing with it, I'm merely pointing out that there is an inconsistency in how the `lfstransfer` module handles it. Because of https://github.com/go-gitea/gitea/blob/7290bfaccb3f6cc14e8b422c19ada4d5548f331d/modules/lfstransfer/backend/backend.go#L45 it uses `LOCAL_ROOT_URL` for all the requests where it constructs the request URL itself, but `Download` (via https://github.com/go-gitea/gitea/blob/7290bfaccb3f6cc14e8b422c19ada4d5548f331d/modules/lfstransfer/backend/backend.go#L182) uses whatever the previous `batch` request has returned, which uses `ROOT_URL`. This means that this code will break in any configuration where there is a meaningful distinction between `ROOT_URL` and `LOCAL_ROOT_URL`. > The "peculiar network configuration" should be fixed or use some workaround to make `ROOT_URL` work. I could work around the network issue but my main motivation for wanting to use the SSH LFS transport is avoiding having to expose the HTTP LFS endpoint publicly in the first place, so this wouldn't help.
Author
Owner

@florolf commented on GitHub (Mar 9, 2025):

The document also says that "you do not need to change the default value" https://github.com/go-gitea/gitea/blob/main/custom/conf/app.example.ini#L128-L136

As a further note: I'm actually not trying to change it from its default value. The default value would be correct but the LFS Download operation is not making use of it, as described above.

@florolf commented on GitHub (Mar 9, 2025): > The document also says that "you do not need to change the default value" https://github.com/go-gitea/gitea/blob/main/custom/conf/app.example.ini#L128-L136 As a further note: I'm actually not trying to change it from its default value. The default value would be correct but the LFS `Download` operation is not making use of it, as described above.
Author
Owner

@wxiaoguang commented on GitHub (Mar 10, 2025):

Thank you for the clarification. I see your point, it makes sense.

Let's see how to convert the "public action.Href" to an internal URL ........

@wxiaoguang commented on GitHub (Mar 10, 2025): Thank you for the clarification. I see your point, it makes sense. Let's see how to convert the "public action.Href" to an internal URL ........
Author
Owner

@wxiaoguang commented on GitHub (Mar 10, 2025):

I proposed a PR ( Fix LFS URL #33840 ) and updated the tests. Does it look good to you?

@wxiaoguang commented on GitHub (Mar 10, 2025): I proposed a PR ( Fix LFS URL #33840 ) and updated the tests. Does it look good to you?
Author
Owner

@florolf commented on GitHub (Mar 10, 2025):

I've rebuilt 1.23.5 with this patch on top and tested it in my setup and can confirm that it works, thanks!

@florolf commented on GitHub (Mar 10, 2025): I've rebuilt 1.23.5 with this patch on top and tested it in my setup and can confirm that it works, thanks!
Author
Owner

@wxiaoguang commented on GitHub (Mar 10, 2025):

Thank you very much for the report! The investigation is really helpful.

@wxiaoguang commented on GitHub (Mar 10, 2025): Thank you very much for the report! The investigation is really helpful.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/gitea#14237