go-gitea / gitea

Git with a cup of tea! Painless self-hosted all-in-one software development service, including Git hosting, code review, team collaboration, package registry and CI/CD
https://gitea.com
MIT License
44.21k stars 5.42k forks source link

TFA broken after update from 1.14.x to 1.15.x. #16933

Closed Kusoneko closed 3 years ago

Kusoneko commented 3 years ago

Description

After updating from 1.14.6 to 1.15.0 (presumably when the issue happened as I didn't try login in then and then from 1.15.0 to 1.15.1, I couldn't login with either my scratch code or my TFA TOTP generated code. I had to manually go delete my entry in my MySQL database in the two_factor table to be able to login again. Then I went to set it up again, and using both a desktop TOTP generator and copying the secret into it, as well as using the QR code for a mobile TFA app and made both generate the 6-digit codes, and both generate the exact same codes and switch codes at the exact same time, however, the Enroll into TFA page on my gitea instance is claiming that the new passcodes generated by both using the secret it provides is invalid somehow. I'm assuming there's some form of breaking change that happened with TFA in between 1.14.x and 1.15.x otherwise this wouldn't make any sense, despite my not seeing any TFA related stuff in the changelog for the breaking changes of 1.15.0. I'm essentially wanting to find out what I need to do to fix it. So far I haven't changed anything when building the new versions, only built them and then restarted gitea via # systemctl restart gitea. If there is any manual changes I need to do to fix this in config files or whatever, I would appreciate having them noted somewhere.

Screenshots

Not Applicable

zeripath commented 3 years ago

Did you backup and restore using gitea dump? (I'm suggesting this as a potential cause - not a solution)

Kusoneko commented 3 years ago

No, I did not. If I should have how do I fix this now? Note that besides TFA everything else appears to work fine on both the web app and using git commands locally and pushing/pulling from the gitea instance, so I might have gotten off lightly if that's something that should be done before upgrading versions like this.

techknowlogick commented 3 years ago

@zeripath could this be related to secret not being set?

Kusoneko commented 3 years ago

@zeripath could this be related to secret not being set?

I'd doubt it personally, if we're talking about my app.ini file, I just did # cat /etc/gitea/app.ini | grep SECRET and I have LFS_JWT_SECRET, SECRET_KEY and JWT_SECRET set. RECAPTCHA_SECRET, HCAPTCHA_SECRET and MINIO_SECRET_ACCESS_KEY unset.

zeripath commented 3 years ago

@zeripath could this be related to secret not being set?

that would explain it failing only once I think.

I'm a bit stumped. The usual failure for TOTP is something to do with time offsets but I don't understand why it would have worked previously and not now.

There's nothing that immediately comes to mind as a possible cause - except maybe - just maybe some weird cookie issue.

I can't immediately replicate it here, and so the only thing I can think of is for you to add extra logging and build gitea.

Kusoneko commented 3 years ago

I can't immediately replicate it here, and so the only thing I can think of is for you to add extra logging and build gitea.

I'm not sure what you mean by building gitea after adding extra logging, I just changed to log level to Debug in app.ini and restarted gitea, and couldn't find anywhere in the docs a build setting to use to enable further logging, but I'm missing something clearly. First, the log only contains the following for TFA stuff that I can see:

Sep 02 20:58:05 kusoneko.moe gitea[74645]: 2021/09/02 20:58:05 Started POST /user/settings/security/two_factor/enroll for [::1]:42432
Sep 02 20:58:05 kusoneko.moe gitea[74645]: 2021/09/02 20:58:05 ...s/context/context.go:740:1() [D] Session ID: probably_private
Sep 02 20:58:05 kusoneko.moe gitea[74645]: 2021/09/02 20:58:05 ...s/context/context.go:741:1() [D] CSRF Token: probably_private
Sep 02 20:58:05 kusoneko.moe gitea[74645]: 2021/09/02 20:58:05 Completed POST /user/settings/security/two_factor/enroll 302 Found in 21.101646ms
Sep 02 20:58:06 kusoneko.moe gitea[74645]: 2021/09/02 20:58:06 Started GET /user/settings/security/two_factor/enroll for 127.0.0.1:49340
Sep 02 20:58:06 kusoneko.moe gitea[74645]: 2021/09/02 20:58:06 ...s/context/context.go:740:1() [D] Session ID: probably_private
Sep 02 20:58:06 kusoneko.moe gitea[74645]: 2021/09/02 20:58:06 ...s/context/context.go:741:1() [D] CSRF Token: probably_private
Sep 02 20:58:06 kusoneko.moe gitea[74645]: 2021/09/02 20:58:06 ...s/context/context.go:185:HTML() [D] Template: user/settings/twofa_enroll
Sep 02 20:58:06 kusoneko.moe gitea[74645]: 2021/09/02 20:58:06 Completed GET /user/settings/security/two_factor/enroll 200 OK in 24.028686ms
Sep 02 20:58:06 kusoneko.moe gitea[74645]: 2021/09/02 20:58:06 Started GET /avatar/8749a188a5e167b6fee6b9613ba71d97?size=96 for [::1]:42434
Sep 02 20:58:06 kusoneko.moe gitea[74645]: 2021/09/02 20:58:06 ...s/context/context.go:740:1() [D] Session ID: probably_private
Sep 02 20:58:06 kusoneko.moe gitea[74645]: 2021/09/02 20:58:06 ...s/context/context.go:741:1() [D] CSRF Token: probably_private
Sep 02 20:58:06 kusoneko.moe gitea[74645]: 2021/09/02 20:58:06 Completed GET /avatar/8749a188a5e167b6fee6b9613ba71d97?size=96 302 Found in 2.598738ms
Sep 02 20:58:06 kusoneko.moe gitea[74645]: 2021/09/02 20:58:06 Started GET /user/events for 127.0.0.1:49342
Sep 02 20:58:06 kusoneko.moe gitea[74645]: 2021/09/02 20:58:06 ...s/context/context.go:740:1() [D] Session ID: probably_private
Sep 02 20:58:06 kusoneko.moe gitea[74645]: 2021/09/02 20:58:06 ...s/context/context.go:741:1() [D] CSRF Token: probably_private

Similarly, when looking from the dev tools of the browser, the TFA enroll page indeed starts off with a 302 followed by a 200, and when clicking the Verify button, it reloads but shows an Invalid passcode message. Nothing new seems to appear in the logs.

I did notice however that no matter how many time I leave and come back to the TFA enroll page, the TOTP secret shown on the page is always exactly the same secret (and the QR is likely the same since it gives my phone app the same TOTP secret as well), implying the problem is potentially with it not showing the right secret rather than TFA by itself not working. Hopefully that'll help a little with figuring out what's wrong.

A bit unrelated, but while we're here, I looked at the start of the logs and I'm seeing the following 2 Errors at the start:

Sep 02 20:49:28 kusoneko.moe gitea[74645]: 2021/09/02 20:49:28 cmd/web.go:102:runWeb() [I] Starting Gitea on PID: 74645
Sep 02 20:49:28 kusoneko.moe gitea[74645]: 2021/09/02 20:49:28 ...es/setting/markup.go:113:createMarkupSanitizerRule() [E] Missing required keys from markup.sanitizer.1. Must have ELEMENT and ALLOW_ATTR or ALLOW_DATA_URI_IMAGES defined!
Sep 02 20:49:28 kusoneko.moe gitea[74645]: 2021/09/02 20:49:28 cmd/web.go:146:runWeb() [I] Global init
Sep 02 20:49:28 kusoneko.moe gitea[74645]: 2021/09/02 20:49:28 ...es/setting/markup.go:113:createMarkupSanitizerRule() [E] Missing required keys from markup.sanitizer.1. Must have ELEMENT and ALLOW_ATTR or ALLOW_DATA_URI_IMAGES defined!

and the following ton of warnings right after the PING DATABASE thing:

Sep 02 20:49:28 kusoneko.moe gitea[74645]: 2021/09/02 20:49:28 ...om/urfave/cli/app.go:524:HandleAction() [W] Table public_key column content db type is MEDIUMTEXT, struct type is TEXT
Sep 02 20:49:28 kusoneko.moe gitea[74645]: 2021/09/02 20:49:28 ...om/urfave/cli/app.go:524:HandleAction() [W] Table repository column description db type is MEDIUMTEXT, struct type is TEXT
Sep 02 20:49:28 kusoneko.moe gitea[74645]: 2021/09/02 20:49:28 ...om/urfave/cli/app.go:524:HandleAction() [W] Table repository column topics db type is MEDIUMTEXT, struct type is TEXT
Sep 02 20:49:28 kusoneko.moe gitea[74645]: 2021/09/02 20:49:28 ...om/urfave/cli/app.go:524:HandleAction() [W] Table action column content db type is MEDIUMTEXT, struct type is TEXT
Sep 02 20:49:28 kusoneko.moe gitea[74645]: 2021/09/02 20:49:28 ...om/urfave/cli/app.go:524:HandleAction() [W] Table issue column content db type is MEDIUMTEXT, struct type is TEXT
Sep 02 20:49:28 kusoneko.moe gitea[74645]: 2021/09/02 20:49:28 ...om/urfave/cli/app.go:524:HandleAction() [W] Table pull_request column conflicted_files db type is MEDIUMTEXT, struct type is TEXT
Sep 02 20:49:28 kusoneko.moe gitea[74645]: 2021/09/02 20:49:28 ...om/urfave/cli/app.go:524:HandleAction() [W] Table comment column content db type is MEDIUMTEXT, struct type is TEXT
Sep 02 20:49:28 kusoneko.moe gitea[74645]: 2021/09/02 20:49:28 ...om/urfave/cli/app.go:524:HandleAction() [W] Table comment column patch db type is MEDIUMTEXT, struct type is TEXT
Sep 02 20:49:28 kusoneko.moe gitea[74645]: 2021/09/02 20:49:28 ...om/urfave/cli/app.go:524:HandleAction() [W] Table milestone column content db type is MEDIUMTEXT, struct type is TEXT
Sep 02 20:49:28 kusoneko.moe gitea[74645]: 2021/09/02 20:49:28 ...om/urfave/cli/app.go:524:HandleAction() [W] Table release column note db type is MEDIUMTEXT, struct type is TEXT
Sep 02 20:49:28 kusoneko.moe gitea[74645]: 2021/09/02 20:49:28 ...om/urfave/cli/app.go:524:HandleAction() [W] Table login_source column cfg db type is MEDIUMTEXT, struct type is TEXT
Sep 02 20:49:28 kusoneko.moe gitea[74645]: 2021/09/02 20:49:28 ...om/urfave/cli/app.go:524:HandleAction() [W] Table webhook Column is_system_webhook db default is 0, struct default is
Sep 02 20:49:28 kusoneko.moe gitea[74645]: 2021/09/02 20:49:28 ...om/urfave/cli/app.go:524:HandleAction() [W] Table webhook Column is_system_webhook db nullable is false, struct nullable is true
Sep 02 20:49:28 kusoneko.moe gitea[74645]: 2021/09/02 20:49:28 ...om/urfave/cli/app.go:524:HandleAction() [W] Table webhook column url db type is MEDIUMTEXT, struct type is TEXT
Sep 02 20:49:28 kusoneko.moe gitea[74645]: 2021/09/02 20:49:28 ...om/urfave/cli/app.go:524:HandleAction() [W] Table webhook column secret db type is MEDIUMTEXT, struct type is TEXT
Sep 02 20:49:28 kusoneko.moe gitea[74645]: 2021/09/02 20:49:28 ...om/urfave/cli/app.go:524:HandleAction() [W] Table webhook column events db type is MEDIUMTEXT, struct type is TEXT
Sep 02 20:49:28 kusoneko.moe gitea[74645]: 2021/09/02 20:49:28 ...om/urfave/cli/app.go:524:HandleAction() [W] Table webhook column meta db type is MEDIUMTEXT, struct type is TEXT
Sep 02 20:49:28 kusoneko.moe gitea[74645]: 2021/09/02 20:49:28 ...om/urfave/cli/app.go:524:HandleAction() [W] Table hook_task column payload_content db type is MEDIUMTEXT, struct type is TEXT
Sep 02 20:49:28 kusoneko.moe gitea[74645]: 2021/09/02 20:49:28 ...om/urfave/cli/app.go:524:HandleAction() [W] Table hook_task column request_content db type is MEDIUMTEXT, struct type is TEXT
Sep 02 20:49:28 kusoneko.moe gitea[74645]: 2021/09/02 20:49:28 ...om/urfave/cli/app.go:524:HandleAction() [W] Table hook_task column response_content db type is MEDIUMTEXT, struct type is TEXT
Sep 02 20:49:28 kusoneko.moe gitea[74645]: 2021/09/02 20:49:28 ...om/urfave/cli/app.go:524:HandleAction() [W] Table notice column description db type is MEDIUMTEXT, struct type is TEXT
Sep 02 20:49:28 kusoneko.moe gitea[74645]: 2021/09/02 20:49:28 ...om/urfave/cli/app.go:524:HandleAction() [W] Table email_address Column lower_email db nullable is true, struct nullable is false
Sep 02 20:49:28 kusoneko.moe gitea[74645]: 2021/09/02 20:49:28 ...om/urfave/cli/app.go:524:HandleAction() [W] Table gpg_key column content db type is MEDIUMTEXT, struct type is TEXT
Sep 02 20:49:28 kusoneko.moe gitea[74645]: 2021/09/02 20:49:28 ...om/urfave/cli/app.go:524:HandleAction() [W] Table gpg_key column emails db type is MEDIUMTEXT, struct type is TEXT
Sep 02 20:49:28 kusoneko.moe gitea[74645]: 2021/09/02 20:49:28 ...om/urfave/cli/app.go:524:HandleAction() [W] Table gpg_key_import column content db type is MEDIUMTEXT, struct type is TEXT
Sep 02 20:49:28 kusoneko.moe gitea[74645]: 2021/09/02 20:49:28 ...om/urfave/cli/app.go:524:HandleAction() [W] Table repo_unit column config db type is MEDIUMTEXT, struct type is TEXT
Sep 02 20:49:28 kusoneko.moe gitea[74645]: 2021/09/02 20:49:28 ...om/urfave/cli/app.go:524:HandleAction() [W] Table external_login_user column raw_data db type is MEDIUMTEXT, struct type is TEXT
Sep 02 20:49:28 kusoneko.moe gitea[74645]: 2021/09/02 20:49:28 ...om/urfave/cli/app.go:524:HandleAction() [W] Table external_login_user column avatar_url db type is TEXT, struct type is VARCHAR(255)
Sep 02 20:49:28 kusoneko.moe gitea[74645]: 2021/09/02 20:49:28 ...om/urfave/cli/app.go:524:HandleAction() [W] Table external_login_user column access_token db type is MEDIUMTEXT, struct type is TEXT
Sep 02 20:49:28 kusoneko.moe gitea[74645]: 2021/09/02 20:49:28 ...om/urfave/cli/app.go:524:HandleAction() [W] Table external_login_user column access_token_secret db type is MEDIUMTEXT, struct type is TEXT
Sep 02 20:49:28 kusoneko.moe gitea[74645]: 2021/09/02 20:49:28 ...om/urfave/cli/app.go:524:HandleAction() [W] Table external_login_user column refresh_token db type is MEDIUMTEXT, struct type is TEXT
Sep 02 20:49:28 kusoneko.moe gitea[74645]: 2021/09/02 20:49:28 ...om/urfave/cli/app.go:524:HandleAction() [W] Table protected_branch column whitelist_user_i_ds db type is MEDIUMTEXT, struct type is TEXT
Sep 02 20:49:28 kusoneko.moe gitea[74645]: 2021/09/02 20:49:28 ...om/urfave/cli/app.go:524:HandleAction() [W] Table protected_branch column whitelist_team_i_ds db type is MEDIUMTEXT, struct type is TEXT
Sep 02 20:49:28 kusoneko.moe gitea[74645]: 2021/09/02 20:49:28 ...om/urfave/cli/app.go:524:HandleAction() [W] Table protected_branch column merge_whitelist_user_i_ds db type is MEDIUMTEXT, struct type is TEXT
Sep 02 20:49:28 kusoneko.moe gitea[74645]: 2021/09/02 20:49:28 ...om/urfave/cli/app.go:524:HandleAction() [W] Table protected_branch column merge_whitelist_team_i_ds db type is MEDIUMTEXT, struct type is TEXT
Sep 02 20:49:28 kusoneko.moe gitea[74645]: 2021/09/02 20:49:28 ...om/urfave/cli/app.go:524:HandleAction() [W] Table protected_branch column status_check_contexts db type is MEDIUMTEXT, struct type is TEXT
Sep 02 20:49:28 kusoneko.moe gitea[74645]: 2021/09/02 20:49:28 ...om/urfave/cli/app.go:524:HandleAction() [W] Table protected_branch column approvals_whitelist_user_i_ds db type is MEDIUMTEXT, struct type is TEXT
Sep 02 20:49:28 kusoneko.moe gitea[74645]: 2021/09/02 20:49:28 ...om/urfave/cli/app.go:524:HandleAction() [W] Table protected_branch column approvals_whitelist_team_i_ds db type is MEDIUMTEXT, struct type is TEXT
Sep 02 20:49:28 kusoneko.moe gitea[74645]: 2021/09/02 20:49:28 ...om/urfave/cli/app.go:524:HandleAction() [W] Table commit_status column target_url db type is MEDIUMTEXT, struct type is TEXT
Sep 02 20:49:28 kusoneko.moe gitea[74645]: 2021/09/02 20:49:28 ...om/urfave/cli/app.go:524:HandleAction() [W] Table commit_status column description db type is MEDIUMTEXT, struct type is TEXT
Sep 02 20:49:28 kusoneko.moe gitea[74645]: 2021/09/02 20:49:28 ...om/urfave/cli/app.go:524:HandleAction() [W] Table commit_status column context db type is MEDIUMTEXT, struct type is TEXT
Sep 02 20:49:28 kusoneko.moe gitea[74645]: 2021/09/02 20:49:28 ...om/urfave/cli/app.go:524:HandleAction() [W] Table lfs_lock column path db type is MEDIUMTEXT, struct type is TEXT
Sep 02 20:49:28 kusoneko.moe gitea[74645]: 2021/09/02 20:49:28 ...om/urfave/cli/app.go:524:HandleAction() [W] Table review column content db type is MEDIUMTEXT, struct type is TEXT
Sep 02 20:49:28 kusoneko.moe gitea[74645]: 2021/09/02 20:49:28 ...om/urfave/cli/app.go:524:HandleAction() [W] Table oauth2_application column redirect_uris db type is MEDIUMTEXT, struct type is TEXT
Sep 02 20:49:28 kusoneko.moe gitea[74645]: 2021/09/02 20:49:28 ...om/urfave/cli/app.go:524:HandleAction() [W] Table task column payload_content db type is MEDIUMTEXT, struct type is TEXT
Sep 02 20:49:28 kusoneko.moe gitea[74645]: 2021/09/02 20:49:28 ...om/urfave/cli/app.go:524:HandleAction() [W] Table language_stat Column language db nullable is true, struct nullable is false
Sep 02 20:49:28 kusoneko.moe gitea[74645]: 2021/09/02 20:49:28 ...om/urfave/cli/app.go:524:HandleAction() [W] Table project column board_type db type is INT(11), struct type is INT UNSIGNED
Sep 02 20:49:28 kusoneko.moe gitea[74645]: 2021/09/02 20:49:28 ...om/urfave/cli/app.go:524:HandleAction() [W] Table project column type db type is INT(11), struct type is INT UNSIGNED
Sep 02 20:49:28 kusoneko.moe gitea[74645]: 2021/09/02 20:49:28 ...om/urfave/cli/app.go:524:HandleAction() [W] Table session has column created_unix but struct has not related field

Are these errors and warnings fixable?

Thank you!

zeripath commented 3 years ago

As per our FAQ it is safe to ignore the table warnings although gitea doctor recreate-table should make them go away.

[E] Missing required keys from markup.sanitizer.1. Must have ELEMENT and ALLOW_ATTR or ALLOW_DATA_URI_IMAGES defined!

This implies that, like many people, you have copied app.ini.sample/app.example.ini straight across as your app.ini despite the very large warning at the top of that file NOT to do that. (We have had to comment almost the whole file out in 1.15+ because of this.)

You need to seriously simplify your app.ini dropping whole sections from it that you have not explicitly set. My own app.ini is 75 lines long and really that is still too long.


These app.ini issues aren't obviously the cause of the problem (except where maybe you've incorrectly overconfigured your cookies?)


Looking at your logs I see that the IP address you are posting from to appears to be flipping from 127.0.0.1 to [::1] which is concerning that you might be associated with different sessions etc.

You've sanitized the session id away so I can't check that theyre the same and you've not given me the logs from the GET before the enroll POST so I can't check that either. We need to see a little more of the interaction before the POST.

It's helpful to double check if the issue is a browser specific one - i.e. are there multiple weird cookies on your browser that need to be erased.

You haven't told us whether there's a reverse proxy involved or if Gitea is mounted on a suburl. Are you definitely accessing gitea by its ROOT_URL - maybe the cookies aren't being passed down - the session id being the same should assert that.


Regarding additional logging:

You asserted that debug logs were not helpful - although it does appear that they may help shed further light on this issue so follow the instructions given in issue proforma and give us those logs. My suggestion about us adding extra logging was that we would need to compile in some extra logging at certain places.

Give us the logs as per https://docs.gitea.io/en-us/logging-configuration/#debugging-problems sanitising only the minimum and asserting where things are the same if you've sanitized them away.

Explain your setup, e.g. reverse proxy or not, how are you running gitea, what is your systemd unit file, what version of mysql/mariadb.

Show us your app.ini - you can send me the unsanitised one on discord if you message me directly.

Check if on private browsing or different browser if things work. The problem may be cookie related.

Kusoneko commented 3 years ago

These app.ini issues aren't obviously the cause of the problem (except where maybe you've incorrectly overconfigured your cookies?)

