Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

0.9.5 doesn't work without defining password for redis anymore #219

Open
jab3z opened this issue Jun 10, 2022 · 36 comments
Open

0.9.5 doesn't work without defining password for redis anymore #219

jab3z opened this issue Jun 10, 2022 · 36 comments

Comments

@jab3z
Copy link

jab3z commented Jun 10, 2022

Hello!

After upgrading to 0.9.5 if no password defined for redis url will throw an error:

redis.exceptions.DataError: Invalid input of type: 'NoneType'. Convert to a bytes, string, int or float first.

redis.exceptions.AuthenticationWrongNumberOfArgsError: wrong number of arguments for 'auth' command
On 0.9.4 works fine.

BR,
Dacian

@kencochrane
Copy link
Collaborator

Most likely relates to #218

@erdos4d any ideas?

@banderoz
Copy link

I'd like to add more details about the issue that @jab3z described above.

If there are no username and password in a redis url, django-defender sets username to 'default' and password to None by default.
Since the username is not None or an empty string, redis-client tries to authorize and raises AuthenticationWrongNumberOfArgsError and DataError.

IMO, a way should be added to specify username as None or an empty string during the StrictRedis initialization in django-defender if a user's redis url doesn't contain username.

@erdos4d
Copy link

erdos4d commented Jun 24, 2022

I'm on Ubuntu 22.04 with a clean install of redis 6.0.16 and defender at 0.9.5. I can set DEFENDER_REDIS_URL to redis://127.0.0.1:6379 and it works fine, I can login to the admin and see the attempt. By my reading of the code, this should set username as default and password as None in the StrictRedis constructor. Am I missing something to reproduce this? Can someone share a url/config that will reproduce? Thanks and sorry if this messed anyone up out there.

@banderoz
Copy link

@erdos4d forgot to mention, redis://127.0.0.1:6379 works fine for me too. I get the error while using a real production redis url, something like redis://abc.def.amazonaws.com:6379/1. Redis v5.0.6 and redis-client v4.3.3 are used in production.

@jab3z
Copy link
Author

jab3z commented Jun 24, 2022

Hello,

I haven't debugged why and how the error occurs, simply found the faulty package, checked the release log to not have major changes and reverted to the old version.

Tested only locally with Redis running on docker, but the following URLs were throwing the error when login into admin:

redis://127.0.0.1:6379
redis://127.0.0.1:6379/1
redis://localhost:6379
redis://localhost:6379/1

Let me know if you'd like me to raise a PR with the fix.

BR,
Dacian

@LuberLinder
Copy link

LuberLinder commented Jul 27, 2022

That error happend to me too and also only on the production server. What I did was:

  1. Setting password "mypassword" for redis on the server (by editting /etc/redis/redis.conf or via redis-cli):
root@server:~# redis-cli 
127.0.0.1:6379> config set requirepass mypassword
127.0.0.1:6379> quit
root@server:~# service redis-server restart
  1. Adding DEFENDER_REDIS_URL to Django's settings.py:
DEFENDER_REDIS_URL = 'redis://:mypassword@localhost:6379/0'

That's it. To see blocked users/ips:

root@server:~# redis-cli
127.0.0.1:6379> auth mypassword
127.0.0.1:6379> scan 0

To quick check, for example, if the user "admin" is blocked:

127.0.0.1:6379> get defender:blocked:username:admin

To quick unblock user "admin":

127.0.0.1:6379> del defender:blocked:username:admin

@pmulgaonkar
Copy link

I am getting this error with django-defender 0.9.6 and redis 4.3.5. My Django is 3.2.16.
I cannot set a password on redis since it is used by several other applications. Is there a workaround?
--p

@kencochrane
Copy link
Collaborator

What do you have for defender settings? Specifically "DEFENDER_REDIS_URL" and "DEFENDER_REDIS_NAME" ?

@kencochrane
Copy link
Collaborator

Also, what version of redis server are you using?

@pmulgaonkar
Copy link

Redis server v=5.0.3
DEFENDER_REDIS_URL = 'redis://127.0.0.1:6379'
DEFENDER_REDIS_NAME is not set (docs say that if _NAME is set, it overrides _URL).

Not necessarily relevant, but the other settings in base.py are:
DEFENDER_LOGIN_FAILURE_LIMIT = 5
DEFENDER_BEHIND_REVERSE_PROXY = True
DEFENDER_LOCK_OUT_BY_IP_AND_USERNAME = True
DEFENDER_ACCESS_ATTEMPT_EXPIRATION = 1
DEFENDER_STORE_ACCESS_ATTEMPTS = True
DEFENDER_COOLOFF_TIME = 900
DEFENDER_LOCKOUT_TEMPLATE = 'registration/login_failed.html'

@pmulgaonkar
Copy link

Additional details: And the system is on Alma 8. Python version is 3.6.8.

@pmulgaonkar
Copy link

Here is the full traceback. Dump happens right when the initial login form loads. Well before user enters anything into the credentials field.

Environment:

Request Method: GET
Request URL: https://192.168.1.37/login/

Django Version: 3.2.16
Python Version: 3.6.8
Installed Applications:
['django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.sites',
'django_filters',
'rest_framework.authtoken',
'rest_framework',
'allauth',
'allauth.account',
'allauth.socialaccount',
'allauth.socialaccount.providers.amazon',
'allauth.socialaccount.providers.google',
'allauth.socialaccount.providers.linkedin',
'defender',
'resources',
'rulesstatus',
'rules',
'profiles',
'users',
'reports',
'aws',
'ibm_broker']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'defender.middleware.FailedLoginMiddleware']

Traceback (most recent call last):
File "/home/raxak/.virtualenvs/raxak/lib/python3.6/site-packages/redis/connection.py", line 713, in on_connect
auth_response = self.read_response()
File "/home/raxak/.virtualenvs/raxak/lib/python3.6/site-packages/redis/connection.py", line 839, in read_response
raise response

During handling of the above exception (wrong number of arguments for 'auth' command), another exception occurred:
File "/home/raxak/.virtualenvs/raxak/lib/python3.6/site-packages/django/core/handlers/exception.py", line 47, in inner
response = get_response(request)
File "/home/raxak/.virtualenvs/raxak/lib/python3.6/site-packages/django/core/handlers/base.py", line 181, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/raxak/.virtualenvs/raxak/lib/python3.6/site-packages/django/views/generic/base.py", line 70, in view
return self.dispatch(request, *args, **kwargs)
File "/home/raxak/.virtualenvs/raxak/lib/python3.6/site-packages/django/utils/decorators.py", line 43, in _wrapper
return bound_method(*args, **kwargs)
File "/home/raxak/.virtualenvs/raxak/lib/python3.6/site-packages/defender/decorators.py", line 21, in wrapper
if utils.is_already_locked(request):
File "/home/raxak/.virtualenvs/raxak/lib/python3.6/site-packages/defender/utils.py", line 393, in is_already_locked
ip_blocked = is_source_ip_already_locked(get_ip(request))
File "/home/raxak/.virtualenvs/raxak/lib/python3.6/site-packages/defender/utils.py", line 386, in is_source_ip_already_locked
return REDIS_SERVER.get(get_ip_blocked_cache_key(ip_address))
File "/home/raxak/.virtualenvs/raxak/lib/python3.6/site-packages/redis/commands/core.py", line 1705, in get
return self.execute_command("GET", name)
File "/home/raxak/.virtualenvs/raxak/lib/python3.6/site-packages/redis/client.py", line 1235, in execute_command
conn = self.connection or pool.get_connection(command_name, **options)
File "/home/raxak/.virtualenvs/raxak/lib/python3.6/site-packages/redis/connection.py", line 1387, in get_connection
connection.connect()
File "/home/raxak/.virtualenvs/raxak/lib/python3.6/site-packages/redis/connection.py", line 623, in connect
self.on_connect()
File "/home/raxak/.virtualenvs/raxak/lib/python3.6/site-packages/redis/connection.py", line 719, in on_connect
self.send_command("AUTH", self.password, check_health=False)
File "/home/raxak/.virtualenvs/raxak/lib/python3.6/site-packages/redis/connection.py", line 800, in send_command
self.pack_command(*args), check_health=kwargs.get("check_health", True)
File "/home/raxak/.virtualenvs/raxak/lib/python3.6/site-packages/redis/connection.py", line 858, in pack_command
for arg in map(self.encoder.encode, args):
File "/home/raxak/.virtualenvs/raxak/lib/python3.6/site-packages/redis/connection.py", line 109, in encode
f"Invalid input of type: '{typename}'. "

