What are best practices for setting up a Revshare Pointer?

https://github.com/sharafian/revshare-pointer

I set up a Revshare Pointer for a mobile web app that I am developing. I will be posting details of my set up, but the jist of it is as follows:

  • One AWS CentOS instance for the Revshare Pointer + moneyd (the “App Server”)
  • One AWS CentOS instance the Nginx reverse proxy server (the “Web Server”)

It would be great to kick start a discussion on best practices for a Revshare Pointer, especially as it relates to:

  • Revshare Pointer configuration
  • Ngnix configuration
  • security
1 Like

Please see below for the details of my set up as well as some questions.

Set up

  • two Amazon Machine Image’s CentOS 7 (x86_64) - with Updates HVM.
  • one instance for the koa app + moneyd (the “App Server”) and one for the Nginx reverse proxy (the “Web Server”)

App Server

  • cloned Revshare Pointer from https://github.com/sharafian/revshare-pointer.git
  • configured index.js for private networking (i.e., added private IP address to app.listen())
  • installed Moneyd
  • installed PM2 to run the revshare pointer in the background and to launch it on system startup

Questions

  • I installed moneyd with the command yum install -y https://codius.s3.amazonaws.com/moneyd-xrp-4.0.0-1.x86_64.rpm taken from the Codius tutorial but this time around I also needed to separately install moneyd-xrp-uplink in order for Moneyd to work. What is the latest way to install Moneyd?
  • I noticed that the SPSP query of revshare pointer uses generateAddressAndSecret() that returns a Buffer for sharedSecret. Does this need to be converted to a string? When I curl my revshare pointer it returns a shared_secret that is a JSON coverted from a Buffer, {“type”:“Buffer”,“data”:[84,104,105,115,32,105,115,32,97,32,98,117,102,102,101,114,32,101,120,97,109,112,108,101,46]} but when I curl a payment pointer, e.g., $https://twitter.xrptipbot.com/sharafian it returns a shared_secret that is a string. The reason I ask is because the Coil Chrome Extension states that “Coil is donating” but the counter remains at 0, so I am trying to figure out the cause.

Web Server

  • installed Nginx
  • installed and ran certbot-nginx to obtain certificate
  • added directives for reverse proxy and enhanced security (I referenced the Codius nginx config file)
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

# Load dynamic modules. See /usr/share/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;

events {
  worker_connections 1024;
}

