Skip to content

Instantly share code, notes, and snippets.

@sakurai-youhei
Last active May 23, 2021 11:17
Show Gist options
  • Save sakurai-youhei/9a664f2697e599dcaa939091ffff9816 to your computer and use it in GitHub Desktop.
Save sakurai-youhei/9a664f2697e599dcaa939091ffff9816 to your computer and use it in GitHub Desktop.
Reverse-proxying blynk-server by Nginx with simple WAF
stream {
js_import conf.d/waf.js;
upstream blynk_https {
server blynk:9443;
}
server {
listen 443 ssl;
js_filter waf.inspect;
proxy_pass blynk_https;
proxy_ssl on;
proxy_ssl_verify off;
ssl_certificate conf.d/star.YOURDOMAIN.com.cert.pem;
ssl_certificate_key conf.d/star.YOURDOMAIN.com.pkey.pem;
ssl_session_cache builtin:1000 shared:SSL:10m;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
}
upstream blynk_http {
server blynk:8080;
}
server {
listen 80;
proxy_pass blynk_http;
}
}
/* !!! This is compatible with Nginx **1.19.2** or later !!! */
var ALLOW_LIST = [
/sakurai\.youhei@gmail\.com/,
];
// https://github.com/blynkkk/blynk-server/blob/master/server/core/src/main/java/cc/blynk/server/core/protocol/enums/Command.java
var REGISTER = 1;
var LOGIN = 2;
function inspect(s) {
s.on('upload', function(data, flags) {
var header = parse(data);
if (header.isAppPipeline) {
if ((header.firstbyte === REGISTER || header.firstbyte === LOGIN) &&
!ALLOW_LIST.some(function(r) {return r.exec(data);})) {
s.log('Jamming command=' + header.firstbyte + ': ' + data);
data = data.replace(/@[^.]+\./, '@..');
s.warn('Command was jammed: ' + data);
}
}
s.off('upload');
s.send(data);
});
}
function parse(data) {
var uint8array = new TextEncoder('ascii').encode(data.slice(0, 5));
var isHttp;
var isHardwarePipeline;
var isAppPipeline;
try {
// https://github.com/blynkkk/blynk-server/blob/master/server/http-api/src/main/java/cc/blynk/server/api/http/handlers/BaseHttpAndBlynkUnificationHandler.java
var header4Bytes = 0;
for (var i=0; i < 4; i++) {
header4Bytes += uint8array[i] << (8 * (3 - i));
}
var lastByteOfHeader = uint8array[4];
isHttp = (header4Bytes === 1195725856 || // 'GET '
header4Bytes === 1347375956 || // 'POST'
header4Bytes === 1347769376 || // 'PUT '
header4Bytes === 1212498244 || // 'HEAD'
header4Bytes === 1330664521 || // 'OPTI'
header4Bytes === 1346458691 || // 'PATC'
header4Bytes === 1145392197 || // 'DELE'
header4Bytes === 1414676803 || // 'TRAC'
header4Bytes === 1129270862); // 'CONN'
isHardwarePipeline = (lastByteOfHeader === 32 &&
(header4Bytes === 486539520 || header4Bytes === 33554688));
isAppPipeline = !isHttp && !isHardwarePipeline;
} catch (e) {
isHttp = isHardwarePipeline = isAppPipeline = false;
}
return {firstbyte: uint8array[0],
isHttp: isHttp,
isHardwarePipeline: isHardwarePipeline,
isAppPipeline: isAppPipeline};
}
export default {inspect}
version: "3.5"
services:
blynk:
image: YOUR-BLYNK-IMAGE
restart: unless-stopped
entrypoint: java -jar /blynk/server.jar
nginx:
image: nginx:1.19.2
ports:
- "80:80"
- "443:443"
volumes:
- /YOUR/PATH/TO/etc/nginx/conf.d:/etc/nginx/conf.d
- /var/log/nginx:/var/log/nginx
restart: unless-stopped
command: >-
nginx -g "
load_module modules/ngx_stream_js_module.so;
include /etc/nginx/conf.d/default.stream;
daemon off;
"
@twocolors
Copy link

thx to this solution , can you make support upstream to app|hard and to http ?
I see you check http or app|hard in js ...

this will be cool, all http send to nginx section http.

@laimison
Copy link

laimison commented Apr 8, 2021

I guess http block is not possible here. Packet doesn't have HTTP specifications ( https://github.com/blynkkk/blynk-server/blob/v0.41.15/server/http-api/src/main/java/cc/blynk/server/api/http/handlers/BaseHttpAndBlynkUnificationHandler.java ). For instance you can't use Host header (server_name) to combine this with other domains in Nginx configuration.

It's stream solution provided via Nginx.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment