Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Google Authenticator with pam as a package for TOTP in ssh #4852

Merged
merged 11 commits into from
Dec 17, 2022

Conversation

soraxas
Copy link
Contributor

@soraxas soraxas commented Sep 10, 2021

Motivation: Adds google authenticator.
Linked issues: closes #4884

This PR adds the google authenticator as a package for the libpam. This allows users to use google authenticator to generates TOTP when signing into services such as ssh.


Installing this package alone would have no effects, as it will requires user to manually utilised the installed .so file in their authentication service.

For example, for my usecase, after install this package to volume 1 I can add the following to /etc/ssh/sshd_config

  ...
  auth    requisite                     pam_syno_ipblocklist.so
+ auth required /volume1/@appstore/google-authenticator-libpam/lib/security/pam_google_authenticator.so nullok
  auth    [success=3 default=ignore]    pam_unix.so
  auth    [success=2 default=ignore]    pam_winbind.so use_first_pass
  auth    [success=1 default=ignore]    pam_ldap.so
  auth    [default=die]                 pam_syno_log_fail.so [SSH]
  auth    [default=done]                pam_syno_log_success.so [SSH] log=no
  account [success=3 default=ignore]    pam_unix.so
  ...

After adding that line to sshd_config and generated ~/.google_authenticator, trying to ssh into synology will request TOTP:

$ ssh synology
(foo@synology) Verification code: 
(foo@synology) Password: 
foo@synology ~ $ 

I've set it up such that ssh-ing with password requires TOTP, and ssh-ing with key will not. See other guides, e.g., this, for how to configure it.

Checklist

  • Build rule all-supported completed successfully (local build succeeds, some github build actions fail, until the toolchain cache will be rebuilt with the patches from this PR)
  • Package upgrade completed successfully
  • New installation of package completed successfully

cross/libpam/PLIST Outdated Show resolved Hide resolved
@publicarray
Copy link
Member

publicarray commented Sep 10, 2021

You can use GNU_CONFIGURE = 1, that should get you closer for cross compiling the package

Copy link
Member

@publicarray publicarray left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your contribution, I just overlooked a few tiny things earlier

cross/libpam/Makefile Outdated Show resolved Hide resolved
spk/google-authenticator-libpam/Makefile Outdated Show resolved Hide resolved
@soraxas
Copy link
Contributor Author

soraxas commented Sep 11, 2021

Thanks @publicarray for pointing out some of the things that I've overlooked

@soraxas
Copy link
Contributor Author

soraxas commented Sep 25, 2021

any new updates on merging?

Copy link
Contributor

@hgy59 hgy59 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some more suggestions

Please rename the folder cross/libpam to cross/linux-pam to match the lowercase name of the package.

Even linux-pam is used for BUILD_DEPENDS only and therefore does not install the libpam libraries for google auth., we should add a PLIST file for generic use.
such a PLIST file contains at least the *.so files like

lnk:lib/libpam.so
lnk:lib/libpam.so.0
lib:lib/libpam.so.0.85.1
lnk:lib/libpam_misc.so
lnk:lib/libpam_misc.so.0
lib:lib/libpam_misc.so.0.82.1
lnk:lib/libpamc.so
lnk:lib/libpamc.so.0
lib:lib/libpamc.so.0.82.1

cross/google-authenticator-libpam/PLIST Outdated Show resolved Hide resolved
cross/google-authenticator-libpam/Makefile Show resolved Hide resolved
spk/google-authenticator-libpam/PLIST Outdated Show resolved Hide resolved
cross/libpam/Makefile Outdated Show resolved Hide resolved
cross/libpam/Makefile Outdated Show resolved Hide resolved
cross/libpam/Makefile Outdated Show resolved Hide resolved
@hgy59
Copy link
Contributor

hgy59 commented Sep 25, 2021

I found a way to avoid unsupported archs UNSUPPORTED_ARCHS = $(PPC_ARCHS) $(ARMv5_ARCHS) $(ARMv7L_ARCHS) $(i686_ARCHS)

