istio: Istio allows to break Kubernetes Namespace isolation when using `Ingress Gateway` and `VirtualService`
Describe the bug
In order to enforce Namespace isolation, Kubernetes Ingress
resource only allows references to Services
in the same Namespace
.
In contrast, with Istio
it’s possible to create a VirtualService
resource that references a Service
from another Namespace and expose that Service
to the outside world via Ingress Gateway
.
Expected behavior
Istio
should consistently enforce Kubernetes Namespace isolation.
Steps to reproduce the bug
Use 3 namespaces:
namespace-a
- a namespace owned by “Istio Operator”, where a cluster-wideIstio Ingress Gateway
is definednamespace-b
- a namespace owned by “Team #1”, wherehttpbin
sample application is deployednamespace-c
- a namespace owned by “Team #2”, whereIstio VirtualService
resource is abused to expose to the outside worldhttpbin
service owned by “Team #1”
---
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: shared-gateway
namespace: namespace-a
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
# one Gateway for all services
- "*"
---
apiVersion: v1
kind: Service
metadata:
labels:
app: httpbin
name: httpbin
namespace: namespace-b
spec:
ports:
- name: http
port: 8000
protocol: TCP
targetPort: 8000
selector:
app: httpbin
sessionAffinity: None
type: ClusterIP
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: httpbin
namespace: namespace-c
spec:
hosts:
- "httbin-c.example.org"
gateways:
- shared-gateway.namespace-a.svc.cluster.local
http:
- match:
- uri:
prefix: /
route:
- destination:
port:
number: 8000
# Notice: here we intentionally expose a service from somebody's else namespace !!!
host: httpbin.namespace-b.svc.cluster.local
Version
istioctl version
:
Version: 1.0.1
GitRevision: 42773aacced474d97159902d20579a25b1f98106
User: root@832d5020b1d4
Hub: gcr.io/istio-release
GolangVersion: go1.10.1
BuildStatus: Clean
kubectl version
:
Client Version: version.Info{Major:"1", Minor:"10", GitVersion:"v1.10.0", GitCommit:"fc32d2f3698e36b93322a3465f63a14e9f0eaead", GitTreeState:"clean", BuildDate:"2018-03-27T00:13:02Z", GoVersion:"go1.9.4", Compiler:"gc", Platform:"darwin/amd64"}
Server Version: version.Info{Major:"1", Minor:"10+", GitVersion:"v1.10.6-gke.2", GitCommit:"384b4eaa132ca9a295fcb3e5dfc74062b257e7df", GitTreeState:"clean", BuildDate:"2018-08-15T00:10:14Z", GoVersion:"go1.9.3b4", Compiler:"gc", Platform:"linux/amd64"}
Is Istio Auth enabled or not? Yes
Environment GKE
Cluster state istio-dump.tar.gz
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Reactions: 5
- Comments: 18 (2 by maintainers)
Hey stale bot, it is fixed? (:
Activity!
Is it accurate to say that, per the example provided, this breakdown of namespace isolation only occurs when the “foreign” service’s cluster FQDN is used? If so, I don’t see how this actually violates kubernetes namespace “isolation”, which AFAIK isolates short domain names by namespace, but allows communicating with services across namespaces using the cluster FQDN. Likewise, the “foreign” gateway reference uses the cluster FQDN.
Unless it can be demonstrated that namespace isolation is broken in the case of using references to the short service domain, I think this issue could be deemed invalid; if I’m missing something here, perhaps @yskopets could clarify. The only part of the observed behavior that I found unexpected was referencing the gateway as a service (by it’s FQDN), but that’s really just implementation details leaking through rather than unexpected behavior.
I suppose the issue is that it breaks from Kubernetes namespace isolation specifically with respect to ingress – using native k8s ingress, couldn’t you just deploy a proxy service in your team’s namespace that crosses the namespace boundary? Wouldn’t that be a better analogy for an Istio VirtualService anyway?
activity occurs…
@mabushey Thanks a lot! It’s working now. Figured out that my issue was just missing “svc” in gateway’s FQDN
@sh777 Let’s figure this out… Try adding this:
Make sure you list the namespace in the routing rule, for example here it’s
istio-system
:Also, make sure that your namespace has the sidecar or routing will not work:
Hi @yskopets 😃
Your config does not transverse namespaces. I changed the
httbin-c.example.org
to a name that’s valid for my AWS LoadBalancer. In the browser I get “upstream connect error or disconnect/reset before headers” Which is what I get 100% of the time attempting to access a pod in a namespace that is notdefault
when using a namespace for the VirtualService that is notdefault
. I upgraded from Istio 1.0.1 to 1.0.2 today but see no difference is how this works. VirtualServices only work with thedefault
namespace.I stripped out all namespaces, changed
shared-gateway.namespace-a.svc.cluster.local
toshared-gateway
andhttpbin.namespace-b.svc.cluster.local
tohttpbin.default.svc.cluster.local
. httpbin comes right up in the browser now.