Katello related links return empty content when accessing through a Load balancer

Problem:
I’m trying to expose only the WEB UI (port 443) to the internet. For this, i set up, on AWS, an ALB with it’s own valid certificate (*.myexample.myorgdce.net).
The LB forwards puppet.myexample.myorgdce.net HTTPS requests to my foreman/katello instance (puppet.myexample.example.eu.myorg.cloud) on port 443.


The Foreman Web UI displays everything well (puppet hosts and reports…), EXCEPT when i try to hit anything related to Katello:

If i access directly the node, on port 443 , ALL is good.

[root@puppet ~]# curl -vv [https://$(hostname)/katello/api](https://%24%28hostname%29/katello/api) -u admin:$foreman_password

* About to connect() to puppet.myexample.myorgdce.eu.MyOrg.cloud port 443 (#0)
* Trying 10.250.43.115...
* Connected to puppet.myexample.myorgdce.eu.MyOrg.cloud (10.250.43.115) port 443 (#0)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
* CAfile: /etc/pki/tls/certs/ca-bundle.crt
CApath: none
* NSS: client certificate not found (nickname not specified)
* SSL connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
* Server certificate:
* subject: CN=puppet.myexample.myorgdce.eu.MyOrg.cloud,OU=BDS,O=MyOrg,ST=confusion,C=FR
* start date: Oct 07 09:37:37 2019 GMT
* expire date: Jan 18 09:37:37 2038 GMT
* common name: puppet.myexample.myorgdce.eu.MyOrg.cloud
* issuer: CN=puppet.myexample.myorgdce.eu.MyOrg.cloud,OU=BDS,O=MyOrg,L=Puteaux,ST=confusion,C=FR
* Server auth using Basic with user 'admin'

> GET /katello/api HTTP/1.1
> Authorization: Basic YWRtaW46Y2hhbmdlbWU=
> User-Agent: curl/7.29.0
> Host: puppet.myexample.myorgdce.eu.MyOrg.cloud
> Accept: */*

* NSS: client certificate not found (nickname not specified)
< HTTP/1.1 200 OK
< Date: Mon, 14 Oct 2019 11:14:56 GMT
< Server: Apache
< Foreman_version: 1.23.0
< Foreman_api_version: 2
< Foreman_current_organization: ; ANY
< Foreman_current_location: ; ANY
< Cache-Control: max-age=0, private, must-revalidate
< X-Request-Id: 65925d80-e9d2-42eb-b55b-29e8cebf2465
< X-Runtime: 0.026091
< Vary: Origin,Accept-Encoding
< Strict-Transport-Security: max-age=631139040; includeSubdomains
< X-Frame-Options: sameorigin
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< X-Download-Options: noopen
< X-Permitted-Cross-Domain-Policies: none
< Content-Security-Policy: default-src 'self'; child-src 'self'; connect-src 'self' ws: wss:; img-src 'self' data: *.gravatar.com; script-src 'unsafe-eval' 'unsafe-inline' 'self'; style-src 'unsafe-inline' 'self'
< X-Powered-By: Phusion Passenger 4.0.53
< Set-Cookie: _session_id=6d802c02667a07f38de6b19bec7c3cfe; path=/; secure; HttpOnly; SameSite=Lax
< ETag: W/"664bb5e71fe763682396198fa4a26885"
< Status: 200 OK
< Transfer-Encoding: chunked
< Content-Type: application/json; charset=utf-8
<
[{"href":"/katello/api/capsules/","rel":"capsules"},{"href":"/katello/api/activation_keys/","rel":"activation_keys"},{"href":"/katello/api/activation_keys/","rel":"activation_keys"},{"href":"/katello/api/activation_keys/","rel":"activation_keys"},{"href":"/katello/api/activation_keys/","rel":"activation_keys"},[...]{"href":"/katello/api/sync_plans/","rel":"sync_plans"}]

When i try to access through the LB : the request times out. Performing a foreman-tail suggests that foreman is never reached by the request.
Same goes with synch_plans, views, (anything in the content tab) : page is displayed empty. And trying to create an item through the web ui results in a time out, with item not created.

[root@puppet ~]# curl -vv [https://puppet.myorgdce.MyOrgdce.net/katello/api](https://puppet.myorgdce.myorgdce.net/katello/api) -u admin:$foreman_password

* About to connect() to puppet.myorgdce.MyOrgdce.net port 443 (#0)
* Trying 54.71.4.241...
* Connected to puppet.myorgdce.MyOrgdce.net (54.71.4.241) port 443 (#0)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
* CAfile: /etc/pki/tls/certs/ca-bundle.crt
CApath: none
* SSL connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
* Server certificate:
* subject: CN=*.myorgdce.myorgdce.net
* start date: Oct 14 00:00:00 2019 GMT
* expire date: Nov 14 12:00:00 2020 GMT
* common name: *.myorgdce.MyOrgdce.net
* issuer: CN=Amazon,OU=Server CA 1B,O=Amazon,C=US
* Server auth using Basic with user 'admin'

> GET /katello/api HTTP/1.1
> Authorization: Basic YWRtaW46Y2hhbmdlbWU=
> User-Agent: curl/7.29.0
> Host: puppet.myorgdce.MyOrgdce.net
> Accept: */*

* Connection state changed (MAX_CONCURRENT_STREAMS == 128)!
< HTTP/2 504
< server: awselb/2.0
< date: Mon, 14 Oct 2019 11:21:20 GMT
< content-type: text/html
< content-length: 148
<
<html>
<head><title>504 Gateway Time-out</title></head>
<body bgcolor="white">
<center><h1>504 Gateway Time-out</h1></center>
</body>
</html>

Backend System Status : Stays empty when hit through the LB, but hammer ping on the host is OK

root@puppet ~]# hammer ping
candlepin:
Status: ok
Server Response: Duration: 34ms
candlepin_auth:
Status: ok
Server Response: Duration: 13ms
pulp:
Status: ok
Server Response: Duration: 33ms
pulp_auth:
Status: ok
Server Response: Duration: 27ms
foreman_tasks:
Status: ok
Server Response: Duration: 3ms

What would be the points i need to check in order to cover my bases?
Any prerequisites i need to check to have katello work behind a Loadbalancer?

Expected outcome:
Katello contents should be displayed in the UI whether hitting it through the load balancer (NOK) or directly through the node (OK)

Foreman and Proxy versions:
foreman-proxy-1.23.0-1.el7.noarch
foreman-release-1.23.0-1.el7.noarch
foreman-release-scl-7-2.el7.noarch

Foreman and Proxy plugin versions:

Other relevant data:

#/etc/foreman-installer/scenarios.d/katello-answers.yaml (cert section) :
certs:
   params:
      node_fqdn: "%{::fqdn}"
      cname: ['puppet.myexample.myorgdce.net']
      regenerate: false
      regenerate_ca: false
      generate: true
      deploy: true
      ca_common_name: "%{::fqdn}"
      country: "FR"
      state: "confusion"
      city: "Puteaux"
      org: "MYORG"
      org_unit: "BDS"
      expiration: "36500"
      ca_expiration: "36500"
      user: "root"
      group: "foreman"

#Foreman installer command:
/usr/sbin/foreman-installer -v \
--scenario katello \
--enable-foreman-compute-ec2 \
--foreman-initial-admin-password=$foreman_password \
--enable-foreman-plugin-ansible \
--enable-foreman-plugin-monitoring \
--enable-foreman-plugin-templates \
--enable-foreman-plugin-remote-execution \
--enable-foreman-plugin-openscap \
--foreman-proxy-dhcp=false \
--foreman-proxy-dns=false \
--foreman-initial-organization=$foreman_default_organization \
--foreman-cors-domains=https://puppet.myexample.myorgdce.net

The foreman-tail does give a lot of theses, but am unable to pinpoint articles to help solve that one

[Mon Oct 14 16:43:59.852788 2019] [ssl:error] [pid 25732] [client 10.250.43.41:39178] AH02261: Re-negotiation handshake failed, referer: https://puppet.myorgdce.myorgdce.net/lifecycle_environments
[Mon Oct 14 16:43:59.855985 2019] [ssl:error] [pid 26172] [client 10.250.43.41:39170] AH02261: Re-negotiation handshake failed, referer: https://puppet.myorgdce.myorgdce.net/lifecycle_environments
[Mon Oct 14 16:44:10.927181 2019] [ssl:error] [pid 26175] [client 10.250.43.41:39352] AH02261: Re-negotiation handshake failed, referer: https://puppet.myorgdce.myorgdce.net/lifecycle_environments
[Mon Oct 14 16:44:10.928024 2019] [ssl:error] [pid 26957] [client 10.250.43.41:39410] AH02261: Re-negotiation handshake failed, referer: https://puppet.myorgdce.myorgdce.net/content_views
[Mon Oct 14 16:44:10.928117 2019] [ssl:error] [pid 27166] [client 10.250.43.41:39350] AH02261: Re-negotiation handshake failed, referer: https://puppet.myorgdce.myorgdce.net/lifecycle_environments
[Mon Oct 14 16:44:21.751302 2019] [ssl:error] [pid 27049] [client 10.250.43.41:39444] AH02261: Re-negotiation handshake failed, referer: https://puppet.myorgdce.myorgdce.net/content_views
[Mon Oct 14 16:54:13.600669 2019] [ssl:error] [pid 29757] [client 10.250.43.41:43238] AH02261: Re-negotiation handshake failed, referer: https://puppet.myorgdce.myorgdce.net/about
[Mon Oct 14 16:54:52.129916 2019] [ssl:warn] [pid 30602] [client 10.250.43.110:38782] AH02227: Failed to set r->user to 'SSL_CLIENT_S_DN_CN'
[Mon Oct 14 16:54:52.156119 2019] [ssl:warn] [pid 30360] [client 10.250.43.110:38784] AH02227: Failed to set r->user to 'SSL_CLIENT_S_DN_CN'
[Mon Oct 14 16:54:52.925920 2019] [ssl:warn] [pid 30373] [client 10.250.43.110:38810] AH02227: Failed to set r->user to 'SSL_CLIENT_S_DN_CN'
[Mon Oct 14 16:54:52.951505 2019] [ssl:warn] [pid 30375] [client 10.250.43.110:38812] AH02227: Failed to set r->user to 'SSL_CLIENT_S_DN_CN'
[Mon Oct 14 16:55:03.308002 2019] [ssl:warn] [pid 30604] [client 10.250.43.110:38974] AH02227: Failed to set r->user to 'SSL_CLIENT_S_DN_CN'
[Mon Oct 14 16:55:03.314570 2019] [ssl:warn] [pid 30464] [client 10.250.43.110:38976] AH02227: Failed to set r->user to 'SSL_CLIENT_S_DN_CN'

Hi @mmorizot

Are you using custom signed certs on the Katello/Foreman box? Also does the load balancer do SSL inspection or injection where it put’s it’s own CA into the traffic?

Do you have sticky connections setup on the load balancer as well for each of the services/ports running on the Katello/Foreman box?

hey, thanks for the reply :

Are you using custom signed certs on the Katello/Foreman box?
yes, i only modified the certs parameters according to the “certs” part listed in my post.
Then i leave it to the foreman installer to do it’s voodoo.

Also does the load balancer do SSL inspection or injection where it put’s it’s own CA into the traffic?
The load balancer uses the certificate to terminate the connection and decrypt requests from clients before routing them to the node (where foreman/katello reside).

Do you have sticky connections setup on the load balancer as well for each of the services/ports running on the Katello/Foreman box?
No, since i currently have only one node behind the LB, i did not think using a sticky connection was needed.

I’m using an Amazon ALB, which only (intended) purpose is to forward internet traffic (ie, the web UI part) to the foreman/katello box on port 443.
All the other ports are only open inside the network, but are not exposed to the internet.

The “strange part” from the WEB UI, is that all of foreman’s content is displayed properly. But when i try to display content views, sync_plans, lifecycle_environments, activation_keys, the form comes back empty with only headers displayed (filter form + create button), but the table that is supposed to be displayed under, only returns table headers… but no content.

Note: the sync_status button does display my product with the drop down showing my synchs… but that’s the only “katello” content i get to see.
in the “about” tab, all content EXCEPT “Backend System Status” is displayed. it’s like it’s trying to connect to somewhere, but never succeeds.

Interresting side fact : when i display the /katello/api endpoint, some enpoints appear 4 times (those that are not working for me) :

curl -vv  https://puppet.public-loadbalancer.net/katello/api
* TCP_NODELAY set
* Expire in 149996 ms for 3 (transfer 0x5576337d45c0)
* Expire in 200 ms for 4 (transfer 0x5576337d45c0)
* Connected to puppet.public-loadbalancer.net (50.112.67.57) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: none
  CApath: /etc/ssl/certs
} [5 bytes data]
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
} [512 bytes data]
* TLSv1.3 (IN), TLS handshake, Server hello (2):
{ [98 bytes data]
* TLSv1.2 (IN), TLS handshake, Certificate (11):
{ [4838 bytes data]
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
{ [333 bytes data]
* TLSv1.2 (IN), TLS handshake, Server finished (14):
{ [4 bytes data]
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
} [70 bytes data]
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
} [1 bytes data]
* TLSv1.2 (OUT), TLS handshake, Finished (20):
} [16 bytes data]
* TLSv1.2 (IN), TLS handshake, Finished (20):
{ [16 bytes data]
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN, server accepted to use h2
* Server certificate:
*  subject: CN=*.public-loadbalancer.net
*  start date: Oct 14 00:00:00 2019 GMT
*  expire date: Nov 14 12:00:00 2020 GMT
*  subjectAltName: host "puppet.public-loadbalancer.net" matched cert's "*.public-loadbalancer.net"
*  issuer: C=US; O=Amazon; OU=Server CA 1B; CN=Amazon
*  SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
} [5 bytes data]
* Using Stream ID: 1 (easy handle 0x5576337d45c0)
} [5 bytes data]
> GET /katello/api HTTP/2
> Host: puppet.public-loadbalancer.net
> User-Agent: curl/7.64.0
> Accept: */*
> 
{ [5 bytes data]
* Connection state changed (MAX_CONCURRENT_STREAMS == 128)!
} [5 bytes data]
< HTTP/2 200 
< date: Tue, 15 Oct 2019 14:25:16 GMT
< content-type: application/json; charset=utf-8
< server: Apache
< foreman_version: 1.23.0
< foreman_api_version: 2
< foreman_current_organization: ; ANY
< foreman_current_location: ; ANY
< cache-control: max-age=0, private, must-revalidate
< x-request-id: 9eeb8ea2-fd41-462c-9fde-124b70e3c869
< x-runtime: 0.024219
< vary: Origin,Accept-Encoding
< strict-transport-security: max-age=631139040; includeSubdomains
< x-frame-options: sameorigin
< x-content-type-options: nosniff
< x-xss-protection: 1; mode=block
< x-download-options: noopen
< x-permitted-cross-domain-policies: none
< content-security-policy: default-src 'self'; child-src 'self'; connect-src 'self' ws: wss:; img-src 'self' data: *.gravatar.com; script-src 'unsafe-eval' 'unsafe-inline' 'self'; style-src 'unsafe-inline' 'self'
< x-powered-by: Phusion Passenger 4.0.53
< set-cookie: _session_id=0cc347b34f7ad4da9aa3dee329b8aa56; path=/; secure; HttpOnly; SameSite=Lax
< etag: W/"664bb5e71fe763682396198fa4a26885"
< status: 200 OK
< 
{ [4466 bytes data]
100  4466    0  4466    0     0   6967      0 --:--:-- --:--:-- --:--:--  6967
* Connection #0 to host puppet.public-loadbalancer.net left intact
[
  {
    "href": "/katello/api/capsules/",
    "rel": "capsules"
  },
  {
    "href": "/katello/api/activation_keys/",
    "rel": "activation_keys"
  },
  {
    "href": "/katello/api/activation_keys/",
    "rel": "activation_keys"
  },
  {
    "href": "/katello/api/activation_keys/",
    "rel": "activation_keys"
  },
  {
    "href": "/katello/api/activation_keys/",
    "rel": "activation_keys"
  },
  {
    "href": "/katello/api/content_credentials/",
    "rel": "content_credentials"
  },
  {
    "href": "/katello/api/content_credentials/",
    "rel": "content_credentials"
  },
  {
    "href": "/katello/api/content_credentials/",
    "rel": "content_credentials"
  },
  {
    "href": "/katello/api/content_credentials/",
    "rel": "content_credentials"
  },
  {
    "href": "/katello/api/content_views/",
    "rel": "content_views"
  },
  {
    "href": "/katello/api/content_views/",
    "rel": "content_views"
  },
  {
    "href": "/katello/api/content_views/",
    "rel": "content_views"
  },
  {
    "href": "/katello/api/content_views/",
    "rel": "content_views"
  },
  {
    "href": "/katello/api/content_view_filters/",
    "rel": "content_view_filters"
  },
  {
    "href": "/katello/api/content_view_filters/",
    "rel": "content_view_filters"
  },
  {
    "href": "/katello/api/content_view_filters/",
    "rel": "content_view_filters"
  },
  {
    "href": "/katello/api/content_view_filters/",
    "rel": "content_view_filters"
  },
  {
    "href": "/katello/api/content_view_versions/",
    "rel": "content_view_versions"
  },
  {
    "href": "/katello/api/content_view_versions/",
    "rel": "content_view_versions"
  },
  {
    "href": "/katello/api/content_view_versions/",
    "rel": "content_view_versions"
  },
  {
    "href": "/katello/api/content_view_versions/",
    "rel": "content_view_versions"
  },
  {
    "href": "/katello/api/ansible_collections/",
    "rel": "ansible_collections"
  },
  {
    "href": "/katello/api/ostree_branches/",
    "rel": "ostree_branches"
  },
  {
    "href": "/katello/api/debs/",
    "rel": "debs"
  },
  {
    "href": "/katello/api/docker_manifests/",
    "rel": "docker_manifests"
  },
  {
    "href": "/katello/api/docker_manifest_lists/",
    "rel": "docker_manifest_lists"
  },
  {
    "href": "/katello/api/docker_tags/",
    "rel": "docker_tags"
  },
  {
    "href": "/katello/api/environments/",
    "rel": "environments"
  },
  {
    "href": "/katello/api/environments/",
    "rel": "environments"
  },
  {
    "href": "/katello/api/environments/",
    "rel": "environments"
  },
  {
    "href": "/katello/api/environments/",
    "rel": "environments"
  },
  {
    "href": "/katello/api/errata/",
    "rel": "errata"
  },
  {
    "href": "/katello/api/gpg_keys/",
    "rel": "gpg_keys"
  },
  {
    "href": "/katello/api/gpg_keys/",
    "rel": "gpg_keys"
  },
  {
    "href": "/katello/api/gpg_keys/",
    "rel": "gpg_keys"
  },
  {
    "href": "/katello/api/gpg_keys/",
    "rel": "gpg_keys"
  },
  {
    "href": "/katello/api/host_collections/",
    "rel": "host_collections"
  },
  {
    "href": "/katello/api/host_collections/",
    "rel": "host_collections"
  },
  {
    "href": "/katello/api/host_collections/",
    "rel": "host_collections"
  },
  {
    "href": "/katello/api/host_collections/",
    "rel": "host_collections"
  },
  {
    "href": "/katello/api/module_streams/",
    "rel": "module_streams"
  },
  {
    "href": "/katello/api/organizations/",
    "rel": "organizations"
  },
  {
    "href": "/katello/api/organizations/",
    "rel": "organizations"
  },
  {
    "href": "/katello/api/organizations/",
    "rel": "organizations"
  },
  {
    "href": "/katello/api/organizations/",
    "rel": "organizations"
  },
  {
    "href": "/katello/api/packages/",
    "rel": "packages"
  },
  {
    "href": "/katello/api/package_groups/",
    "rel": "package_groups"
  },
  {
    "href": "/katello/api/files/",
    "rel": "files"
  },
  {
    "href": "/katello/api/products/",
    "rel": "products"
  },
  {
    "href": "/katello/api/products/",
    "rel": "products"
  },
  {
    "href": "/katello/api/products/",
    "rel": "products"
  },
  {
    "href": "/katello/api/products/",
    "rel": "products"
  },
  {
    "href": "/katello/api/puppet_modules/",
    "rel": "puppet_modules"
  },
  {
    "href": "/katello/api/repositories/",
    "rel": "repositories"
  },
  {
    "href": "/katello/api/repositories/",
    "rel": "repositories"
  },
  {
    "href": "/katello/api/repositories/",
    "rel": "repositories"
  },
  {
    "href": "/katello/api/repositories/",
    "rel": "repositories"
  },
  {
    "href": "/katello/api/repository_sets/",
    "rel": "repository_sets"
  },
  {
    "href": "/katello/api/srpms/",
    "rel": "srpms"
  },
  {
    "href": "/katello/api/subscriptions/",
    "rel": "subscriptions"
  },
  {
    "href": "/katello/api/organizations/",
    "rel": "organizations"
  },
  {
    "href": "/katello/api/organizations/",
    "rel": "organizations"
  },
  {
    "href": "/katello/api/organizations/",
    "rel": "organizations"
  },
  {
    "href": "/katello/api/organizations/",
    "rel": "organizations"
  },
  {
    "href": "/katello/api/host_collections/",
    "rel": "host_collections"
  },
  {
    "href": "/katello/api/host_collections/",
    "rel": "host_collections"
  },
  {
    "href": "/katello/api/host_collections/",
    "rel": "host_collections"
  },
  {
    "href": "/katello/api/host_collections/",
    "rel": "host_collections"
  },
  {
    "href": "/katello/api/sync_plans/",
    "rel": "sync_plans"
  },
  {
    "href": "/katello/api/sync_plans/",
    "rel": "sync_plans"
  },
  {
    "href": "/katello/api/sync_plans/",
    "rel": "sync_plans"
  },
  {
    "href": "/katello/api/sync_plans/",
    "rel": "sync_plans"
  }
]

For some reason, when accessing katello content through the LB, the search yields no results

==> /var/log/httpd/foreman-ssl_access_ssl.log <==
10.250.43.26 - - [15/Oct/2019:18:39:50 +0000] "GET /api/v2/bookmarks?search=controller%3Dkatello_sync_plans HTTP/1.1" 200 138 "https://puppet.public-loadbalancer.net/sync_plans" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.75 Safari/537.36"

==> /var/log/foreman/production.log <==
2019-10-15T18:39:50 [I|app|d1e80aaf] Started GET "/api/v2/bookmarks?search=controller%3Dkatello_sync_plans" for 91.221.254.6 at 2019-10-15 18:39:50 +0000
2019-10-15T18:39:50 [I|app|d1e80aaf] Processing by Api::V2::BookmarksController#index as JSON
2019-10-15T18:39:50 [I|app|d1e80aaf]   Parameters: {"search"=>"controller=katello_sync_plans", "apiv"=>"v2"}
2019-10-15T18:39:50 [D|tax|d1e80aaf] Current location set to Default Location
2019-10-15T18:39:50 [D|tax|d1e80aaf] Current organization set to myorg
2019-10-15T18:39:50 [I|app|d1e80aaf]   Rendering api/v2/bookmarks/index.json.rabl within api/v2/layouts/index_layout
2019-10-15T18:39:50 [I|app|d1e80aaf]   Rendered api/v2/bookmarks/index.json.rabl within api/v2/layouts/index_layout (1.4ms)
2019-10-15T18:39:50 [D|app|d1e80aaf] Body: {
  "total": 18,
  "subtotal": 0,
  "page": 1,
  "per_page": 20,
  "search": "controller=katello_sync_plans",
  "sort": {
    "by": null,
    "order": null
  },
  "results": []
}

2019-10-15T18:39:50 [I|app|d1e80aaf] Completed 200 OK in 14ms (Views: 4.0ms | ActiveRecord: 2.0ms)

==> /var/log/httpd/foreman-ssl_access_ssl.log <==
10.250.43.26 - - [15/Oct/2019:18:39:57 +0000] "GET /content-views/views/content-views.html HTTP/1.1" 304 - "https://puppet.public-loadbalancer.net/content_views" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.75 Safari/537.36"

==> /var/log/foreman/production.log <==
2019-10-15T18:39:57 [I|app|f67b969a] Started GET "/content-views/views/content-views.html" for 91.221.254.6 at 2019-10-15 18:39:57 +0000

==> /var/log/httpd/foreman-ssl_access_ssl.log <==
10.250.43.26 - - [15/Oct/2019:18:39:57 +0000] "GET /api/v2/bookmarks?search=controller%3Dkatello_content_views HTTP/1.1" 200 140 "https://puppet.public-loadbalancer.net/content_views""Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.75 Safari/537.36"

==> /var/log/foreman/production.log <==
2019-10-15T18:39:57 [I|app|1df1451c] Started GET "/api/v2/bookmarks?search=controller%3Dkatello_content_views" for 91.221.254.6 at 2019-10-15 18:39:57 +0000
2019-10-15T18:39:57 [I|app|1df1451c] Processing by Api::V2::BookmarksController#index as JSON
2019-10-15T18:39:57 [I|app|1df1451c]   Parameters: {"search"=>"controller=katello_content_views", "apiv"=>"v2"}
2019-10-15T18:39:57 [D|tax|1df1451c] Current location set to Default Location
2019-10-15T18:39:57 [D|tax|1df1451c] Current organization set to myorg
2019-10-15T18:39:57 [I|app|1df1451c]   Rendering api/v2/bookmarks/index.json.rabl within api/v2/layouts/index_layout
2019-10-15T18:39:57 [I|app|1df1451c]   Rendered api/v2/bookmarks/index.json.rabl within api/v2/layouts/index_layout (0.8ms)
2019-10-15T18:39:57 [D|app|1df1451c] Body: {
  "total": 18,
  "subtotal": 0,
  "page": 1,
  "per_page": 20,
  "search": "controller=katello_content_views",
  "sort": {
    "by": null,
    "order": null
  },
  "results": []
}

2019-10-15T18:39:57 [I|app|1df1451c] Completed 200 OK in 10ms (Views: 2.2ms | ActiveRecord: 1.3ms)

@mmorizot

Can I try to access the katello box on my side from outside the load balancer and see if i can see anything odd? You can send me a private message with the fqdn/ip and I can look here. I don’t need the username/password I just want to see if I can hit some api endpoints.

in order to cover my bases, is there any documentation regarding how to only expose the WebUI (443) to the internet?
basically, i’m using an ALB to forward 443 requests to the 443 port on my node.

All other ports are only visible in the private subnet.

I think i got it. For some reason, when accessing through a load balancer, in a “katello content”, the ssl username is lost.

By adding this in the katello.conf, it seems to fix the issue :
in /etc/httpd/conf.d/05-foreman-ssl.d/katello.conf

<LocationMatch /rhsm|/katello/api>
#ADDED THE NEXT LINE IN 
  SSLUsername SSL_CLIENT_S_DN_CN

# if ssl_client_certa is present set the header, otherwise don't override
  # a reverse proxy may already be sending the cert through this header
  SetEnvIf SSL_CLIENT_CERT "^..*" client_cert_present=1
  RequestHeader set SSL_CLIENT_CERT "%{SSL_CLIENT_CERT}s" env=!client_cert_present
  SSLVerifyClient optional
  SSLRenegBufferSize 16777216
  SSLVerifyDepth 2

Katello relies on SSL client authentication in various places. Beware that if your webserver is reachable directly then anyone can pretend to be any client. This is potentially a huge security hole.

fair enough.
is there a documentation you can point to?
i’m only trying to expose the WebUI (on port 443) to the internet.

I have HTTPS from my browser to my load balancer (public), with valid certificate AND HTTPS between my load balancer and my Foreman/Katello node with a self-signed certificate.

All other ports (puppet, candlepin, foreman-proxy…) are only exposed in my internal network.

How come only katello end points are affected, why isn’t the rest of the foreman end points affected by this?

What you’re attempting to do is currently unsupported. You may be able to get it to work but be prepared to supply patches when things break.

There’s actually still some code in Katello that uses the fqdn/domain to generate URLs rather than the foreman_url setting.

Be aware that various resources (puppet, foreman-proxy) also connect the port 443 and actually use client certs to authenticate.

1 Like

thanks, I appreciate the heads up.
Is this use case planned on the katello/foreman road map?
i believe it could be quite interesting, should we want to deploy in a cloud infrastructure:

  • the foreman UI would be “public” facing to allow monitoring and interaction.
  • all the rest would be in a private network.

I don’t know if this particular use case is on the roadmap, but running behind a load balancer is certainly planned. However, we are an open source community. If this is important to you then we highly welcome you to collaborate. It’s in my experience how the most useful features are built: a user needs it and cares about it. Others will gladly point you in the right direction.