4

Docker File

# Start from the latest golang base image
FROM golang:latest

# Add Maintainer Info
LABEL maintainer="Sumit Thakur <sumitthakur@yahoo.com>"

# Set the Current Working Directory inside the container
WORKDIR /app

# Copy go mod and sum files
COPY go.mod go.sum ./

# Download all dependencies. Dependencies will be cached if the go.mod and go.sum files are not changed
RUN go mod download

# Copy the source from the current directory to the Working Directory inside the container
COPY . .

# Build the Go app
RUN go build -o testapp myapplication.go testapp.go

# Expose port 50051 / for internal comunication 

ENV PORT 50051
RUN echo $PORT

EXPOSE ${PORT}

# Command to run the executable
CMD ["./testapp"]

Build Docker file with

docker build -t testapp  -f Dockerfile .

that's perfect working

Run Docker file

docker run -d -p 50051:50051 testapp

that's will also working fine

I check with the running container

docker ps

this will give me

CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                      NAMES
57cd3c01bcda        testapp           "./testapp"       2 seconds ago       Up 2 seconds        0.0.0.0:50051->50051/tcp   gracious_bhaskara

and when i check the network inspect with

docker network inspect bridge

this will give me

[
    {
        "Name": "bridge",
        "Id": "30850a823d3040e7d8eaf804c122ce3d26b35650f6f792cf1f4ce77d66167eeb",
        "Created": "2020-02-19T07:34:24.993299775Z",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.17.0.0/16",
                    "Gateway": "172.17.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "57cd3c01bcda3fbf7d0bf67136ebbb8afb312c4f6ca70eeee15cda6e10fff4e2": {
                "Name": "gracious_bhaskara",
                "EndpointID": "2a42056609e8140d190f1efde41320138867d3905053e7f381bd91b1f053c251",
                "MacAddress": "02:42:ac:11:00:02",
                "IPv4Address": "172.17.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {
            "com.docker.network.bridge.default_bridge": "true",
            "com.docker.network.bridge.enable_icc": "true",
            "com.docker.network.bridge.enable_ip_masquerade": "true",
            "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
            "com.docker.network.bridge.name": "docker0",
            "com.docker.network.driver.mtu": "1500"
        },
        "Labels": {}
    }
]

Everthing works fine Except when i trying to connect the docker host

curl -H "Content-type:application/json" -X GET 'https://localhost:50051/testapp/v1/order'
or
curl -H "Content-type:application/json" -X GET 'https://172.17.0.2:50051/testapp/v1/order'

it gives me

Note: Unnecessary use of -X or --request, GET is already inferred.
*   Trying 0.0.0.0...
* TCP_NODELAY set
* Connected to 0.0.0.0 (127.0.0.1) port 50051 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/cert.pem
  CApath: none
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* error:1400410B:SSL routines:CONNECT_CR_SRVR_HELLO:wrong version number
* stopped the pause stream!
* Closing connection 0
curl: (35) error:1400410B:SSL routines:CONNECT_CR_SRVR_HELLO:wrong version number

Test openssl:

openssl s_client https://localhost:50051/testapp/v1/order -connect localhost:50051 

Result:

CONNECTED(00000005)
4488771180:error:140040E5:SSL routines:CONNECT_CR_SRVR_HELLO:ssl handshake failure:/BuildRoot/Library/Caches/com.apple.xbs/Sources/libressl/libressl-22.200.4/l
ibressl-2.6/ssl/ssl_pkt.c:585:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 0 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : 0000
    Session-ID: 
    Session-ID-ctx: 
    Master-Key: 
    Start Time: 1582109828
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)
---

Application Code

package main

import (
    "io"
    "net/http"
    "github.com/gorilla/handlers"
)
func main() {
    http.HandleFunc("/testapp/v1/order", testHandler)
    headersOk := handlers.AllowedHeaders([]string{""})
    http.ListenAndServe(":50051", headersOk)
}
func testHandler(w http.ResponseWriter, r *http.Request) {
    io.WriteString(w, "Heyyy!")
}

Anyone Help I'm stuck here 1-2 days don't know what to do ?

