Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

integrate LDAP as external auth service #1

Open
doujiang24 opened this issue Apr 13, 2023 · 18 comments
Open

integrate LDAP as external auth service #1

doujiang24 opened this issue Apr 13, 2023 · 18 comments

Comments

@doujiang24
Copy link
Member

Now envoy does not support it yet: envoyproxy/envoy#20920

Could be easy to do it with the envoy Golang filter extension.
Seems https://github.com/go-ldap/ldap is a proper choice.

@XiaoYaoheihei
Copy link

I am studying MoE series of articles,I am interested in this direction, who should I contact?

@doujiang24
Copy link
Member Author

@XiaoYaoheihei thanks for asking.

there are four projects published in "开源之夏", https://summer-ospp.ac.cn/org/projectlist?lang=zh&orgName=MOSN%20%E7%A4%BE%E5%8C%BA&pageNum=1&pageSize=50&programName=
But, we are limited to 3 projects that could be chosen eventually.

We intend to close this project in the internal discussion, so you are recommended to choose other projects.
The only chance that this project could be choen, is no one pick one of the other 3 projects.

But this issue is still very useful for Envoy and MOSN, still welcome to contribute, just out of the "开源之夏" project.

@jackj-ohn1
Copy link

@XiaoYaoheihei thanks for asking.

there are four projects published in "开源之夏", https://summer-ospp.ac.cn/org/projectlist?lang=zh&orgName=MOSN%20%E7%A4%BE%E5%8C%BA&pageNum=1&pageSize=50&programName= But, we are limited to 3 projects that could be chosen eventually.

We intend to close this project in the internal discussion, so you are recommended to choose other projects. The only chance that this project could be choen, is no one pick one of the other 3 projects.

But this issue is still very useful for Envoy and MOSN, still welcome to contribute, just out of the "开源之夏" project.

oh, is that means the project wouldn't be present at summer-ospp? I recently glance at the project in summer-ospp and have a strong willing to apply it

@doujiang24
Copy link
Member Author

according to the rule of summer-ospp, it is there. but you are recommended to choose the others, you could treat it as it is not there.

The only chance that this project could be choen, is no one pick one of the other 3 projects.

we are limited to 3 projects that could be chosen eventually.

@jackj-ohn1
Copy link

according to the rule of summer-ospp, it is there. but you are recommended to choose the others, you could treat it as it is not there.

The only chance that this project could be choen, is no one pick one of the other 3 projects.

we are limited to 3 projects that could be chosen eventually.

so disappointing, I’ve got great interest on the project.

@doujiang24
Copy link
Member Author

@jackj-ohn1 Sorry for that.

But this issue is still very useful for Envoy and MOSN, still welcome to contribute, just out of the "开源之夏" project

if you still are interested in it, this project is still open.

@Makonike
Copy link
Contributor

Makonike commented May 20, 2023

Hello @doujiang24 , I am interested in this project, and here is my design. It is inspired by Kong. I would appreciate it if you could review my design and provide insights on areas that could be optimized.

Target

Leveraging Envoy Go extension technology, we aim to integrate LDAP-based access control capabilities into Envoy. Only requests that pass the LDAP server's authentication will be proxied to the upstream service.

During this process, we can optimize the system by implementing user information caching with a duration defined by config.cache_ttl. This approach will help reduce the frequency of LDAP server access.

Usage

The client set credentials in Authorization header in the following format:

credentials := base base64(username:password)

An example of the Authorization header is as follows (c2VydmljZXVzZXI6bXlzZWNyZXQK, which is the base64-encoded value of serviceuser:mysecret):

Authorization: base c2VydmljZXVzZXI6bXlzZWNyZXQK

Bind Mode and Search Mode

If no filter is specified in its configuration, the middleware runs in the default bind mode, meaning it tries to make a simple bind request to the LDAP server with the credentials provided in the request headers. If the bind succeeds, the middleware forwards the request, otherwise it returns a 401 Unauthorized status code.

If a filter query is specified in the middleware configuration, and the Authentication Source referenced has a bindDN and a bindPassword, then the middleware runs in search mode. In this mode, a search query with the given filter is issued to the LDAP server before trying to bind. If result of this search returns only 1 record, it tries to issue a bind request with this record, otherwise it aborts a 401 Unauthorized status code.

Config

Required

  • host, string, required

Host on which the LDAP server is running.

  • port, number, default 389, required

TCP port where the LDAP server is listening. 389 is the default port for non-SSL LDAP and AD. 636 is the port required for SSL LDAP and AD. If ldaps is configured, you must use port 636.

  • base_dn, string, required

The baseDN option should be set to the base domain name that should be used for bind and search queries.

  • attribute, string, default "cn", required

