This patch enables one to configure a whitelist of RPC commands that can be called for each allowed client IP.
Let's look at the motivating use case for this feature. Consider a website that accepts bitcoin payments using the bitcoind API directly. The webserver and bitcoind are on separate servers. It is desirable that the webserver be able to call getnewaddress() and gettransaction (or listtransactions). It is highly undesirable (security risk) that the webserver be able to call any of the send* commands or stop command, or probably others, especially because the public-facing webserver is the most likely target to be attacked and possibly compromised.
At this point, let's not get distracted with a discussion about using hot wallets vs cold storage vs 3rd party API. Instead suffice to say that the website has a need to do this, but desires to be as secure about it as possible.
It is also possible to envision more complex scenarios with various client IPs, each with differering requirements / permissions, or all the same, as in a pool of frontend webservers.
Okay, so -rpcipcmds to the rescue. Now the site administrator can configure bitcoind to only allow desired RPC calls from the webserver IP. Any other command results in "Method not allowed for client IP." json-rpc error.
./bitcoind --help | grep rpcip -rpcipcmds=<ip>,<cmd> Allow only specific commands from specified IP address. <ip>,<cmd1>,<cmd2>,<cmd3>...
Example bitcoin.conf usage:
rpcallowip=192.168.2.200 rpcipcmds=192.168.2.200,getnewaddress rpcipcmds=127.0.0.1,getnewaddress,sendtoaddress,getinfo,stop,help
Implementation Notes:
If an IP is allowed with rpcallowip but does not have an rpcipcmds entry then all commands can be used.
WildCards in IP are accepted.
Works with single command invocation and also batch invocation.
For batch invocation, all commands are checked before any command is called. So all or nothing.
Some might find the syntax a little funky. I considered using <ip>:<cmd> format, one per line, but rejected it because it requires specifying the same IP over and over. The CSV format enables <ip>,<cmd>,<cmd>,<cmd>... per line and is easy to read/grok and to parse. So that was my thought process.
This is my first bitcoind modification effort, and my first ever github pull request. Also, I am not a networking expert, and my C++ is very rusty. It is likely something could have been done better, code or pull request does not meet standards, etc. If so, my apologies in advance. The patch meets my needs so far, and I felt I should contribute it in case it can benefit others. Feel free to re-work, re-write etc as necessary.
-rpcipcmds is kind of hard to read. I originally called it rpcallowipmethods. But that didn't format nicely with the other commands in the help. This does.
Testing:
- Has been briefly tested with both single and batch invocation from localhost as well as a remote IP. Tested with IPv4 addresses only.
- I did not create a unit test for it. Maybe could test with localhost.... remote IP seems hard.