http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 2048;

    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;

    # Load modular configuration files from the /etc/nginx/conf.d directory.
    # See http://nginx.org/en/docs/ngx_core_module.html#include
    # for more information.
    include /etc/nginx/conf.d/*.conf;

    server {
        server_name  example.com www.example.com;
        root         /usr/share/nginx/html;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        location / {
	        proxy_pass http://PRIVATE_IP_ADDRESS:8080;
        	proxy_http_version 1.1;
        	proxy_set_header Upgrade $http_upgrade;
        	proxy_set_header Connection "upgrade";
        	proxy_set_header Host $host;
        	proxy_cache_bypass $http_upgrade
        }

        error_page 404 /404.html;
            location = /40x.html {
        }
  
        error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }
    
    listen [::]:443 ssl ipv6only=on; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

    ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384;
    ssl_ecdh_curve secp384r1;
    ssl_session_timeout 10m;
    ssl_session_cache shared:SSL:10m;
    ssl_session_tickets off;
    ssl_stapling on;
    ssl_stapling_verify on;
    
    resolver 1.1.1.1 1.0.0.1 valid=300s;
    resolver_timeout 5s;
  
    add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
    add_header X-Frame-Options DENY;
    add_header X-Content-Type-Options nosniff;
    add_header X-XSS-Protection "1; mode=block";

    }

    server {
    if ($host = www.example.com) {
        return 301 https://$host$request_uri;
    } # managey Certbot

    if ($host = example.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

        listen       80 default_server;
        listen       [::]:80 defau
`lt_server;
        server_name  example.com www.example.com;
    return 404; # managed by Certbot

}}

Questions

  • This config gives a Qualys A rating, but should anything be added/modified generally? Also, to potentially fix the issue that I am experiencing with the Coil Chrome Extension?

It’s awesome that you’re experimenting with this project! I unfortunately haven’t been able to devote too much time but if you documented how to run it then I hope it could be really useful to a lot of people.

I installed moneyd with the command yum install -y https://codius.s3.amazonaws.com/moneyd-xrp-4.0.0-1.x86_64.rpm taken from the Codius tutorial but this time around I also needed to separately install moneyd-xrp-uplink in order for Moneyd to work. What is the latest way to install Moneyd?

@wilsonianb has been working on an updated Moneyd RPM that he might be able to share some information about. Otherwise, if you have NPM on your system (with NVM so that you can install global modules) you can install moneyd as per the tutorial.

I noticed that the SPSP query of revshare pointer uses generateAddressAndSecret() that returns a Buffer for sharedSecret. Does this need to be converted to a string?

You’re right; pushing a fix for this right now.

This config gives a Qualys A rating, but should anything be added/modified generally? Also, to potentially fix the issue that I am experiencing with the Coil Chrome Extension?

Regarding your nginx config, it’s dangerous to expose your revshare pointer service like that. It’s meant to be run in the backend, where some kind of API is making calls to the add/remove pointer endpoints and essentially proxying the actual SPSP endpoint.

That’s how I initially thought of it, but given your use case I think it makes a lot of sense to allow it to be run standalone. Based on that, I think I’ll add authentication (if you or anyone else in the community wanted to take a stab at that it would be awesome, otherwise I’ll try to get to it sometime soon).

With auth configured and enabled for the add/remove pointer endpoints, it should be safe to expose it to the internet in the way you laid out. When you want to edit things, you could make curl commands locally with the auth token you configured, or I might also make a simple GUI that makes it easy to add/remove payment pointers.

Hope this helps!

Thanks for the feedback!

I can document how to run one and share it as soon as it is ready later this week.

I can take a stab at it. I hope that I can write some usable code. If there is anyone else in the community that wants to contribute, please let me know.

Thanks again! I’m glad this project exists in the first place.

Here are barebone instructions to set up a Revshare Pointer. I can write up a comprehensive one (with explanations) at a later date as soon as the authentication is added. If anyone has any suggestions to improve the set up, please let me know.

Prerequisites

  • Two AWS CentOS 7 (x86_64): one for your revshare pointer Koa app + Moneyd (App Server) and one for your Nginx reverse proxy server (Web Server)
  • Nodejs
  • An XRP Wallet
  • A domain

Set up App Server

  1. Ensure ports are open for 8080 (only traffic from Web Server’s private IP address), 22 in AWS

  2. ssh into your App Server and switch to the root user. Be sure to replace /path/my-key-pair with your own. Also, centos@ec2-198-51-100-1.compute-1.amazonaws.com with your own.

ssh -i
/path/my-key-pair centos@ec2-198-51-100-1.compute-1.amazonaws.com
sudo su

  1. Install Nodejs

curl -sL https://rpm.nodesource.com/setup_10.x | sudo bash -
yum install nodejs

  1. Install Moneyd

yum install -y https://codius.s3.amazonaws.com/moneyd-xrp-4.0.0-1.x86_64.rpm
npm install -g moneyd-uplink-xrp

  1. Configure and run Moneyd. You will be prompted to enter your secret so have your XRP wallet credentials ready.

moneyd xrp:configure
systemctl start moneyd-xrp
systemctl status moneyd-xrp

  1. Install git and clone revshare-pointer-server from github into folder /var/www/revshare

yum install -y git
git clone GitHub - sharafian/revshare-pointer: Create ILP payment pointers that split payments to multiple destinations /var/www/revshare

  1. Configure the Koa app for private networking. Replace paste here with the App Server’s private IP address.

cd /var/www/revshare
vi index.js

# /var/www/revshare/index.js
app
  .use(parser)
  .use(router.routes())
  .use(router.allowedMethods())
  .listen(process.env.PORT || 8080, ‘paste here’)
  1. Install dependencies and test it

sudo npm install
sudo npm install
node index
CTRL+C

  1. Install PM2

npm install -g pm2@latest

  1. Set up PM2 to run the revshare pointer in the background and to launch on system startup

pm2 start index.js
pm2 startup systemd

Set up Web Server

  1. Ensure ports are open for 80, 8080, 22, 443 in AWS

  2. ssh into your Web Server and switch to the root user

ssh -i /path/my-key-pair centos@ec2-198-51-100-1.compute-
1.amazonaws.com
sudo su

  1. Install and start Nginx

yum install epel-release
yum install nginx
systemctl start nginx
systemctl enable nginx

  1. Install Certbot for Nginx

yum install certbot-nginx

  1. Update and reload default config file. Find the server_name line to replace _ with your domain name so that it looks like this: server_name example.com www.example.com;

vi /etc/nginx/nginx.conf
nginx -t
systemctl reload nginx

  1. Create two A records for your domain wherever you do your DNS management

example.com. 300 IN A Your Web Server’s public IP address
*.example.com. 300 IN A Your Web Server’s public IP address

  1. Obtain certificate. Be sure to replace example.com and www.example.com with your domain name. Also, you will be asked a series of questions including one to choose whether HTTPS access is required or optional: choose 2, Secure – Make all requests redirect to secure HTTPS access

certbot –nginx -d example.com -d www.example.com

  1. Setup reverse proxy server. Find the line where location / is defined in the server block and insert the below code in between the brackets. Substitute ‘paste here’ with your App Server’s private IP address.

vi /etc/nginx/nginx.conf

# /etc/nginx/nginx.conf
location / {
  proxy_pass http://’paste here’:8080;
  proxy_http_version 1.1;
  proxy_set_header Upgrade $http_upgrade;
  proxy_set_header Connection 'upgrade';
  proxy_set_header Host $host;
  proxy_cache_bypass $http_upgrade;
}
  1. Check updates and reload Nginx

nginx -t
systemctl reload nginx

  1. Make sure that SElinux is set to allow Nginx to act as a proxy

setsebool -P httpd_can_network_connect 1

  1. Test it out! Replace https://twitter.xrptipbot.com/sharafian with your own Payment Pointer

curl -i -H “Accept: application/spsp4+json” -H “Content-Type: application/spsp4+json” -X GET https://twitter.xrptipbot.com/sharafian

I intend to use auth0’s JWT implementation for node.js for the authentication. Users will be able to login with a private key (stored in a .env file) and obtain a JWT access token. I’ll stick to the standard and define an exp claim for expiration. Users would include the access token in a request to the add/remove endpoints to make any modifications to the payout details. Thoughts, anyone?

I’ve written a HS256 based authentication for the Revshare Pointer. I referenced @sabinebertram repository for ilp-spsp-pull-payment-pointer as well as articles from auth0 and IETF. I’m still pretty new to koajs as well as authentication so feedback from the community would be appreciated!

You can try it out by following the instructions below (assumes you already have moneyd installed and running).

Install and run:

git clone --single-branch --branch feat/auth https://github.com/surferwat/revshare-pointer.git
cd revshare-pointer
npm install
DEBUG=revshare-pointer* node index

Login:

curl -i -H “Accept: application/json” -H “Authorization: Bearer test” -X POST http://localhost:8080/login

Create a revshare payment pointer (replace the word, token, with the access token that you received in the response when logging in)

curl -i -d ‘{“payout”: [{“percent”:90,“pointer”:“$twitter.xrptipbot.com/sharafian_“},{“percent”:10,“pointer”:”$twitter.xrptipbot.com/Coil”}]}’ -H “Content-Type: application/json” -H “Accept: application/json” -H “Authorization: Bearer token” -X POST http://localhost:8080/pointers/koa1

You can see the Revshare Pointer in action here: https://www.gorillarecipe.com

I added modify and delete endpoints. To install:

git clone --single-branch --branch feat/endpoints https://github.com/surferwat/revshare-pointer.git

@surferwat that’s an awesome effort :+1:

Thanks!

The authorize function in auth.js needs to be fixed. The next() needs to be preplaced with return next() otherwise the function suspends and passes control downstream before unwinding the stack to resume the upstream behavior which in this case results in a 404 even when the authorization is successful.

@surferwat Thanks for contributing to this project, those are great features! If you make a PR to my revshare-pointer repo then I’d like to review your changes so that we can merge these features in. It would also be great to merge your instructions into the README for this project

1 Like

Sounds good. I will make a PR as soon as it’s ready. Thank you!

I made a PR to your revshare-pointer repo for the authentication (#2), endpoints (#3), and README (#4).

Responded to your PRs; Had a few comments but overall looks good!

2 Likes