warpgate icon indicating copy to clipboard operation
warpgate copied to clipboard

SSO Keycloak

Open Bloody3556 opened this issue 1 year ago • 14 comments

Hello following the SSO page, I try to configure Keycloak, but the configuration causes the warpgate service to crash. Keycloak manages SAML or OIDC.

I corrected my error it is an interface problem between the chair and the keyboard

I test Keycloak in a poc to test the tool

external_host: mywarpgate:8888
sso_providers:
  - name: keycloak
    label: test_SSO
    provider:
      type: custom
      client_id: Warpgate
      client_secret: (censored)
      issuer_url: keycloak_portal
      scopes: ["email"]

recordings:
  enable: true
  path: /var/lib/warpgate/recordings
external_host: ~
database_url: "sqlite:/var/lib/warpgate/db"
ssh:
  enable: true
  listen: "0.0.0.0:2222"
  keys: /var/lib/warpgate/ssh-keys
  host_key_verification: prompt
http:
  enable: true
  listen: "0.0.0.0:8888"
  certificate: /var/lib/warpgate/tls.certificate.pem
  key: /var/lib/warpgate/tls.key.pem
mysql:
  enable: true
  listen: "0.0.0.0:33306"
  certificate: /var/lib/warpgate/tls.certificate.pem
  key: /var/lib/warpgate/tls.key.pem
log:
  retention: 7days
  send_to: ~
config_provider: database

thanks for the help

Bloody3556 avatar Apr 25 '23 07:04 Bloody3556

After correcting my omission, I have test_SSO which appears

image

But the client gives nothing, I click and nothing

And in the logs

avril 25 11:39:42 warpgate warpgate[8043]: 25.04.2023 09:39:42  WARN HTTP: warpgate_protocol_http::logging: Request failed method=GET url=https://mywarpgate:8888/@warpgate/api/auth/state status=404 Not F>

However I followed the tutorial, with the hosts etc...

image

Bloody3556 avatar Apr 25 '23 09:04 Bloody3556

came here looking for the answer. I'm having same issue as you.

I even tried both urls:

https://sso.<redacted>/realms/<redacted>/.well-known/openid-configuration
https://sso.<redacted>/realms/<redacted>/

I'm getting error code 400: Bad Request from sso after clicking on that button.

firestrife23 avatar Sep 09 '23 20:09 firestrife23

Could you please run Warpgate with the debug flag to capture the error that causes that 500 response?

Eugeny avatar Sep 09 '23 20:09 Eugeny

seem like it's not pointing to correct url such as https://sso.<redacted>/realms/<redacted> instead it's trying to reach https://sso.<redacted>

Here's debug output:

20:17:14  INFO Warpgate version=0.8.0
20:17:14  INFO Using config: "/data/warpgate.yaml"
20:17:14  INFO summary="PRAGMA foreign_keys = ON; …" db.statement="\n\nPRAGMA foreign_keys = ON;\n" rows_affected=0 rows_returned=0 elapsed=31.028µs
20:17:14  INFO summary="PRAGMA foreign_keys = ON; …" db.statement="\n\nPRAGMA foreign_keys = ON;\n" rows_affected=0 rows_returned=0 elapsed=28.254µs
20:17:14  INFO summary="PRAGMA foreign_keys = ON; …" db.statement="\n\nPRAGMA foreign_keys = ON;\n" rows_affected=0 rows_returned=0 elapsed=12.177µs
20:17:14  INFO summary="PRAGMA foreign_keys = ON; …" db.statement="\n\nPRAGMA foreign_keys = ON;\n" rows_affected=0 rows_returned=0 elapsed=12.038µs
20:17:14  INFO summary="PRAGMA foreign_keys = ON; …" db.statement="\n\nPRAGMA foreign_keys = ON;\n" rows_affected=0 rows_returned=0 elapsed=15.427µs
20:17:14  INFO summary="PRAGMA foreign_keys = ON; …" db.statement="\n\nPRAGMA foreign_keys = ON;\n" rows_affected=0 rows_returned=0 elapsed=12.074µs
20:17:14  INFO summary="CREATE TABLE IF NOT …" db.statement="\n\nCREATE TABLE IF NOT EXISTS \"seaql_migrations\" (\n  \"version\" text NOT NULL PRIMARY KEY,\n  \"applied_at\" bigint NOT NULL\n)\n" rows_affected=0 rows_returned=0 elapsed=220.742µs
20:17:14  INFO Applying all pending migrations
20:17:14  INFO summary="CREATE TABLE IF NOT …" db.statement="\n\nCREATE TABLE IF NOT EXISTS \"seaql_migrations\" (\n  \"version\" text NOT NULL PRIMARY KEY,\n  \"applied_at\" bigint NOT NULL\n)\n" rows_affected=0 rows_returned=0 elapsed=338.504µs
20:17:14  INFO summary="CREATE TABLE IF NOT …" db.statement="\n\nCREATE TABLE IF NOT EXISTS \"seaql_migrations\" (\n  \"version\" text NOT NULL PRIMARY KEY,\n  \"applied_at\" bigint NOT NULL\n)\n" rows_affected=0 rows_returned=0 elapsed=173.853µs
20:17:14  INFO summary="CREATE TABLE IF NOT …" db.statement="\n\nCREATE TABLE IF NOT EXISTS \"seaql_migrations\" (\n  \"version\" text NOT NULL PRIMARY KEY,\n  \"applied_at\" bigint NOT NULL\n)\n" rows_affected=0 rows_returned=0 elapsed=168.077µs
20:17:14  INFO summary="SELECT \"version\", \"applied_at\" FROM …" db.statement="\n\nSELECT\n  \"version\",\n  \"applied_at\"\nFROM\n  \"seaql_migrations\"\nORDER BY\n  \"version\" ASC\n" rows_affected=0 rows_returned=8 elapsed=187.572µs
20:17:14  INFO No pending migrations
20:17:14  INFO summary="UPDATE \"recordings\" SET \"ended\" …" db.statement="\n\nUPDATE\n  \"recordings\"\nSET\n  \"ended\" = ?\nWHERE\n  \"ended\" IS NULL\n" rows_affected=0 rows_returned=0 elapsed=114.107µs
20:17:14  INFO summary="UPDATE \"sessions\" SET \"ended\" …" db.statement="\n\nUPDATE\n  \"sessions\"\nSET\n  \"ended\" = ?\nWHERE\n  \"ended\" IS NULL\n" rows_affected=1 rows_returned=0 elapsed=28.561229ms
20:17:14  INFO summary="SELECT \"roles\".\"id\", \"roles\".\"name\" FROM …" db.statement="\n\nSELECT\n  \"roles\".\"id\",\n  \"roles\".\"name\"\nFROM\n  \"roles\"\n" rows_affected=0 rows_returned=1 elapsed=96.113µs
20:17:14  INFO summary="SELECT \"roles\".\"id\", \"roles\".\"name\" FROM …" db.statement="\n\nSELECT\n  \"roles\".\"id\",\n  \"roles\".\"name\"\nFROM\n  \"roles\"\nWHERE\n  \"roles\".\"name\" = ?\n" rows_affected=0 rows_returned=1 elapsed=80.743µs
20:17:14  INFO summary="SELECT \"targets\".\"id\", \"targets\".\"name\", \"targets\".\"kind\", …" db.statement="\n\nSELECT\n  \"targets\".\"id\",\n  \"targets\".\"name\",\n  \"targets\".\"kind\",\n  \"targets\".\"options\"\nFROM\n  \"targets\"\nWHERE\n  \"targets\".\"kind\" = ?\n" rows_affected=0 rows_returned=1 elapsed=80.931µs
20:17:14  INFO summary="SELECT \"target_roles\".\"id\", \"target_roles\".\"target_id\", \"target_roles\".\"role_id\" …" db.statement="\n\nSELECT\n  \"target_roles\".\"id\",\n  \"target_roles\".\"target_id\",\n  \"target_roles\".\"role_id\"\nFROM\n  \"target_roles\"\nWHERE\n  \"target_roles\".\"target_id\" = ?\n  AND \"target_roles\".\"role_id\" = ?\n" rows_affected=0 rows_returned=1 elapsed=76.449µs
20:17:14  INFO --------------------------------------------
20:17:14  INFO Warpgate is now running.
20:17:14  INFO Accepting SSH connections on 0.0.0.0:2222
20:17:14  INFO Accepting HTTP connections on https://0.0.0.0:8888
20:17:14  INFO summary="DELETE FROM \"log\" WHERE …" db.statement="\n\nDELETE FROM\n  \"log\"\nWHERE\n  \"timestamp\" < ?\n" rows_affected=0 rows_returned=0 elapsed=131.947µs
20:17:14  INFO Accepting MySQL connections on 0.0.0.0:33306
20:17:14  INFO --------------------------------------------
20:17:14  INFO summary="SELECT \"recordings\".\"id\", \"recordings\".\"name\", \"recordings\".\"started\", …" db.statement="\n\nSELECT\n  \"recordings\".\"id\",\n  \"recordings\".\"name\",\n  \"recordings\".\"started\",\n  \"recordings\".\"ended\",\n  \"recordings\".\"session_id\",\n  \"recordings\".\"kind\"\nFROM\n  \"recordings\"\nWHERE\n  \"ended\" IS NOT NULL\n  AND \"ended\" < ?\n" rows_affected=0 rows_returned=0 elapsed=66.914µs
20:17:14  INFO summary="DELETE FROM \"sessions\" WHERE …" db.statement="\n\nDELETE FROM\n  \"sessions\"\nWHERE\n  \"ended\" IS NOT NULL\n  AND \"ended\" < ?\n" rows_affected=0 rows_returned=0 elapsed=88.912µs
20:17:14 DEBUG Database cleaned up, next in 60480s
20:17:14  INFO Listening address=0.0.0.0:2222
20:17:14  INFO Listening address=0.0.0.0:8888
20:17:14  INFO listening addr=socket://0.0.0.0:8888
20:17:14  INFO server started
20:17:14  INFO tls config loaded.
20:17:14  INFO Listening address=0.0.0.0:33306
20:17:39 DEBUG decided upon suite TLS13_AES_128_GCM_SHA256    
20:17:39 DEBUG Client unwilling to resume, DHE_KE not offered    
20:17:39 DEBUG Chosen ALPN protocol [104, 50]    
20:17:39 DEBUG parse error (invalid HTTP version parsed) with 64 bytes
20:17:39 DEBUG read_head error: invalid HTTP version parsed (found HTTP2 preface)
20:17:39 DEBUG send frame=Settings { flags: (0x0), initial_window_size: 1048576, max_frame_size: 16384, max_header_list_size: 16777216 }
20:17:39 DEBUG Connection: received frame=Settings { flags: (0x0), enable_push: 0, initial_window_size: 4194304, max_header_list_size: 10485760 } peer=Server
20:17:39 DEBUG Connection: send frame=Settings { flags: (0x1: ACK) } peer=Server
20:17:39 DEBUG Connection: received frame=WindowUpdate { stream_id: StreamId(0), size_increment: 1073741824 } peer=Server
20:17:39 DEBUG Connection: send frame=WindowUpdate { stream_id: StreamId(0), size_increment: 983041 } peer=Server
20:17:39 DEBUG Connection: received frame=Headers { stream_id: StreamId(1), flags: (0x5: END_HEADERS | END_STREAM) } peer=Server
20:17:39 DEBUG Connection: received frame=Settings { flags: (0x1: ACK) } peer=Server
20:17:39 DEBUG Connection: received settings ACK; applying Settings { flags: (0x0), initial_window_size: 1048576, max_frame_size: 16384, max_header_list_size: 16777216 } peer=Server
20:17:39 DEBUG Connection: send frame=Headers { stream_id: StreamId(1), flags: (0x5: END_HEADERS | END_STREAM) } peer=Server
20:17:39 DEBUG Connection: received frame=Headers { stream_id: StreamId(3), flags: (0x5: END_HEADERS | END_STREAM) } peer=Server
20:17:39  INFO HTTP: Request method=GET url=https://warp.<redacted>/@warpgate status=200 OK
20:17:39 DEBUG Connection: send frame=Headers { stream_id: StreamId(3), flags: (0x4: END_HEADERS) } peer=Server
20:17:39 DEBUG Connection: send frame=Data { stream_id: StreamId(3), flags: (0x1: END_STREAM) } peer=Server
20:17:39 DEBUG Connection: received frame=Headers { stream_id: StreamId(5), flags: (0x5: END_HEADERS | END_STREAM) } peer=Server
20:17:39  INFO HTTP: Request method=GET url=https://warp.<redacted>/@warpgate/api/info status=200 OK
20:17:39 DEBUG Connection: send frame=Headers { stream_id: StreamId(5), flags: (0x4: END_HEADERS) } peer=Server
20:17:39 DEBUG Connection: send frame=Data { stream_id: StreamId(5), flags: (0x1: END_STREAM) } peer=Server
20:17:39 DEBUG Connection: received frame=Headers { stream_id: StreamId(7), flags: (0x5: END_HEADERS | END_STREAM) } peer=Server
20:17:39  INFO HTTP: Request method=GET url=https://warp.<redacted>/@warpgate/api/sso/providers status=200 OK
20:17:39 DEBUG Connection: send frame=Headers { stream_id: StreamId(7), flags: (0x4: END_HEADERS) } peer=Server
20:17:39 DEBUG Connection: send frame=Data { stream_id: StreamId(7), flags: (0x1: END_STREAM) } peer=Server
20:17:39 DEBUG Connection: received frame=Headers { stream_id: StreamId(9), flags: (0x5: END_HEADERS | END_STREAM) } peer=Server
20:17:39  WARN HTTP: Request failed method=GET url=https://warp.<redacted>/@warpgate/api/auth/state status=404 Not Found
20:17:39 DEBUG Connection: send frame=Headers { stream_id: StreamId(9), flags: (0x5: END_HEADERS | END_STREAM) } peer=Server
20:17:41 DEBUG Connection: received frame=Headers { stream_id: StreamId(11), flags: (0x5: END_HEADERS | END_STREAM) } peer=Server
20:17:41 DEBUG HTTP: starting new connection: https://sso.<redacted>/    
20:17:41 DEBUG resolving host="sso.<redacted>"
20:17:45 DEBUG HTTP: connecting to 192.168.1.10:443
20:17:45 DEBUG HTTP: connected to 192.168.1.10:443
20:17:45 DEBUG flushed 111 bytes
20:17:45 DEBUG parsed 13 headers
20:17:45 DEBUG incoming body is content-length (5829 bytes)
20:17:45 DEBUG incoming body completed
20:17:45 DEBUG pooling idle connection for ("https", sso.<redacted>)
20:17:45 DEBUG HTTP: starting new connection: https://sso.<redacted>/    
20:17:45 DEBUG resolving host="sso.<redacted>"
20:17:49 DEBUG HTTP: connecting to 192.168.1.10:443
20:17:49 DEBUG HTTP: connected to 192.168.1.10:443
20:17:49 DEBUG flushed 108 bytes
20:17:49 DEBUG parsed 13 headers
20:17:49 DEBUG incoming body is content-length (2941 bytes)
20:17:49 DEBUG incoming body completed
20:17:49 DEBUG pooling idle connection for ("https", sso.<redacted>)
20:17:49  INFO HTTP: Request method=GET url=https://warp.<redacted>/@warpgate/api/sso/providers/SSO/start?next=%2F status=200 OK
20:17:49 DEBUG Connection: send frame=Headers { stream_id: StreamId(11), flags: (0x4: END_HEADERS) } peer=Server
20:17:49 DEBUG Connection: send frame=Data { stream_id: StreamId(11), flags: (0x1: END_STREAM) } peer=Server