Sumit Bon
  • 49
  • 1
  • 1
  • 6
  • Are you able to curl the endpoint inside the container? – alessiosavi Feb 19 '20 at 08:39
  • yes if i do `docker exec -it bash` and execute `./testapp` and then i hit curl it will give me the result – Sumit Bon Feb 19 '20 at 08:43
  • I don't understand why i'm not able to curl from system. I just stuck there. – Sumit Bon Feb 19 '20 at 08:45
  • 2
    Please, use `curl -H "Content-type:application/json" -X GET 'http://localhost:50051/testapp/v1/order' -v` and post the output. Have a look on the log server side. Probably you hit `http` instead of `https`. – alessiosavi Feb 19 '20 at 08:50
  • thanks,it will now show's me `curl: (35) LibreSSL SSL_connect: SSL_ERROR_SYSCALL in connection to localhost:50051 ` – Sumit Bon Feb 19 '20 at 08:56
  • Can you include the actual application code that's setting up the network listener in the question? It matters what the bind address is, and if there's TLS-related setup. – David Maze Feb 19 '20 at 11:18
  • Hi @DavidMaze i update the application code in above please check its a basic server code in golang. – Sumit Bon Feb 19 '20 at 11:48
  • If your server binds to `localhost` as you've shown it will be inaccessible from outside the current container. Try changing the bind address in the `ListenAndServe` call to `:50051` with no specific host (or to `0.0.0.0:50051` to match the pattern in other languages). – David Maze Feb 19 '20 at 11:52
  • i did that but it shows me now `curl: (35) error:1400410B:SSL routines:CONNECT_CR_SRVR_HELLO:wrong version number` – Sumit Bon Feb 19 '20 at 12:06

3 Answers3

1

From the discussion in the comment, the problem seems related to the https handshake.

A simple solution, is to query the service using the following URL:

curl -H "Content-type:application/json" -X GET 'https://localhost:50051/testapp/v1/order' -v -k

Using the -k, you are going to ignore the HTTPS validation.

NOTE: i've changed the URL from http to https.

alessiosavi
  • 2,753
  • 2
  • 19
  • 38
  • it will give me now `curl: (35) LibreSSL SSL_connect: SSL_ERROR_SYSCALL in connection to localhost:50051 ` – Sumit Bon Feb 19 '20 at 09:03
  • are you sure that you are using the `https` site instead of the `http`? In this case, please run these command and post the output: `openssl s_client https://localhost:50051/testapp/v1/order-connect` and `gnutls-cli https://localhost:50051/testapp/v1/order` – alessiosavi Feb 19 '20 at 09:20
  • I update input/output for openssl s_client in above. Please check – Sumit Bon Feb 19 '20 at 10:31
0

From inside the container, you need to listen on all interfaces, not localhost or the loopback interface. Networking is namespaced in docker, so you get not only a new private ip, but also a separate loopback interface inside the container that cannot be reached externally. To do this, change:

http.ListenAndServe("localhost:50051", headersOk)

To:

http.ListenAndServe(":50051", headersOk)
BMitch
  • 231,797
  • 42
  • 475
  • 450
  • yeah i changed that i'll update above but this when i hit curl it will give me `curl: (35) error:1400410B:SSL routines:CONNECT_CR_SRVR_HELLO:wrong version number` – Sumit Bon Feb 19 '20 at 12:26
  • 1
    @SumitBon there's no SSL configured here, go back to your original curl command from your question, http, not https. – BMitch Feb 19 '20 at 13:07
  • i did that but here's the problem i'm facing if i run the curl inside the **docker container** it works fine but from **system** it gave me result `curl: (7) Failed to connect to 0.0.0.0 port 50051: Connection refused` **doesn't understand why this happens** – Sumit Bon Feb 20 '20 at 06:12
  • @SumitBon your original command did not curl to `0.0.0.0`, it was to `localhost`, use the original curl command. – BMitch Feb 20 '20 at 14:26
0
  1. The code provided on main.go does not start TLS, so stop tring to curl with https, it won't works. curl with http will work

    package main
    
    import (
        "io"
        "net/http"
    
        "github.com/gorilla/handlers"
    )
    
    func main() {
        http.HandleFunc("/testapp/v1/order", testHandler)
        headersOk := handlers.AllowedHeaders([]string{""})
        http.ListenAndServe(":50051", headersOk)
    }
    func testHandler(w http.ResponseWriter, r *http.Request) {
        io.WriteString(w, "Heyyy!")
    }
    
  2. The command openssl s_client https://localhost:50051/testapp/v1/order -connect localhost:50051 confirm to you that TLS is not present on the port you requested

  3. Lot of comments confirm that using https is not relevant, again TLS is not activated on your code

  4. curl -H "Content-type:application/json" -X GET 'http://localhost:50051/testapp/v1/order' works. That confirm again TLS is not used

Conclusion:

Do not try to curl https when TLS is not activated on your code

J-Jacques M
  • 978
  • 6
  • 16
  • thanks i got your point totally understand but here's my problem everything goes perfect except if i run the curl inside the container it works fine but from system it gave me result `curl: (7) Failed to connect to 0.0.0.0 port 50051: Connection refused` – Sumit Bon Feb 20 '20 at 06:14