processone / ejabberd-contrib

Growing and curated ejabberd contributions repository - PR or ask to join !
http://ejabberd.im
248 stars 137 forks source link

Cannot get ejabbed_auth_http working on latest (v18.09) docker container #262

Closed atomic-tang closed 5 years ago

atomic-tang commented 5 years ago

I currently have an ejabberd server up and running on an ec2 AWS instance but I'm trying to migrate it to a kubernetes cluster by containerizing it. The ejabberd version is 18.01.29 and I've tried pulling and running a docker image tagged 18.01 with my ejabberd server configuration but I could not install the ejabberd_auth_http module from the docker image. I got the following error:

/home/ejabberd/.ejabberd-modules/sources/ejabberd-contrib/ejabberd_auth_http/src/ejabberd_auth_http.erl:33: can't find include file "scram.hrl" /home/ejabberd/.ejabberd-modules/sources/ejabberd-contrib/ejabberd_auth_http/src/ejabberd_auth_http.erl:100: record scram undefined /home/ejabberd/.ejabberd-modules/sources/ejabberd-contrib/ejabberd_auth_http/src/ejabberd_auth_http.erl:261: record scram undefined /home/ejabberd/.ejabberd-modules/sources/ejabberd-contrib/ejabberd_auth_http/src/scram2.erl:31: can't find include file "scram.hrl" /home/ejabberd/.ejabberd-modules/sources/ejabberd-contrib/ejabberd_auth_http/src/scram2.erl:116: undefined macro 'SCRAM_DEFAULT_ITERATION_COUNT' /home/ejabberd/.ejabberd-modules/sources/ejabberd-contrib/ejabberd_auth_http/src/scram2.erl:130: undefined macro 'SCRAM_DEFAULT_ITERATION_COUNT' /home/ejabberd/.ejabberd-modules/sources/ejabberd-contrib/ejabberd_auth_http/src/scram2.erl:45: function iterations/0 undefined /home/ejabberd/.ejabberd-modules/sources/ejabberd-contrib/ejabberd_auth_http/src/scram2.erl:45: function password_to_scram/1 undefined /home/ejabberd/.ejabberd-modules/sources/ejabberd-contrib/ejabberd_auth_http/src/scram2.erl:121: function iterations/0 undefined /home/ejabberd/.ejabberd-modules/sources/ejabberd-contrib/ejabberd_auth_http/src/scram2.erl:124: function iterations/0 undefined /home/ejabberd/.ejabberd-modules/sources/ejabberd-contrib/ejabberd_auth_http/src/scram2.erl:132: record scram undefined /home/ejabberd/.ejabberd-modules/sources/ejabberd-contrib/ejabberd_auth_http/src/scram2.erl:139: record scram undefined /home/ejabberd/.ejabberd-modules/sources/ejabberd-contrib/ejabberd_auth_http/src/scram2.erl:145: record scram undefined /home/ejabberd/.ejabberd-modules/sources/ejabberd-contrib/ejabberd_auth_http/src/scram2.erl:146: record scram undefined /home/ejabberd/.ejabberd-modules/sources/ejabberd-contrib/ejabberd_auth_http/src/scram2.erl:149: record scram undefined /home/ejabberd/.ejabberd-modules/sources/ejabberd-contrib/ejabberd_auth_http/src/scram2.erl:151: record scram undefined /home/ejabberd/.ejabberd-modules/sources/ejabberd-contrib/ejabberd_auth_http/src/scram2.erl:153: variable 'IterationCount' is unbound /home/ejabberd/.ejabberd-modules/sources/ejabberd-contrib/ejabberd_auth_http/src/scram2.erl:155: variable 'ServerKey' is unbound /home/ejabberd/.ejabberd-modules/sources/ejabberd-contrib/ejabberd_auth_http/src/scram2.erl:155: variable 'StoredKey' is unbound /home/ejabberd/.ejabberd-modules/sources/ejabberd-contrib/ejabberd_auth_http/src/scram2.erl:156: variable 'Salt' is unbound /home/ejabberd/.ejabberd-modules/sources/ejabberd-contrib/ejabberd_auth_http/src/scram2.erl:161: record scram undefined /home/ejabberd/.ejabberd-modules/sources/ejabberd-contrib/ejabberd_auth_http/src/scram2.erl:175: record scram undefined /home/ejabberd/.ejabberd-modules/sources/ejabberd-contrib/ejabberd_auth_http/src/scram2.erl:176: record scram undefined /home/ejabberd/.ejabberd-modules/sources/ejabberd-contrib/ejabberd_auth_http/src/scram2.erl:177: record scram undefined /home/ejabberd/.ejabberd-modules/sources/ejabberd-contrib/ejabberd_auth_http/src/scram2.erl:178: record scram undefined /home/ejabberd/.ejabberd-modules/sources/ejabberd-contrib/ejabberd_auth_http/src/scram2.erl:180: type scram() undefined /home/ejabberd/.ejabberd-modules/sources/ejabberd-contrib/ejabberd_auth_http/src/scram2.erl:181: record scram undefined /home/ejabberd/.ejabberd-modules/sources/ejabberd-contrib/ejabberd_auth_http/src/scram2.erl:182: variable 'StoredKey' is unbound /home/ejabberd/.ejabberd-modules/sources/ejabberd-contrib/ejabberd_auth_http/src/scram2.erl:135: Warning: call to crypto:rand_bytes/1 will fail, since it was removed in 20.0; use crypto:strong_rand_bytes/1 /home/ejabberd/.ejabberd-modules/sources/ejabberd-contrib/ejabberd_auth_http/src/scram2.erl:137: Warning: variable 'StoredKey' is unused /home/ejabberd/.ejabberd-modules/sources/ejabberd-contrib/ejabberd_auth_http/src/scram2.erl:138: Warning: variable 'ServerKey' is unused /home/ejabberd/.ejabberd-modules/sources/ejabberd-contrib/ejabberd_auth_http/src/scram2.erl:160: Warning: variable 'IterationCount' is unused /home/ejabberd/.ejabberd-modules/sources/ejabberd-contrib/ejabberd_auth_http/src/scram2.erl:160: Warning: variable 'Salt' is unused /home/ejabberd/.ejabberd-modules/sources/ejabberd-contrib/ejabberd_auth_http/src/scram2.erl:160: Warning: variable 'ServerKey' is unused /home/ejabberd/.ejabberd-modules/sources/ejabberd-contrib/ejabberd_auth_http/src/scram2.erl:160: Warning: variable 'StoredKey' is unused Error: {compilation_failed,"/home/ejabberd/.ejabberd-modules/sources/ejabberd-contrib/ejabberd_auth_http/src/ejabberd_auth_http.erl"}

I had done some research and I came to the conclusion that the module had been updated and therefore, no longer works with older versions of ejabberd. I've tried installing the module for the image tags 18.03, 18.04 and 18.06 and none of them worked either.

So I then attempted to install the module on the latest tag/version (18.09) which confirmed my suspicions as it finally worked. Only problem was that when I restarted the container with the module installed I got the following error:

04:01:01.009 [error] Unknown option 'auth_opts' 04:01:01.009 [error] Failed to load configuration file /home/ejabberd/conf/ejabberd.yml 04:01:01.009 [critical] Failed to start ejabberd application: unknown_option

I've tried rebuilding a docker container using the configuration of my original ejabberd server by replacing the one in the ecs/conf directory but since version 18.09 no longer ignores parameters it can't read, the docker container failed to run as it was unable to read the "auth_opts" and "auth_method: http" parameters in my configuration file.

I've also tried installing the module on the docker container with the "auth_opts" commented out and "auth_method" set to internal and then updating the configuration file at /home/ejabberd/conf/ejabberd.yml but still no luck :(

If I could just get the module installed and have the docker container running with my current ejabberd server configuration for the module, I will be able to deploy ejabberd to my kubernetes cluster. Please help!

badlop commented 5 years ago

I had done some research and I came to the conclusion that the module had been updated and therefore, no longer works with older versions of ejabberd. I've tried installing the module for the image tags 18.03, 18.04 and 18.06 and none of them worked either.

You can rollback ejabberd-contrib to an older version, for example this one of January: git checkout 156331c123928efe5cfc164e023def750c08ecf8

I've tried rebuilding a docker container using the configuration of my original ejabberd server by replacing the one in the ecs/conf directory but since version 18.09 no longer ignores parameters it can't read, the docker container failed to run as it was unable to read the "auth_opts" and "auth_method: http" parameters in my configuration file.

