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

RFC: ACL #5

Open
till opened this issue Jun 5, 2020 · 3 comments
Open

RFC: ACL #5

till opened this issue Jun 5, 2020 · 3 comments

Comments

@till
Copy link
Contributor

till commented Jun 5, 2020

I have another proposal, so here it comes... If you have time, I'd like your input. I'll build everything, etc..

Proposal

I want a basic service firewall so I can stop dealing with iptables/firewalld on the docker host system.

So, my "proposal" is: I wanted a way to set ACL on frontends, via service/container labels.

Example 1

A simple ACL to ensure a service can be accessed only from 1.1.1.1:

labels:
 - com.byjg.easyhaproxy.definitions=service
 - com.byjg.easyhaproxy.mode.service=tcp
 - com.byjg.easyhaproxy.port.service=443
 - com.byjg.easyhaproxy.host.service=dns.service.name
 # ACL here
 - com.byjg.easyhaproxy.acl-name.0.service=service-fw
 - com.byjg.easyhaproxy.acl-value.0.service="src 1.1.1.1"

It would render the following config block:

frontend service_in_443_1
    bind *:443
    mode tcp
    acl service-fw src 1.1.1.1
    tcp-request connection reject if !service-fw

    default_backend my_backend_server

Do you think this is over-complicating it?

Example 2

Here is another example — I have an internal API server, I want to ensure that requests originate from 10.0.1.0/24 or 10.0.2.2 and each request must start with /api/v2:

labels:
 - com.byjg.easyhaproxy.definitions=web
 - com.byjg.easyhaproxy.port.web=80
 - com.byjg.easyhaproxy.host.web=dns
 # ACL here
 - com.byjg.easyhaproxy.acl-name.0.web=service-fw
 - com.byjg.easyhaproxy.acl-value.0.web="src 10.0.1.0/24 10.0.2.2"
 - com.byjg.easyhaproxy.acl-name.1.web=service-fw
 - com.byjg.easyhaproxy.acl-value.1.web="path_beg -i /api/v2"

It would render to:

frontend http_in_80_1
    bind *:80
    mode http

    # same ACL name, I think combines them — both must be true
    acl service-fw src 10.0.1.0/24 10.0.2.2
    acl service-fw path_beg -i /api/v2
    http-request deny if !service-sw

    acl is_rule_dns_1_1 hdr(host) -i dns
    acl is_rule_dns_1_2 hdr(host) -i dns:80
    use_backend srv_dns_80_1 if is_rule_dns_1_1 OR is_rule_dns_1_2 

Different acl-names would render another http-request deny if statement.

Thoughts?

@byjg
Copy link
Owner

byjg commented Jun 8, 2020

Sorry for my delay. I was testing the another PR.

First of all, I like the idea of implement more functionality to the service, however we have to keep in mind that we cannot make it so complex that we'll lose the proposal to be an easy haproxy :)

Anyway, the idea still can be worked, and I have some questions.

Example 1:

  • You defined an acl to reject if the src is 1.1.1.1. But if instead of reject the src, I only accept if it is from that source?

Example 2

  • In this example exists the case exactly to accept only connections from a source and add if the path begins with /api/v2 .

The only issue is that it is not clear the exact action.

So, my suggestion is follow anything in this line:

example 1:

labels:
 - com.byjg.easyhaproxy.definitions=service
 - com.byjg.easyhaproxy.mode.service=tcp
 - com.byjg.easyhaproxy.port.service=443
 - com.byjg.easyhaproxy.host.service=dns.service.name
 # ACL here
 - com.byjg.easyhaproxy.acl-reject.0.service="src 1.1.1.1"

It would render the following config block:

frontend service_in_443_1
    bind *:443
    mode tcp
    acl reject-0 src 1.1.1.1
    tcp-request connection reject if !reject-0

    default_backend my_backend_server

example 2

labels:
 - com.byjg.easyhaproxy.definitions=web
 - com.byjg.easyhaproxy.port.web=80
 - com.byjg.easyhaproxy.host.web=dns
 # ACL here
 - com.byjg.easyhaproxy.acl-accept.0.web="src 10.0.1.0/24 10.0.2.2"
 - com.byjg.easyhaproxy.acl-accept.1.web="path_beg -i /api/v2"

It would render to:

frontend http_in_80_1
    bind *:80
    mode http

    # same ACL name, I think combines them — both must be true
    acl accept-0 src 10.0.1.0/24 10.0.2.2
    acl accept-1 path_beg -i /api/v2
    http-request deny if !accept-0 AND !accept-1

    acl is_rule_dns_1_1 hdr(host) -i dns
    acl is_rule_dns_1_2 hdr(host) -i dns:80
    use_backend srv_dns_80_1 if is_rule_dns_1_1 OR is_rule_dns_1_2 

@byjg
Copy link
Owner

byjg commented Jul 10, 2020

Any comment?

@till
Copy link
Contributor Author

till commented Jul 10, 2020

@byjg sorry, bit swamped. Saw this in my inbox and been meaning to do something.

So basically, you would do "acl-reject" and "acl-accept"? And then render based on that? I think I like that idea! :)

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

2 participants