Bitcoind
使與 bitcoind 伺服器的遠端 RPC 連接安全
我在 Ubuntu 伺服器上設置了一個 bitcoind 伺服器,我可以在伺服器上遠端執行命令。我正在使用 Java/RPC 執行此操作。要執行命令,我需要提供使用者名和密碼。但我認為這還不夠安全。這就是我在這裡問的原因。我怎樣才能使這個連接真正安全?首先,我認為我只能允許來自特定 IP 的請求,但這不起作用,因為我的應用程序在 Google 的 App Engine 上執行,因此沒有靜態 IP。
任何想法如何使這個安全?這是我的程式碼,如果感興趣的話:
import java.io.IOException; import java.util.Arrays; import java.util.List; import java.util.UUID; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.ParseException; import org.apache.http.auth.AuthScope; import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.util.EntityUtils; import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; public class RPCClient { private static final String COMMAND_GET_BALANCE = "getbalance"; private static final String COMMAND_GET_INFO = "getinfo"; private static final String COMMAND_GET_NEW_ADDRESS = "getnewaddress"; private JSONObject invokeRPC(String id, String method, List<String> params) { // CloseableHttpClient httpclient = HttpClientBuilder.create().build(); // // httpclient.getCredentialsProvider(); DefaultHttpClient httpclient = new DefaultHttpClient(); JSONObject json = new JSONObject(); json.put("id", id); json.put("method", method); if (null != params) { JSONArray array = new JSONArray(); array.addAll(params); json.put("params", params); } JSONObject responseJsonObj = null; try { httpclient.getCredentialsProvider().setCredentials(new AuthScope("55.233.188.139", 9332), new UsernamePasswordCredentials("myUser", "mySuperSecurePW")); StringEntity myEntity = new StringEntity(json.toJSONString()); System.out.println(json.toString()); HttpPost httppost = new HttpPost("http://55.233.188.139:9332"); httppost.setEntity(myEntity); System.out.println("executing request" + httppost.getRequestLine()); HttpResponse response = httpclient.execute(httppost); HttpEntity entity = response.getEntity(); System.out.println("----------------------------------------"); System.out.println(response.getStatusLine()); if (entity != null) { System.out.println("Response content length: " + entity.getContentLength()); // System.out.println(EntityUtils.toString(entity)); } JSONParser parser = new JSONParser(); responseJsonObj = (JSONObject) parser.parse(EntityUtils.toString(entity)); } catch (ClientProtocolException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ParseException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (org.json.simple.parser.ParseException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { // When HttpClient instance is no longer needed, // shut down the connection manager to ensure // immediate deallocation of all system resources httpclient.getConnectionManager().shutdown(); } return responseJsonObj; } public Double getBalance(String account) { String[] params = { account }; JSONObject json = invokeRPC(UUID.randomUUID().toString(), COMMAND_GET_BALANCE, Arrays.asList(params)); return (Double)json.get("result"); } public String getNewAddress(String account) { String[] params = { account }; JSONObject json = invokeRPC(UUID.randomUUID().toString(), COMMAND_GET_NEW_ADDRESS, Arrays.asList(params)); return (String)json.get("result"); } public JSONObject getInfo() { JSONObject json = invokeRPC(UUID.randomUUID().toString(), COMMAND_GET_INFO, null); return (JSONObject)json.get("result"); } public JSONObject getInfo(String command) { JSONObject json = invokeRPC(UUID.randomUUID().toString(), command, null); return (JSONObject)json.get("result"); } public static void main(String[] args) { System.out.println(new RPCClient().getInfo()); } }
編輯:我剛剛注意到您的問題要求 App Engine 特定的解決方案。此解決方案僅適用於您對執行程式碼的 Linux 伺服器有 100% 的控制權,因此這在 App Engine 上不起作用(或者我不知道它現在是否具有建構隧道的能力)。無論如何,我建議您將程式碼從應用引擎移動到虛擬伺服器,以更好地控制您的堆棧,因為如果輪詢 bitcoind 進行交易,您可能會很快達到 App Engine 的限制。
通過 SSH 從執行程式碼的電腦到執行
bitcoind
.建立這樣一個在斷開連接時重新啟動的隧道的一種簡單方法是AutoSSH。
這是一個 AutoSSH 範例腳本:
<http://www.ubuntugeek.com/automatically-restart-ssh-sessions-and-tunnels-using-autossh.html>
建議:
- 為節點與外部之間的通信建構 API-REST、WS 或任何等效項。
- 盡可能限制對 RPC 節點的訪問(僅在本地訪問節點),您應該將比特幣節點視為數據庫。僅使用您的 ubuntu 伺服器來執行 RPC 和外部服務。
- 永遠不要將與節點的連接暴露給外部。查看比特幣 RPC 文件以獲取更多資訊。
<https://bitcoincore.org/en/doc/>
抱歉,我的自動校對器讓我相信這是西班牙語論壇。