I have an unsecured Postfix
instance in a container that listens to port 25
. This port is not exposed using a Service
. The idea is that only a PHP
container that runs inside the same pod should be able to connect to Postfix and there is no need for additional Postfix
configuration .
Is there any way for other processes that run in the same network or Kubernetes
cluster to connect to this hidden port?
From what I know, only other containers in the same Pod can connect to an unexposed port, via localhost
.
I'm interested from a security point of view.
P.S. I now that one should make sure it has multiple levels of security in place but I'm interested only theoretically if there is some way to connect to this port from outside the pod.
Yes, you can use kubectl port-forward
to set up a tunnel directly to it for testing purposes.
From what I know, only other containers in the same Pod can connect to an unexposed port, via
localhost
.
Not exactly. How this is implemented is a detail of the particular container runtime in use.
...I'm interested only theoretically if there is some way to connect to this port from outside the pod.
So here we go :)
For example on GKE you can easily access Pod from other Pod if you know Target Pod's IP.
I have used the following setup on GKE:
apiVersion: v1
kind: Pod
metadata:
annotations:
run: fake-web
name: fake-default-knp
spec:
containers:
- image: mendhak/http-https-echo
imagePullPolicy: IfNotPresent
name: fake-web
The Docker file for that image can be found here. It specifies EXPOSE 80 443
So, container listens on these 2 Ports.
$kubectl exec fake-default-knp -- netstat -tulpn
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 :::443 :::* LISTEN 1/node
tcp 0 0 :::80 :::* LISTEN 1/node
I have no services:
$kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 40d
and only 2 Pods.
$kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP
busybox-sleep-less 1/1 Running 3476 40d 10.52.1.6
fake-default-knp 1/1 Running 0 13s 10.52.0.50
And I can connect to
$kubectl exec busybox-sleep-less -- telnet 10.52.0.50 80
Connected to 10.52.0.50
$kubectl exec busybox-sleep-less -- telnet 10.52.0.50 443
Connected to 10.52.0.50
As you can see, container is accessible on POD_IP:container_port
from other pod (located on another node)
P.S> It worth checking "Inter-process communications (IPC)" if you really would like to continue using unsecured Postfix and prefer avoiding "unauthorized access from outside of Pod". It is described here.
Hope that helps!
Edit 30-Jan-2020
I decided to play with it a little bit. Technically, you can achieve what you want with the help of iptables
. You need to specifically ACCEPT all traffic from localhost
on port25 and DROP from everywhere else.
something like:
cat iptab.txt
# Generated by xtables-save v1.8.2 on Thu Jan 30 16:37:27 2020
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -s 127.0.0.1/32 -p 6 -m tcp --dport 80 -j ACCEPT
-A INPUT -p 6 -m tcp --dport 80 -j DROP
COMMIT
I've tested it and can't telnet on port 80 from anywhere except that very Pod. Please note that I had to run my container in privileged mode in order to be able editing iptables
rules directly from Pod. But that is going beyond initial question. :)