processone / ejabberd

Robust, Ubiquitous and Massively Scalable Messaging Platform (XMPP, MQTT, SIP Server)
https://www.process-one.net/en/ejabberd/
Other
6.03k stars 1.5k forks source link

Cannot give REST API access to admin #4008

Closed greffgreff closed 1 year ago

greffgreff commented 1 year ago

I will eventually move ejabberd to another machine and would like to perform room creation along other command over http with admin credentials.

To create a room, I perform a POST to https://localhost:5443/api/create_room with body:

{
    "name": "happiness",
    "host": "localhost",
    "service": "conference.localhost"
}

and with basic auth set with the right credentials (admin, admin). However, I get the following error response:

{
    "status": "error",
    "code": 10,
    "message": "You are not authorized to call this command."
}

I tried fiddling with admin access in the config file a bit but reverted all changes to the following:

hosts:
  - localhost

loglevel: 4
log_rotate_size: 10485760
log_rotate_date: ""
log_rotate_count: 1
log_rate_limit: 100

certfiles:
  - /home/ejabberd/conf/server.pem

ca_file: "/home/ejabberd/conf/cacert.pem"

listen:
  -
    port: 5222
    ip: "::"
    module: ejabberd_c2s
    max_stanza_size: 262144
    shaper: c2s_shaper
    access: c2s
    starttls_required: true
  -
    port: 5269
    ip: "::"
    module: ejabberd_s2s_in
    max_stanza_size: 524288
  -
    port: 5443
    ip: "::"
    module: ejabberd_http
    tls: true
    request_handlers:
      "/admin": ejabberd_web_admin
      "/api": mod_http_api
      "/bosh": mod_bosh
      "/captcha": ejabberd_captcha
      "/upload": mod_http_upload
      "/ws": ejabberd_http_ws
      "/oauth": ejabberd_oauth
  -
    port: 5280
    ip: "::"
    module: ejabberd_http
    request_handlers:
      "/admin": ejabberd_web_admin
  -
    port: 1883
    ip: "::"
    module: mod_mqtt
    backlog: 1000

s2s_use_starttls: optional

acl:
  local:
    user_regexp: ""
  loopback:
    ip:
      - 127.0.0.0/8
      - ::1/128
      - ::FFFF:127.0.0.1/128
  admin:
    user:
      - "admin@localhost"

access_rules:
  local:
    allow: local
  c2s:
    deny: blocked
    allow: all
  announce:
    allow: admin
  configure:
    allow: admin
  muc_create:
    allow: 
      - local
      - admin
  pubsub_createnode:
    allow: 
      - local
      - admin
  trusted_network:
    allow: loopback

api_permissions:
  "console commands":
    from:
      - ejabberd_ctl
    who: all
    what: "*"
  "admin access":
    who:
      access:
        allow:
          acl: loopback
          acl: admin
      oauth:
        scope: "ejabberd:admin"
        access:
          allow:
            acl: loopback
            acl: admin
    what:
      - "*"
      - "!stop"
      - "!start"
    from:
      - ejabberd_ctl
      - mod_http_api
  "public commands":
    who:
      ip: 127.0.0.1/8
    what:
      - status
      - connected_users_number
...

Thanks in advance! ✌

prefiks commented 1 year ago

Could you switch for a moment to debug loglevel (with ejabberdctl set_loglevel debug) issue another request and see what is logged in (you should get info about user/ip address/module of initiator)? Maybe this will allow to see what api_permissions didn't allow you to execute this command.

greffgreff commented 1 year ago

Hello again! Thanks for replying this quickly! Below are the logs from when performing the POST request with debug logs enabled (this is being ran in docker):

