alyda
alyda

Reputation: 569

SSH config file port forwarding not working as expected in Docker (compose)

I have a Docker Compose file with nginx, php, redis, and a container dedicated to SSH tunneling.

I have an ssh config file on my mac that works as expected when I run ssh my-tunnel, and that is exposed to the image via the file ./ssh/config

This is my Dockerfile for the ssh tunnel

FROM alpine:edge

RUN apk add --update openssh-client && rm -rf /var/cache/apk/*

# cagataygurturk/docker-ssh-tunnel:0.0.1
CMD rm -rf /root/.ssh && mkdir /root/.ssh && \
    cp /run/secrets/ssh_config /root/.ssh/config && \
    cp /run/secrets/ssh_key /root/.ssh/id_rsa && \
    chmod -R 600 /root/.ssh/* && \
    # see https://man.openbsd.org/ssh
    ssh -4 -o StrictHostKeyChecking=no -N $TUNNEL_HOST \
    && while true; do sleep 30; done;
EXPOSE 1-65535

This is my docker-compose.yaml (abridged)

version: '3.1'

services:
  php:
    ...
    links:
     - ssh-tunnel

  ssh-tunnel:
    build:
      context: ./ssh
    secrets:
      - ssh_config
      - ssh_key
    environment:
      TUNNEL_HOST: my-tunnel

secrets:
  ssh_config:
    file: ./ssh/config
  ssh_key:
    file: ./ssh/id_rsa

The only output I get from this container is Warning: Permanently added '[IP_SPECIFIED_IN_CONFIG]:PORT_SPECIFIED_IN_CONFIG_FILE' (ECDSA) to the list of known hosts. and the application is unable to connect to tunneled services. The only way I can fix this is by changing the CMD to

CMD rm -rf /root/.ssh && mkdir /root/.ssh && \
cp /run/secrets/ssh_config /root/.ssh/config && \
cp /run/secrets/ssh_key /root/.ssh/id_rsa && \
chmod -R 600 /root/.ssh/* && \
# see https://man.openbsd.org/ssh
ssh -4 -o StrictHostKeyChecking=no -N $TUNNEL_HOST \
-L *:$LOCAL_PORT_1:$REMOTE_HOST_1:$REMOTE_PORT_1 \
-L *:$LOCAL_PORT_2:$REMOTE_HOST_2:$REMOTE_PORT_2 \
&& while true; do sleep 30; done;

This is not ideal because of the need for multiple local forwards, otherwise I would just use this container.

Why does the configuration that does not specify local forwards using the command line option -L not work? I know the config file (containing the local forwards) is being read because the IP address gets added to known_hosts.

output of netstat -an

# WORKING
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address            Foreign Address         
State
tcp        0      0 127.0.0.11:34951         0.0.0.0:*               LISTEN
tcp        0      0 127.0.0.1:$LOCAT_PORT_2  0.0.0.0:*               LISTEN
tcp        0      0 127.0.0.1:$LOCAL_PORT_1  0.0.0.0:*               LISTEN
tcp        0      0 172.20.0.3:34902         HostName:Port     
ESTABLISHED
udp        0      0 127.0.0.11:50743         0.0.0.0:*
Active UNIX domain sockets (servers and established)
Proto RefCnt Flags       Type       State         I-Node Path

# NOT WORKING
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State
tcp        0      0 0.0.0.0:$LOCAL_PORT_2   0.0.0.0:*               LISTEN
tcp        0      0 127.0.0.11:39857        0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:$LOCAL_PORT_1   0.0.0.0:*               LISTEN
tcp        0      0 172.21.0.3:47994        Hostname:Port     ESTABLISHED
udp        0      0 127.0.0.11:42928        0.0.0.0:*
Active UNIX domain sockets (servers and established)
Proto RefCnt Flags       Type       State         I-Node Path

Upvotes: 2

Views: 3016

Answers (1)

alyda
alyda

Reputation: 569

Figured it out, in my ~/.ssh/config file, I specified

LocalForward PORT PUBLIC_URL:PORT

instead of

LocalForward *:PORT PUBLIC_URL:PORT

Upvotes: 3

Related Questions