Attribute to be used to search the user; e.g., “cn”.

Optional

  • filter, string, default ""

If not empty, the middleware will run in search mode, filtering search results with the given query.

Filter queries can use the %s placeholder that is replaced by the username provided in the Authorization header of the request. For example: (&(objectClass=inetOrgPerson)(gidNumber=500)(uid=%s)), (cn=%s).

  • bind_dn, string, default ""

The domain name to bind to in order to authenticate to the LDAP server when running on search mode. Leaving this empty with search mode means binds are anonymous, which is rarely expected behavior. It is not used when running in bind_mode.

  • bind_password, string, default ""

The password corresponding to the bindDN specified when running in search mode, used in order to authenticate to the LDAP server.

  • cache_ttl, number, default 60

Cache expiry time in seconds.

  • ldaps, bool, default false

Set to true to connect using the LDAPS (LDAP over SSL) protocol. When ldaps is configured, you must use port 636.

  • start_tls, bool, default false

Set it to true to issue StartTLS (Transport Layer Security) extended operation over ldap connection. If the start_tls setting is enabled, ensure the ldaps setting is disabled.

  • certificateAuthority, string, default ""

The certificateAuthority option should contain a PEM-encoded certificate to use to establish a connection with the LDAP server if the connection uses TLS but that the certificate was signed by a custom Certificate Authority.

  • timeout, number, default 10000

An optional timeout in milliseconds when waiting for connection with LDAP server.

@doujiang24
Copy link
Member Author

@Makonike Great, it's good to ship.

@spacewander
Copy link
Member

I would like to add some comments on the design:

ldap_host, string, required

Could we get rid of the ldap_ prefix since we are using them in the ldap extension? So with the ldap_port

header_type, string, default ldap, required

I am afraid that the "header_type" configuration is almost only used by Kong. The "ldap c2VydmljZXVzZXI6bXlzZWNyZXQK" is actually Kong's special implementation and "Basic c2VydmljZXVzZXI6bXlzZWNyZXQK" are actually used widely, especially in the browser. Other API gateways like APISIX and traefik only support the latter format. You don't need to keep API compatible with Kong's unique implementation. We can remove this option in the first version.

ldaps, bool, default false, required

I would recommend using a general option to enable TLS, for example, "tls". So we can follow the same style in different extensions.

@spacewander
Copy link
Member

BTW, I would recommend taking a look at Traefik and Tyk for the API design instead of Kong, because we are developing a Go extension, not a Lua one. For example, a Go developer may call "keepalive" as "idle_timeout" or something else.

@Makonike
Copy link
Contributor

BTW, I would recommend taking a look at Traefik and Tyk for the API design instead of Kong, because we are developing a Go extension, not a Lua one. For example, a Go developer may call "keepalive" as "idle_timeout" or something else.

Thank you sincerely for the recommendations! I shall make the necessary revisions to my design shortly.

@Makonike
Copy link
Contributor

Hello @doujiang24 @spacewander , I have already updated my design. Please take a look. Additionally, I would like to inquire about the necessity of maintaining a connection pool to reuse LDAP connections.

@spacewander
Copy link
Member

spacewander commented May 23, 2023

@Makonike
Could you provide your design in a separate online doc? It is very hard to figure out what you have changed in the issue.

There are some issues in the new design, for example:
Authorization: base c2VydmljZXVzZXI6bXlzZWNyZXQK should be Authorization: Basic c2VydmljZXVzZXI6bXlzZWNyZXQK

And ldaps is still remained...

Besides, I think an extension level certificateAuthority is overkilled for the first version, since a certificate already has a size in KBs.

maintaining a connection pool to reuse LDAP connections

It's usually done in the LDAP client itself. I would like to use the default option first.

@spacewander
Copy link
Member

I would recommend providing an MVP (all with the default value, not tls/start_tls), and then adding more features in the later iterations.

@Makonike
Copy link
Contributor

I would recommend providing an MVP (all with the default value, not tls/start_tls), and then adding more features in the later iterations.

ok, here is my design, and here is my demo.

@spacewander
Copy link
Member

I would recommend providing an MVP (all with the default value, not tls/start_tls), and then adding more features in the later iterations.

ok, here is my design, and here is my demo.

LGTM except for some comments. To comment on it, I register a fresh feishu account.

@doujiang24
Copy link
Member Author

@Makonike the next step, you could create a PR with the the MVP version, including doc, code and tests, thanks!

@Makonike
Copy link
Contributor

@Makonike the next step, you could create a PR with the the MVP version, including doc, code and tests, thanks!

OK. Thank you for your guidance!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants