The Ethernet node RPC port is open to the network security configuration being attacked


Ethereum supports RPC mode. When this mode is enabled, the Ethereum account can automatically complete some operations, such as automatic transfer to the wallet after digging out coins in the mine pool. Attackers mainly use RPC open ports, so they can protect themselves by limiting RPC ports.

1, The following main attack methods are analyzed:

  • 1. Batch scan common open RPC ports such as port 8545 or port 18545
  • 2. After scanning the open port, use eth.getBlockByNumber (query block height), eth.accounts (query wallet address) and eth.getBalance (query wallet balance) to perform corresponding actions.
  • 3. Keep trying to send the eth.sendTransaction command. If the command takes effect, it will transfer the balance in the wallet to the attacker's wallet. Some people will ask, the transfer needs the key to participate. How does the hacker bypass the key?

Originally, Ethereum accounts support the unlock account command, which is provided to facilitate some mechanized transactions. In token trading, some people use computers to carry out high-frequency trading to obtain the fluctuation spread (the same is true for high-frequency trading of stocks, sometimes trading back and forth dozens of times a minute).
Ethereum can set in high-frequency transactions (or automatic transfer of ore pool) for a period of time without entering a password, and the length of time is specified by the user. If the hacker sends the "balance transfer" instruction within this period of time, the Ethereum account (wallet or web account) will automatically perform this operation and transfer the Ethereum in the wallet to the hacker's wallet.

I have been attacked in my own Ethereum private chain and public chain, hoping to attract everyone's attention.

2, How should users prevent such attacks?

2.1 port restrictions

  • 1. Change the default RPC API port. The configuration method is as follows: – rpcport 18545 or -- wsport 18546; If the node deployed in the docker container mode is used, the port can be modified when the container starts mapping ports (making port scanning ineffective)

  • 2. Change the RPC API listening address to a fixed IP address or network segment. The configuration method is as follows: – rpcaddr 192.168.1.100 or -- wsaddr 192.168.1.100, – rpcaddr 192.168.1.100/24 or -- wsaddr 192.168.1.100/24

Note: rpcaddr: HTTP-RPC server listening address, wsaddr: websocket server listening address

Note: this method is to restrict IP at the Ethereum node

  • 3. Configure a firewall or security group to restrict access to RPC API ports. For example, only 192.168.1.100 is allowed to access port 8545 (only commands from specific IP are accepted):
iptables -A INPUT -s 192.168.1.101 -p TCP --dport 8545 -j ACCEPT
iptables -A INPUT -p TCP --dport 8545 -j DROP

Or use UFW firewall. UFW or uncompleted firewall is an interface of iptables to simplify the process of configuring firewall. It is generally used in ubuntu system

1.install UFW 
  $ sudo apt-get install ufw

2.Set default policy
  $ sudo ufw default deny incoming
  $ sudo ufw default allow outgoing

3.Allow Ethernet p2p Network port
 We will also enable the Ethereum network so that our nodes can communicate and synchronize with the public blockchain network. For example, the Ethernet port is 30303
  $ sudo ufw allow 30303

Note: this method is to restrict the IP and port in the server of the deployment node. The physical server can be restricted through iptables firewall, and the ECS can be restricted through security group

  • 4. Enable the RPC port. We only allow connections from our trusted nodes to our Ethereum clients. The default RPC port for the Ethereum port is 8545.
$ sudo ufw allow from <IP addr> to any port 8545

For example, if my external server IP address is 192.168.1.101, if you use a different RPC port than 8545, you should also specify the corresponding port.

sudo ufw allow from 192.168.1.101 to any port 8545

Note: UFW and sudo ufw enable are required to set the above rules

To sum up, it is recommended that you configure it to allow everyone to connect to Ethereum RPC and network ports. Be sure to allow any other incoming connections required by the server in the firewall or security group, while limiting any unnecessary connections for your server functionality and security.

2.2 private key security

  • 1. The account information (keystore) should not be stored on the node (because the account is not on the node, the unlockAccount will not be used)

Note: usually, the account information should not be stored in the node, but if you need to flush the transactions of an account, it may be operated manually by the node. At this time, make sure that only the trusted IP address of your node rpc port can be connected, otherwise the account funds may be transferred.

  • 2. For any transfer, sendTransaction and sendRawTransaction of web3 are used to send the transaction signed by the private key (restrict unsafe transfer commands)
  • 3. The private key is physically isolated (such as cold wallet, manual copying) or stored in high-strength encryption, and the security of the key is guaranteed

Note: in addition to the above points, there are many points to pay attention to in the security configuration of the private key. Because this article describes the network security of the RPC port, the private key security will not be repeated here.

3, RPC port access encryption and access control

If the geth node has to be exposed to the public network, it will face many security risks. One possible remedy is to encrypt RPC access. Higher security can be achieved through nginx's HTTP basic Auth(Http basic authentication) technology.

Principle: by configuring nginx's reverse proxy and encryption technology, you can assign a new url to the application running on linux. Accessing the application is equivalent to accessing this url. If external users want to access this url, they must enter a user name and password, otherwise access will be denied. For the geth node, the RPC port must be exposed to all users before. If NBHA technology is adopted, a url is assigned to geth, and the user name and password are required to access the geth node. At this time, the geth node does not have to open the RPC port.

3.1 nginx configuration

For the deployment method of nginx using docker, please refer to my previous articles [three minute tutorial] docker rapid deployment of nginx service

After the nginx service is deployed, perform the following operations:

  • Install htpasswd tool
# docker exec -it nginx bash
# apt-get update
# apt-get install apache2-utils -y
  • Create an authenticated user name and password
# htpasswd -c /etc/nginx/geth.htpasswd eth  
New password:   Input password
Re-type new password: Enter the password again
Adding password for user eth   (Is already a user eth Add password)

3.2 http request configuration

A password file named geth.htpasswd will be created under / etc/nginx, and the user name will be set to eth. Entering the above command will prompt the user to enter the password twice. Modify the nginx configuration, open the file / etc/nginx / sites enabled / default, and modify the contents as follows:

server {
    listen 80 default_server;
    server_name localhost;
 
    location / {
        try_files $uri $uri/ =404;
    }
 
    location /eth {
        auth_basic "Restricted Area";
        auth_basic_user_file /etc/nginx/geth.htpasswd;
        proxy_pass http://localhost:8545;
      }
    access_log  /var/log/nginx/localhost.log  main;
}

Here, set the name of the server as localhost, the url corresponding to geth as localhost/eth, and the corresponding password file through auth_basic_user_file instructions.

At this time, you can access it in the browser to see the effect. The effect that should appear at this time should be:

visit: http://localhost/ , page 404 appears

visit: http://localhost/eth After entering the correct user name and password, click OK. If there is no error, the configuration is successful.

So far, nginx has successfully built a layer of security protection for geth, and mapped an external access url to geth. Now you don't have to access geth through http: / /: but directly access the mapped url. Such as geth attach http://username:password@ip/eth, so it's time to disable external access to the rpc port exposed by geth. Tencent cloud and Alibaba cloud have security groups to implement this operation.

curl -H "Content-Type: application/json" -X POST --data '{"jsonrpc":"2.0","method":"eth_syncing","params":[],"id":1}' http://eth:123456@lijie.bbef.top/eth

3.3 Android ios access configuration

The Http module used by web3j is OkHttp3. The user name and password information required for authentication can be added in the way of OkHttp3 adding authentication. When Http authentication is not used, web3j build the Admin object as follows:

Admin ethClient;
ethClient = Admin.build(new HttpService(url));

How to add authentication user name and password:

private static OkHttpClient buildBasicAuthClient() {
        return new OkHttpClient.Builder().authenticator(new Authenticator() {
            @Override
            public Request authenticate(Route route, Response response) throws IOException {
                String credential = okhttp3.Credentials.basic(Define.userName, Define.passwd);
                return response.request().newBuilder().header("Authorization", credential).build();
            }
        }).build();
 }
 
Admin ethClient;
ethClient = Admin.build(new HttpService(url,buildBasicAuthClient(),false));

3.4 nginx cross domain configuration

OK, now you can use Web3j to access the geth node with Http authentication protection.
The above is suitable for Android clients, while ios clients call web3.js to access Http Basic Authentication to protect resources
ios clients access geth differently from Android clients. Since there is no web3j like library of open source and mature OC language, the ios side can only establish an Html page through webview, and call the API function of web3.js through JS in the page to access geth. When accessing the geth node with Http Basic Authentication in the browser, an error will be reported. This is the problem that the browser reports JS cross domain access. After a Google search, follow the online solution to CROS and add the configuration file of nginx to the final configuration:

