{"id":16655800,"url":"https://github.com/bjhaid/pam_hook","last_synced_at":"2025-03-21T16:32:00.172Z","repository":{"id":64297573,"uuid":"93354390","full_name":"bjhaid/pam_hook","owner":"bjhaid","description":"Pam based webhook authentication for Kubernetes","archived":false,"fork":false,"pushed_at":"2020-08-23T06:21:19.000Z","size":25098,"stargazers_count":77,"open_issues_count":4,"forks_count":8,"subscribers_count":7,"default_branch":"master","last_synced_at":"2024-10-13T09:54:10.953Z","etag":null,"topics":["authentication","kubernetes","kubernetes-webhook","pam","pam-hook","pamhook"],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bjhaid.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-06-05T01:50:48.000Z","updated_at":"2024-08-31T12:34:55.000Z","dependencies_parsed_at":"2023-01-15T09:01:36.893Z","dependency_job_id":null,"html_url":"https://github.com/bjhaid/pam_hook","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bjhaid%2Fpam_hook","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bjhaid%2Fpam_hook/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bjhaid%2Fpam_hook/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bjhaid%2Fpam_hook/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bjhaid","download_url":"https://codeload.github.com/bjhaid/pam_hook/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":221817058,"owners_count":16885453,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["authentication","kubernetes","kubernetes-webhook","pam","pam-hook","pamhook"],"created_at":"2024-10-12T09:54:23.231Z","updated_at":"2024-10-28T10:29:29.454Z","avatar_url":"https://github.com/bjhaid.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Build Status](https://api.travis-ci.org/bjhaid/pam_hook.svg?branch=master)](https://travis-ci.org/bjhaid/pam_hook)\n\n# pam_hook\n\nA [PAM](http://www.linux-pam.org/) webhook endpoint that can be used with [Kubernetes](https://github.com/kubernetes/kubernetes).\n\n### You should consider using this if:\n\n- You currently use Unix users (for authentication) and groups (for authorization) and want a seamless migration of your existing authentication and authorization mechanisms.\n- You use LDAP with caching set up (such as [SSSD](https://linux.die.net/man/8/sssd) or [nsscache](https://github.com/google/nsscache)), and would like to take advantage of it (`pam_hook`'s reliance on PAM gives you the existing cache for free).\n- You want some tooling that you can fully automate from the command line.\n- You are shopping for a Kubernetes authentication mechanism.\n\n### Usage instructions\n\n- Run `pam_hook` as below:\n\n```\n$\u003e ./pam_hook -cert-file pamhook_cert.crt -key-file pamhook_key.crt -signing-key foo -bind-port 6443\n```\n\nMost of the flags can be configured also via environment variables, run for more options:\n\n```\n$\u003e ./pam_hook -help\nUsage of ./pam_hook:\n  -alsologtostderr\n        log to standard error as well as files\n  -audience string\n        Server that consumes the pam_hook endpoint, configurable via PAMHOOK_AUDIENCE environment variable\n  -bind-address string\n        Address to bind pam_hook to\n  -bind-port string\n         (default \"8080\")\n  -cert-file string\n        Absolute path to TLS CA certificate, configurable via PAMHOOK_TLS_CERT_FILE environment variable\n  -disable-mlock\n        Disable calling sys mlock\n  -key-file string\n        Absolute path to TLS private key file, configurable via PAMHOOK_TLS_KEY_FILE environment variable\n  -log_backtrace_at value\n        when logging hits line file:N, emit a stack trace\n  -log_dir string\n        If non-empty, write log files in this directory\n  -logtostderr\n        log to standard error instead of files\n  -pam-service-name string\n        PAM service name against which to perform user authentication during token creation, configurable via PAMHOOK_PAM_SERVICE_NAME environment variable\n  -server-name string\n        The domain name for pam-hook, configurable via PAMHOOK_SERVERNAME environment variable\n  -signing-key string\n        Key for signing the token (required), configurable via PAMHOOK_SIGNING_KEY environment variable\n  -stderrthreshold value\n        logs at or above this threshold go to stderr\n  -token-expires-in int\n        Specifies how long the token is valid for in minutes, configurable via PAMHOOK_TOKEN_EXPIRES_IN environment variable (default 10)\n  -v value\n        log level for V logs\n  -vmodule value\n        comma-separated list of pattern=N settings for file-filtered logging\n```\n\nCommand line flags override options configured via environment variables.\n\n**Notes on select options**\n\nSome options relate to JSON Web Tokens (JWT) used by Kubernetes Webhook Token Authentication.\n\n- `audience`: The audience claim that identifies the recipients that the JWT is intended for\n- `server-name`: The issuer claim identifies the principal that issued the JWT\n- `pam-service-name`: The PAM service against which user authentications are performed during token creation. For example, \"passwd\".\n- `disable-mlock`: Prevents a call to _unix.Mlockall()_, which would have prevented sensitive authentication material in memory from appearing in core dumps.\n\n**Kubernetes Webhook Token Authentication configuration**\n\n- Create a kubeconfig file as below\n\n```\napiVersion: v1\nclusters:\n- cluster:\n    certificate-authority: /Users/bjhaid/ca.pem\n    server: https://pamhook:6443/authenticate\n  name: pamhook\nusers:\n  - name: pamhook\n    user:\n      client-certificate: /Users/bjhaid/pamhook.pem\n      client-key: /Users/bjhaid/pamhook.key\ncurrent-context: pamhook\ncontexts:\n- context:\n    cluster: pamhook\n    user: pamhook\n  name: pamhook\n```\n\n- Pass the path to the kubeconfig file to the `kube-apiserver` via the\n  `--authentication-token-webhook-config-file` flag (see the\n  [Kubernetes documentation](https://kubernetes.io/docs/admin/authentication/#webhook-token-authentication)\n  for more information).\n- Get a token: `curl -u bjhaid --cacert pamhook_cert.crt https://pamhook:6443/token`\n\n**Note**:\n\nYou can also override the token expiration, however the override cannot be\nlarger than the configured expiration, e.g:\n\n```bash\ncurl -u bjhaid --cacert pamhook_cert.crt https://pamhook:6443/token?token-expires-in=3\n```\n\nin the above the token will expire in 3 minutes.\n\n### How it works\n\n- The user hits the `/token` endpoint of `pamhook` and gets a token in exchange for their\n  OS username and password. Here's an example request:\n\n```bash\ncurl --cacert pamhook_cert.crt https://localhost:6443/token -u bjhaid\nEnter host password for user 'bjhaid':\neyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiIiLCJleHAiOjE0OTY2MTQwMzcsImlhdCI6MTQ5NjYxMjIzNywiaXNzIjoiIiwidXNlcm5hbWUiOiJiamhhaWQifQ.8GVZJJPa_GYxcsHy-WBMYlel_JSyoSLXnwnt4Bp_Nk0\n```\n\n- `pam_hook` authenticates the user against PAM. If the username and password combination\n  is valid and the user's account or password has not expired, `pam_hook` returns with an\n  HMAC signed JWT token which contains the user's `username`, `issuer`, `issued_at`, `expiry` and\n  token audience. Otherwise it returns with `Authentication failure`.\n\nA successful response will look something like:\n`eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiIiLCJleHAiOjE0OTY2MTQwMzcsImlhdCI6MTQ5NjYxMjIzNywiaXNzIjoiIiwidXNlcm5hbWUiOiJiamhhaWQifQ.8GVZJJPa_GYxcsHy-WBMYlel_JSyoSLXnwnt4Bp_Nk0`\n\nwhile a failure will simply be the string `\"Authentication failure\"`.\n\n- The user makes Kubernetes API calls using the received token, and `kube-api-server` hits\n  the configured `pam_hook` endpoint. If the token is valid and not expired `pam_hook`\n  responds with:\n\n```json\n{\n  \"apiVersion\": \"authentication.k8s.io/v1beta1\",\n  \"kind\": \"TokenReview\",\n  \"status\": {\n    \"authenticated\": true,\n    \"user\": {\n      \"username\": \"bjhaid\",\n      \"uid\": \"1000\",\n      \"groups\": [\"bjhaid\", \"sudo\"]\n    }\n  }\n}\n```\n\nHowever if the token is invalid or has expired `pam_hook` responds with:\n\n```\n{\n  \"apiVersion\": \"authentication.k8s.io/v1beta1\",\n  \"kind\": \"TokenReview\",\n  \"status\": {\n    \"authenticated\": false\n  }\n}\n```\n\n- Kubernetes proceeds based on the value of `\"authenticated\"`.\n\n### Healthcheck:\n\nHealth check route is `/heartbeat`\n\n### Building:\n\n```\nmake build\n```\n\n### Testing:\n\n```\nmake test\n```\n\n### Running in Docker (Host Auth)\n\n```\n  docker run -it --rm  -e \"PAMHOOK_SIGNING_KEY=foo\" \\\n  -v /etc/nsswitch.conf:/etc/nsswitch.conf \\\n  -v /etc/group:/etc/group -v /etc/shadow:/etc/shadow \\\n  -v /etc/passwd:/etc/passwd -v /etc/pam.conf:/etc/pam.conf \\\n  -v /etc/pam.d/:/etc/pam.d -p 6443:6443 \\\n  -v $PWD/pamhook_cert.crt:/etc/ssl/certs/pamhook_cert.crt \\\n  -v $PWD/pamhook_key.crt:/etc/ssl/private/pamhook_key.crt \\\n  --cap-add IPC_LOCK \\\n  bjhaid/pam_hook:0.4.2 /usr/bin/pam_hook \\\n  -cert-file /etc/ssl/certs/pamhook_cert.crt \\\n  -key-file /etc/ssl/private/pamhook_key.crt \\\n  -bind-port 6443 -v 2\n\n```\n\nMake sure you change the certs to match your actual certificate path. On OSX,\nyou'll need to prepend the etc directories with `/private`, OSX also does not\nhave `/etc/nsswitch` and `/etc/pam.conf`\n\n### License\n\n[MIT](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbjhaid%2Fpam_hook","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbjhaid%2Fpam_hook","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbjhaid%2Fpam_hook/lists"}