Right, and this means that to work ejabberd_auth_http in recent ejabberd, you must copy its beam files to the ejabberd ebin/ path (where all the other beam files are), so that they are read when ejabberd starts, and those options are known and accepted.

atomic-tang commented 5 years ago

Thanks for responding. I've tried moving the beam files into the ejabberd ebin/ path but I get a permission denied error. I've also tried running the docker container with the --privileged flag to gain root privileges but I get a "Failed RPC connection to the node" error.

badlop commented 5 years ago

Well, if you can't get root privileges to copy your custom beam files to that system ejabberd installation, you can install ejabberd as a non-privileged user. For example, run this as your user:

./configure --enable-user --prefix=$HOME/ejalocal
make install
cd $HOME/ejalocal
./sbin/ejabberdctl live

And remember, you always have the option to use an older ejabberd-contrib in accordance with the ejabberd version you have installed, as I mentioned in a previous comment.

atomic-tang commented 5 years ago

I am trying to get it to work using the docker-ejabberd repo. So I am limited to what I can install and do with the container 😞

badlop commented 5 years ago

Ok, then install the module from this old commit: git checkout 156331c

atomic-tang commented 5 years ago

Ok my docker container is finally running with the module installed after playing around and reading #200 but now I am getting the following error whenever I try to authenticate via websocket connection: (websocket|<0.585.0>) Failed c2s PLAIN authentication for username@host from 100.115.174.137: Invalid username or password Since I am using ejabberd_auth_http, shouldn't ejabberd call the external api request to authenticate users? I've checked my main backend and it didn't receive any requests from ejabberd.

firecow commented 5 years ago

@atomic-tang I'm trying to make ejabberd_auth_http work with ejabberd/ecs:18.09 from dockerhub. Can you please share your Dockerfile? I'm not quite following the steps required to "circumvent" this issue.

firecow commented 5 years ago

Here is what i've got so far, but it is still giving me the Unknown option 'auth_opts'

FROM ejabberd/ecs:18.09

