Marcus Whybrow
Marcus Whybrow

Reputation: 19998

Python Remote Procedure Call (Without the Remote Part)

I have a Python server which is not running as root, which fronts an application I am developing. However there are some application features which require access to RAW sockets which means root privileges.

Obviously I do not want to run the main server as root, and so my solution is to create a daemon process or command line script which runs as root providing guarded access to said features.

However I want put aside stdin/stdout communication and use an RPC style of interaction such as Pyro. But this exposes the RPC interface to anyone with network access to the machine, whereas I know that the process calling the RPC methods will be another process on the same machine.

Is there not a sort of inter-process procedure call standard which could be used in a similar (local machine only) fashion? I imagine the server doing something like this:

# Server not running as root
pythonically, returned, values = other_process_running_as_root.some_method()

And the process running as root exposing a method:

# Daemon running as root
@expose_this_method
def some_method():
    # Play with RAW sockets
    return pythonically, returned, values

Is anything like this possible?

Upvotes: 5

Views: 3260

Answers (3)

joeforker
joeforker

Reputation: 41747

This is an easy problem. You should be able to get what you want from any RPC mechanism that can use Unix sockets, or use regular TCP sockets but only accept connections from the loopback interface (listen on 127.0.0.1).

The multiprocessing library in the Python standard library supports local IPC, too. http://docs.python.org/library/multiprocessing.html#module-multiprocessing.connection

Upvotes: 2

Thomas K
Thomas K

Reputation: 40330

Following my comment, I was interested to see if it was possible, so I had a go at putting this together: https://github.com/takowl/ZeroRPC

Bear in mind that this is thrown together in an hour or so, so it's almost certainly inferior to any serious solution (e.g. any errors on the server side will crash it...). But it works as you suggested:

Server:

rpcserver = zerorpc.Server("ipc://myrpc.ipc")

@rpcserver.expose
def product(a, b):
    return a * b

rpcserver.run()

Client:

rpcclient = zerorpc.Client("ipc://myrpc.ipc")

print(rpcclient.product(5, 7))
rpcclient._stopserver()

Upvotes: 3

9000
9000

Reputation: 40884

Pyro has a number of security features specifically to limit the access to the RPC interface. Are these too much of a performance burden to use?

Upvotes: 0

Related Questions