<p>I am very new in Istio therefore it might be simple question but I have several confusion regarding Istio.I am using Istio 1.8.0 and 1.19 for k8s.Sorry for the multiple questions but will be appreciate if you can help me to clarify best approaches.</p>
<ol>
<li><p>After I inject Istio, I suppose ı could not able to access service to service directly inside pod but as you can see below ı can. Maybe I 've misunderstanding but is it expected behaviour? Meanwhile how can I debug whether services talk each other via envoy proxy with mTLS ? I am using <code>STRICT</code> mode and should I deploy peerauthentication the namespace where microservices are running to avoid this?</p>
<pre><code> kubectl get peerauthentication --all-namespaces
 NAMESPACE      NAME      AGE
 istio-system   default   26h
</code></pre>
</li>
<li><p>How can I restrict the traffic lets say api-dev service should not be access to auth-dev but can access backend-dev?</p>
</li>
<li><p>Some of the microservices needs to commnunicate with database where its also running in <code>database</code> namespace. We have also some which we do not want to inject istio also using same database? So, should database also deployed in the same namespace where we have istio injection? If yes, then does it mean I need to deploy another database instance for rest of services?</p>
</li>
</ol>
<hr />
<pre><code>    $ kubectl get ns --show-labels
    NAME              STATUS   AGE    LABELS
    database          Active   317d   name=database
    hub-dev           Active   15h    istio-injection=enabled
    dev               Active   318d   name=dev


    capel0068340585:~ semural$ kubectl get pods -n hub-dev
    NAME                                     READY   STATUS    RESTARTS   AGE
    api-dev-5b9cdfc55c-ltgqz                  3/3     Running   0          117m
    auth-dev-54bd586cc9-l8jdn                 3/3     Running   0          13h
    backend-dev-6b86994697-2cxst              2/2     Running   0          120m
    cronjob-dev-7c599bf944-cw8ql              3/3     Running   0          137m
    mp-dev-59cb8d5589-w5mxc                   3/3     Running   0          117m
    ui-dev-5884478c7b-q8lnm                   2/2     Running   0          114m
    redis-hub-master-0                        2/2     Running   0           2m57s
    
    $ kubectl get svc -n hub-dev
    NAME                    TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
    api-dev                ClusterIP   xxxxxxxxxxxxx      &lt;none&gt;        80/TCP    13h
    auth-dev               ClusterIP   xxxxxxxxxxxxx      &lt;none&gt;        80/TCP    13h
    backend-dev            ClusterIP   xxxxxxxxxxxxx      &lt;none&gt;        80/TCP    14h
    cronjob-dev            ClusterIP   xxxxxxxxxxxxx      &lt;none&gt;        80/TCP    14h
    mp-dev                 ClusterIP   xxxxxxxxxxxxx      &lt;none&gt;        80/TCP    13h
    ui-dev                 ClusterIP   xxxxxxxxxxxxx      &lt;none&gt;        80/TCP    13h
    redis-hub-master       ClusterIP   xxxxxxxxxxxxx      &lt;none&gt;        6379/TCP  3m47s
    


