-
Notifications
You must be signed in to change notification settings - Fork 5.7k
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
Add password authentication to Redis ports #2952
Conversation
Test PASSed. |
Test FAILed. |
@@ -1315,6 +1365,7 @@ def start_ray_processes(address_info=None, | |||
num_redis_shards=1, | |||
redis_max_clients=None, | |||
redis_protected_mode=False, | |||
redis_password=None, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We probably want to remove all instances of the redis_protected_mode
/protected_mode
argument, right? And also essentially remove everything from #2697, right (e.g., the code for making the temp file and stuff)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I was planning to do that in a follow-up PR so I don't change too much at once. If you think it's more appropriate, I'll clean up redis_protected_mode
in this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A follow up PR is fine.
src/ray/gcs/redis_context.cc
Outdated
@@ -135,7 +135,30 @@ RedisContext::~RedisContext() { | |||
} | |||
} | |||
|
|||
Status RedisContext::Connect(const std::string &address, int port, bool sharding) { | |||
static std::string default_password = ""; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This appears in multiple places. Consider moving it to https://github.com/ray-project/ray/blob/master/src/ray/constants.h.
Test PASSed. |
Test PASSed. |
30ba031
to
7200454
Compare
Test PASSed. |
Test PASSed. |
Test PASSed. |
doc/source/security.rst
Outdated
----------------------------- | ||
|
||
Ray instances should run on a secure network without public facing ports. | ||
The most common threat for Ray instances is unautherized access to Redis, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo "unauthorized"
python/ray/test/test_ray_init.py
Outdated
password = "some_password" | ||
exception = None | ||
|
||
# Fix for #3045 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Include the full URL
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, I don't think we need to make a global variable, in generally we should be doing less in the fixture and more in the actual test. Why not move everything to the actual tests and just leave something like
Lines 205 to 209 in 6240ccb
@pytest.fixture | |
def shutdown_only(): | |
yield None | |
# The code after the yield will run as teardown code. | |
ray.shutdown() |
in the fixture?
python/ray/test/test_ray_init.py
Outdated
|
||
@pytest.fixture | ||
def start_ray_with_password(): | ||
ray.shutdown() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are we calling ray.shutdown
at the start of the fixture? We don't do this in any of our other tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead, our fixtures usually do something like
ray.init()
yield None
ray.shutdown()
python/ray/test/test_ray_init.py
Outdated
try: | ||
info = ray.init(redis_password=password) | ||
except Exception as e: | ||
info = ray.init(redis_password=None) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the purpose of this codepath?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I intended to test that an exception is thrown when passing a redis_password
without using raylet, although I can do this instead:
Lines 2165 to 2167 in 6240ccb
@pytest.mark.skipif( | |
os.environ.get("RAY_USE_NEW_GCS") == "on", | |
reason="New GCS API doesn't have a Python API yet.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I'd just skip the test entirely in the non-raylet case. If you want to include a test for the non-raylet case then I'd just make it a separate test.
python/ray/test/test_ray_init.py
Outdated
|
||
|
||
@pytest.fixture | ||
def use_credis(): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can also just use
Lines 2165 to 2167 in 6240ccb
@pytest.mark.skipif( | |
os.environ.get("RAY_USE_NEW_GCS") == "on", | |
reason="New GCS API doesn't have a Python API yet.") |
python/ray/test/test_ray_init.py
Outdated
def test_raylet_only(self, start_ray_with_password, use_credis): | ||
password, info, exception, use_raylet = start_ray_with_password | ||
if use_raylet and not use_credis: | ||
assert exception is None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's natural to just run the test and if it raises an exception, then pytest will report the error. Instead, we're catching the exception and then asserting that the exception is not None
, which is very roundabout.
python/ray/test/test_ray_init.py
Outdated
|
||
|
||
class TestRedisPassword(object): | ||
def test_raylet_only(self, start_ray_with_password, use_credis): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These tests can probably all be combined into one.
src/ray/gcs/redis_context.cc
Outdated
@@ -135,7 +135,30 @@ RedisContext::~RedisContext() { | |||
} | |||
} | |||
|
|||
Status RedisContext::Connect(const std::string &address, int port, bool sharding) { | |||
Status authenticate_redis(redisContext *context, const std::string &password) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These functions don't follow the naming convention I think. @pcmoritz can comment, but I think it should be AuthenticateRedis
.
python/ray/test/test_ray_init.py
Outdated
# Check that we can run a task | ||
task_id = f.remote() | ||
ready, running = ray.wait([task_id], timeout=5000) | ||
assert len(ready) > 0, "Expected task to complete" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Kind of a nit, but task_id
should be object_id
.
Also, instead of doing wait
followed by an assert, maybe just do ray.get(object_id)
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you mind if I keep the ray.wait
? While testing, I ran into a case where ray.get
wouldn't fail, but block indefinitely (I think this was when I discovered the issues with the new GCS).
Test PASSed. |
Test PASSed. |
Test FAILed. |
@pschafhalter looks good to me except there are linting errors. Could you fix those? |
Test FAILed. |
Test PASSed. |
@igoriokas thanks! I'll fix this in a follow-up PR. |
What do these changes do?
ray.init(redis_password="my_password")
redis_password
is set, but Raylet is not runningRelated issue number
#2925
#2457