RUN exec bin/ejabberdctl "foreground" & sleep 10 \
    && bin/ejabberdctl modules_update_specs \
    && echo "Install http auth module" \
    && bin/ejabberdctl module_install ejabberd_auth_http \
    && echo "Copying .so and .beam file into ebin" \
    && cp .ejabberd-modules/sources/ejabberd-contrib/ejabberd_auth_http/deps/fusco/ebin/*.beam .ejabberd-modules/ejabberd_auth_http/ebin/ \
    && cp .ejabberd-modules/sources/ejabberd-contrib/ejabberd_auth_http/deps/cuesport/ebin/*.beam .ejabberd-modules/ejabberd_auth_http/ebin/ \
    && cp .ejabberd-modules/sources/ejabberd-contrib/ejabberd_auth_http/deps/fusco/priv/*.so .ejabberd-modules/ejabberd_auth_http/priv/ \
    && echo "Install rest module" \
    && bin/ejabberdctl module_install mod_rest

COPY ejabberd.yml /home/ejabberd/conf/ejabberd.yml

Is this even the right way to install contrib modules in a docker setup?

atomic-tang commented 5 years ago

@firecow as @badlop mentioned before you need to also copy the beam files in .ejabberd-modules/ejabberd_auth_http/ebin/* to lib/ejabberd-18.9.0/ebin/ but you will get a permission denied error when you try to do this in your RUN command of your docker file.

To overcome this, you will need to have the beam files in your directory/host first so that you can add another COPY command in your dockerfile to copy these files into lib/ejabberd-18.9.0/ebin/ – the same way you had copied the ejabberd.yml file into the /home/ejabberd/conf/ejabberd.yml

To get these files you can first run the default build i.e. ejabberd/ecs:18.09 and running docker exec -it <container-id> sh to access the container's shell. Then manually install the modules in the shell using bin/ejabberdctl modules_update_specs and bin/ejabberdctl module_install ejabberd_auth_http. Once installed, you will be able to download the files from the container onto your machine by running docker cp <container-id>:/home/ejabberd/.ejabberd-modules/ejabberd_auth_http/ebin <whatever path you want on your machine>.

Finally, in your docker file you can add COPY <path to beam files>/* lib/ejabberd-18.9.0/ebin/ and start building the docker image. But on another note, I tried running your dockerfile and it seems that the ejabberd version is 18.6.0 and not 18.9.0, so make sure to change lib/ejabberd-18.9.0/ebin/ to lib/ejabberd-18.6.0/ebin/.

badlop commented 5 years ago

now I am getting the following error whenever I try to authenticate via websocket connection:

Do you mean, you get that auth error when using websocket, but works when using other connection method?

firecow commented 5 years ago

Thanks for helping me @atomic-tang

FROM ejabberd/ecs:18.09

COPY modules/ejabberd_auth_http /home/ejabberd/.ejabberd-modules
COPY modules/ejabberd_auth_http/ebin/* /home/ejabberd/lib/ejabberd-18.6.0/ebin/

COPY ejabberd.yml /home/ejabberd/conf/ejabberd.yml

Still no luck....

ejabberd_1  | 13:44:44.636 [error] Unknown option 'auth_opts'

I don't even have the auth_opts in my ejabberd.yml Can you spot any obvious mistakes?

firecow commented 5 years ago

Doh...

FROM ejabberd/ecs:18.09

COPY modules/ejabberd_auth_http /home/ejabberd/.ejabberd-modules/ejabberd_auth_http
COPY modules/ejabberd_auth_http/ebin/* /home/ejabberd/lib/ejabberd-18.6.0/ebin/

COPY ejabberd.yml /home/ejabberd/conf/ejabberd.yml

Here is a setup that works

ejabberd.yml

auth_method: http
auth_opts:
  host: "http://nginx"
  path_prefix: "/"
auth_use_cache: false
auth_password_format: plain

nginx.conf

location /check_password {
    return 200 'true';
}

location /user_exists {
    return 200 'true';
}
cromain commented 5 years ago

it's best to just port that module to master (see #263) then create a container which depends on ejabberd/ecs and just does module_install, instead of copying an older version from local host with potential compilation incompatibilities.

damirci commented 5 years ago

Doh...

FROM ejabberd/ecs:18.09

COPY modules/ejabberd_auth_http /home/ejabberd/.ejabberd-modules/ejabberd_auth_http
COPY modules/ejabberd_auth_http/ebin/* /home/ejabberd/lib/ejabberd-18.6.0/ebin/

COPY ejabberd.yml /home/ejabberd/conf/ejabberd.yml

Here is a setup that works

ejabberd.yml

auth_method: http
auth_opts:
  host: "http://nginx"
  path_prefix: "/"
auth_use_cache: false
auth_password_format: plain

nginx.conf

location /check_password {
    return 200 'true';
}

location /user_exists {
    return 200 'true';
}

I did the same actions on my instance and it fails on start, and surprisingly with no error just logs on ejabberd.log like below:

2018-11-26 12:15:20.462 [notice] <0.97.0>@lager_file_backend:152 Changed loghwm of c:/ProgramData/ejabberd/logs/error.log to 100 2018-11-26 12:15:20.462 [notice] <0.97.0>@lager_file_backend:152 Changed loghwm of C:/ProgramData/ejabberd/logs/ejabberd.log to 100 2018-11-26 12:15:20.813 [info] <0.80.0>@ejabberd_config:start:69 Loading configuration from C:/ProgramData/ejabberd/conf/ejabberd.yml

firecow commented 5 years ago

@damirci What happens after Loading configuration from C:/ProgramData/ejabberd/conf/ejabberd.yml

damirci commented 5 years ago

@firecow there is no other log in files and just ejabberd start fails.

TheDuc commented 5 years ago

I followed the same steps, but the container won't start because of the following error:

08:20:12.512 [debug] Loading ejabberd_auth_http at localhost
08:20:12.513 [warning] Third-party module 'ejabberd_auth_http' doesn't export options validator; consider to upgrade the module
08:20:12.513 [critical] Failed to start module ejabberd_auth_http because it doesn't export start/2 callback: is it really an ejabberd module?
08:20:12.514 [critical] ejabberd initialization was aborted because a module start failed.

do I need to copy some extra files, or is ejabberd_auth_http outdated?

tomhoefer commented 5 years ago

I had the same issue and thanks to https://github.com/processone/ejabberd-contrib/issues/262#issuecomment-4398856 I could fix it. However is there any plan to provide an official contribution in order to get rid of that inconvenient workaround?

cromain commented 5 years ago

I guess it should be working out of the box using ejabberd/ecs:18.12.1 Closing this as I understand root problem was ejabberd_auth_http HEAD was beyond older 18.09 API.