Exception Type: DataError at /login/
Exception Value: Invalid input of type: 'NoneType'. Convert to a bytes, string, int or float first.

@kencochrane
Copy link
Collaborator

@pmulgaonkar any chance you can try this version out? I think it will fix your issue, but not 100% #227

@pmulgaonkar
Copy link

Sorry. I don't understand. You want me to pull the file [defender/connection.py] and replace the one in my current build?
Or do you want me to try with redis >= 6

--p

@kencochrane
Copy link
Collaborator

Try with the 'connection.py' file that is in that PR/branch on your local build, using your current redis server.

Ken

@pmulgaonkar
Copy link

Tried it. Error went away and login was permitted. However defender does not trigger even after multiple incorrect password attempts.

@kencochrane
Copy link
Collaborator

I'm glad the error went away, but I'm confused as to why defender isn't working. Does it work fine with the older version 0.9.4?

@pmulgaonkar
Copy link

Will revert version and try again, but we have been using defender successfully for a long time with defender 0.6.0. Now going through the process of upgrading along with redis and django, and started with 0.9.6.

But downgrading to 0.9.4 also does not not work. No redis error, but defender functionality (blocking) does not happen.

Probably something in my code since we are using a custom login function that we had to modify while upgrading django. (Old system was still on django 1.11) Probably something we are doing wrong.

Will test and report.

kencochrane added a commit that referenced this issue Feb 23, 2023
* fixing issue #219 don't add Redis username by default
@kencochrane
Copy link
Collaborator

At first look, that looks fine to me. Not sure why that isn't working.

@pmulgaonkar
Copy link

pmulgaonkar commented Feb 25, 2023

My previous comment vanished. I systematically redid the code and now everything is working, but with 0.9.4.

Thanks for all your help @kencochrane Really appreciate it.

@kencochrane
Copy link
Collaborator

Great, my fix has been merged into the master branch. Feel free to try that version, hopefully that works for you.

I'll cut a new release this weekend when I get a chance.

@kencochrane
Copy link
Collaborator

@pmulgaonkar @jab3z I released 0.9.7 with the fix for using Redis 5 with no password; see if that works for you.

@warmnerds
Copy link

am having the same problem here, redis server activates the localhost url even when i hardcode the redis url from a managed redis server

@kencochrane
Copy link
Collaborator

What versions are you using?

@warmnerds
Copy link

warmnerds commented Nov 20, 2023 via email

@warmnerds
Copy link

warmnerds commented Nov 20, 2023 via email

@kencochrane
Copy link
Collaborator

And you don’t see any errors or messages in the logs at all?

do you see the same error when running the version that is on the master branch?

@warmnerds
Copy link

warmnerds commented Nov 20, 2023 via email

@kencochrane
Copy link
Collaborator

Ok, do you see that same error using the latest version on the master branch?

@warmnerds
Copy link

Yes, am seeing the same error. even with the latest versions. and it is a stressful experience...

@kencochrane
Copy link
Collaborator

Ok, does your managed URL have any special characters in it? Could you post the config that you are using (mask out any sensitive info) so we can try and duplicate what you are seeing.

@kencochrane
Copy link
Collaborator

One more question, how are you installing the latest version on master?

@warmnerds
Copy link

i do not get this but am using pip install ... the statement am not fully getting 'One more question, how are you installing the latest version on master?'

as for the caches..
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "*********************:6379",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
}
}
}

and the answer is yes the url has special characters, just to be precise am using render.com managed redis. you can try it out it is completely free....

@kencochrane
Copy link
Collaborator

So you did

pip install git+https://github.com/jazzband/django-defender.git

@kencochrane
Copy link
Collaborator

Have you tried to set the DEFENDER_REDIS_URL or DEFENDER_REDIS_NAME ? or any of the other DEFENDER_ variables?

@warmnerds
Copy link

setting the DEFENDER_REDIS_URL, was all i wanted and everything now works fine, if anything then i will let you know..

in your documentation explicitly outline that DEFENDER_REDIS_URL has to be for the managed url or they have to set it clearly in production otherwise it loads default redis localhost. this will raise errors....

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants