0

I am trying to proxy SSH traffic from nginx (listening on port 7999) to a bitbucket server (listening on port 7998) on the back-end. Both nginx and bitbucket are running inside Docker containers. If I login to the nginx container and do telnet bitbucket.domain-name.com 7998 it connects. On the host machine if I do netstat -pnlt I get:

Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp6       0      0 :::2377                 :::*                    LISTEN      24477/dockerd       
tcp6       0      0 :::7946                 :::*                    LISTEN      24477/dockerd       
tcp6       0      0 :::80                   :::*                    LISTEN      24477/dockerd       
tcp6       0      0 :::443                  :::*                    LISTEN      24477/dockerd       
tcp6       0      0 :::7999                 :::*                    LISTEN      24477/dockerd   

But, I when I do this on my computer: git clone ssh://git@domain-name.com:7999/project_key/repo_name.git I get

Cloning into 'repo_name'...
ssh: connect to host domain-name.com port 7999: Connection refused
fatal: Could not read from remote repository.

And when I do telnet domain-name.com 7999 I get telnet: Unable to connect to remote host: Connection refused.

It seems the problem is nginx is not listening on port 7999 inside the docker container. But, on the host I can see dockerd is listening on port 7999. I imagine I might not have the nginx config correct, but am not sure. Here are the relevant bits from the config files.

docker-compose.yaml (nginx)

services:
    nginx:
        ports:
            - "80:8080"
            - "443:8443"
            - "7999:7997"

nginx.conf (inside the nginx container)

stream {
    server {
        listen 7997;
        proxy_pass bitbucket1.cybertron.ninja:7998;
    }
}

And here's some output executed inside the nginx container:

root@6d123f454eef:/# netstat -pnlt
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name                                                                        
tcp        0      0 0.0.0.0:8080            0.0.0.0:*               LISTEN      10/nginx: master pr                                                                     
tcp        0      0 0.0.0.0:8443            0.0.0.0:*               LISTEN      10/nginx: master pr                                                                     
tcp        0      0 127.0.0.11:44703        0.0.0.0:*               LISTEN      -            

Any ideas how to fix this issue? I'm stumped.

MikeyE
  • 125
  • 10
  • Do you have iptables, firewalld, or any other firewall running? – tilleyc Sep 19 '21 at 03:45
  • Looks like nginx is not reading your config file. Where did you put it? Is it included in the main config? – Gerald Schneider Sep 19 '21 at 10:17
  • @tilleyc iptables is running, but no custom rules are defined, only the ones automatically defined by dockerd. – MikeyE Sep 23 '21 at 03:11
  • @GeraldSchneider here is an excerpt from `docker-compose.yaml`: volumes: - ./configs/nginx:/etc/nginx/conf.d:ro. I can confirm that nginx is indeed reading its config files. If it wasn't it would not proxy ports 80->8080 or 443->8443. – MikeyE Sep 23 '21 at 03:13
  • 1
    Your netstat output from inside the container does not show the port 7997 from your config. If you added that config later, did you restart the container? – Gerald Schneider Sep 23 '21 at 04:57

1 Answers1

1

I just set up a testing environment for your case with the little information you provide. Assuming what you provided is everything you changed, this can't work.

The default nginx.conf inside the official nginx container has the include directive inside a http block:

http {
    # ...
    include /etc/nginx/conf.d/*.conf;
}

If you just place your .conf file into the conf.d directory nginx will fail with the following error message:

2021/09/23 05:58:30 [emerg] 1#1: "stream" directive is not allowed here in /etc/nginx/conf.d/blah.conf:1

Since your nginx is running I can only assume you placed the config into the directory after it started and didn't restart or reload nginx.

The stream directive must be in the root of the configuration, you need to provide a modified nginx.conf as well.

Copy the nginx.conf from your container:

docker cp test_nginx_1:/etc/nginx/nginx.conf .

Add your config there, or add a second include directive with a separate directory and mount it as a volume as well:

For example, add outside of the http {} block:

include /etc/nginx/conf.stream.d/*.conf;

Add this into your docker-compose.yml

services:
nginx:
    image: nginx
    volumes:
        - ./config/nginx.conf:/etc/nginx/nginx.conf:ro
        - ./config/nginx:/etc/nginx/conf.d:ro
        - ./config/nginx_stream:/etc/nginx/conf.stream.d:ro

run docker-compose up -d, and it works.

Gerald Schneider
  • 19,757
  • 8
  • 52
  • 79