Thanks, that fixed the errors and most of the warnings, I assume the last 2 that gitea doctor didn't fix, where it says the table's field should be int unsigned and that it's currently int(10) unsigned is far from the end of the world.

Well, I did configure them a bit, but I just swapped it from storing the sessions from file mode to memory mode, and deleted all my cookies for the instance to see if something changed, indeed, the TOTP secret has changed afterwards, but it's sticking to the new secret now, and still refusing codes. This is a really odd issue.

Looking at your logs I see that the IP address you are posting from to appears to be flipping from 127.0.0.1 to [::1] which is concerning that you might be associated with different sessions etc.

You've sanitized the session id away so I can't check that they're the same and you've not given me the logs from the GET before the enroll POST so I can't check that either. We need to see a little more of the interaction before the POST.

It's helpful to double check if the issue is a browser specific one - i.e. are there multiple weird cookies on your browser that need to be erased.

They were identical for that specific snippet.

You haven't told us whether there's a reverse proxy involved or if Gitea is mounted on a subgitea-log.txt. Are you definitely accessing gitea by its ROOT_URL - maybe the cookies aren't being passed down - the session id being the same should assert that.

Regarding additional logging:

You asserted that debug logs were not helpful - although it does appear that they may help shed further light on this issue so follow the instructions given in issue proforma and give us those logs. My suggestion about us adding extra logging was that we would need to compile in some extra logging at certain places.

