Problem
Another t/suki Windows user ran into an SSL issue when trying to push code to the gitplace. Previously, someone on the DemureSoft team had this issue as well on Windows. Both problems look like go-gitea/gitea#31297.
Checking go-gitea/gitea#31297, I see that the problem for the original poster was an incorrect NGINX configuration. However, while there are differences, I don't see any obvious major differences in the NGINX config they are using and the one I'm using.
The Demuresoft team member was able to merely switch from the HTTPS url for the repo to SSH to workaround the problem. However, I feel like HTTPS urls should work.
Reproduction
I think first, I need to figure out how to reliably recreate the issue so I can test it on my own without needing help from one of the affected users.
I believe this bug happens because the Git installer for Windows can install the Git Credential Manager. I don't believe I've ever installed this on Linux. In fact, if I try to use HTTPS authentication on Linux it always fails:
git clone https://git.tsuki.games/exodrifter/fish-factsination.git
Cloning into 'fish-factsination'...
Username for 'https://git.tsuki.games': exodrifter
Password for 'https://exodrifter@git.tsuki.games':
remote: Credentials are incorrect or have expired. Retry your command or see https://codeberg.org/forgejo/forgejo/issues/2809 for more information
fatal: Authentication failed for 'https://git.tsuki.games/exodrifter/fish-factsination.git/'
This makes sense to me because my account has two-factor authentication and I believe the default Linux credential manager only does username and password authentication.
Git Manual: 1
Fortunately, Git has a credentials system that can help with this. Git has a few options provided in the box:
- The default is not to cache at all. Every connection will prompt you for your username and password.
[...]
- If you’re using Windows, you can enable the Git Credential Manager feature when installing Git for Windows or separately install the latest GCM as a standalone service. This is similar to the “osxkeychain” helper described above, but uses the Windows Credential Store to control sensitive information. It can also serve credentials to WSL1 or WSL2. See GCM Install Instructions for more information.
GCM README: 2
GCM supports (in alphabetical order) Azure DevOps, Azure DevOps Server (formerly Team Foundation Server), Bitbucket, GitHub, and GitLab. Compare to Git's built-in credential helpers (Windows: wincred, macOS: osxkeychain, Linux: gnome-keyring/libsecret), which provide single-factor authentication support for username/password only.
I think in order to replicate the same issue, I have to also use Git Credential Manager.
On Arch, I install GCM with:
yay -S https://aur.archlinux.org/packages/git-credential-manager-binThen, to finish the installation I look at the README for GCM. It redirects me to the installation instructions which in turn tells me that Linux requires additional configuration. Here, I find out that the corresponding commands to enable GCM with Git's built-in credential cache is:
export GCM_CREDENTIAL_STORE=cache
# or
git config --global credential.credentialStore cacheSo I try that, but it doesn't work:
$ export GCM_CREDENTIAL_STORE=cache
$ git clone https://git.tsuki.games/exodrifter/fish-factsination.git
Cloning into 'fish-factsination'...
Username for 'https://git.tsuki.games': exodrifter
Password for 'https://exodrifter@git.tsuki.games':
remote: Credentials are incorrect or have expired. Retry your command or see https://codeberg.org/forgejo/forgejo/issues/2809 for more information
fatal: Authentication failed for 'https://git.tsuki.games/exodrifter/fish-factsination.git/'
I notice that other distributions mention running
git-credential-manager configure, so I
do that and try again:
$ git-credential-manager configure
Configuring component 'Git Credential Manager'...
Configuring component 'Azure Repos provider'...
$ git clone https://git.tsuki.games/exodrifter/fish-factsination.git
Cloning into 'fish-factsination'...
This time, it opens a new browser tab asking for authorization. When authorize it, I get the secure connection failed error that the other users were having. This is what I see in firefox:
Secure Connection Failed
An error occurred during a connection to 127.0.0.1:39629. SSL received a record that exceeded the maximum permissible length.
Error code: SSL_ERROR_RX_RECORD_TOO_LONG
- The page you are trying to view cannot be shown because the authenticity of the received data could not be verified.
- Please contact the website owners to inform them of this problem.
I notice that the URL looks like this:
https://127.0.0.1:39629/?code=<redacted>&state=<redacted>
So I manually change it to http:
http://127.0.0.1:39629/?code=<redacted>&state=<redacted>
This gives me a new webpage that reads:
Authentication successful
You can now close this page.
Sure enough, when I go back to my terminal I see that authentication succeeded:
remote: Enumerating objects: 555, done.
remote: Counting objects: 100% (555/555), done.
remote: Compressing objects: 100% (446/446), done.
remote: Total 555 (delta 287), reused 141 (delta 54), pack-reused 0 (from 0)
Receiving objects: 100% (555/555), 301.26 KiB | 3.38 MiB/s, done.
Resolving deltas: 100% (287/287), done.
Filtering content: 100% (15/15), 882.86 KiB | 231.00 KiB/s, done.
As I suspected, the problem matches what's described in go-gitea/gitea#31297. However, it's unclear why the callback URL is HTTPS...
OAuth Callback URL
I figure that maybe the OAuth application is registered with the incorrect callback URL. Checking the Forgejo admin settings, I see that the Git Credential Manager has been pre-registered on the Application Integrations page. I can't view or edit it; the typical button has been replaced with a disabled button reading "Locked". Hovering over the button, the tooltip reads:
Forgejo pre-registers some OAuth2 applications on startup if enabled in config. To prevent unexpected behavior, these can neither be edited nor removed. Please refer to the OAuth2 documentation for more information.
The documentation mentions: 3
To prevent unexpected behavior, they are being displayed as locked in the UI and their creation can instead be controlled by the
DEFAULT_APPLICATIONSparameter inapp.ini.
All the DEFAULT_APPLICATIONS
parameter does is control whether or not they are
created in the first place.
I try to run through the authorization process again. This time, I take a closer look at the OAuth prompt:
Authorize "Git Credential Manager" to access your account?
If you grant the access, it will be able to access and write to all your account information, including private repos and organizations.
This application was created by t/suki.
With scopes: .
You will be redirected to http://127.0.0.1:35609/ if you authorize this application.
I suppose the application must be configured
correctly, since it says that it's trying
to redirect to http. I suppose there
must be some other reason the URL is being remapped
to https. Maybe it's NGINX?
NGINX http to https redirect
First, I need to find out if NGINX is redirecting http to https. I find this page, which describes how to do it in two different ways:
Insert the following code into the nginx.conf file:
server { listen 80 default_server; server_name _; return 301 https://$host$request_uri; }
To perform a more complex URL manipulation, use the rewrite directive:
server { listen 80 default_server; server_name _; rewrite ^/[old-page]$ https://[domain]/[new-page] permanent; }
I use SWAG, which provides examples and
automatically includes files which don't end in
.sample. So, I search all the files for
something similar and I find
nginx/site-confs/default.conf:
## Version 2024/12/17 - Changelog: https://github.com/linuxserver/docker-swag/commits/master/root/defaults/nginx/site-confs/default.conf.sample
# redirect all traffic to https
server {
listen 80 default_server;
listen [::]:80 default_server;
location / {
return 301 https://$host$request_uri;
}
}
I think maybe this is applying to all
hosts, and as a result redirecting the
127.0.0.1 URL, so I update it:
# redirect all traffic to https
server {
listen 80 default_server;
listen [::]:80 default_server;
+ server_name git.tsuki.games;
location / {
return 301 https://$host$request_uri;
}
}I list the domain explicitly, as NGINX recommends as such: 4
The exact names hash table is searched first. If a name is not found, the hash table with wildcard names starting with an asterisk is searched. If the name is not found there, the hash table with wildcard names ending with an asterisk is searched.
Searching wildcard names hash table is slower than searching exact names hash table because names are searched by domain parts. Note that the special wildcard form “
.example.org” is stored in a wildcard names hash table and not in an exact names hash table.Regular expressions are tested sequentially and therefore are the slowest method and are non-scalable.
For these reasons, it is better to use exact names where possible. For example, if the most frequently requested names of a server are
example.organdwww.example.org, it is more efficient to define them explicitly:
This does not work. Checking the networking tab, I see that the browser receives a 303 response and the https URL as the redirect location, so it looks like this isn't the right place since the NGINX redirect is a 301. I remove the line I added and search for a 303 response in NGINX configs instead. However, there are no results:
$ grep -rnw nginx/ -e "return 303"
$ grep -rnw nginx/ -e "303"
$
I don't see any other redirect or any other configuration that redirects http to https in the NGINX config, so maybe it's not NGINX either.
I think I'm going to give up on this problem for now.