firestrife23 avatar Sep 09 '23 20:09 firestrife23

Did this get resolved? I have the same issue and I get this

WARN HTTP: Request failed method=GET url=https://host.domain.de:8888/@warpgate/api/auth/state status=404 Not Found

MarcelRei avatar Oct 09 '23 14:10 MarcelRei

Unfortunately no, I have decided to go with https://goteleport.com/ for now.

firestrife23 avatar Oct 09 '23 15:10 firestrife23

Dear,

We have the same issue and after some times we found that problem comes from. The good config is :

issuer_url: https://<SSO_URL>/auth/realms/master

BornTKill avatar Oct 12 '23 08:10 BornTKill

That doesn't work as well. Has anyone seen that warning before?

WARN HTTP: Request failed method=GET url=https://host.domain.de:8888/@warpgate/api/auth/state status=404 Not Found

MarcelRei avatar Oct 16 '23 09:10 MarcelRei

I am also experiencing this issue with :

WARN HTTP: warpgate_protocol_http::logging: Request failed method=GET url=https:///@warpgate/api/auth/state status=404 Not Found

I am also having this message in the browser :

claims verification error: Invalid audiences: 236469395113640674 is not a trusted audience

However i am not using Keycloak but Zitadel, and the id '236469395113640674' is the id of the app (warpgate) in zitadel