2023-03-14 21:17:25 2023-03-14 20:17:25.223045+00:00 [info] (<0.751.0>) Accepted connection [::ffff:172.17.0.1]:40422 -> [::ffff:172.17.0.2]:5443
2023-03-14 21:17:25 2023-03-14 20:17:25.223311+00:00 [debug] S: [{[<<"admin">>],ejabberd_web_admin},
2023-03-14 21:17:25     {[<<"api">>],mod_http_api},
2023-03-14 21:17:25     {[<<"bosh">>],mod_bosh},
2023-03-14 21:17:25     {[<<"captcha">>],ejabberd_captcha},
2023-03-14 21:17:25     {[<<"upload">>],mod_http_upload},
2023-03-14 21:17:25     {[<<"ws">>],ejabberd_http_ws},
2023-03-14 21:17:25     {[<<"oauth">>],ejabberd_oauth}]
2023-03-14 21:17:25 
2023-03-14 21:17:25 2023-03-14 20:17:25.223462+00:00 [info] (<0.752.0>) Accepted connection [::ffff:172.17.0.1]:40426 -> [::ffff:172.17.0.2]:5443
2023-03-14 21:17:25 2023-03-14 20:17:25.223614+00:00 [debug] S: [{[<<"admin">>],ejabberd_web_admin},
2023-03-14 21:17:25     {[<<"api">>],mod_http_api},
2023-03-14 21:17:25     {[<<"bosh">>],mod_bosh},
2023-03-14 21:17:25     {[<<"captcha">>],ejabberd_captcha},
2023-03-14 21:17:25     {[<<"upload">>],mod_http_upload},
2023-03-14 21:17:25     {[<<"ws">>],ejabberd_http_ws},
2023-03-14 21:17:25     {[<<"oauth">>],ejabberd_oauth}]
2023-03-14 21:17:25 
2023-03-14 21:17:25 2023-03-14 20:17:25.230896+00:00 [debug] ({tlssock,#Port<0.35>,#Ref<0.3091510976.904003586.28913>}) http query: 'POST' <<"/api/create_room">>
2023-03-14 21:17:25 
2023-03-14 21:17:25 2023-03-14 20:17:25.231027+00:00 [debug] [<<"api">>,<<"create_room">>] matches [<<"api">>]
2023-03-14 21:17:25 2023-03-14 20:17:25.231189+00:00 [info] API call create_room [{<<"name">>,<<"happiness">>},
2023-03-14 21:17:25                       {<<"host">>,<<"localhost">>},
2023-03-14 21:17:25                       {<<"service">>,<<"conference.localhost">>}] from ::ffff:172.17.0.1:40426
2023-03-14 21:17:25 2023-03-14 20:17:25.236530+00:00 [debug] Option 'auth_method' is not defined for virtual host 'admin'. This is a bug, please report it with the following stacktrace included:
2023-03-14 21:17:25 ** exception error: bad argument
2023-03-14 21:17:25    in function  ets:lookup_element/3
2023-03-14 21:17:25       called as ets:lookup_element(ejabberd_options,
2023-03-14 21:17:25                                    {auth_method,<<"admin">>},
2023-03-14 21:17:25                                    2)
2023-03-14 21:17:25       *** argument 2: not a key that exists in the table
2023-03-14 21:17:25    in call from ejabberd_config:get_option/1 (src/ejabberd_config.erl, line 162)
2023-03-14 21:17:25    in call from ejabberd_auth:auth_modules/1 (src/ejabberd_auth.erl, line 859)
2023-03-14 21:17:25    in call from ejabberd_auth:check_password_with_authmodule/6 (src/ejabberd_auth.erl, line 260)
2023-03-14 21:17:25    in call from ejabberd_auth:check_password/6 (src/ejabberd_auth.erl, line 225)
2023-03-14 21:17:25    in call from mod_http_api:extract_auth/1 (src/mod_http_api.erl, line 99)
2023-03-14 21:17:25    in call from mod_http_api:perform_call/4 (src/mod_http_api.erl, line 185)
2023-03-14 21:17:25    in call from mod_http_api:process/2 (src/mod_http_api.erl, line 143)
2023-03-14 21:17:25 2023-03-14 20:17:25.236814+00:00 [debug] Option 'auth_use_cache' is not defined for virtual host 'admin'. This is a bug, please report it with the following stacktrace included:
2023-03-14 21:17:25 ** exception error: bad argument
2023-03-14 21:17:25    in function  ets:lookup_element/3
2023-03-14 21:17:25       called as ets:lookup_element(ejabberd_options,
2023-03-14 21:17:25                                    {auth_use_cache,<<"admin">>},
2023-03-14 21:17:25                                    2)
2023-03-14 21:17:25       *** argument 2: not a key that exists in the table
2023-03-14 21:17:25    in call from ejabberd_config:get_option/1 (src/ejabberd_config.erl, line 162)
2023-03-14 21:17:25    in call from ejabberd_auth:db_get_password/3 (src/ejabberd_auth.erl, line 610)
2023-03-14 21:17:25    in call from ejabberd_auth:db_check_password/7 (src/ejabberd_auth.erl, line 669)
2023-03-14 21:17:25    in call from ejabberd_auth:'-check_password_with_authmodule/6-fun-0-'/8 (src/ejabberd_auth.erl, line 250)
2023-03-14 21:17:25    in call from lists:foldl/3 (lists.erl, line 1267)
2023-03-14 21:17:25    in call from ejabberd_auth:check_password_with_authmodule/6 (src/ejabberd_auth.erl, line 248)
2023-03-14 21:17:25    in call from ejabberd_auth:check_password/6 (src/ejabberd_auth.erl, line 225)
2023-03-14 21:17:25 2023-03-14 20:17:25.237295+00:00 [debug] Option 'auth_password_format' is not defined for virtual host 'admin'. This is a bug, please report it with the following stacktrace included:
2023-03-14 21:17:25 ** exception error: bad argument
2023-03-14 21:17:25    in function  ets:lookup_element/3
2023-03-14 21:17:25       called as ets:lookup_element(ejabberd_options,
2023-03-14 21:17:25                                    {auth_password_format,<<"admin">>},
2023-03-14 21:17:25                                    2)
2023-03-14 21:17:25       *** argument 2: not a key that exists in the table
2023-03-14 21:17:25    in call from ejabberd_config:get_option/1 (src/ejabberd_config.erl, line 162)
2023-03-14 21:17:25    in call from ejabberd_auth:db_check_password/7 (src/ejabberd_auth.erl, line 673)
2023-03-14 21:17:25    in call from ejabberd_auth:'-check_password_with_authmodule/6-fun-0-'/8 (src/ejabberd_auth.erl, line 250)
2023-03-14 21:17:25    in call from lists:foldl/3 (lists.erl, line 1267)
2023-03-14 21:17:25    in call from ejabberd_auth:check_password_with_authmodule/6 (src/ejabberd_auth.erl, line 248)
2023-03-14 21:17:25    in call from ejabberd_auth:check_password/6 (src/ejabberd_auth.erl, line 225)
2023-03-14 21:17:25    in call from mod_http_api:extract_auth/1 (src/mod_http_api.erl, line 99)
2023-03-14 21:17:25 2023-03-14 20:17:25.237763+00:00 [debug] Option 'auth_use_cache' is not defined for virtual host 'admin'. This is a bug, please report it with the following stacktrace included:
2023-03-14 21:17:25 ** exception error: bad argument
2023-03-14 21:17:25    in function  ets:lookup_element/3
2023-03-14 21:17:25       called as ets:lookup_element(ejabberd_options,
2023-03-14 21:17:25                                    {auth_use_cache,<<"admin">>},
2023-03-14 21:17:25                                    2)
2023-03-14 21:17:25       *** argument 2: not a key that exists in the table
2023-03-14 21:17:25    in call from ejabberd_config:get_option/1 (src/ejabberd_config.erl, line 162)
2023-03-14 21:17:25    in call from ejabberd_auth:db_check_password/7 (src/ejabberd_auth.erl, line 673)
2023-03-14 21:17:25    in call from ejabberd_auth:'-check_password_with_authmodule/6-fun-0-'/8 (src/ejabberd_auth.erl, line 250)
2023-03-14 21:17:25    in call from lists:foldl/3 (lists.erl, line 1267)
2023-03-14 21:17:25    in call from ejabberd_auth:check_password_with_authmodule/6 (src/ejabberd_auth.erl, line 248)
2023-03-14 21:17:25    in call from ejabberd_auth:check_password/6 (src/ejabberd_auth.erl, line 225)
2023-03-14 21:17:25    in call from mod_http_api:extract_auth/1 (src/mod_http_api.erl, line 99)
2023-03-14 21:17:25 2023-03-14 20:17:25.237927+00:00 [debug] Invalid auth data: {error,invalid_auth}
prefiks commented 1 year ago

I think that this is will be fixed if you pass username as admin@localhost instead of just admin (at least i think this is what those error suggest).

greffgreff commented 1 year ago

Ah yes! I see that the admin user does not have access to create_room command:

2023-03-15 23:44:37 2023-03-15 22:44:37.041527+00:00 [info] (<0.763.0>) Accepted connection [::ffff:172.17.0.1]:37868 -> [::ffff:172.17.0.2]:5443
2023-03-15 23:44:37 2023-03-15 22:44:37.047857+00:00 [info] API call create_room [{<<"name">>,<<"happiness">>},
2023-03-15 23:44:37                       {<<"host">>,<<"localhost">>},
2023-03-15 23:44:37                       {<<"service">>,<<"conference.localhost">>}] from ::ffff:172.17.0.1:37868
2023-03-15 23:45:15 2023-03-15 22:45:15.669309+00:00 [debug] ({tlssock,#Port<0.38>,#Ref<0.1782831003.1684406274.165456>}) http query: 'POST' <<"/api/create_room">>
2023-03-15 23:45:15 
2023-03-15 23:45:15 2023-03-15 22:45:15.669448+00:00 [debug] [<<"api">>,<<"create_room">>] matches [<<"api">>]
2023-03-15 23:45:15 2023-03-15 22:45:15.669507+00:00 [info] API call create_room [{<<"name">>,<<"happiness">>},
2023-03-15 23:45:15                       {<<"host">>,<<"localhost">>},
2023-03-15 23:45:15                       {<<"service">>,<<"conference.localhost">>}] from ::ffff:172.17.0.1:37868
2023-03-15 23:45:15 2023-03-15 22:45:15.669724+00:00 [debug] Command 'create_room' execution denied (CallerInfo=#{caller_module =>
2023-03-15 23:45:15                                                          mod_http_api,
2023-03-15 23:45:15                                                      caller_server =>
2023-03-15 23:45:15                                                          <<"localhost">>,
2023-03-15 23:45:15                                                      ip =>
2023-03-15 23:45:15                                                          {0,0,0,0,0,65535,
2023-03-15 23:45:15                                                           44049,1},
2023-03-15 23:45:15                                                      tag => <<>>,
2023-03-15 23:45:15                                                      usr =>
2023-03-15 23:45:15                                                          {<<"admin">>,
2023-03-15 23:45:15                                                           <<"localhost">>,
2023-03-15 23:45:15                                                           <<>>}})

Is there a way to allow all commands such as this one to the admin without manually giving access to the commands one by one?

prefiks commented 1 year ago

You can, and "admin access" rule will allow executing any command (except start and stop) by having "*". But that rule only accept connections from localhost (127.0.0.1 and ipv6 equivalents), while your requests originates from ::ffff:172.17.0.1 - which doesn't match specified addresses. You can remove acl: localhost from who sections to allow access from everywhere, or you can modify section in acl to list addresses that you want to use.

greffgreff commented 1 year ago

Thanks that makes a lot of sense