But this requires to patch the toolchains and this does not work with the current dev-env

@hgy59
Copy link
Contributor

hgy59 commented Sep 25, 2021

@soraxas hi, it would be great, when you add a wiki page about how to configure TOTP with google auth.
We already have some package specific wiki pages, most have a link in the Package Documentation Index or are at least added to the sidebar.

/etc/ssh/sshd_config might be a typo. This file does not look like your example (but /etc/pam.d/sshd does).

@hgy59
Copy link
Contributor

hgy59 commented Sep 25, 2021

The failing builds will be solved by patching the related toolchains. but those github actions (checks) will still fail, as the toolchains are cached and will not get patched, until the patches are merged and the toolchains are rebuilt.

@soraxas
Copy link
Contributor Author

soraxas commented Sep 26, 2021

Thanks @hgy59 for the review and fixes/patches on the PR.
And YES that is correct it should be the /etc/pam.d/sshd file, not the one mentioned above.

I'll try write a wiki entry regarding how to set it up.

@soraxas
Copy link
Contributor Author

soraxas commented Sep 26, 2021

I've added a wiki entry at https://github.com/SynoCommunity/spksrc/wiki/Google-Authenticator-PAM

@hgy59
Copy link
Contributor

hgy59 commented Sep 26, 2021

I've added a wiki entry at https://github.com/SynoCommunity/spksrc/wiki/Google-Authenticator-PAM

Just a hint to make the guide independent of the volume the package is installed in:

you can reference the *.so file by
auth required /var/packages/google-authenticator-libpam/target/lib/security/pam_google_authenticator.so nullok
instead of
auth required /volume1/@appstore/google-authenticator-libpam/lib/security/pam_google_authenticator.so nullok

Copy link
Contributor

@hgy59 hgy59 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM
can anyone test this on ARMv7 or even qoriq (needs local build)?

@hgy59
Copy link
Contributor

hgy59 commented Sep 26, 2021

I can confirm that at least the google-authenticator app runs on ppc853x-5.2, arch-x64-7.0 and arch-aarch64-6.1.

on aarch64 I had to call google-autenticator -Q ANSI, otherwise the generated password contained illegal characters for manual configuration in the android app.
This might not be related to the -Q parameter, but one of the randomly generated passwords contained a / character that was not accepted by the android app.

@soraxas
Copy link
Contributor Author

soraxas commented Sep 26, 2021

Ah thanks for the tips I never knew they are symlinked over there.

re ANSI: I see we can add that to the wiki

@hgy59
Copy link
Contributor

hgy59 commented Sep 26, 2021

with qrencode you can generate QR codes on the console. This tool is available within DSM.
$ qrencode -t ansi "https://www.google.com/chart?chs=200x200&chld=M|0&cht=qr&chl=otpauth://totp/soraxas@hostname%3Fsecret%XXXXXXXXXXXXXXXX"
qrencode-google-authenticator-example

unfortunately the android google-authenticator is not able to read this output (but the dedicated qrreader app sometimes can).

@hgy59
Copy link
Contributor

hgy59 commented Sep 26, 2021

until now the google-autenticator does not work.

pam_google_authenticator.so has invalid entry in library path:

# readelf -d   /var/packages/google-authenticator-libpam/target/lib/security/pam_google_authenticator.so

