1
votes

I have kubernetes cluster with installed Istio. I have two pods, for example, sleep1 and sleep2 (containers with installed curl). I want to configure istio to permit traffic from sleep1 to www.google.com and forbid traffic from sleep2 to www.google.com.

So, I created ServiceEntry:

---
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: google
spec:
  hosts: 
  - www.google.com
  - google.com
  ports: 
  - name: http-port
    protocol: HTTP
    number: 80
  resolution: DNS

Gateway

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: istio-egressgateway
spec:
  selector:
    istio: egressgateway
  servers:
  - port:
      number: 80
      name: http-port
      protocol: HTTP
    hosts:
    - "*"

two virtualServices (mesh->egress, egress->google)

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: mesh-to-egress
spec:
  hosts: 
  - www.google.com
  - google.com
  gateways:
  - mesh
  http:
  - match:
    - gateways:
      - mesh
      port: 80
    route:
    - destination:
        host: istio-egressgateway.istio-system.svc.cluster.local
        port:
          number: 80
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: egress-to-google-int
spec:
  hosts: 
  - www.google.com
  - google.com
  gateways:
  - istio-egressgateway
  http:
  - match: 
    - gateways:
      - istio-egressgateway
      port: 80
    route:
    - destination:
        host: google.com
        port:
          number: 80
      weight: 100

As result, I can curl google from both pods.

And the question again: can i permit traffic from sleep1 to www.google.com and forbid traffic from sleep2 to www.google.com? I know that this is possible to do with kubernetes NetworkPolicy and black/white lists (https://istio.io/docs/tasks/policy-enforcement/denial-and-list/), but both methods are forbids (permits) traffic to specific ips or maybe I missed something?

2

2 Answers

3
votes

You can create different service accounts for sleep1 and sleep2. Then you create an RBAC policy to limit access to the istio-egressgateway policy, so sleep2 will not be able to access any egress traffic through the egress gateway. This should work with forbidding any egress traffic from the cluster, that does not originate from the egress gateway. See https://istio.io/docs/tasks/traffic-management/egress/egress-gateway/#additional-security-considerations.

If you want to allow sleep2 access other services, but not www.google.com, you can use Mixer rules and handlers, see this blog post. It shows how to allow a certain URL path to a specific service account.

2
votes

I think you're probably on the right track on the denial option. It is also not limited to IP as we may see attribute-based example for Simple Denial and Attribute-based Denial

So, for example, if we write a simple denial rule for Sleep2 -> www.google.com:

apiVersion: "config.istio.io/v1alpha2"
kind: handler
metadata:
  name: denySleep2Google
spec:
  compiledAdapter: denier
  params:
    status:
      code: 7
      message: Not allowed
---
apiVersion: "config.istio.io/v1alpha2"
kind: instance
metadata:
  name: denySleep2GoogleRequest
spec:
  compiledTemplate: checknothing
---
apiVersion: "config.istio.io/v1alpha2"
kind: rule
metadata:
  name: denySleep2
spec:
  match: destination.service.host == "www.google.com" && source.labels["app"]=="sleep2"
  actions:
  - handler: denySleep2Google
    instances: [ denySleep2GoogleRequest ]

Please check and see if this helps. Also, the "match" field in the "rule" entry is based on istio expression language around the attributes. Some vocabulary can be found in this doc.