Skip to content

Commit 7ea3432

Browse files
authored
Sample nginx config for HTTP to HTTPS proxying (#49)
Sample nginx config for HTTP to HTTPS proxying Needed for validator providers who have authentication requirements to use their services.
1 parent 52b48b1 commit 7ea3432

File tree

5 files changed

+321
-0
lines changed

5 files changed

+321
-0
lines changed

doc/https-for-rpc-providers.md

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# HTTPS connections to RPC providers
2+
3+
The pyth-client code does not have native TLS support to connect to various RPC providers that require HTTPS connections in order to safeguard authentication credentials that a customer requires to access their services.
4+
5+
This lack will be remedied in a future release but in order to address the problem, we have provided some example `nginx` configurations for three providers as well as a wrapper configuration that will permit a developer or operations tech to run `nginx` locally without superuser privileges and on high numbered ports. The configurations as provided expose the following ports and map to the following providers:
6+
7+
| Port number | Provider | protocol notes |
8+
| ---- | ------------ | ------------------------------- |
9+
| 7800 | Blockdaemon | websocket only |
10+
| 7900 | Blockdaemon | HTTP RPC and websocket |
11+
| 7801 | Figment | websocket only |
12+
| 7901 | Figment | HTTP RPC and websocket |
13+
| 7802 | TritonOne | websocket only |
14+
| 7902 | TritonOne | HTTP RPC and websocket |
15+
16+
## Running `nginx` as a standalone, unprivileged process
17+
18+
1. Make sure `nginx` is installed on your machine, in your VM or, in your container.
19+
2. Clone a copy of this repository or copy the `nginx-configs` directory to the machine in question.
20+
3. `cd doc/nginx-configs`
21+
4. In `standalone-dev-nginx.conf` replace `127.0.0.1` with the appropriate DNS resolver for your network, if necessary. This can usually be retrived via `grep nameserver /etc/resolv.conf`.
22+
5. For the RPC provider(s) which you are using, be sure to replace `YOUR_SERVER` and `REPLACE_ME_WITH_YOUR_AUTH_TOKEN` in the appropriate configuration file.
23+
6. You can then run `nginx` as with the command `nginx -c $(pwd)/standalone-dev-nginx.conf -g 'daemon off;'`
24+
25+
An example follows.
26+
27+
```
28+
[pyth@pyth-dev-vm nginx-configs]$ nginx -c $(pwd)/standalone-dev-nginx.conf -g 'daemon off;'
29+
nginx: [alert] could not open error log file: open() "/var/log/nginx/error.log" failed (13: Permission denied)
30+
31+
^C
32+
[pyth@pyth-dev-vm nginx-configs]$
33+
```
34+
35+
There are a few caveats.
36+
37+
1. On most Linux distributions, the error shown above about `/var/log/nginx/error_log` failing to open is normal. It's a hardcoded default for most builds. It can be safely ignored.
38+
2. The full, absolute path must be provided for the configuration file. Any relative paths are assumed to be relative to `nginx`'s application data directory (usually `/usr/share/nginx/...`).
39+
40+
You can test any of the HTTP RPC interface for the providers with the following command line. Replace `<PORT NUMBER>` with one of the port numbers in the table above.
41+
42+
`curl http://localhost:<PORT NUMBER> -X POST -H 'Content-Type: application/json' -d '{"jsonrpc":"2.0","id":1,"method":"getHealth"}'`
43+
44+
An example of the output expected:
45+
46+
```
47+
[pyth@pyth-dev-vm nginx-configs]$ curl http://localhost:7901 -X POST -H 'Content-Type: application/json' -d '{"jsonrpc":"2.0","id":1,"method":"getHealth"}'
48+
{"jsonrpc":"2.0","result":"ok","id":1}
49+
[pyth@pyth-dev-vm nginx-configs]$
50+
```
51+
52+
You can test any of the websocket interface for the providers with the following command line. Replace `<PORT NUMBER>` with one of the port numbers in the table above.
53+
54+
`curl --include --no-buffer --header "Connection: Upgrade" --header "Upgrade: websocket" --header "Host: api.mainnet-beta.solana.com" --header "Origin: https://api.mainnet-beta.solana.com" --header "Sec-WebSocket-Key: abcdefghijklmnop==" --header "Sec-WebSocket-Version: 13" http://localhost:<PORT NUMBER>/`
55+
56+
An example to test the websocket interface:
57+
58+
```
59+
[pyth@pyth-dev-vm nginx-configs]$ curl --include \
60+
--no-buffer \
61+
--header "Connection: Upgrade" \
62+
--header "Upgrade: websocket" \
63+
--header "Host: api.mainnet-beta.solana.com" \
64+
--header "Origin: https://api.mainnet-beta.solana.com" \
65+
--header "Sec-WebSocket-Key: abcdefghijklmnop==" \
66+
--header "Sec-WebSocket-Version: 13" \
67+
http://localhost:7801/
68+
HTTP/1.1 101 Switching Protocols
69+
upgrade: websocket
70+
connection: Upgrade
71+
sec-websocket-accept: FX/kNn6LL8gnqQea2uak6E6sPOU=
72+
73+
^C
74+
[pyth@pyth-dev-vm nginx-configs]$
75+
```
76+
77+
The virtual server configurations found in `nginx-configs/...` are meant as a sample to be used reference material. Each `nginx` installation will require tweaking and fine tuning if it varies much from the software provided.
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
#
2+
# Blockdaemon configuration snippet
3+
#
4+
# Can be included directly in /etc/nginx/sites-available/ (Debian based distros)
5+
# or /etc/nginx/conf.d/ (Red Hat based distros)
6+
#
7+
# YOUR_SERVER and REPLACE_ME_WITH_YOUR_AUTH_TOKEN should be replaced with the
8+
# appropriate values for your organization
9+
#
10+
11+
# Blockdaemon with bearer token authentication
12+
server {
13+
listen 7900;
14+
15+
location / {
16+
try_files /nonexistent-used-for-try-testing @$http_upgrade;
17+
}
18+
19+
location @websocket {
20+
# Cheat a little to make sure we don't have a trailing slash on the
21+
# path or we get a 405 response (method not allowed)
22+
proxy_pass https://YOUR_SERVER-solana-01.bdnodes.net/$http_upgrade;
23+
proxy_http_version 1.1;
24+
proxy_set_header Host $proxy_host;
25+
# websocket requirements
26+
proxy_set_header Upgrade $http_upgrade;
27+
proxy_set_header Connection "Upgrade";
28+
# Blockdaemon specific authentication requirement
29+
proxy_set_header Authorization "Bearer REPLACE_ME_WITH_YOUR_AUTH_TOKEN";
30+
proxy_redirect https://$proxy_host http://$server_name:$server_port;
31+
proxy_redirect https:// http://;
32+
}
33+
34+
location @ {
35+
proxy_pass https://YOUR_SERVER-solana-01.bdnodes.net$request_uri;
36+
proxy_http_version 1.1;
37+
proxy_set_header Host $proxy_host;
38+
# HTTP v.1.1 keepalive requirements
39+
proxy_set_header Connection "";
40+
# Blockdaemon specific authentication requirement
41+
proxy_set_header Authorization "Bearer REPLACE_ME_WITH_YOUR_AUTH_TOKEN";
42+
proxy_redirect https://$proxy_host http://$server_name:$server_port;
43+
proxy_redirect https:// http://;
44+
}
45+
}
46+
47+
#
48+
# This is a separate port for handling only websocket connections that some developers
49+
# have found greatly eases debugging. It provides the same functionality as the first
50+
# location stanza in the virtual server above.
51+
#
52+
53+
server {
54+
listen 7800;
55+
56+
location / {
57+
proxy_pass https://YOUR_SERVER-solana-01.bdnodes.net/websocket;
58+
proxy_http_version 1.1;
59+
proxy_set_header Host $proxy_host;
60+
# websocket requirements
61+
proxy_set_header Upgrade $http_upgrade;
62+
proxy_set_header Connection "Upgrade";
63+
# Blockdaemon specific authentication requirement
64+
proxy_set_header Authorization "Bearer REPLACE_ME_WITH_YOUR_AUTH_TOKEN";
65+
proxy_redirect https://$proxy_host http://$server_name:$server_port;
66+
proxy_redirect https:// http://;
67+
}
68+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
#
2+
# Figment configuration snippet
3+
#
4+
# Can be included directly in /etc/nginx/sites-available/ (Debian based distros)
5+
# or /etc/nginx/conf.d/ (Red Hat based distros)
6+
#
7+
# YOUR_SERVER and REPLACE_ME_WITH_YOUR_AUTH_TOKEN should be replaced with the
8+
# appropriate values for your organization
9+
#
10+
11+
# Figment RPC & websocket with auth
12+
server {
13+
listen 7901;
14+
15+
location / {
16+
try_files /nonexistent-used-for-try-testing @$http_upgrade;
17+
}
18+
19+
location @websocket {
20+
proxy_pass https://solana--mainnet.datahub.figment.io$request_uri;
21+
proxy_http_version 1.1;
22+
proxy_set_header Host $proxy_host;
23+
# websocket requirements
24+
proxy_set_header Upgrade $http_upgrade;
25+
proxy_set_header Connection "Upgrade";
26+
# Figment specific authentication requirement
27+
proxy_set_header Authorization REPLACE_ME_WITH_YOUR_AUTH_TOKEN;
28+
proxy_redirect https://$proxy_host http://$server_name:$server_port;
29+
proxy_redirect https:// http://;
30+
}
31+
32+
location @ {
33+
proxy_pass https://solana--mainnet.datahub.figment.io$request_uri;
34+
proxy_http_version 1.1;
35+
proxy_set_header Host $proxy_host;
36+
proxy_set_header Connection "";
37+
# Figment specific authentication requirement
38+
proxy_set_header Authorization REPLACE_ME_WITH_YOUR_AUTH_TOKEN;
39+
proxy_redirect https://$proxy_host http://$server_name:$server_port;
40+
proxy_redirect https:// http://;
41+
}
42+
}
43+
44+
#
45+
# This is a separate port for handling only websocket connections that some developers
46+
# have found greatly eases debugging. It provides the same functionality as the first
47+
# location stanza in the virtual server above.
48+
#
49+
50+
server {
51+
listen 7801;
52+
location / {
53+
proxy_pass https://solana--mainnet.datahub.figment.io;
54+
proxy_http_version 1.1;
55+
proxy_set_header Host $proxy_host;
56+
# websocket requirements
57+
proxy_set_header Upgrade $http_upgrade;
58+
proxy_set_header Connection "Upgrade";
59+
# Figment specific authentication requirement
60+
proxy_set_header Authorization REPLACE_ME_WITH_YOUR_AUTH_TOKEN;
61+
proxy_redirect https://$proxy_host http://$server_name:$server_port;
62+
proxy_redirect https:// http://;
63+
}
64+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#
2+
# This config file exists to be able to run nginx as an non-root user
3+
# on high numbered ports. It will include the config files for the
4+
# individual RPC publishers located in this directory.
5+
#
6+
7+
worker_processes 4;
8+
9+
events {
10+
worker_connections 1024;
11+
}
12+
13+
pid /tmp/nginx.pid;
14+
# Replace error with debug if you want much more detailed information
15+
error_log /tmp/error_log error;
16+
17+
http {
18+
proxy_temp_path /tmp/proxy_temp;
19+
client_body_temp_path /tmp/client_temp;
20+
fastcgi_temp_path /tmp/fastcgi_temp;
21+
uwsgi_temp_path /tmp/uwsgi_temp;
22+
scgi_temp_path /tmp/scgi_temp;
23+
24+
access_log /tmp/access_log;
25+
26+
default_type application/octet-stream;
27+
include /etc/nginx/mime.types;
28+
29+
sendfile on;
30+
31+
proxy_cache_path /tmp/proxy_cache_temp levels=1:2 keys_zone=one:10m;
32+
33+
# Maximum 32bit integer value
34+
keepalive_requests 2147483647;
35+
keepalive_timeout 65;
36+
37+
# FIXME Replace with whatever your /etc/resolv.conf contains
38+
resolver 127.0.0.1;
39+
40+
include ./*-virt-server-config.conf;
41+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
#
2+
# TritonOne configuration snippet
3+
#
4+
# Can be included directly in /etc/nginx/sites-available/ (Debian based distros)
5+
# or /etc/nginx/conf.d/ (Red Hat based distros)
6+
#
7+
# YOUR_SERVER and REPLACE_ME_WITH_YOUR_AUTH_TOKEN should be replaced with the
8+
# appropriate values for your organization
9+
#
10+
11+
# TritonOne RPC & websocket
12+
server {
13+
listen 7902;
14+
15+
location / {
16+
try_files /nonexistent-used-for-try-testing @$http_upgrade;
17+
}
18+
19+
location @websocket {
20+
# With authentication
21+
proxy_pass https://YOUR_SERVER.rpcpool.com/REPLACE_ME_WITH_YOUR_AUTH_TOKEN$request_uri;
22+
23+
# Without authentication, i.e. IP allow listed
24+
#proxy_pass https://YOUR_SERVER.rpcpool.com$request_uri;
25+
proxy_http_version 1.1;
26+
proxy_set_header Host $proxy_host;
27+
# websocket requirements
28+
proxy_set_header Upgrade $http_upgrade;
29+
proxy_set_header Connection "Upgrade";
30+
proxy_redirect https://$proxy_host http://$server_name:$server_port;
31+
proxy_redirect https:// http://;
32+
}
33+
34+
location @ {
35+
# With authentication
36+
proxy_pass https://YOUR_SERVER.rpcpool.com/REPLACE_ME_WITH_YOUR_AUTH_TOKEN$request_uri;
37+
38+
# Without authentication, i.e. IP allow listed
39+
#proxy_pass https://YOUR_SERVER.rpcpool.com$request_uri;
40+
proxy_http_version 1.1;
41+
proxy_set_header Host $proxy_host;
42+
proxy_set_header Connection "";
43+
proxy_redirect https://$proxy_host http://$server_name:$server_port;
44+
proxy_redirect https:// http://;
45+
}
46+
}
47+
48+
#
49+
# This is a separate port for handling only websocket connections that some developers
50+
# have found greatly eases debugging. It provides the same functionality as the first
51+
# location stanza in the virtual server above.
52+
#
53+
54+
server {
55+
listen 7802;
56+
57+
location / {
58+
# With authentication
59+
proxy_pass https://YOUR_SERVER.rpcpool.com/REPLACE_ME_WITH_YOUR_AUTH_TOKEN;
60+
61+
# Without authentication, i.e. IP allow listed
62+
#proxy_pass https://YOUR_SERVER.rpcpool.com;
63+
proxy_http_version 1.1;
64+
proxy_set_header Host $proxy_host;
65+
# websocket requirements
66+
proxy_set_header Upgrade $http_upgrade;
67+
proxy_set_header Connection "Upgrade";
68+
proxy_redirect https://$proxy_host http://$server_name:$server_port;
69+
proxy_redirect https:// http://;
70+
}
71+
}

0 commit comments

Comments
 (0)