Proxy transparente para nodeport em kubernetes

Proxy transparente para nodeport em kubernetes

Eu tenho um kubernetes configurado com um pod contendo os seguintes contêineres:

  1. Recipiente de lula
  2. transocks (como redsocks); um proxy SOCKS transparente

Estou executando isso em k3s localmente em um PC Linux e quero fazer proxy transparente de todo o tráfego de saída do PC por meio desse proxy transparente. Portanto, o tráfego do host de saída é forçado para a porta transocks no pod do Kubernetes. No momento não está funcionando, a conexão simplesmente expira.

Eu sei que as regras de iptables que estou usando são boas porque funcionaram quando executei os contêineres acima diretamente no docker usando rede host. Os usuários de squid e transocks eram uid 31 e 32. Criei as seguintes regras de iptables:

#iptables -t nat -A OUTPUT -m owner --uid-owner 31 -j ACCEPT
#iptables -t nat -A OUTPUT -m owner --uid-owner 32 -j ACCEPT
#iptables -t nat -A OUTPUT -p tcp --dport 80 -j REDIRECT --to-port 12345
#iptables -t nat -A OUTPUT -p tcp --dport 443 -j REDIRECT --to-port 12345

Onde 12345 é a porta em que os transocks estão escutando. Novamente, essas regras funcionam muito bem no docker usando rede host. transocks encaminha para 127.0.0.1:3128 (porta squid) e é proxy de forma transparente. No entanto, quando tento usar um pod kubernetes usando um nodeport (30345 para transocks, 30128 para squid), parece não estar funcionando. A conexão simplesmente trava até expirar.

Devo mencionar que também tentei o mesmo com o DNS, onde redireciono o tráfego de saída vinculado a 53 para a porta 9053 (porta DNS mapeada no docker) e funciona, mas quando o uso no Kubernetes e redireciono para o nodeport (30053 ) ele trava da mesma maneira. Então, por algum motivo, as portas do nó parecem não funcionar quando você redireciona o tráfego para elas. Eu queria saber se alguém poderia me dizer o que estou perdendo aqui. Não devo entender muito bem a rede kubernetes.

Caso alguém queira ver o manifesto dos meus kuebrnetes, aqui estão eles.

Implantação

{
  "apiVersion": "apps/v1",
  "kind": "Deployment",
  "metadata": {
    "name": "webfilter",
    "labels": {
      "app": "webfilter"
    }
  },
  "spec": {
    "replicas": 1,
    "selector": {
      "matchLabels": {
        "app": "webfilter"
      }
    },
    "template": {
      "metadata": {
        "labels": {
          "app": "webfilter"
        }
      },
      "spec": {
        "containers": [
          {
            "name": "squid",
            "image": "jusschwa/squid-ssl:latest",
            "ports": [
              {
                "containerPort": 3128
              }
            ]
          }, {
            "name": "transocks",
            "image": "jusschwa/transocks-proxy:latest",
            "ports": [
              {
                "containerPort": 12345
              }
            ]
          }
        ]
      }
    }
  }
}

Serviço

{
  "apiVersion": "v1",
  "kind": "Service",
  "metadata": {
    "name": "webfilter",
    "labels": {
      "app": "webfilter"
    }
  },
  "spec": {
    "type": "NodePort",
    "selector": {
      "app": "webfilter"
    },
    "ports": [
      {
        "name": "squid",
        "protocol": "TCP",
        "port": 3128,
        "targetPort": 3128,
        "nodePort": 30128
      },
      {
        "name": "transocks",
        "protocol": "TCP",
        "port": 12345,
        "targetPort": 12345,
        "nodePort": 30345
      }
    ]
  }
}

regras de iptables

iptables -t nat -A OUTPUT -m owner --uid-owner root -j ACCEPT
iptables -t nat -A OUTPUT -m owner --uid-owner 31 -j ACCEPT # squid user
iptables -t nat -A OUTPUT -m owner --uid-owner 32 -j ACCEPT # transocks user
iptables -t nat -A OUTPUT -m owner --uid-owner 32 -j ACCEPT # unbound user
iptables -t nat -A OUTPUT -p tcp --dport 80 -j REDIRECT --to-ports 30345
iptables -t nat -A OUTPUT -p tcp --dport 443 -j REDIRECT --to-ports 30345
iptables -t nat -A OUTPUT -p udp --dport 53 -j REDIRECT --to-ports 30053

Obrigado novamente pela ajuda.

Responder1

Se alguém estiver interessado, achei muito difícil tentar usar uma porta de nó e, em vez disso, optei por apenas mover os transocks para seu próprio pod e usar a rede host, junto com as regras de encaminhamento acima para fazer isso funcionar. Aqui está o manifesto que usei para o pod transocks:

{
  "apiVersion": "v1",
  "kind": "Pod",
  "metadata": {
    "name": "transocks"
  },
  "spec": {
    "hostNetwork": true,
    "dnsPolicy": "ClusterFirstWithHostNet",
    "containers": [
      {
        "name": "transocks",
        "image": "jusschwa/transocks-proxy"
      }
    ]
  }
}

Este é o transocks toml que estou usando:

listen = "0.0.0.0:12345"

# Connect to HTTP Proxy
proxy_url = "http://127.0.0.1:30128"

[log]
level = "error"

30128 é o nodeport para o proxy squid.

informação relacionada