A enterprise-level enhanced gateway based on spring cloud gateway, out of the box, supports such as canary request-based response cache filter, canary load balancer, universal signature authentication filter, oidc v1/oauth2.x authentication filter, ip filter, Traffic replication filter, quota-request limiter-based filter Injector, canary-based fault injector filter, and canary-based humanized log filter, etc.
Tips: The latest version and documentation are currently being sorted out. It is recommended to deploy in the test environment first. If you have any questions or suggestions, please submit an Issue
git clone https://github.com/wl4g/escg.git
cd escg/
# The profiles supports: -Pbuild:tar, -Pbuild:springjar, -Pbuild:docker, -Pbuild:native
mvn -U install -DskipTests -Pbuild:tar
cd src/main/resources/cert.d/
./cert-tool.sh ca
./cert-tool.sh pem-p12 ca.pem ca-key.pem
./cert-tool.sh cert wl4g.io 192.168.88.2,10.88.8.5
./cert-tool.sh pem-p12 wl4g.io.pem wl4g.io-key.pem
./cert-tool.sh cert client1 192.168.88.2,10.88.8.5
./cert-tool.sh pem-p12 client1.pem client1-key.pem
curl
: no alternative certificate subject name matches target host name '192.168.88.3'
,
Using the above script tool will contain localhost,127.0.0.1
by default.Preconditions (startup configuration)
-Djavax.net.debug
options are all|ssl|handshake|warning|...
java -Djavax.net.debug=all -jar escg-1.0.0-bin.jar --server.ssl.enabled=true --server.ssl.client-auth=NONE
curl
testingcurl -vsSkL -XGET \
-H 'X-Escg-Trace: y' \
-H 'X-Escg-Log: y' \
-H 'X-Escg-Log-Level: 10' \
--cacert ca.pem \
--cert client1.pem \
--key client1-key.pem \
'https://localhost:18085/_fallback' | jq
java -Djavax.net.debug=all -jar escg-1.0.0-bin.jar --server.ssl.enabled=true --server.ssl.client-auth=NEED
curl
testingcurl -vsSkL -XGET \
-H 'X-Escg-Trace: y' \
-H 'X-Escg-Log: y' \
-H 'X-Escg-Log-Level: 10' \
--cacert ca.pem \
--cert client1.pem \
--key client1-key.pem \
'https://localhost:18085/_fallback' | jq
src/test/resources/bootstrap.yml
)spring:
profiles:
include: "service-discovery,route-filter-splitting"
export localIp=$(ifconfig|grep -A 4 -E '^em*|^eno*|^enp*|^ens*|^eth*|^wlp*'|grep 'inet'|awk '{print $2}'|head -1 2>/dev/null)
# for testing positive example
curl -vsSkL -XGET \
-H 'X-Escg-Trace: y' \
-H 'X-Escg-Log: y' \
-H 'X-Escg-Log-Level: 10' \
"http://$localIp:18085/productpage-with-IpFilter/get"
# for testing negative example
curl -vsSkL -XPOST \
-H 'X-Escg-Trace: y' \
-H 'X-Escg-Log: y' \
-H 'X-Escg-Log-Level: 10' \
-H 'Content-Type: application/json' \
-H 'X-Forwarded-For: 1.1.1.2' \
-d '{"name":"jack"}' \
"http://$localIp:18085/productpage-with-IpFilter/post"
TODO
src/test/resources/bootstrap.yml
spring:
profiles:
include: "service-discovery,route-filter-splitting"
## for testing positive example1
curl -vsSkL -XGET \
-H 'X-Escg-Trace: y' \
-H 'X-Escg-Log: y' \
-H 'X-Escg-Log-Level: 10' \
-H 'X-Escg-Fault: y' \
'http://localhost:18085/productpage-with-FaultInjector/get'
## for testing positive example2
curl -vsSkL -XPOST \
-H 'Content-Type: application/json' \
-H 'X-Escg-Trace: y' \
-H 'X-Escg-Log: y' \
-H 'X-Escg-Log-Level: 10' \
-H 'X-Escg-Fault: y' \
-d '{"name":"jack"}' \
'http://localhost:18085/productpage-with-FaultInjector/post'
src/test/resources/example/example-route-splitting.yml
or src/test/resources/example/example-route-composite.yml
)...
filters:
- RewritePath=/productpage-with-SimpleSignAuthing/(?<segment>.*),/$\{segment}
- name: SimpleSignAuthing
args:
app-id-extractor: Parameter
app-id-param: appId
secret-param: appSecret
sign-replay-verify-enabled: true
sign-replay-verify-bloom-expire-seconds: 604800
sign-param: sign
sign-algorithm: S256
sign-hashing-mode: SimpleParamsBytesSortedHashing
sign-hashing-include-params: ['*']
sign-hashing-exclude-params: ['response_type','__iscg_log']
add-sign-auth-client-id-header: X-Sign-Auth-AppId
...
Run the test harness class in Idea/Eclipse/VsCode: com.wl4g.escg.security.sign.SimpleSignGenerateTool
to generate test request parameters.
redis-cli -c -h localhost -p 6379 -a '123456'
## Note: The configuration 'app-id-extractor' is 'Parameter'
set escg:auth:sign:secret:oijvin6crxu2qdqvpgls9jmijz4t6istxs <myAppSecret>
## for testing positive example
export APPID=oijvin6crxu2qdqvpgls9jmijz4t6istxs
export APPSECRET=njbbaiocxsbzzmtfsnenfvupzjyoioyu
export NONCE=nxFCAq0qrzFwqHcwfX0xvainRmQk6FvO
export TIMESTAMP=1652777325198
export SIGN=aa9c39efe90ef44bbcae258bb0b40653489186ac58266e092e3e420f1caa1573
export REMOTE_IP=127.0.0.1
curl -vL \
-H 'X-Escg-Trace: y' \
-H 'X-Escg-Log: y' \
-H 'X-Escg-Log-Level: 10' \
-H 'X-Response-Type: 10' \
"http://${REMOTE_IP}:18085/productpage-with-SimpleSignAuthing/get?appId=${APPID}&nonce=${NONCE}×tamp=${TIMESTAMP}&sign=${SIGN}"
{
"args": {
"appId": "oijvin6crxu2qdqvpgls9jmijz4t6istxs",
"nonce": "nxFCAq0qrzFwqHcwfX0xvainRmQk6FvO",
"sign": "aa9c39efe90ef44bbcae258bb0b40653489186ac58266e092e3e420f1caa1573",
"timestamp": "1652777325198"
},
"headers": {
"Accept": "*/*",
"Content-Length": "0",
"Forwarded": "proto=http;host=\"127.0.0.1:18085\";for=\"127.0.0.1:50442\"",
"Host": "httpbin.org",
"Traceparent": "00-b9072cb8bcff2b47082b2f53199ef1a8-c02cf95da1747fb9-01",
"User-Agent": "curl/7.68.0",
"X-Amzn-Trace-Id": "Root=1-6283728d-27e55d6370e6b361627c5ea8",
"X-Forwarded-Host": "127.0.0.1:18085",
"X-Forwarded-Prefix": "/productpage-with-SimpleSignAuthing",
"X-Escg-Log": "y",
"X-Escg-Log-Dyeing-State": "b9072cb8bcff2b47082b2f53199ef1a8",
"X-Escg-Log-Level": "10",
"X-Escg-Trace": "y",
"X-Response-Type": "10",
"X-Sign-Auth-Appid": "oijvin6crxu2qdqvpgls9jmijz4t6istxs"
},
"origin": "127.0.0.1, 61.140.45.61",
"url": "http://127.0.0.1:18085/get?appId=oijvin6crxu2qdqvpgls9jmijz4t6istxs&nonce=nxFCAq0qrzFwqHcwfX0xvainRmQk6FvO×tamp=1652777325198&sign=aa9c39efe90ef44bbcae258bb0b40653489186ac58266e092e3e420f1caa1573"
}
{"code":423,"status":"Normal","requestId":null,"timestamp":1652781711036,"message":"[TEST-423] illegal_signature","data":{}}
redis-cli -c -h localhost -p 6379 -a '123456'
del escg:auth:sign:replay:bloom:productpage-service-route-with-SimpleSignAuthing
## The cache key format example is:'escg:auth:sign:event:failure:<routeId>:<yyMMdd>', of course, both prefixes and suffixes can be configured globally.
hgetall escg:auth:sign:event:success:productpage-service-route-with-SimpleSignAuthing:220517
hgetall escg:auth:sign:event:failure:productpage-service-route-with-SimpleSignAuthing:220517
## for testing negative example(limited)
ab -n 2000 -c 15 \
-H 'X-Escg-Trace: y' \
-H 'X-Escg-Log: y' \
-H 'X-Escg-Log-Level: 10' \
-m POST \
'http://localhost:18085/productpage-with-IamRequestLimiter/post?response_type=json'
Preconditions: Please make sure that the global default setup is:
spring.escg.requestlimit.limiter.[rate|quota].defaultStrategy.includeHeaders=true
, or configure by routeId+limitKey:{"includeHeaders":true, ...}
, refer to follower2.8.4
curl -vsSkL -XPOST \
-H 'X-Escg-Trace: y' \
-H 'X-Escg-Log: y' \
-H 'X-Escg-Log-Level: 10' \
-X POST \
'http://localhost:18085/productpage-with-IamRequestLimiter/post?response_type=json'
HTTP/1.1 200 OK
X-Request-Id: 643603ccd11aadf5a705191e5c11b2a4
X-Escg-RateLimit-Requested-Tokens: 1
X-Escg-RateLimit-Replenish-Rate: 10
X-Escg-RateLimit-LimitKey: 127.0.0.1
X-Escg-RateLimit-Burst-Capacity: 200
X-Escg-RateLimit-Remaining: 199
X-Escg-QuotaLimit-Remaining: 474
X-Escg-QuotaLimit-Cycle: 220518
X-Escg-QuotaLimit-LimitKey: /productpage-with-IamRequestLimiter/post
X-Escg-QuotaLimit-Request-Capacity: 1000
...
...
java -jar escg-1.0.0-bin.jar \
--spring.escg.requestlimit.limiter.rate.defaultStrategy.defaultBurstCapacity=1000 \
--spring.escg.requestlimit.limiter.rate.defaultStrategy.defaultReplenishRate=10 \
--spring.escg.requestlimit.limiter.rate.defaultStrategy.defaultRequestedTokens=1 \
--spring.escg.requestlimit.limiter.quota.defaultStrategy.requestCapacity=1000 \
--spring.escg.requestlimit.limiter.quota.defaultStrategy.cycleDatePattern=yyMMdd
## The cache key format example is:'escg:requestlimit:config:rate:<routeId>:<limitKey>', of course, both prefixes and suffixes can be configured globally.
## The keyResolver is Header(X-Forward-Ip)
hset escg:requestlimit:config:rate productpage-service-route-with-IamRequestLimiter:127.0.0.1 '{"includeHeaders":true,"burstCapacity":1000,"replenishRate":1,"requestedTokens":1}'
hset escg:requestlimit:config:quota productpage-service-route-with-IamRequestLimiter:127.0.0.1 '{"requestCapacity":1000,"cycleDatePattern":"yyMMddHH","includeHeaders":true}'
## The keyResolver is Path
hset escg:requestlimit:config:rate productpage-service-route-with-IamRequestLimiter:/productpage-with-IamRequestLimiter/get '{"includeHeaders":true,"burstCapacity":1000,"replenishRate":1,"requestedTokens":1}'
hset escg:requestlimit:config:quota productpage-service-route-with-IamRequestLimiter:/productpage-with-IamRequestLimiter/get '{"requestCapacity":1000,"cycleDatePattern":"yyMMddHH","includeHeaders":true}'
## The keyResolver is Principal(appId)
hset escg:requestlimit:config:rate productpage-service-route-with-IamRequestLimiter:oijvin6crxu2qdqvpgls9jmijz4t6istxs '{"includeHeaders":true,"burstCapacity":1000,"replenishRate":1,"requestedTokens":1}'
hset escg:requestlimit:config:quota productpage-service-route-with-IamRequestLimiter:oijvin6crxu2qdqvpgls9jmijz4t6istxs '{"requestCapacity":1000,"cycleDatePattern":"yyMMddHH","includeHeaders":true}'
## ...
## The cache key format example is:'escg:requestlimit:token:quota:<yyMMdd> <routeId>:<limitKey>', of course, both prefixes and suffixes can be configured globally.
hgetall escg:requestlimit:token:quota:220517
hget escg:requestlimit:token:quota:220517 productpage-service-route-with-IamRequestLimiter:127.0.0.1
## The cache key format example is:'escg:requestlimit:event:hits:rate:<routeId>:<yyMMdd>', of course, both prefixes and suffixes can be configured globally.
hgetall escg:requestlimit:event:hits:rate:productpage-service-route-with-IamRequestLimiter:220517
hgetall escg:requestlimit:event:hits:quota:productpage-service-route-with-IamRequestLimiter:220517
src/test/resources/bootstrap.yml
spring:
profiles:
include: "service-discovery,route-filter-splitting"
## Mock actual upstream http server.
python3 -m http.server -b 0.0.0.0 8888
## Mock traffic mirror upstream http server. see: escg-route.yaml#secure-httpbin-service-route
## Online by default: http://httpbin.org/
## [Optional] You can also use docker to local build an httpbin server.
#docker run -d --name=httpbin -p 8889:80 kennethreitz/httpbin
## 1. Send a mock request and observe that both terminals have output.
## 2. Then observe the output of the simulated mirror http server, and the response of the simulated real http server.
## for testing positive example1
curl -vsSkL -XGET -H 'X-Escg-Trace: y' -H 'X-Escg-Log-Level: 10' 'http://localhost:18085/productpage-with-TrafficReplicator/get'
## for testing positive example2
curl -vsSkL -XPOST \
-H 'X-Escg-Trace: y' \
-H 'X-Escg-Log: y' \
-H 'X-Escg-Log-Level: 10' \
-H 'Content-Type: application/json' \
-d '{"name":"jack"}' \
'http://localhost:18085/productpage-with-TrafficReplicator/post'
## for testing positive example
curl -vsSkL -XGET \
-H 'X-Escg-Trace: y' \
-H 'X-Escg-Log: y' \
-H 'X-Escg-Log-Level: 10' \
-H 'X-Escg-Cache: y' \
"http://localhost:18085/productpage-with-ResponseCache/get"
## for testing negative example
curl -vsSkL -XGET \
-H 'X-Escg-Trace: y' \
-H 'X-Escg-Log: y' \
-H 'X-Escg-Log-Level: 10' \
-H 'X-Escg-Cache: n' \
"http://localhost:18085/productpage-with-ResponseCache/get"
TODO
TODO
## for testing positive example
curl -vsSkL -XPOST \
-H 'X-Escg-Trace: y' \
-H 'X-Escg-Log: y' \
-H 'X-Escg-Log-Level: 10' \
-H 'X-Escg-Cache: y' \
-H 'X-Escg-Canary: v1' \
"http://localhost:18085/productpage-with-CanaryLoadBalancer/post"
## for testing positive example
curl -vsSkL -XPOST \
-H 'X-Escg-Trace: y' \
-H 'X-Escg-Log: y' \
-H 'X-Escg-Log-Level: 10' \
-H 'X-Escg-Cache: y' \
-H 'X-Escg-Canary: v2' \
"http://localhost:18085/productpage-with-CanaryLoadBalancer/post"
curl -v 'http://localhost:18086/actuator/escg/routes' | jq
curl -v 'http://localhost:18086/actuator/metrics' | jq
curl -v 'http://localhost:18086/actuator/prometheus'
ab -n 10000 -c 1000 \
-H 'X-Escg-Trace: y' \
-H 'X-Escg-Log: y' \
-H 'X-Escg-Log-Level: 0' \
-H 'X-Escg-Fault: y' \
-H 'X-Escg-Canary: v1' \
-m POST \
'http://localhost:18085/productpage-with-IamRequestLimiter/post?&response_type=json'
com.wl4g.escg.requestlimit=TRACE
, an error will be displayed: ERR Error running ... @user_script:1: user_script:1: attempt to call field 'replicate_commands' (a nil value)
Refer1: stackoverflow attempt-to-call-field-replicate-commands-a-nil-value
Resolved: Since redis3.0 does not support the command 'replicate_commands()', just upgrade to redis3.2+
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。