Прозрачное проксирование на nodeport в kubernetes

У меня есть kubernetes с pod, содержащим следующие контейнеры:

  1. Squid контейнер
  2. transocks (как redsocks); прозрачный SOCKS прокси

Я запускаю это в k3s локально на linux PC и хочу прозрачно проксировать весь исходящий трафик с PC через этот прозрачный прокси. Таким образом, исходящий трафик хоста принудительно направляется на порт transocks в kubernetes pod. Сейчас это не работает, соединение просто разрывается.

Я знаю, что правила iptables, которые я использую, хороши, потому что они работали, когда я запускал вышеуказанные контейнеры непосредственно в docker, используя сеть хоста. Пользователи squid и transocks имели uid 31 и 32. Я создал следующие правила 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

Где 12345 - порт, на котором прослушивается transocks. Опять же, эти правила отлично работают под docker, используя сеть хоста. transocks перенаправляет на 127.0.0.1:3128 (порт squid), и он проксируется прозрачно. Однако, когда я пробую это с помощью kubernetes pod, используя nodeport (30345 для transocks, 30128 для squid), кажется, что это не работает. Соединение просто зависает, пока не завершится.

Я должен упомянуть, что я также пробовал то же самое с dns, где я перенаправляю выходной трафик, связанный с 53, на порт 9053 (порт dns, отображенный в docker), и это работает, но когда я использую его в kubernetes и перенаправляю на nodeport (30053), он зависает точно так же. По какой-то причине порты узлов не работают, когда вы перенаправляете на них трафик. Я хотел бы узнать, может ли кто-нибудь сказать мне, что я упускаю. Наверное, я не очень хорошо понимаю сетевые технологии kubernetes.

Если кто-то хочет посмотреть мой манифест kuebrnetes, вот он.

Развертывание

{
  "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
              }
            ]
          }
        ]
      }
    }
  }
}

Сервис

{
  "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
      }
    ]
  }
}

правила 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

Еще раз спасибо за помощь.

0
задан 31 July 2021 в 02:08
1 ответ

Если кому-то интересно, я обнаружил, что попытка использовать порт узла слишком сложна, и вместо этого решил просто переместить трансокки в свой собственный модуль и использовать сеть хоста вместе с приведенными выше правилами переадресации, чтобы это работало. Вот манифест, который я использовал для модуля Transocks:

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

Это томl Transocks, который я использую:

listen = "0.0.0.0:12345"

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

[log]
level = "error"

30128 — порт узла для прокси-сервера squid.

1
ответ дан 31 July 2021 в 23:47

Теги

Похожие вопросы