Как запустить несколько socat и перенаправить как TCP, так и UDP трафик?

Вопрос или проблема

Я хочу перенаправить Microsoft Remote Desktop на сервере Linux, предполагая, что удаленный Windows-хост имеет адрес 192.168.1.100, я хочу запустить:

socat TCP4-LISTEN:3389,fork TCP4:192.168.1.100:3389
socat UDP4-LISTEN:3389,fork UDP4:192.168.1.100:3389

Это работает нормально, когда я запускаю службу вручную в оболочке, но я хочу запустить ее с помощью systemd и записывать логи в /var/log/socat-rdp.log.

После нескольких попыток я могу запустить службу следующим образом:

[Unit]
Description=Socat RDP Forwarding Service
After=network.target

[Service]
Type=forking
User=root
ExecStart=/bin/sh -c "/usr/bin/socat TCP4-LISTEN:3389,fork TCP4:192.168.3.153:3389 > /var/log/socat-rdp.log 2>&1 & /usr/bin/socat UDP4-LISTEN:3389,fork UDP4:192.168.3.153:3389 > /var/log/socat-rdp.log 2>&1 &"
ExecStop=/bin/kill $MAINPID

[Install]
WantedBy=multi-user.target

Эта конфигурация запускается и работает обычно, но когда я останавливаю службу с помощью systemctl stop socat-rdp, она возвращает код ошибки 1, хотя процесс socat завершен как обычно.

Существуют ли лучшие решения?

Я нашел альтернативное решение для проблемы с запуском нескольких экземпляров socat и перенаправлением как TCP, так и UDP трафика. Вместо того чтобы использовать systemd для управления службой, я использовал Docker для достижения желаемого результата.

Я нашел образ Docker alpine/socat и использую Docker Compose для запуска двух экземпляров socat одновременно для TCP и UDP. Вот мой файл Docker Compose:

---
services:
  socat_rdp_tcp:
    image: alpine/socat
    container_name: socat_rdp_tcp
    command: "TCP-LISTEN:3389,fork TCP:192.168.1.100:3389"
    ports:
      - 3389:3389

  socat_rdp_udp:
    image: alpine/socat
    container_name: socat_rdp_udp
    command: "UDP-LISTEN:3389,fork UDP:192.168.1.100:3389"
    ports:
      - 3389:3389/udp

Образ Docker:
alpine/socat

Когда вы запускаете команду socat напрямую в терминале и завершаете их (возможно, killall socat ?), возвращаемый код – Exit 143?
Самый простой грязный хак – использовать SuccessExitStatus=143 в разделе [Service].

Ответ или решение

Для настройки пересылки трафика RDP (Remote Desktop Protocol) на сервере Linux с использованием socat, вам потребуется управлять как TCP, так и UDP трафиком. Несмотря на то что вы можете запускать эти команды вручную в терминале, использование systemd для автоматизации этого процесса может быть более эффективным и надежным.

Подход через systemd

В вашем случае вы уже создали службу systemd, которая правильно настраивает socat для передачи обоих типов трафика. Однако есть некоторые аспекты, которые можно улучшить для предотвращения ошибок при остановке службы.

Вот модифицированный пример вашего файла службы socat.service:

[Unit]
Description=Socat RDP Forwarding Service
After=network.target

[Service]
Type=simple
User=root
ExecStart=/usr/bin/socat TCP4-LISTEN:3389,fork TCP4:192.168.1.100:3389 > /var/log/socat-rdp.log 2>&1 &
ExecStart=/usr/bin/socat UDP4-LISTEN:3389,fork UDP4:192.168.1.100:3389 >> /var/log/socat-rdp.log 2>&1 &
SuccessExitStatus=143
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

Объяснение параметров:

  1. Type=simple: Указывает systemd, что служба не создает дочерний процесс и что основной процесс – это те команды, которые запускаются в ExecStart.

  2. SuccessExitStatus=143: Это помогает избежать ошибок остановки, когда socat завершает работу с кодом 143 (что может происходить при нормальном завершении работы через сигнал SIGTERM).

  3. RemainAfterExit=yes: Указывает, что служба должна считаться активной даже после завершения всех дочерних процессов, что может быть полезно в вашем случае.

  4. & в ExecStart: Обратите внимание, что использование & в команде может привести к тому, что процессы будут работать в фоновом режиме, что не всегда является желаемым поведением в systemd.

Альтернативный подход через Docker

Как вы упомянули в дальнейшем, использование Docker для развертывания socat является интересным подходом с возможностью изоляции среды выполнения. Вот ваш файл docker-compose.yml, который вы уже предложили:

version: '3'
services:
  socat_rdp_tcp:
    image: alpine/socat
    container_name: socat_rdp_tcp
    command: "TCP-LISTEN:3389,fork TCP:192.168.1.100:3389"
    ports:
      - 3389:3389

  socat_rdp_udp:
    image: alpine/socat
    container_name: socat_rdp_udp
    command: "UDP-LISTEN:3389,fork UDP:192.168.1.100:3389"
    ports:
      - 3389:3389/udp

С помощью этого подхода вы можете легко управлять экземплярами socat как контейнерами, что дает больше гибкости при обновлениях и масштабировании.

Заключение

Оба подхода – использование systemd или Docker – имеют свои плюсы и минусы. Если вы предпочитаете оставаться на базе Linux и использовать нативное управление процессами, улучшение конфигурации systemd – это отличный выбор. В противном случае, если вы открыты к контейнеризации, Docker может значительно упростить управление сервисом и его зависимостями.

Убедитесь, что вы логируете выходные данные socat для дальнейшего анализа, чтобы иметь возможность быстро выявлять и устранять возможные проблемы.

Теперь вы обладаете всеми необходимыми указаниями для настройки вашего сервиса перехвата трафика RDP с помощью socat, как через systemd, так и с использованием Docker.

Оцените материал
Добавить комментарий

Капча загружается...