Last active
May 23, 2021 11:17
-
-
Save sakurai-youhei/9a664f2697e599dcaa939091ffff9816 to your computer and use it in GitHub Desktop.
Reverse-proxying blynk-server by Nginx with simple WAF
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# empty |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* !!! 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} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
" | |
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
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.