{"id":22138983,"url":"https://github.com/cwaldbieser/synthproxy","last_synced_at":"2025-03-24T10:41:24.578Z","repository":{"id":24734791,"uuid":"28147100","full_name":"cwaldbieser/synthproxy","owner":"cwaldbieser","description":"LDAP proxy that synthesizes group membership attributes from an external database.","archived":false,"fork":false,"pushed_at":"2015-10-09T03:40:27.000Z","size":376,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-01-29T16:08:42.514Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cwaldbieser.png","metadata":{"files":{"readme":"README.rst","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":"2014-12-17T17:13:07.000Z","updated_at":"2018-03-12T14:08:41.000Z","dependencies_parsed_at":"2022-08-18T03:11:12.889Z","dependency_job_id":null,"html_url":"https://github.com/cwaldbieser/synthproxy","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cwaldbieser%2Fsynthproxy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cwaldbieser%2Fsynthproxy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cwaldbieser%2Fsynthproxy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cwaldbieser%2Fsynthproxy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cwaldbieser","download_url":"https://codeload.github.com/cwaldbieser/synthproxy/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245256779,"owners_count":20585968,"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":[],"created_at":"2024-12-01T20:13:08.508Z","updated_at":"2025-03-24T10:41:24.555Z","avatar_url":"https://github.com/cwaldbieser.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"##################\nLDAP Proxy Servers\n##################\n\n* *bindproxy*: An LDAP proxy server that records the last **failed** BIND\n  for a DN.  If the same invalid credential is provided, a failure response\n  is returned to the client without consulting the proxied server.  This\n  helps prevent accounts from getting locked out by a password policy when\n  a misconfigured client (e.g. smart phone email client) rapidly presents\n  the **same** wong credentials multiple times.\n* *synthproxy*: An LDAP proxy server that examines search result DNs returned\n  from the proxied server and merges attributes from an external CouchDB\n  database into the result.  This allows multi-valued attributes like\n  `memberOf` to be manipulated independently.\n\n--------\nClusters\n--------\n\nBecause Twisted is single threaded, it may be desirable to run multiple\nbindproxy daemons on a multi-core/multi-processor host if it is determined\nthat the service is CPU bound during high load (i.e. if the CPU becomes\na bottleneck).  It is possible this may occur because LDAP requests and\nresponses are encoded/decoded using pure Python.\n\nTo take advantage of multiple cores/processors in a CPU-bound scenario,\nmultiple bindproxy services may be run and place behind a TCP load\nbalancer.  The services can be configured to communicate their cache\nstates amongst each other.\n\nTo run a cluster of proxy daemons, create one config file for each node.\nThis config file will inherit from the usual places (system, user, local\nconfigs).  It should specify the endpoint for the LRU cluster service and\nthe endpoint for each peer.  For example (`bindproxy-0.cfg`)::\n\n    [Application]\n    endpoint = tcp:10390\n\n    [Cluster]\n    endpoint = unix:address=/tmp/bindproxy/bp0.sock\n    peer0 = unix:path=/tmp/bindproxy/bp1.sock\n\nIf your config files follow this naming convention, you can use the shell script\n:program:`bpcluster.sh` to run `twistd bindproxy` with the appropriate \narguments for each node.  The `synthcluster.sh` works identically for\nthe `synthproxy` subcommand.  When a node starts up, it will try to connect to its \npeers.  It will retry at intervals until the peer connections have been \nestablished.\n\nWhen a node caches a result, it communicates the cached results to its peers.\n\nThe `twistd balancer` command may be used to create a simple TCP load balancer\nin front of the cluster.\n\n---\nTLS\n---\n\nThe LDAP proxies can be configured to communicate with the proxied host(s) \nusing TLS.  Set the `LDAP` -\u003e `use_starttls` option to 1.\n\nThe Proxy itself can be conigured to respond to a request to initiate a StartTLS \nsession with clients.  The `LDAP` -\u003e `proxy_cert` option must be set to the path\nof a file containing a PEM formatted certificate or certificate chain followed by\na corresponding PEM formatted private key.  If this option is present and the\nclient issues a StartTLS request, the proxy server will respond and establish\na TLS session.  If this option is not present, the proxy server will respond with\nan error code indicating that StartTLS is not available.\n\n----------------------\nMultiple Proxied Hosts\n----------------------\nMultiple LDAP hosts can be proxied.  Provide a unique option under the `LDAP`\nsection for each service.  The option must start with 'proxied_url'.  E.g.\n'proxied_url_1 = ldap://first.example.org:389' and \n'proxied_url_2 = ldap://second.example.org:389'.  The host will be queried in \na round-robin fashion.\n\n---------\nBindProxy\n---------\n\nRecords failed BIND attempts.  If the same invalid credentials are presented,\na failure response is returned, and the proxied LDAP service is *not* consulted.\n\nThe use case is to prevent account lockouts due to the *same* bad credentials\nbeing repeatedly presented (e.g. by a misconfigured mail client).\n\nThe bindproxy has an optional web service that can be used to clear cached BIND\nresults for a DN.  The `[WebService]` section, `endpoint` option controls where\nthis service listens.  Authentication can be configured via the command line\nby passing an `--auth` option to `twistd` or \n`bpcluster.sh` or `synthcluster.sh`.  The only valid web service\nURL is:\n\n  DELETE http://$HOST[:$PORT]/cache/$DN\n\nIssuing a DELETE HTTP request to this URL removes the cached entry for the DN.\nIn a cluster, the removal is communicated to peers.\n\n=====\nUsage\n=====\n\nTo run in the foreground::\n\n    $ twistd -n bindproxy\n\nTo run as a daemon::\n\n    $ twisted bindproxy\n\nAdditional options can be found by adding the `--help` option.\n\n----------\nSynthProxy\n----------\n\nWhen search results are returned from the proxied LDAP service, an external CouchDB\ndatabase is consulted.  If a DN corresponding to a search result is found, the \n`memberOf` attributes from that external lookup are added to the result before it is\nreturned to the client.  This allows group memberships for an account to be maintained\nin a separate database.\n\n=====\nUsage\n=====\n\nTo run in the foreground::\n\n    $ twistd -n synthproxy\n\nTo run as a daemon::\n\n    $ twisted synthproxy\n\nAdditional options can be found by adding the `--help` option.\n\n=============\nCouchDB Setup\n=============\n\nYour CouchDB database must be set up with a design document and a view that \nwill emit a value which is a 2 element list-- the attribute name and an\nattribute value.  Multi-values attributes may should emit multiple rows.\n\nAn example view is as follows:\n.. code-block:: javascript\n\n    {\n       \"attribs\": {\n           \"map\": \"function(doc) {\\n  var dn = doc[\\\"dn\\\"];\\n  var attrib = doc[\\\"attrib\\\"];\\n  var value = doc[\\\"value\\\"];\\n  emit(dn, [attrib, value]);\\n}\"\n       }\n    }\n\nAn example document might look like this:\n.. code-block:: javascript\n\n    {\n        \"_id\": \"2788d56289351b834ae127701e002e09\", \n        \"_rev\": \"3-5e5212a443d68ee10b989b515fe6abed\", \n        \"attrib\": \"memberOf\", \n        \"dn\": \"uid=esteban,ou=people,dc=example,dc=fr\", \n        \"order\": 0, \n        \"value\": \"cn=warriors,ou=groups,dc=example,dc=fr\"\n    }\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcwaldbieser%2Fsynthproxy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcwaldbieser%2Fsynthproxy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcwaldbieser%2Fsynthproxy/lists"}