Dynamic section at offset 0x86c0 contains 28 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [libpam.so.0]
 0x0000000000000001 (NEEDED)             Shared library: [libdl.so.2]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
 0x000000000000000e (SONAME)             Library soname: [pam_google_authenticator.so]
 0x000000000000000f (RPATH)              Library rpath: [/spksrc/spk/google-authenticator-libpam/work-aarch64-6.1/install//var/packages/google-authenticator-libpam/target/lib:/var/packages/google-authenticator-libpam/target/lib]

@hgy59
Copy link
Contributor

hgy59 commented Sep 26, 2021

pam_google_authenticator.so has invalid entry in library path:

The invalid rpath does not cause the error.

I created a test user ssh_test and configured google pam as descripbed in the wiki.
When I log in, it still asks for a password.

Some information grabbed from /var/log/auth.log

first I changed the mod of ~/.google_authenticator to 600 as stated by the log entry:

2021-09-26T18:16:22+02:00 XXXXX sshd(pam_google_authenticator)[16540]: Secret file "/var/services/homes/ssh_test/.google_authenticator" permissions (0777) are more permissive than 0600

further logs:

2021-09-26T18:23:47+02:00 XXXXX sshd(pam_google_authenticator)[23953]: Could not find a valid BASE32 encoded secret in "/var/services/homes/ssh_test/.google_authenticator"
2021-09-26T18:23:47+02:00 XXXXX sshd(pam_google_authenticator)[23953]: No secret configured for user ssh_test, asking for code anyway.
2021-09-26T18:23:47+02:00 XXXXX sshd(pam_google_authenticator)[23953]: Invalid verification code for ssh_test
2021-09-26T18:23:47+02:00 XXXXX sshd[23953]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=192.168.0.98  user=ssh_test
2021-09-26T18:23:47+02:00 XXXXX sshd[23953]: error opening connection to nslcd: No such file or directory

@hgy59
Copy link
Contributor

hgy59 commented Sep 26, 2021

So indeed, the secret in .google_autenticator is not a valid BASE32 string.

This might be related to the diskstation model with aarch64 (aarch64 GNU/Linux synology_rtd1296_ds218) and could explain, why the generated qr code was not accepted.

On my DS-210+ (ppc853x-5.2) the secret is valid BASE32.

@soraxas
Copy link
Contributor Author

soraxas commented Sep 26, 2021

Ah yep I checked and the permission for ~/.google_authenticator is important (mine is 400)

Does google-authenticator works on your DS-210+?

Furthermore, if the issue is with the encoding within ~/.google_authenticator, can you generate the file on some other machine (e.g. laptop, presumingly one where it has no issue with the encoding), rsync it to your DS and see if it works?

@hgy59
Copy link
Contributor

hgy59 commented Sep 26, 2021

Ah yep I checked and the permission for ~/.google_authenticator is important (mine is 400)

Does google-authenticator works on your DS-210+?

Furthermore, if the issue is with the encoding within ~/.google_authenticator, can you generate the file on some other machine (e.g. laptop, presumingly one where it has no issue with the encoding), rsync it to your DS and see if it works?

Now I tried on armv7 (armv7l GNU/Linux synology_armada370_ds115j) and there are wrong base32 secretes too.
For me it looks like an issue with arm processors.

the binary file is ok for this arch, but the source code might have issues with cross compilation.

# file /var/packages/google-authenticator-libpam/target/bin/google-authenticator
/var/packages/google-authenticator-libpam/target/bin/google-authenticator: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, for GNU/Linux 2.6.32, stripped

@hgy59
Copy link
Contributor

hgy59 commented Sep 26, 2021

I don't know what's wrong here, but all (but the 32-bit ppc) generate base64 encoded secrets.

base32 has only uppercase letters, digits and the = for padding.
the / and + sign and lowercase letters are valid for base64 encoded content.

@hgy59
Copy link
Contributor

hgy59 commented Sep 26, 2021

Just installed libpem-google-authenticator on a debian system and it runs like a charm.
All the questions you documented are asked and even the QR code is displayed in the console.

On the diskstation it does not work and the only question is asks is:

By default, tokens are good for 30 seconds and in order to compensate for
possible time-skew between the client and the server, we allow an extra
token before and after the current time. If you experience problems with poor
time synchronization, you can increase the window from its default
size of 1:30min to about 4min. Do you want to do so (y/n)

May be there is a better repository for google-autenticatoravailable?

This is an ugly tool, it does not even support a --version parameter.

@hgy59
Copy link
Contributor

hgy59 commented Sep 26, 2021

Problem SOLVED!

There is /bin/google-authenticator already installed by DSM. This one has the strange base64 behaviour.
This must be a customized version of synology for their 2FA solution.

So it is not possible to call the authenticator of this package without the full qualified path:
/var/packages/google-authenticator-libpam/target/bin/google-authenticator

With this, all runs as expected and the qr code is displayed as console output and codes are base32.

On DSM 5.2 there is no default app so this is the only test above with the real google-authenticator that created valid secrets.

Sorry for the noise, but it would be worth to mention this in the wiki.

PS:
should we create a symlink like sc-google-authenticator (or sc-ga) to make this package more handy?

@soraxas
Copy link
Contributor Author

soraxas commented Sep 27, 2021

Oh that's interesting, I didn't realise DSM comes with a pre-packaged google-authenticator in newer versions (and I wonder why did their pre-packaged version generates invalid code, yet our cross-compiled one works).

Symlink sounds like a good solution, and I think the full name sc-google-authenticator is more recognisable.

@hgy59
Copy link
Contributor

hgy59 commented Sep 27, 2021

Symlink sounds like a good solution, and I think the full name sc-google-authenticator is more recognisable.

Done.

BTW the DSM 5.2 has installed google-authenticator too (/usr/syno/bin/google-authenticator)
This one creates secrets in base32, but is not compatible either, as the secrets have only 10 bytes (instead of 16).

So Synology has it's own 2FA system that is not compatible with google-authenticator.
Their bad, not giving a custom name to their version of the authenticator.

@soraxas
Copy link
Contributor Author

soraxas commented Sep 28, 2021

Awesome thanks for adding the symlink!

I've updated the wiki page to the corresponding symlink, and I've put a link that points to your post for details on this strange base64 behaviour.

soraxas and others added 8 commits December 17, 2022 20:35
Signed-off-by: Tin Lai <oscar@tinyiu.com>
Signed-off-by: Tin Lai <oscar@tinyiu.com>
Signed-off-by: Tin Lai <oscar@tinyiu.com>
- fix spksrc.patch.mk (authored by @th0ma7)
- fix order in spksrc.tc.mk to apply patches after files are writable (by spksrc.tc-fix.mk)
- fix signature of function quotactl in quota.h
- fix the executable name
- add wiki page as support url
- create link sc-google-authenticator to avoid conflict with synology specific version
@hgy59 hgy59 force-pushed the google-authenticator-libpam branch from 1343978 to 4626c34 Compare December 17, 2022 20:39
@hgy59 hgy59 merged commit e719f41 into SynoCommunity:master Dec 17, 2022
@hgy59 hgy59 added the status/published Published and activated (may take up to 48h until visible in DSM package manager) label Dec 17, 2022
th0ma7 added a commit to th0ma7/spksrc that referenced this pull request Dec 19, 2022
th0ma7 added a commit that referenced this pull request Dec 20, 2022
* rustc: Install compiler with toolchain at spksrc.tc.mk time

* tc-rust.mk: Use flock to avoid collisions on parallel builds

* spksrc: Use realpath for RUSTUP_HOME, CARGO_HOME and PATH

* cryptography: Update to 38.0.4 and test build with new rustc

* rustc: Update bcrypt to 4.0.1 and test rustc py310 & py311

* python310-311: Align maturin usage and version

* python310+311: Further align code & dependencies

* pip: Update from versiopn 22.2.2 to 22.3.1

* setuptools: Align with py310+py311 version

* tc.mk: Fix to align with PR #4852

* poetry: Remove as unused anymore

* cffi: Update from version 1.15.0 to 1.15.1

* python310: Update from version 3.10.8 to 3.10.9

* python311: Update from version 3.11.0 to 3.11.1
@hgy59 hgy59 mentioned this pull request Feb 12, 2023
10 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status/published Published and activated (may take up to 48h until visible in DSM package manager)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

patches for native and toolchain packages do not work
3 participants