[Solved] Cannot configure API address: Unable to call https://172.24.0.4:9000/api/

Hello there!
I saw many similar topics,
but, I believe here’s something different:

I’m trying to setup SSL (LetsEncrypt suff) for my Graylog setup, using Docker Compose.

I’m stuck with the following error:
( “https+://” - I’m new user. 2 links limit. )

graylog_1 | 2020-12-01 19:20:31,382 WARN : org.graylog2.shared.rest.resources.ProxiedResource - Unable to call https+://172.24.0.4:9000/api/system/metrics/multiple on node <b9d3468d-d294-439e-9e04-747876c2e448>: Hostname 172.24.0.4 not verified:

I’m setting HTTPS for my domain - mydomain.example.com.
And what seems most strange to me, - I can go to https+://mydomain.example.com:9000/api/system/metrics/multiple
yes, on port 9000 with, yes, all the LetsEncrypt SSL stuff.
So SSL is working for me!
Good.

But I cannot make Graylog go to API by mydomain.example.com.
It always goes to 172.24.0.4!
That’s really frustrating.
I’ve lost whole day, trying to configure this address.
Looks like played with all the “puzzles” with GRAYLOG_WEB_ENDPOINT_URI, GRAYLOG_REST_TRANSPORT_URI, GRAYLOG_HTTP_EXTERNAL_URI, GRAYLOG_REST_LISTEN_URI etc.

Here’s my actual docker-compose.yml:
( “https+://” - I’m new user. 2 links limit. )

version: '2'

volumes:
  local_storage_nosql:

services:
  nosql:
    image: mongo:4.0
    volumes:
      - local_storage_nosql:/data/db
      - ./graylog.js:/docker-entrypoint-initdb.d/graylog.js:ro
    environment:
    # provide your credentials here
    - MONGO_INITDB_ROOT_USERNAME=root
    - MONGO_INITDB_ROOT_PASSWORD=kjhgjkhgjkhgjkhgjkhgk
    ports:
      - 27017:27017

  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.10.0
    environment:
      - http.host=0.0.0.0
      - discovery.type=single-node
      - xpack.security.enabled=false
      - transport.host=localhost
      - network.host=0.0.0.0
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"

  graylog:
    image: graylog/graylog:4.0
    volumes:
      - ./g.crt:/usr/share/graylog/data/config/ssl/cert.crt:ro
      - ./g.key:/usr/share/graylog/data/config/ssl/key.key:ro
      - ./newkeystore.jks:/usr/share/graylog/ssl/certs/graylog-cacerts.jks:ro
    environment:
      - GRAYLOG_IS_MASTER=true
      - GRAYLOG_PASSWORD_SECRET=STlvln2h5I2OsF0Hz0ebJSZG9SzJ0NYpnQTyRh3VJ2aVQ95cWwcTXSzgMU18ryNSsG2n9Voj4q7dFZqhwrNC1gvZd3VDLTPY
      - GRAYLOG_ROOT_PASSWORD_SHA2=9a3f982d63aee554970b640fcec5688378756e3e1eda0829495a7b59c395188b
      - GRAYLOG_HTTP_ENABLE_GZIP=true
      - GRAYLOG_HTTP_ENABLE_TLS=true
      - GRAYLOG_HTTP_TLS_CERT_FILE=/usr/share/graylog/data/config/ssl/cert.crt
      - GRAYLOG_HTTP_TLS_KEY_FILE=/usr/share/graylog/data/config/ssl/key.key
      - GRAYLOG_MONGODB_URI=mongodb://graylog:dfgdgdfgdgdfgdfg@nosql:27017/graylog
      - GRAYLOG_MESSAGE_JOURNAL_ENABLED=false
      - GRAYLOG_SERVER_JAVA_OPTS=-Djavax.net.ssl.trustStore=/usr/share/graylog/ssl/certs/graylog-cacerts.jks -Djavax.net.ssl.trustStorePassword=secret
      - GRAYLOG_REST_TRANSPORT_URI=https://mydomain.example.com:9000/
      - GRAYLOG_WEB_ENDPOINT_URI=https+://mydomain.example.com:9000/api/
      - GRAYLOG_REST_LISTEN_URI=https+://mydomain.example.com:9000/api/
      - GRAYLOG_WEB_LISTEN_URI=https+://mydomain.example.com:9000/
      - GRAYLOG_ELASTICSEARCH_HOSTS=https+://elasticsearch:9200
      - GRAYLOG_ELASTICSEARCH_VERSION=7
    depends_on:
      - nosql
      - elasticsearch
    ports:
      - "9000:9000"
      - "12201:12201/tcp"
      - "12201:12201/udp"

Please, help.
I’m totally lost.

P.S.
"https+://" - I’m new user. 2 links limit.

Hello @dimedrol, welcome!

When you say “make Graylog go to API by mydomain.example.com”, what do you mean? How are you directing Graylog to this URL?

The Graylog JVM trust store includes trust for major root CAs by default I believe, but I don’t know if that includes LetsEncrypt. You may need to add the certificate chain to the trust store for this to work for you.

Thanks, @ttsandrew !

As I wrote above - all the ssl-stuff already added.
I followed tons of instructions from the i-net.
But IP address which is used to access “backend” REST API is not related with certificate in any way.

The main problem is - whatever I did, GrayLog always tries to use internal (Docker network?) IP (172.24.0.4) -

 Unable to call https://172.24.0.4:9000

I want to configure GrayLog, so it use https://mydomain.example.com:9000/api… for REST calls.
Because I can access this SSL-ed address from browser.

But, I cannot tell GrayLog to use this DNS. It always goes to internal IP.

Are you setting http_bind_address?

#### HTTP bind address
#
# The network interface used by the Graylog HTTP interface.
#
# This network interface must be accessible by all Graylog nodes in the cluster and by all clients
# using the Graylog web interface.
#
# If the port is omitted, Graylog will use port 9000 by default.
#
# Default: 127.0.0.1:9000
 http_bind_address = 10.1.1.100:9000
#http_bind_address = [2001:db8::1]:9000

According to my docker-compose shown above - no. (this time)
Which value should I use for http_bind_address (GRAYLOG_HTTP_BIND_ADDRESS) for this HTTPS case?
GRAYLOG_HTTP_BIND_ADDRESS=https://mydomain.example.com:9000 ?

Update:
When using:

- GRAYLOG_HTTP_BIND_ADDRESS=mydomain.example.com:9000

Result:

graylog_1| Suppressed: com.google.common.util.concurrent.ServiceManager$FailedService: JerseyService [FAILED]
graylog_1| Caused by: java.net.BindException: Cannot assign requested address

When using:

- GRAYLOG_HTTP_BIND_ADDRESS=https://mydomain.example.com:9000

Result: stuck on starting.

those settings are no longer needed or given in Graylog.

As @ttsandrew pointed our your new settings are http_bind_* those. You really want to read the docs what those settings should be and not guess: https://docs.graylog.org/en/4.0/pages/configuration/server.conf.html#web-rest-api

@jan thanks for answer.
As I wrote above - “I followed tons of instructions from the i-net” , including official documentation.
OK, now my config looks like this:

  graylog:
    image: graylog/graylog:4.0
    volumes:
      - ./g.crt:/usr/share/graylog/data/config/ssl/cert.crt:ro
      - ./g.key:/usr/share/graylog/data/config/ssl/key.key:ro
      - ./newkeystore.jks:/usr/share/graylog/ssl/certs/graylog-cacerts.jks:ro
    environment:
      - GRAYLOG_IS_MASTER=true
      - GRAYLOG_PASSWORD_SECRET=STlvln2h5I2OsF0Hz0ebJSZG9SzJ0NYpnQTyRh3VJ2aVQ95cWwcTXSzgMU18ryNSsG2n9Voj4q7dFZqhwrNC1gvZd3VDLTPY
      - GRAYLOG_ROOT_PASSWORD_SHA2=9a3f982d63aee554970b640fcec5688378756e3e1eda0829495a7b59c395188b
      - GRAYLOG_HTTP_ENABLE_TLS=true
      - GRAYLOG_HTTP_TLS_CERT_FILE=/usr/share/graylog/data/config/ssl/cert.crt
      - GRAYLOG_HTTP_TLS_KEY_FILE=/usr/share/graylog/data/config/ssl/key.key
      - GRAYLOG_MONGODB_URI=mongodb://graylog:Spiffy93Bright55Ladybug59@nosql:27017/graylog
      - GRAYLOG_MESSAGE_JOURNAL_ENABLED=false
      - GRAYLOG_SERVER_JAVA_OPTS=-Djavax.net.ssl.trustStore=/usr/share/graylog/ssl/certs/graylog-cacerts.jks -Djavax.net.ssl.trustStorePassword=secret
      - GRAYLOG_HTTP_EXTERNAL_URI=https://mydomain.example.com:9000/
      - GRAYLOG_HTTP_BIND_ADDRESS=0.0.0.0:9000
      - GRAYLOG_ELASTICSEARCH_HOSTS=http://elasticsearch:9200
      - GRAYLOG_ELASTICSEARCH_VERSION=7
    depends_on:
      - nosql
      - elasticsearch
    ports:
      - "9000:9000"
      - "12201:12201/tcp"
      - "12201:12201/udp"

No changes in result.
See the logs:

WHY Graylog keep trying this internal 172.24.0.4 address for REST API ?!
I want Graylog to use Letsencrypt-certified external address.
How to configure it?
This external address is up and running perfectly well.

Here’s my Graylog welcome screen, which is working and HTTPS-enabled:

REST API is accessible and protected by user/pass (just like home page):

…and it’s working (with all the SSLs and so on)

So, as I said, looks like SSL itself is not a problem.
The main problem - how to configure GrayLog to use external DNS-name for REST calls…

@ttsandrew , @jan - any toughts?..

he @dimedrol

Graylog will connect to itself for various reasons. This connection is done to the http_publish_uri- means your certificate need to include the hostname/ip that is configured for that

From the docs ( https://docs.graylog.org/en/4.0/pages/configuration/server.conf.html#web-rest-api )

  • The HTTP URI of this Graylog node which is used to communicate with the other Graylog nodes in the cluster and by all clients using the Graylog web interface.
  • The URI will be published in the cluster discovery APIs, so that other Graylog nodes will be able to find and connect to this Graylog node.
  • This configuration setting has to be used if this Graylog node is available on another network interface than $http_bind_address, for example if the machine has multiple network interfaces or is behind a NAT gateway.
  • This configuration setting must not be configured to a wildcard address!
  • If http_bind_address contains a wildcard IPv4 address (0.0.0.0), http_publish_uri will be filled with the first non-loopback IPv4 address of this machine instead.

so you need to make that include the right protocol via configuration PLUS the certificate need to be valid for that configured ip/hostname.

Wooohoooo!!!
This was a missing part of my “puzzle”! (in particular combination!) - GRAYLOG_HTTP_PUBLISH_URI=https://mydomain.example.com:9000/
Thank you @jan so much for idea!
So, for everyone, - this is my working docker-compose.yml:

version: '3'

volumes:
  local_storage_nosql:

services:
  nosql:
    image: mongo:4.0
    volumes:
      - local_storage_nosql:/data/db
      - ./graylog.js:/docker-entrypoint-initdb.d/graylog.js:ro
    network_mode: "host"
    # Due to HOST network, open MONGODB only for local interface:
    command: mongod --bind_ip 127.0.0.1
    environment:
    # provide your credentials here
    - MONGO_INITDB_ROOT_USERNAME=root
    - MONGO_INITDB_ROOT_PASSWORD=passwordpasswordpassword
    ports:
      - 27017:27017
    
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.10.0
    network_mode: "host"
    # Due to HOST network, open ELASTICSEARCH only for local interface (127.0.0.1)
    environment:
      - http.host=127.0.0.1
      - discovery.type=single-node
      - xpack.security.enabled=false
      - transport.host=localhost
      - network.host=127.0.0.1
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"

  graylog:
    image: graylog/graylog:4.0
    # Using HOST network, for easier GrayLog self-requests. ATTN! Firewall rules!
    network_mode: "host"
    volumes:
      - ./g.crt:/usr/share/graylog/data/config/ssl/cert.crt:ro
      - ./g.key:/usr/share/graylog/data/config/ssl/key.key:ro
    environment:
      - GRAYLOG_ROOT_TIMEZONE=Europe/Riga
      - GRAYLOG_IS_MASTER=true
      # CHANGE ME!
      - GRAYLOG_PASSWORD_SECRET=STlvln2h5I2OsF0Hz0ebJSZG9SzJ0NYpnQTyRh3VJ2aVQ95cWwcTXSzgMU18ryNSsG2n9Voj4q7dFZqhwrNC1gvZd3VDLTPY
      - GRAYLOG_ROOT_PASSWORD_SHA2=9a3f982d63aee554970b640fcec5688378756e3e1eda0829495a7b59c395188b
      - GRAYLOG_HTTP_ENABLE_GZIP=true
      - GRAYLOG_HTTP_ENABLE_TLS=true
      - GRAYLOG_HTTP_TLS_CERT_FILE=/usr/share/graylog/data/config/ssl/cert.crt
      - GRAYLOG_HTTP_TLS_KEY_FILE=/usr/share/graylog/data/config/ssl/key.key
      - GRAYLOG_MONGODB_URI=mongodb://graylog:passwordpasswordpassword@127.0.0.1:27017/graylog
      - GRAYLOG_MESSAGE_JOURNAL_ENABLED=false
      - GRAYLOG_HTTP_EXTERNAL_URI=https://mydomain.example.com:9000/
      - GRAYLOG_HTTP_PUBLISH_URI=https://mydomain.example.com:9000/
      - GRAYLOG_HTTP_BIND_ADDRESS=0.0.0.0:9000
      - GRAYLOG_ELASTICSEARCH_HOSTS=http://127.0.0.1:9200
      - GRAYLOG_ELASTICSEARCH_VERSION=7
    depends_on:
      - nosql
      - elasticsearch
    ports:
      - "9000:9000"
      - "12201:12201/tcp"
      - "12201:12201/udp" 

And notice - there’s no any mentions of *.JKS (Java Key Storage) files, related Java settings, etc.
SSL/HTTPS is working with only 2 files - cert.crt and key.key which were received from LetsEncrypt CertBot for mydomain.example.com

Job’s done.

1 Like

@dimedrol

just to be complete - you do not need a custom JKS, because you use lets-encrypt certificates that can be verified with the given CAs on a default debian system (what the image based on). If you had created your own self-signed certificates it would have been different.

In addition when http_external_uri and http_publish_uri are the same - only the later one is needed to be defined. As the default of http_external_uri is what is in http_publish_uri.

Plus this is all working in your environment because mydomain.example.com is also resolvable to the container IP … (or Graylog is able to reach itself over that domain name to be exact).

Yes, @jan good point.
And I’ve updated docker-compose configuration above:

  1. Using Compose version 3
  2. Using HOST network
  3. Restricting MongoDB and ElasticSearch to local interface only (due to HOST network)

I’ve updated to Docker HOST network, because I’ve experienced some problems on other “clean” host,
GrayLog said:

WARN  [ProxiedResource] Unable to call http://mydomain.example.com:9000/api/system/metrics/multiple on node <8sj4991c-ed04-4005-8ad5-c17fd7f443fd>
java.net.SocketTimeoutException: connect timed out

So, the HOST network for Docker solved this problem.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.