Give us the logs as per https://docs.gitea.io/en-us/logging-configuration/#debugging-problems sanitising only the minimum and asserting where things are the same if you've sanitized them away.

Explain your setup, e.g. reverse proxy or not, how are you running gitea, what is your systemd unit file, what version of mysql/mariadb.

Show us your app.ini - you can send me the unsanitised one on discord if you message me directly.

Check if on private browsing or different browser if things work. The problem may be cookie related.

Right, my gitea instance is configured to listen to localhost:3001 (unless I'm misunderstanding the app.ini comments), except for ssh requests which is actually using the git user and openssh's sshd. SSH works fine, so that's not the issue. The server is actually serving multiple (mostly personal) web apps and services, so to prevent port collision issues and all that, all of them are being run behind nginx as a reverse proxy (except for one or 2 webpages that nginx serves itself), unless they're not web apps and therefore don't require port 443/80 to be used without fiddling around with ports in a browser.

The results of $ mysql --version: mysql Ver 15.1 Distrib 10.6.4-MariaDB, for Linux (x86_64) using readline 5.1

SystemD service file: gitea.service

The logs after stopping gitea, removing all my cookies from my browser, then restarting gitea, while I go speedrun to the TFA enroll page are here: log.txt The Session IDs were renamed id# and the CSRF Tokens token# with sed, so they should have the same number for all occurrences of each.

The app.ini configuration for the looks like this: app.ini Note that I'm not sure in this app.ini file (which I did a quick cleanup of) what's left that is by default and thus can be removed and what isn't. I'm off to bed for now though, so I'll perhaps think about looking it up later.

Thanks.

EDIT: Moved the code snippets for each file to actual attachments to prevent a 30-meters long wall of text.

wxiaoguang commented 3 years ago

Then I went to set it up again, and using both a desktop TOTP generator and copying the secret into it, as well as using the QR code for a mobile TFA app and made both generate the 6-digit codes, and both generate the exact same codes and switch codes at the exact same time, however, the Enroll into TFA page on my gitea instance is claiming that the new passcodes generated by both using the secret it provides is invalid somehow.

A small question, have you checked your system time (running Gitea instance) is accurate and correct? You can check your system time here: https://time.is . Or check time by google:

$ curl -v "https://google.com" 2>&1 | grep -i "date:" | grep -v "^\*"
< date: Fri, 03 Sep 2021 06:57:17 GMT

$ date -u
Fri Sep  3 06:57:17 UTC 2021
Kusoneko commented 3 years ago

Then I went to set it up again, and using both a desktop TOTP generator and copying the secret into it, as well as using the QR code for a mobile TFA app and made both generate the 6-digit codes, and both generate the exact same codes and switch codes at the exact same time, however, the Enroll into TFA page on my gitea instance is claiming that the new passcodes generated by both using the secret it provides is invalid somehow.

A small question, have you checked your system time (running Gitea instance) is accurate and correct? You can check your system time here: https://time.is . Or check time by google:

$ curl -v "https://google.com" 2>&1 | grep -i "date:" | grep -v "^\*"
< date: Fri, 03 Sep 2021 06:57:17 GMT

$ date -u
Fri Sep  3 06:57:17 UTC 2021
$ curl -v "https://google.com" 2>&1 | grep -i "date:" | grep -v "^\*";date -u
< date: Fri, 03 Sep 2021 07:15:23 GMT
Fri Sep  3 07:16:24 AM UTC 2021

That's odd, it's apparently off by a full minute, I'm not sure how to fix that though.

wxiaoguang commented 3 years ago

You see, it's your system time's problem.

TOTP won't work correctly if the error between your server's time and client's time is greater than a few seconds.

The time window for a TOTP code is usually 30 seconds. The larger the error is, the more likely the OTP code will fail. When the error is greater than 30 seconds, the OTP code will always fail.

As long as you set your server's time to the correct time, the problem will disappear.

So it's not Gitea's bug 😊

wxiaoguang commented 3 years ago

PS: Maybe the TOTP problem should be written into FAQ. I know many people use servers with wrong system time.

zeripath commented 3 years ago

@wxiaoguang I meant to suggest timing but I was distracted by them saying it had previously worked but yes this would be consistent with that being the issue.

So I'm gonna close.

Kusoneko commented 3 years ago

Just to confirm, I went and enabled and started systemd-timesyncd that was for some reason not enabled nor started, and tried again and this time it worked. Thank you everyone!