GithubHelp home page GithubHelp logo

zhaow-de / pam-keycloak-oidc Goto Github PK

View Code? Open in Web Editor NEW
61.0 2.0 13.0 10 KB

PAM module connecting to Keycloak for user authentication using OpenID Connect/OAuth2, with MFA/2FA/TOTP support

License: MIT License

Makefile 7.36% Go 92.64%
keycloak pam-module oauth2 oidc openid-connect

pam-keycloak-oidc's People

Contributors

ihard avatar zhaow-de avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

pam-keycloak-oidc's Issues

OTP isn't being enforced

It seems that any, or no OTP code succeeds on a user that has an OTP configured. Have I missed something here? Thanks

# echo ${PAM_PASS}123456 | /opt/pam-keycloak-oidc/pam-keycloak-oidc
2021/07/22 11:55:04 [snip]-(user) Authentication succeeded

# echo ${PAM_PASS}000000 | /opt/pam-keycloak-oidc/pam-keycloak-oidc
2021/07/22 11:55:12 [snip]-(user) Authentication succeeded

# echo ${PAM_PASS} | /opt/pam-keycloak-oidc/pam-keycloak-oidc
2021/07/22 11:55:54 [snip]-(user) Authentication succeeded

Auth fails if the password ends with 6 numbers at the end

If a password incidentally has 6 numbers at the end the module will assume that those 6 numbers are an otp code and hence the login will fail.

I'm not sure what the best approach to this is. A global setting to block otp only fixes this if no user uses 2fa.
Maybe best would be to try to auth first with the code and afterwards with the full supplied string/password.

like so on main.go line 247+:

	if err != nil {
		if hasOtpInPassword {
			// we parsed the password and assumed the last 6 digits were an otp code... sadly they weren't
			// so let's try again with the full password
			accessToken, err = passwordCredentialsTokenEx(
				oauth2Context,
				oauth2Config,
				fmt.Sprintf(config.UsernameFormat, username),
				inputStdio,
				"",
				config.Scope,
				extraParameters,
			)
		}

		if err != nil {
			log.Print(sid, strings.ReplaceAll(err.Error(), "\n", ". "))
			os.Exit(2)
		}
	}

support

Is this code actively supported and/or is development continuing?

Auth Fails when Local User is not present

I am trying to use this PAM module to authenticate when connecting through SSH.
I have followed every step of the tutorial, and step 8 where the module is tested locally is successful :) !
I have added the following line to my /etc/pam.d/sshd file:

@include radiusd

However, I have found that if a local user does not exist with the same name as my Keycloak user, then the login attempts fail with the following message in /var/log/pam-keycloak-oidc.log:

 oauth2: cannot fetch token: 401 Unauthorized. Response: {"error":"invalid_grant","error_description":"Invalid user credentials"}

If I create a local user with the same name as my keycloak user (and a different/no password), the login attempt is successful and I instead see this line in /var/log/pam-keycloak-oidc.log:

Authentication succeeded

Auth fails if password contains !!

If passwor containins string "!!", its return Unauthorized even if right password is entered.

`export PAM_USER=user; echo 'test!!' | ./pam-keycloak-oidc

2023/08/22 21:44:49 [605d97de-1a1c-4a0f-a28a-eeeeee]-(user) oauth2: cannot fetch token: 401 Unauthorized. Response: {"error":"invalid_grant","error_description":"Invalid user credentials"`

Pam not working as expected

Hi, I am trying to use your project. But for me it is not working. I did a bit of debugging and found out that pam isn't providing the password to the stdin. The environment variable PAM_USER is set.

FROM ubuntu

RUN apt-get update && apt-get install -y openssh-server nano wget \
 && mkdir -p /opt/pam-keycloak-oidc \
 && wget -O /opt/pam-keycloak-oidc/pam-keycloak-oidc https://github.com/zhaow-de/pam-keycloak-oidc/releases/download/r1.1.5/pam-keycloak-oidc.linux-amd64 \
 && apt-get purge -y wget \
 && chmod +x /opt/pam-keycloak-oidc/pam-keycloak-oidc \
 && mkdir -p /run/sshd

COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh

ENTRYPOINT ["/entrypoint.sh"]
#!/bin/sh

ssh-keygen -A

cat >  /opt/pam-keycloak-oidc/pam-keycloak-oidc.tml << EOF
# name of the dedicated OIDC client at Keycloak
client-id="demo-pam"
# the secret of the dedicated client
client-secret="57f0e684-a59d-404d-9906-bfe154e8f6ba"
# special callback address for no callback scenario
redirect-url="urn:ietf:wg:oauth:2.0:oob"
# OAuth2 scope to be requested, which contains the role information of a user
scope="pam_roles"
# name of the role to be matched, only Keycloak users who is assigned with this role could be accepted
vpn-user-role="demo-pam-authentication"
# retrieve from the meta-data at https://keycloak.example.com/auth/realms/demo-pam/.well-known/openid-configuration
endpoint-auth-url="http://pc-marcel:8084/auth/realms/master/protocol/openid-connect/auth"
endpoint-token-url="http://pc-marcel:8084/auth/realms/master/protocol/openid-connect/token"
# 1:1 copy, to 'fmt' substituion is required
username-format="%s"
# to be the same as the particular Keycloak client
access-token-signing-method="RS256"
# a key for XOR masking. treat it as a top secret
xor-key="scmi"
EOF

cat > /debug.sh << EOF
#!/bin/bash

echo a
echo \$(tr -d '\0' < /dev/stdin)
echo b \$PAM_USER c
EOF

chmod +x /tnt

cat /etc/pam.d/sshd

cat > /etc/pam.d/sshd << EOF
account required                        pam_permit.so
auth    [success=1 default=ignore]	pam_exec.so     expose_authtok  log=/var/log/pam-keycloak-oidc.log	/debug.sh
auth    requisite                       pam_deny.so
auth    required                        pam_permit.so
EOF

#/bin/bash
/usr/sbin/sshd -De
ssh [email protected]

[marcel@pc-marcel ssh]$ sudo docker exec -it ssh cat /var/log/pam-keycloak-oidc.log
[sudo] password for marcel: 
*** Sun Aug  1 19:47:25 2021
a
INCO
b admin c
*** Sun Aug  1 19:47:32 2021
a
I
b admin c
[marcel@pc-marcel ssh]$ 

At the position of the I should be the password.

I tested it with the 8. step in your readme and it worked.

Documentation for error messages

Hello,

Was stoked to find this pam module, but I'm getting an error "Authentication was successful but authorization failed" that is not explained within the code comments or README.

Would you kindly consider adding an explanation of what this error means? ...and also tell me so I might be able to leverage this amazing module?

Auth Fails in PAM

So if I test manually:

echo "SomePassword" | pam-keycloak-oidc

it succeeds but when I add:

account required                        pam_permit.so
auth    [success=1 default=ignore]      pam_exec.so     expose_authtok  log=/var/log/pam-keycloak-oidc.log      /opt/pam-keycloak-oidc/pam-keycloak-oidc
auth    requisite                       pam_deny.so
auth    required                        pam_permit.so

to /etc/pam.d/sshd

and then try to login with the same password, I get
2021/08/25 17:30:24 [15eabd42-079e-4d71-9d8c-0c60bc7e95dc]-(testy) oauth2: cannot fetch token: 401 Unauthorized. Response: {"error":"invalid_grant","error_description":"Invalid user credentials"}

I am not sure what could be causing this.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.