----------


    $ kubectl exec -ti ui-dev-5884478c7b-q8lnm -n hub-dev sh
    Defaulting container name to oneapihub-ui.
    Use 'kubectl describe pod/ui-dev-5884478c7b-q8lnm -n hub-dev' to see all of the containers in this pod.
    /usr/src/app $ curl -vv  http://hub-backend-dev
    *   Trying 10.254.78.120:80...
    * TCP_NODELAY set
    * Connected to backend-dev (10.254.78.120) port 80 (#0)
    &gt; GET / HTTP/1.1
    &gt; Host: backend-dev
    &gt; User-Agent: curl/7.67.0
    &gt; Accept: */*
    &gt;
    * Mark bundle as not supporting multiuse
    &lt; HTTP/1.1 404 Not Found
    &lt; content-security-policy: default-src 'self'

    &lt;
    &lt;!DOCTYPE html&gt;
    &lt;html lang=&quot;en&quot;&gt;
    &lt;head&gt;
    &lt;meta charset=&quot;utf-8&quot;&gt;
    &lt;title&gt;Error&lt;/title&gt;
    &lt;/head&gt;
    &lt;body&gt;
    &lt;pre&gt;Cannot GET /&lt;/pre&gt;
    &lt;/body&gt;
    &lt;/html&gt;
    * Connection #0 to host oneapihub-backend-dev left intact
    /usr/src/app $
</code></pre>

<ol>
<li>According to <a href="https://istio.io/latest/docs/concepts/security/#peer-authentication" rel="nofollow noreferrer">documentation</a>, if you use <code>STRICT</code> mtls, then workloads should only accept encrypted traffic.</li>
</ol>
<h2>Peer authentication</h2>
<blockquote>
<p>Peer authentication policies specify the mutual TLS mode Istio enforces on target workloads. The following modes are supported:</p>
<ul>
<li>PERMISSIVE: Workloads accept both mutual TLS and plain text traffic.
This mode is most useful during migrations when workloads without
sidecar cannot use mutual TLS. Once workloads are migrated with
sidecar injection, you should switch the mode to STRICT.</li>
<li>STRICT: Workloads only accept mutual TLS traffic.</li>
<li>DISABLE: Mutual TLS is disabled. From a security perspective, you
shouldn’t use this mode unless you provide your own security
solution.</li>
</ul>
<p>When the mode is unset, the mode of the parent scope is inherited. Mesh-wide peer authentication policies with an unset mode use the PERMISSIVE mode by default.</p>
</blockquote>
<p>Also worth to take a look <a href="https://banzaicloud.com/blog/istio-mtls/#mtls-modes-in-practice" rel="nofollow noreferrer">here</a>, as it's very well described here by banzaicloud.</p>
<hr />
<p>You can enable strict mtls mode <a href="https://istio.io/latest/docs/tasks/security/authentication/authn-policy/#globally-enabling-istio-mutual-tls-in-strict-mode" rel="nofollow noreferrer">globally</a>, but also per specific <a href="https://istio.io/latest/docs/tasks/security/authentication/authn-policy/#namespace-wide-policy" rel="nofollow noreferrer">namespace</a> or <a href="https://istio.io/latest/docs/tasks/security/authentication/authn-policy/#enable-mutual-tls-per-workload" rel="nofollow noreferrer">workload</a>.</p>
<hr />
<ol start="2">
<li>You can use istio <a href="https://istio.io/latest/docs/reference/config/security/authorization-policy/" rel="nofollow noreferrer">Authorization Policy</a> to do that.</li>
</ol>
<blockquote>
<p>Istio Authorization Policy enables access control on workloads in the mesh.</p>
</blockquote>
<p>There is an example.</p>
<blockquote>
<p>The following is another example that sets action to “DENY” to create a deny policy. It denies requests from the “dev” namespace to the “POST” method on all workloads in the “foo” namespace.</p>
</blockquote>
<pre><code>apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
 name: httpbin
 namespace: foo
spec:
 action: DENY
 rules:
 - from:
   - source:
       namespaces: [&quot;dev&quot;]
   to:
   - operation:
       methods: [&quot;POST&quot;]
</code></pre>
<hr />
<ol start="3">
<li>You can set up Database without injecting it and then add it to Istio registry using <a href="https://istio.io/latest/docs/reference/config/networking/service-entry/" rel="nofollow noreferrer">ServiceEntry</a> object so it would be able to communicate with the rest of istio services.</li>
</ol>
<blockquote>
<p>ServiceEntry enables adding additional entries into Istio’s internal service registry, so that auto-discovered services in the mesh can access/route to these manually specified services. A service entry describes the properties of a service (DNS name, VIPs, ports, protocols, endpoints). These services could be external to the mesh (e.g., web APIs) or mesh-internal services that are not part of the platform’s service registry (e.g., a set of VMs talking to services in Kubernetes). In addition, the endpoints of a service entry can also be dynamically selected by using the workloadSelector field. These endpoints can be VM workloads declared using the WorkloadEntry object or Kubernetes pods. The ability to select both pods and VMs under a single service allows for migration of services from VMs to Kubernetes without having to change the existing DNS names associated with the services.</p>
</blockquote>
<p>There are examples in istio documentation:</p>
<ul>
<li><a href="https://istio.io/latest/blog/2018/egress-tcp/" rel="nofollow noreferrer">Consuming External TCP Services</a></li>
<li><a href="https://istio.io/latest/blog/2018/egress-mongo/" rel="nofollow noreferrer">Consuming External MongoDB Services</a></li>
</ul>
<hr />
<p>To answer your main question about how to debug mtls communication</p>
<p>The most basic test would be to try to call from not injected pod to injected pod, with a curl for example. There is istio <a href="https://istio.io/latest/docs/tasks/security/authentication/mtls-migration/" rel="nofollow noreferrer">documentation</a> about that.</p>
<p>You can also use <code>istioctl x describe</code>, more about it <a href="https://istio.io/latest/docs/ops/diagnostic-tools/istioctl-describe/#verifying-strict-mutual-tls" rel="nofollow noreferrer">here</a>.</p>
<hr />
<p>Not sure what's wrong with the <code>curl -vv  http://hub-backend-dev</code>, but as it's 404 I suspect it might be an issue with your istio dependencies, like wrong virtual service configuration.</p>