WilliamB78 avatar Oct 16 '23 10:10 WilliamB78

For the SSO to work the external_host variable needs to be set, otherwise the SSO button does nothing when clicked. The GET https://@warpgate/api/auth/state 404 is fairly normal from what I've seen, and it doesn't actually affect anything. The bad request is the lack of a correct return URL

Skyler84 avatar Oct 16 '23 13:10 Skyler84

I too am seeing this issue. I'm using JumpCloud OIDC and am getting code verification error: invalid_client after authenticating against jumpcloud. seeing a bunch of these in the logs as well:

WARN HTTP: warpgate_protocol_http::logging: Request failed method=GET url=https://<warpgate_host>:8888/@warpgate/api/auth/state status=404 Not Found

Here's the relevant part of my config:

sso_providers:
  - name: jumpcloud
    label: JumpCloud
    provider:
      type: custom
      client_id: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
      client_secret: xxxxxxxxxxxxxxxxxxxxxxxxxxxx
      issuer_url: https://oauth.id.jumpcloud.com/
      scopes: ["email"]

lravelo avatar Oct 17 '23 20:10 lravelo

I managed to get Keycloak working using this config:

external_host: fqdn:8888
sso_providers:
  - name: keycloak
    label: Keycloak
    provider:
      type: custom
      client_id: <client_id from keycloak>
      client_secret: <secret_from_keycloak>
      issuer_url: https://keycloak_fqdn/realms/<keycloak_realm>
      scopes: ["email"]

No, while this works with the warpgate's website login, my ssh client doesn't want to use the provided host link from the warpgate's website, which then looks something like this:

ssh '<user@domain>:<target>@<warpgate_fqdn:8888' -p 2222

ssh simply can't resolve the host.

budachst avatar Feb 16 '24 18:02 budachst

Remove :8888 from your ssh command

firestrife23 avatar Feb 16 '24 22:02 firestrife23

Ha ha - yes. I don't know, why I expected something else to happen… Then it's most likely simply a bug, when the command snippet gets created.

budachst avatar Feb 16 '24 22:02 budachst