server {
    listen 80 default_server;
    server_name localhost;
 
    location / {
        try_files $uri $uri/ =404;
    }
 
    location /eth {
        auth_basic "Restricted Area";
        auth_basic_user_file /etc/nginx/geth.htpasswd;
        proxy_pass http://localhost:8545;
        if ($request_method = 'OPTIONS') {
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers'         'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Auth        orization';
        
        add_header 'Access-Control-Max-Age' 1728000;
        add_header 'Content-Type' 'text/plain charset=UTF-8';
        add_header 'Content-Length' 0;
        return 204;
          }
     }
    access_log  /var/log/nginx/localhost.log  main;
}

3.5 nginx https configuration

Of course, in addition to HTTP basic authentication, you can also configure Https with certificate protection, which is more secure.
The transmission process of HTTP protocol is clear text, so it is very unsafe to use HTTP protocol to transmit private information. HTTPS protocol is a network protocol constructed by SSL+HTTP protocol, which can carry out encrypted transmission and identity authentication. It is safer than HTTP protocol. It can encrypt the transmitted content. HTTPS requires a CA certificate. Alibaba cloud can apply for a free Symantec certificate. Alibaba cloud certificates need to have an available domain name, which is mapped to the ip address of the node. After applying for the certificate, download it to the node, and then configure it in the configuration file of nginx.

nginx configures HTTPS as follows:

server{
    listen 443 ssl; 
    server_name localhost;
    charset utf-8;
    ssl_certificate /etc/nginx/cert/xxx.pem;
    ssl_certificate_key  /etc/nginx/cert/xxx.key;
    ssl_session_timeout 5m;
    ssl_protocols  TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers AESGCM:ALL:!DH:!EXPORT:!RC4:+HIGH:!MEDIUM:!LOW:!aNULL:!eNULL;
    ssl_prefer_server_ciphers on;
    location / {
        try_files $uri $uri/ =404;
    }
 
    location /eth {
        auth_basic "Restricted Area";
        auth_basic_user_file /etc/nginx/geth.htpasswd;
        proxy_pass http://localhost:8545;
        if ($request_method = 'OPTIONS') {
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';

        add_header 'Access-Control-Max-Age' 1728000;
        add_header 'Content-Type' 'text/plain charset=UTF-8';
        add_header 'Content-Length' 0;
        return 204;
        }
     } 
     access_log  /var/log/nginx/localhost.log  main;
}

After restarting nginx service, https can be used

3.6 nginx access control configuration

In some cases, we may also need to allow only some IP S to access. Of course, this requirement can be implemented on the security group of Alibaba cloud or Tencent cloud, or using the iptables firewall of the server. The following method is implemented by using the function of access control in nginx. Nginx is configured as follows:

server{
    listen 443 ssl; 
    server_name localhost;
    charset utf-8;
    ssl_certificate /etc/nginx/cert/xxx.pem;
    ssl_certificate_key  /etc/nginx/cert/xxx.key;
    ssl_session_timeout 5m;
    ssl_protocols  TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers AESGCM:ALL:!DH:!EXPORT:!RC4:+HIGH:!MEDIUM:!LOW:!aNULL:!eNULL;
    ssl_prefer_server_ciphers on;
    location / {
        try_files $uri $uri/ =404;
    }
 
    location /eth {
        auth_basic "Restricted Area";
        auth_basic_user_file /etc/nginx/geth.htpasswd;
        proxy_pass http://localhost:8545;
        if ($request_method = 'OPTIONS') {
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';

        add_header 'Access-Control-Max-Age' 1728000;
        add_header 'Content-Type' 'text/plain charset=UTF-8';
        add_header 'Content-Length' 0;
        return 204;
        }
       #####Restrictions are only partial IP visit##############
       allow 49.7.66.132;
       allow 124.65.8.139;
       deny all;
       ######Restrictions are only partial IP visit##############
     } 
     access_log  /var/log/nginx/localhost.log  main;
}

For example, in the above configuration, the IP that appears in allow is accessible, and the IP that does not appear in allow is accessible https://localhost/eth A 403 access denied status code will appear.

The above is all the content shared today.

I hope you can solve your actual needs and problems through the above methods.

If you have any questions during the deployment process, you can scan the following QR code and add my personal wechat. Note: Region - career direction - nickname. Welcome to join the blockchain technology exchange group to learn and communicate with more blockchain technology leaders.

Original is not easy, codeword is not easy. If you think this article is a little useful to you, please like this article, leave a message or forward it, because this will be the driving force for me to output more high-quality articles. Thank you!

Keywords: rpc Web Security Ethereum

Added by uatec on Mon, 25 Oct 2021 10:05:28 +0300