Closed olekristoffer closed 1 year ago
Hi there @olekristoffer,
I think this is a great idea! However I cant promise it any time soon as it would require a substantial amount of work to reorganize how I manage user identities (which Im planning on doing as I want this to be easier to manage).
So yes! Hopefully! Maybe! Soon :P
Would be a big change. A move from device based auth to user based auth, or a combination of the two.
Right now I like its relative simplicity.
Well,` one step closer to this now as the most recent version separates device from user. Gonna add Webauthn support before I get to this however.
Wag now has webauthn, and the changes I've made to facilitate that have made adding this almost trivial, so I'll be looking in to adding this real soon.
My main concern with this change is that you'll still have to define your policies for what authorised users can access in the wag configuration file itself.
So it'd be rather split in terms of management, users could be managed with
My current plan of attack is to use OIDC with a groups claim where the groups will match with the polices defined in the config.json
this means that all management will be able to be done centrally for the most part, bar tweaking the access policies.
Unfortunately this will not support googles IdP as for some reason they dont support the group claims that other identity providers do, so its not possible to map user groups to oidc assertion (and Im not writing a special case just for google)
Nice. We use Keycloak for OAuth/IdP so having this support would be awesome. It moves all our authentication into a common mechanism and makes the use of existing groups really useful.
Looking forward to this.
Ha! Well good, ironically I'm using keycloak to test my first versions!
Hm, unfortunately while adding oidc as an authentication method is trivial, having the groups be able to change for a user on demand is less so, might take a bit longer than I thought.
@olekristoffer this feature now exists in its beta form here: https://github.com/NHAS/wag/releases/tag/v3.2.1-pre-release
Currently all this allows users to do is authorise with the identity provider, and will mean that users will still need policies, groups and devices created and registered with wag directly.
Im planning on using the OIDC claims to do groups automatically in the future, so only group policy and device registration will be handled on the wag server itself.
Hope this works for you!
As usual, please provide any UI/UX feedack :)
Sweet this feature is now fully completely, the OIDC IdP can now manage what groups a user is in on the wag side, without wag ever having to directly know about the user.
As this was a huge change, Im still going to leave it in pre-release for a bit until someone tests it.
But it can be found here: https://github.com/NHAS/wag/releases/tag/v3.2.1-pre-release
For completeness (and since I havent written up the docs in a sensible place yet) here are some instructions on running it with keycloak.
config.json policies:
"Policies": {
"*": {
"Mfa": ["1.1.1.1"],
"Allow": [
"google.com"
]
},
"group:nerds": {
"Mfa": [
"192.168.3.4/32"
],
"Allow": [
"192.168.3.5/32"
]
},
"group:administrators": {
"Mfa": [
"8.8.8.8"
]
}
}
After setting up your realm in keycloak create groups (note the group:
prefix):
Create a client (i just used the default account
):
Click on account
In Settings
:
enable Client Authentication
, Authorisation
, Standard Flow
and Direct Access grants
like so:
Set your valid redirect URLS to your vpn domain with /authorise/oidc
as the direction, also add +
in web origins.
Add your credentials from Credentials
to the wag config file Authenticators.OIDC.ClientID/ClientSecret
In Client scopes
:
Click on the dedicated scope
Add a mapper by configuration
Choose Group Membership
Set Name
and Token Claim Name
to groups
(or whatever group name you want, just update it in the wag config file if its not groups). And disable Full group path
Then from here, add your users as you usually would, you can also disable other authentication methods in wag. But this message is long enough.
Hope someone plays with it!
Now on main branch so this issue will be closed :)
I'd like to reopen this, only so I can understand how it is supposed to work. More than a little excited about the prospect of mapping groups to our domain.
The oidc part in keycloak, no problem. But I'm not sure what I'm to expect as a user when I try to logon. Am I supposed to get a redirect to the OIDC.IssuerURL
and be returned on successful authentication?
I'm not getting anywhere.
"Authenticators": {
"Issuer": "otp-uat.domain.tld",
"DomainURL": "https://otp-uat.domain.tld",
"DefaultMethod": "oidc",
"Methods": [
"totp",
"oidc"
],
"OIDC": {
"IssuerURL": "https://sso.domain.tld/auth/realms/opusvl",
"ClientSecret": "SecretKey",
"ClientID": "wag-uat",
"GroupsClaimName": "groups"
}
},
I even tried removing the totp
entry. I just get the same MFA behaviour.
I'm missing the bit about mfa_type
in Users
.
Updated my record with mfa_type
of oidc
and now I get a redirect to auth. I just need to resolve the redirect now.
Effectively a user has an MFA method that gets set in the sqlite3 database (which you've seen).
If their mfa_type
is already set then they'll continue to use the previous MFA method of their choice, so we dont accidentally lock users out if we suddenly add methods.
You should use wag users -reset-mfa -username <your.username.here>
command to reset their MFA. This will then prompt them on next usage to select a method of MFA which should do the rest for you.
Other than that your configuration file looks correct. If resetting the users mfa doesnt work, try creating a new user (and give me the logs of what happens and I'll sort it out).
Wowsers, just got this working on my UAT system, and have to say - well done.
Awesome!
Really glad to hear it's all working for you. This was an especially big piece of work and pretty fun to build.
Tell me how it goes or if you find any issues with it.
But for now since you've confirmed its working and it's released to the world I'm going to mark this as closed.
I may be a bit premature.
The SSO auth works just fine. I sign in and see in the console the groups that it pulls from the claim.
I thought I would then be able to create Policies that match the groups, and not have any Group section in config.json
as the groups and membership come from the claim. All I needed to do was add the policy for that group. But I even added in an empty group to test.
"Acls": {
"Policies": {
"group:access-role-people": {
"MFA": [
"10.0.0.1/32",
"10.0.0.2/32"
]
}
}
But when I attempt to access something in the group, I get nowhere. If I look at the firewall I also don't see any "Mfa" rules against my device.
2023/03/02 20:46:05 paul.b 192.168.254.28 used sso to login with groups: [access-files-developer access-role-people ... ]
"paul.b": {
"LastPacketTimestamp": 0,
"Expiry": 0,
"MFA": null,
"Public": [
"10.0.6.254/32",
"192.168.254.1/32"
],
"Devices": [
{
"IP": "192.168.254.28",
"Authorized": true
},
{
"IP": "192.168.254.27",
"Authorized": false
},
{
"IP": "192.168.254.3",
"Authorized": false
}
]
},
Ah this is one of those times where the devil is in the detail. You need to make your groups be prefixed with the wag group:
prefix.
So the log should look like:
2023/03/02 20:46:05 paul.b 192.168.254.28 used sso to login with groups: [group:access-files-developer group:access-role-people ... ]
This is actually done for a good reason. Its so if you accidentally have things in the groups claim (say you have another application that also wants groups
in its oidc claim) it doesnt overlap with wag's groups and you dont end up giving users unintentional access.
I think this could be made clear by making it wag:<group_name>
or wag-group:<group_name>
.
This is just a lack of docs on my behalf (docs website coming soon, as soon as I can bear writing web stuff again)
ooh, not liking that so much :( My whole point of using sso was to reuse the group membership.
In fact I would have imaginged if you wanted wag specific groups you could make wag specific groups, no need for a group:
prefix, eg.
wag-access-roles-people
... and should the groups
claim contain only groups anyhow?
That's a valid point. More than happy to change it, very easy to change.
PS. If you would like some assistance with documentation, I have been given the go ahead to spend some time to assist.
Frankly the real blocker for documentation at the moment is the fact I have to create a website for it. I dont mind writing documentation once I've got a little thing set up, I've just currently got 0 motivation to actually make the site (going to be statically generated using hugo with the docsy theme unless I find something better).
But when it exists, I'll add you to the repo to write up things if you want!
@paulb-opusvl Howdy, I've added you to the docs page I've made. Feel free to put whatever you want in there, I'll be getting a proper domain for it soon, then adding it to the wag main page.
For documentation, I was expecting a readthedocs or github pages, both would require me to learn how.
Back on oauth2 and groups. Upgraded to 4.1.1.1 and it works, as long as you understand what's expected. The oauth group claim contains groups that are NOT prefixed with group:
. To manage their ACL you use them as you would a user, eg. no group:
prefix.
"access-role-projectmanagement": {
"Mfa": [
"10.0.6.125/32",
"10.0.4.125/32"
]
},
This seems a little strange, especially when you get to the management UI which I'm loving. As you can't manage these as groups, as the UI expects the prefix. So you manage the rule as if a user.
When you logon as an oauth2 user you wont see anything in the groups to indicate what you are a member of, but looking at the user you will see all of your oauth2 groups. Also the UI Diagnostics, Firewall State will show you the rules are getting applied.
On the docs side of things: The repo is github pages but uses Hugo instead of readthedocs. So a simple commit will be built and displayed on the page (ill add a link to the page in that repos read me).
For writing your own docs, have a look in the content folder and make sure it works by using the local build first, which I have instructions for in the read me.
On the oauth2 side of things:
You should upgrade to v4.1.3, after you pointed out that having the group:
requirement for OIDC claims made it hard to reuse existing groups I did a small release to remove that restriction.
Also, is it important a user knows what groups they're part of? As I can add that to the /status page and/or the authorisation confirmation page
E.g the code below is how an oidc group is converted into a wag group.
groups := []string{}
for i := range groupsIntf {
conv, ok := groupsIntf[i].(string)
if !ok {
log.Println("Error, could not convert group claim to string, probably error in oidc idP configuration")
http.Error(w, "Server Error", http.StatusInternalServerError)
return
}
groups = append(groups, "group:"+conv)
}
Docs for this: https://nhas.github.io/wag-vpn.github.io/docs/guides/single_sign_on_with_keycloak/
Check out the management section :)
Hi
Thank you for a great project, it is really useful.
Would it be possible for to extend wag to support user authentication using OpenID Connect / oauth 2.0 protocol? This would add the benefit of both simplifying the user managment and allow for a rich set of MFA solutions in addtion to supporting single sign-on from different providers. Authentication could be implemented using locally hosted services, e.g. by using implementations such as keycloak, or provided by trusted third parties for example google or github?
https://github.com/coreos/go-oidc https://pkg.go.dev/golang.org/x/oauth2#section-readme
examples: https://fusionauth.io/blog/2020/10/22/securing-a-golang-app-with-oauth https://medium.com/@pliutau/getting-started-with-oauth2-in-go-2c9fae55d187