SwooSSH simplfies SSH access and identity management. To begin -
- Deploy swoossh server
- Add user identities wired to their OpenIDC email addresses from swoossh server console
- Compile swoossh command and deploy to your posix fleet
- Modify sshd config
/etc/ssh/sshd_config
of fleet to trust CA key usingTrustedUserCAKeys
directive and to invoke the compiled swoossh command using AuthorizedPrincipalsCommand directive as below -
TrustedUserCAKeys /path_to_CA_public_key
AuthorizedPrincipalsCommandUser root
AuthorizedPrincipalsCommand /path_to_compiled_swoossh_cmd -targetUser %u -cert %k -type %t -en_key env_var_name_for_entitlement
What you get in return -
- Agent-less certificate based SSH authentication
- Posix user accounts wired to their OpenIDC identities
- Auto provisioning of users as they login to your fleet hosts
- Creation of any missing posix groups on the host
- Users authorized only if their group membership matches to the host's ownership criteria
- UID of user created is the same as what is set in user's swoossh profile
- GID of group created is the same as what is set for the group in swoossh
- Password of the user on the host is reset to the latest value upon login
- Configurable certificate validity period, defaults to 5 days in implementation provided
- SSH Certificate Authority with pluggable support for CA signer implementations
- AWS key-storage backed signer implementation provided
- SSH Certificates with the following custom extensions
- User's POSIX ID
- User's Primary Group
- User's Secondary Groups
- User's latest password
- User's SUDO rules
- SSH POSIX client command with following abilities -
- Matches user to any existing POSIX account by matching name and UID
- Creates user locally if logging in for first time
- When creating a user, can authorize user by comparing host's environment (env vars, ec2 tags) and user groups presented in the certificate
- Adds locally any missing groups for the user presented in the certificate
- Optionally can treat missing principal ID in certificate to be root user
- Reset the matched user's password with the value passed in the certificate
- Can be extended to appending SUDO rules by plugging in an implementation
- Pluggable storage ability for users and groups
- Provides storage implementation for AWS dynamodb based store (Schema in details)
- User identities can be fetched from OpenID compliant IdP
- Has built in support for Google Identities
- Web UI Console for server access
- Admin and non-admin roles for web based access
- Admin role can be derived by nominating a field and specific value(s) in JWT claims
- Rest APIs for administration and user interfaces to the CA server
- Admin APIs can be called using API Key based authentication too
- AWS DynamoDB table - The default implementation requires an AWS DynamoDB table for storage. DDB schema can be found in the
ddb_schema
directory. - AWS Secrets Manager - AWS Secrets Manager for storage and retrieval of CA Signing Keys, encryption secrets for swoossh server.
The server requires a yaml
based configuration file, a sample of which is provided. Below is an explanation of fields included in the YAML configuration -
- Certificate Authority signer's private keys are to be supplied as AWS Secret Manager entries in the
HostCertSignerKey
andUserCertSignerKey
sub-sections of theCAServer
section of config file. The default implementation expects the private key in thePEM
format. CertMaxValidityDays
section specifies lifetime of SSH certificates issued by the CA.
As mentioned above, default implementation of Swoossh uses AWS DynamoDB as the storage. The schema for the DDB table is provided in the ddb_schema
directory.
DDBTableName
specifies name of the DDB table.GSIPosixIDIndexName
,GSIUUIDIndexName
,GSISecondaryGroupsIndexName
,GSINameIndexName
,GSIEmailIndexName
,GsiTypeIndexName
specify the names of GSI tables of DDB table.
This section specifies http server's configuration.
OauthConfig
section -ClientID
specifies the client ID of your OpenID client.ClientSecret
specifies the client secret path in AWS Secrets Manager. Please note that the entry in secret must be a single tuple json object with the key name"secret"
and its value set to the OpenID secret value. For ex:{"secret": "my_oauth_client_secret"}
Scopes
section specifies the list of scopes that your OpenID client requires to obtain user identities from the IDP.OauthCallBackHandlerPath
is the path where user's are returned back with the authorization token to your server after a successful OpenID dance.OauthStateParamName
is the name of parameter used for storing OpenID state. Usually specified by your OpenID IDP.OauthClaimsEntitlementsField
is the name of the claims field among other OpenID Claims returned by your IDP to claim the user's role for the specific purpose of identifying the user's role in Swoossh. More inRoles in Swoossh
section below.OauthEndPointAuthURL
OauthEndPointTokenURL
OIDCIssuerURL
- APIKeyCreds section -
This section specifies the list of admin API key credentials. Each credential comprises of a keyID and a corresponding secret.
ApiKeyID
specifies the keyIDApiKeySecret
specifies the secret's path in AWS Secrets Manager. Please note that the entry in secret must be a single tuple json object with the key name"secret"
and its value set to the API Key value. For ex:{"secret": "my_api_key_value"}
ApiKeySignatureValiditySecs
specifies in seconds the validity of API signature.ApiKeyAuthzReqHeader
specifies the header where the admin API Key based Signature is passedCookieKey
is the key value to lookup the cookie's value in requests to the server's web console.CookieSecret
specifies the AWS Secrets Manager path to the secret used to sign cookie values. Please note that the entry in secret must be a single tuple json object with the key name"secret"
and its value set to the cookie signing secret value. For ex:{"secret": "cookie_signing_secret"}
AdminUserClaimsMatches
is the value of the admin user's claims to match in OpenID claims from the OIDC provider.AdminHomeTmplName
is the template to be used for fetching the admin home page from swoossh server. Path should be relative to the server startup script.HomeTmplName
is the template to be used for fetching normal user's home page. Path should be relative to the server startup script.
The default implementation supports two different roles - admin and a normal user. Admin users are able to administer the server and users. Normal users are able to download their SSH certificates, change their Unix Passwords (detailed below) and upload a new SSH Public key.
Setup the OauthClaimsEntitlementsField
value to instruct swoossh server to look up the OpenID claim for corresponding value of the user.
For instance if OauthClaimsEntitlementsField
value is set to "SwoosshRole"
, Swoossh will look for "SwoosshRole"
field in OpenIDC claims in
list of claims obtained from the IDToken from the IDC. For a user to be considered as an administrator, the value of this field in the OpenIDC claims must match
to the value set for the AdminUserClaimsMatches
field. For instance, if the "SwoosshRole"
claims value returned for a user is "admin"
, Swoossh checks if
this value matches to the AdminUserClaimsMatches
field's value defined in the config and only considers the user as admin, if there is a positive match.
Admin roles can add new users using the API or through the web console.
Pls note that primary/secondary groups associated with the user need to be added in the gid:groupname format. For ex: 1223:devops
Admin roles can add new groups using the API or through the web console. Pls note that you are not required to add the user's primary group separately as it is done at the time of user addition.
The default implementation allows users to change password to their Posix account and sync it to hosts as part of their login sequence.
Swoossh's home interface has a field for users to input pre-generated shadow compatible password hashes. For ex: "openssl passwd -6 -salt xyz yourpass"
Users are allowed to rotate their SSH keys by uploading a new public key from their home page of Swoossh web interface. Certificates issued thereafter will have the new public key signed.
To initialize swoossh and administer it, you will need to add an admin user manually to the DynamoDB table. Thereafter user administration can be done by logging in as that admin user over the web interface. However if you are working off the Admin APIs using API Key based mechanism, you may administer the server without above requirement.
For Swoossh's principal command to create user upon first time login, it needs to authorize the user's account on the host
by comparing user's groups presented in certificate against owner entitlement on the host.
Owner entitlements can be sourced by way of an environment variable made available (to Swoossh command's RunAsUser) for lookup.
The name of this environment variable should be supplied as value to flag "en_key"
of the principal's command.
Alternatively, Swoossh can source host's entitlements from AWS EC2 tags.
Swoossh command looks for EC2 tags for key that matches the "en_key"
value passed in flag.
More than
The RunAs user to be provided in sshd configuration for principals command should have necessary privileges for Swoossh command to perform the tasks expected of it on the host. For default installation of Swoossh command it means that the RunAs user account must have privileges to create users, groups and change user passwords.
If you wanted to use a different storage layer with Swoossh instead of the default, all you have to do is to implement the interfaces declared in storage/store.go
, storage/sshuserstore.go
, storage/sshgroupstore.go
, storage/sshcertstore.go
and supply your implementation while creating DefaultHTTPServer in main swoossh file as -
srv := &httpserver.DefaultHTTPServer{
Store: myCustomStorage,
...
..
.
Interested in modifying the default principal command to suit your requirements? Implement the interfaces in host.go
, posixhost.go
and sudo.go
files in authorizedprincipals
directory.
Call your implementation in the main.go file of cmd
directory as -
func prepareHost(entitlementsKey string, targetUser string) (myCustomHost, error) {
...
host := myCustomHost{
...
}
...
return myCustomHost, nil
}
Swoossh is opinionated in the way it does things
- Uses SSH Cert's extensions to carry payload about the user.
- Swoossh's principals command can create a non-existant user on the host after ascertaining that the user is authorized to login. The authorization logic looks for at least one match among the user's primary/secondary groups presented in the certificate and the host system's entitlements (sourced from env_var or EC2 tags).
- Principals command ensures that the UID and GIDs of the user created are consistent across fleet.
- Principals command can create missing groups the user is associated with on the host
- Principals command can change the password of the user to the latest value
Users trying to login to a host where their account is not already setup will be unable to authenticate to the host using their username as the target username (login_name). This happens because under the SSH protocol, the login_name presented in the incoming connection must exist on the system before the connection can be passed through for further validation which includes certificate validation. You can work your way around this. Here's how -
- When you login to a host that hasn't got your account setup yet, your login attempt will fail.
- This can either mean that your certificate is not valid or your account does not exist on that host (assuming the host is setup with Swoossh properly).
- Make sure you have got yourself a valid certificate from Swoossh server console.
- Try logging in once again. If it succeeds, you had a bad certificate to blame. Life continues.
- But if the login attempt failed, it is very likely because your account does not exist on the host.
- Try changing the login_name (-l flag or the
user
part inuser@host
in your ssh connection command) value to a generic user account name that is known to exist on your fleet. For instance,nobody
, this account is likely to exist in all flavours of linux. Don't forget to pass your certificate along though - Since the account exists on the host, SSH server allows the connection attempt and hands over the validation to Swoossh command once it verifies that the certificate is signed by a trusted CA. Swoossh command validates whether the certificate is valid and if so, proceeds to create the user account presented in the certificate once authorization checks pass.
- Since the login_name does not match up to the username presented in the certificate, Swoossh command nevertheless rejects the login attempt but not before user account creation is done.
- Now try changing back your login_name back to your own user_name and attempt login. Since the user account would have been created by Swoossh command during the previous attempt, your login should succeed. If your login still fails, it means that user account did not happen in the last attempt. It is likely that Swoossh failed to create your account because authorization checks failed. Other reasons could be Swoossh command being mis-configured or not being properly installed on the host. You may have to reach your administrator for help.