Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add ip-restriction wasm-go plugin #759

Merged
merged 39 commits into from
Mar 12, 2024
Merged

Conversation

Renz7
Copy link
Contributor

@Renz7 Renz7 commented Jan 6, 2024

Ⅰ. Describe what this PR did

ip-restriction impl.

Ⅱ. Does this pull request fix one issue?

fixes #607

Ⅲ. Why don't you add test cases (unit test/integration test)?

Ⅳ. Describe how to verify it

  1. e2e test pass
=== RUN   TestHigressConformanceTests/WasmPluginsIpRestriction
    suite.go:209: 🔥 Running Conformance Test: WasmPluginsIpRestriction
    suite.go:212: 🧳 Applying Manifests: tests/go-wasm-ip-restriction.yaml
    apply.go:149: 🏗 Creating httproute-app-root Ingress
    apply.go:149: 🏗 Creating ip-restriction WasmPlugin
=== RUN   TestHigressConformanceTests/WasmPluginsIpRestriction/WasmPlugins_ip-restriction
    go-wasm-ip-restriction.go:114: Making GET request to http://localhost/info
Sending Request:
< GET /info HTTP/1.1
< Host: foo.com
< User-Agent: Go-http-client/1.1
< X-Echo-Set-Header: 
< X-Real-Ip: 10.0.0.1
< Accept-Encoding: gzip
< 
< 

    http.go:252: Request failed, not ready yet: Get "http://localhost/info": read tcp [::1]:59799->[::1]:80: read: connection reset by peer (after 2.25µs)
Sending Request:
< GET /info HTTP/1.1
< Host: foo.com
< User-Agent: Go-http-client/1.1
< X-Echo-Set-Header: 
< X-Real-Ip: 10.0.0.1
< Accept-Encoding: gzip
< 
< 

Received Response:
< HTTP/1.1 200 OK
< Content-Length: 946
< Content-Type: application/json
< Date: Sat, 06 Jan 2024 21:39:10 GMT
< Req-Arrive-Time: 1704577150678
< Req-Cost-Time: 30
< Resp-Start-Time: 1704577150708
< Server: istio-envoy
< X-Content-Type-Options: nosniff
< X-Envoy-Upstream-Service-Time: 27
< 
< {
<  "path": "/info",
<  "host": "foo.com",
<  "method": "GET",
<  "proto": "HTTP/1.1",
<  "headers": {
<   "Accept-Encoding": [
<    "gzip"
<   ],
<   "Original-Host": [
<    "foo.com"
<   ],
<   "Req-Start-Time": [
<    "1704577150678"
<   ],
<   "User-Agent": [
<    "Go-http-client/1.1"
<   ],
<   "X-B3-Sampled": [
<    "0"
<   ],
<   "X-B3-Spanid": [
<    "e098143fdb025c78"
<   ],
<   "X-B3-Traceid": [
<    "9e2c95aff2973c44e098143fdb025c78"
<   ],
<   "X-Echo-Set-Header": [
<    ""
<   ],
<   "X-Envoy-Attempt-Count": [
<    "1"
<   ],
<   "X-Envoy-Decorator-Operation": [
<    "infra-backend-v1.higress-conformance-infra.svc.cluster.local:8080/*"
<   ],
<   "X-Envoy-Internal": [
<    "true"
<   ],
<   "X-Forwarded-For": [
<    "192.168.65.1"
<   ],
<   "X-Forwarded-Proto": [
<    "http"
<   ],
<   "X-Real-Ip": [
<    "10.0.0.1"
<   ],
<   "X-Request-Id": [
<    "26590565-af76-4463-a43d-dde9289fcf1e"
<   ]
<  },
<  "namespace": "higress-conformance-infra",
<  "ingress": "",
<  "service": "",
<  "pod": "infra-backend-v1-55b649759b-79klt"
< }

Sending Request:
< GET /info HTTP/1.1
< Host: foo.com
< User-Agent: Go-http-client/1.1
< X-Echo-Set-Header: 
< X-Real-Ip: 10.0.0.1
< Accept-Encoding: gzip
< 
< 

Received Response:
< HTTP/1.1 200 OK
< Content-Length: 946
< Content-Type: application/json
< Date: Sat, 06 Jan 2024 21:39:10 GMT
< Req-Arrive-Time: 1704577150717
< Req-Cost-Time: 41
< Resp-Start-Time: 1704577150758
< Server: istio-envoy
< X-Content-Type-Options: nosniff
< X-Envoy-Upstream-Service-Time: 40
< 
< {
<  "path": "/info",
<  "host": "foo.com",
<  "method": "GET",
<  "proto": "HTTP/1.1",
<  "headers": {
<   "Accept-Encoding": [
<    "gzip"
<   ],
<   "Original-Host": [
<    "foo.com"
<   ],
<   "Req-Start-Time": [
<    "1704577150717"
<   ],
<   "User-Agent": [
<    "Go-http-client/1.1"
<   ],
<   "X-B3-Sampled": [
<    "0"
<   ],
<   "X-B3-Spanid": [
<    "fb89cb20ee8f98a0"
<   ],
<   "X-B3-Traceid": [
<    "47a84500ad20cd49fb89cb20ee8f98a0"
<   ],
<   "X-Echo-Set-Header": [
<    ""
<   ],
<   "X-Envoy-Attempt-Count": [
<    "1"
<   ],
<   "X-Envoy-Decorator-Operation": [
<    "infra-backend-v1.higress-conformance-infra.svc.cluster.local:8080/*"
<   ],
<   "X-Envoy-Internal": [
<    "true"
<   ],
<   "X-Forwarded-For": [
<    "192.168.65.1"
<   ],
<   "X-Forwarded-Proto": [
<    "http"
<   ],
<   "X-Real-Ip": [
<    "10.0.0.1"
<   ],
<   "X-Request-Id": [
<    "b21a8100-821e-4bb8-ab0f-2e37d8140e55"
<   ]
<  },
<  "namespace": "higress-conformance-infra",
<  "ingress": "",
<  "service": "",
<  "pod": "infra-backend-v1-55b649759b-fzvbp"
< }

Sending Request:
< GET /info HTTP/1.1
< Host: foo.com
< User-Agent: Go-http-client/1.1
< X-Echo-Set-Header: 
< X-Real-Ip: 10.0.0.1
< Accept-Encoding: gzip
< 
< 

Received Response:
< HTTP/1.1 200 OK
< Content-Length: 946
< Content-Type: application/json
< Date: Sat, 06 Jan 2024 21:39:10 GMT
< Req-Arrive-Time: 1704577150761
< Req-Cost-Time: 4
< Resp-Start-Time: 1704577150766
< Server: istio-envoy
< X-Content-Type-Options: nosniff
< X-Envoy-Upstream-Service-Time: 4
< 
< {
<  "path": "/info",
<  "host": "foo.com",
<  "method": "GET",
<  "proto": "HTTP/1.1",
<  "headers": {
<   "Accept-Encoding": [
<    "gzip"
<   ],
<   "Original-Host": [
<    "foo.com"
<   ],
<   "Req-Start-Time": [
<    "1704577150761"
<   ],
<   "User-Agent": [
<    "Go-http-client/1.1"
<   ],
<   "X-B3-Sampled": [
<    "0"
<   ],
<   "X-B3-Spanid": [
<    "4c97cb5592ea1e3a"
<   ],
<   "X-B3-Traceid": [
<    "c6ce79bf16fb3b994c97cb5592ea1e3a"
<   ],
<   "X-Echo-Set-Header": [
<    ""
<   ],
<   "X-Envoy-Attempt-Count": [
<    "1"
<   ],
<   "X-Envoy-Decorator-Operation": [
<    "infra-backend-v1.higress-conformance-infra.svc.cluster.local:8080/*"
<   ],
<   "X-Envoy-Internal": [
<    "true"
<   ],
<   "X-Forwarded-For": [
<    "192.168.65.1"
<   ],
<   "X-Forwarded-Proto": [
<    "http"
<   ],
<   "X-Real-Ip": [
<    "10.0.0.1"
<   ],
<   "X-Request-Id": [
<    "7b83869d-3350-4b22-ac99-dcae83398586"
<   ]
<  },
<  "namespace": "higress-conformance-infra",
<  "ingress": "",
<  "service": "",
<  "pod": "infra-backend-v1-55b649759b-fzvbp"
< }

    http.go:263: Request passed
    go-wasm-ip-restriction.go:114: Making GET request to http://localhost/info
Sending Request:
< GET /info HTTP/1.1
< Host: foo.com
< User-Agent: Go-http-client/1.1
< X-Echo-Set-Header: 
< X-Real-Ip: 10.0.0.2
< Accept-Encoding: gzip
< 
< 

Received Response:
< HTTP/1.1 403 Forbidden
< Content-Length: 45
< Content-Type: text/plain
< Date: Sat, 06 Jan 2024 21:39:10 GMT
< Server: istio-envoy
< 
< {"message":"Your IP address is not allowed."}

Sending Request:
< GET /info HTTP/1.1
< Host: foo.com
< User-Agent: Go-http-client/1.1
< X-Echo-Set-Header: 
< X-Real-Ip: 10.0.0.2
< Accept-Encoding: gzip
< 
< 

Received Response:
< HTTP/1.1 403 Forbidden
< Content-Length: 45
< Content-Type: text/plain
< Date: Sat, 06 Jan 2024 21:39:10 GMT
< Server: istio-envoy
< 
< {"message":"Your IP address is not allowed."}

Sending Request:
< GET /info HTTP/1.1
< Host: foo.com
< User-Agent: Go-http-client/1.1
< X-Echo-Set-Header: 
< X-Real-Ip: 10.0.0.2
< Accept-Encoding: gzip
< 
< 

Received Response:
< HTTP/1.1 403 Forbidden
< Content-Length: 45
< Content-Type: text/plain
< Date: Sat, 06 Jan 2024 21:39:10 GMT
< Server: istio-envoy
< 
< {"message":"Your IP address is not allowed."}

    http.go:263: Request passed
    go-wasm-ip-restriction.go:114: Making GET request to http://localhost/info
Sending Request:
< GET /info HTTP/1.1
< Host: foo.com
< User-Agent: Go-http-client/1.1
< X-Echo-Set-Header: 
< X-Real-Ip: 192.168.1.1
< Accept-Encoding: gzip
< 
< 

Received Response:
< HTTP/1.1 403 Forbidden
< Content-Length: 45
< Content-Type: text/plain
< Date: Sat, 06 Jan 2024 21:39:10 GMT
< Server: istio-envoy
< 
< {"message":"Your IP address is not allowed."}

Sending Request:
< GET /info HTTP/1.1
< Host: foo.com
< User-Agent: Go-http-client/1.1
< X-Echo-Set-Header: 
< X-Real-Ip: 192.168.1.1
< Accept-Encoding: gzip
< 
< 

Received Response:
< HTTP/1.1 403 Forbidden
< Content-Length: 45
< Content-Type: text/plain
< Date: Sat, 06 Jan 2024 21:39:10 GMT
< Server: istio-envoy
< 
< {"message":"Your IP address is not allowed."}

Sending Request:
< GET /info HTTP/1.1
< Host: foo.com
< User-Agent: Go-http-client/1.1
< X-Echo-Set-Header: 
< X-Real-Ip: 192.168.1.1
< Accept-Encoding: gzip
< 
< 

Received Response:
< HTTP/1.1 403 Forbidden
< Content-Length: 45
< Content-Type: text/plain
< Date: Sat, 06 Jan 2024 21:39:10 GMT
< Server: istio-envoy
< 
< {"message":"Your IP address is not allowed."}

    http.go:263: Request passed
    go-wasm-ip-restriction.go:114: Making GET request to http://localhost/info
Sending Request:
< GET /info HTTP/1.1
< Host: foo.com
< User-Agent: Go-http-client/1.1
< X-Echo-Set-Header: 
< X-Real-Ip: 192.168.0.1
< Accept-Encoding: gzip
< 
< 

Received Response:
< HTTP/1.1 200 OK
< Content-Length: 949
< Content-Type: application/json
< Date: Sat, 06 Jan 2024 21:39:10 GMT
< Req-Arrive-Time: 1704577150793
< Req-Cost-Time: 3
< Resp-Start-Time: 1704577150797
< Server: istio-envoy
< X-Content-Type-Options: nosniff
< X-Envoy-Upstream-Service-Time: 3
< 
< {
<  "path": "/info",
<  "host": "foo.com",
<  "method": "GET",
<  "proto": "HTTP/1.1",
<  "headers": {
<   "Accept-Encoding": [
<    "gzip"
<   ],
<   "Original-Host": [
<    "foo.com"
<   ],
<   "Req-Start-Time": [
<    "1704577150793"
<   ],
<   "User-Agent": [
<    "Go-http-client/1.1"
<   ],
<   "X-B3-Sampled": [
<    "0"
<   ],
<   "X-B3-Spanid": [
<    "660156d0270e9f71"
<   ],
<   "X-B3-Traceid": [
<    "bb1fa2231419cab9660156d0270e9f71"
<   ],
<   "X-Echo-Set-Header": [
<    ""
<   ],
<   "X-Envoy-Attempt-Count": [
<    "1"
<   ],
<   "X-Envoy-Decorator-Operation": [
<    "infra-backend-v1.higress-conformance-infra.svc.cluster.local:8080/*"
<   ],
<   "X-Envoy-Internal": [
<    "true"
<   ],
<   "X-Forwarded-For": [
<    "192.168.65.1"
<   ],
<   "X-Forwarded-Proto": [
<    "http"
<   ],
<   "X-Real-Ip": [
<    "192.168.0.1"
<   ],
<   "X-Request-Id": [
<    "25ef2479-3f78-476c-87a6-a8ef09eee3a3"
<   ]
<  },
<  "namespace": "higress-conformance-infra",
<  "ingress": "",
<  "service": "",
<  "pod": "infra-backend-v1-55b649759b-79klt"
< }

Sending Request:
< GET /info HTTP/1.1
< Host: foo.com
< User-Agent: Go-http-client/1.1
< X-Echo-Set-Header: 
< X-Real-Ip: 192.168.0.1
< Accept-Encoding: gzip
< 
< 

Received Response:
< HTTP/1.1 200 OK
< Content-Length: 949
< Content-Type: application/json
< Date: Sat, 06 Jan 2024 21:39:10 GMT
< Req-Arrive-Time: 1704577150801
< Req-Cost-Time: 2
< Resp-Start-Time: 1704577150803
< Server: istio-envoy
< X-Content-Type-Options: nosniff
< X-Envoy-Upstream-Service-Time: 1
< 
< {
<  "path": "/info",
<  "host": "foo.com",
<  "method": "GET",
<  "proto": "HTTP/1.1",
<  "headers": {
<   "Accept-Encoding": [
<    "gzip"
<   ],
<   "Original-Host": [
<    "foo.com"
<   ],
<   "Req-Start-Time": [
<    "1704577150801"
<   ],
<   "User-Agent": [
<    "Go-http-client/1.1"
<   ],
<   "X-B3-Sampled": [
<    "0"
<   ],
<   "X-B3-Spanid": [
<    "c09de19a0428596d"
<   ],
<   "X-B3-Traceid": [
<    "2254caab0f769626c09de19a0428596d"
<   ],
<   "X-Echo-Set-Header": [
<    ""
<   ],
<   "X-Envoy-Attempt-Count": [
<    "1"
<   ],
<   "X-Envoy-Decorator-Operation": [
<    "infra-backend-v1.higress-conformance-infra.svc.cluster.local:8080/*"
<   ],
<   "X-Envoy-Internal": [
<    "true"
<   ],
<   "X-Forwarded-For": [
<    "192.168.65.1"
<   ],
<   "X-Forwarded-Proto": [
<    "http"
<   ],
<   "X-Real-Ip": [
<    "192.168.0.1"
<   ],
<   "X-Request-Id": [
<    "74ba572b-e85a-46b6-b0b7-8ca51961faf6"
<   ]
<  },
<  "namespace": "higress-conformance-infra",
<  "ingress": "",
<  "service": "",
<  "pod": "infra-backend-v1-55b649759b-fzvbp"
< }

Sending Request:
< GET /info HTTP/1.1
< Host: foo.com
< User-Agent: Go-http-client/1.1
< X-Echo-Set-Header: 
< X-Real-Ip: 192.168.0.1
< Accept-Encoding: gzip
< 
< 

Received Response:
< HTTP/1.1 200 OK
< Content-Length: 949
< Content-Type: application/json
< Date: Sat, 06 Jan 2024 21:39:10 GMT
< Req-Arrive-Time: 1704577150806
< Req-Cost-Time: 3
< Resp-Start-Time: 1704577150809
< Server: istio-envoy
< X-Content-Type-Options: nosniff
< X-Envoy-Upstream-Service-Time: 3
< 
< {
<  "path": "/info",
<  "host": "foo.com",
<  "method": "GET",
<  "proto": "HTTP/1.1",
<  "headers": {
<   "Accept-Encoding": [
<    "gzip"
<   ],
<   "Original-Host": [
<    "foo.com"
<   ],
<   "Req-Start-Time": [
<    "1704577150806"
<   ],
<   "User-Agent": [
<    "Go-http-client/1.1"
<   ],
<   "X-B3-Sampled": [
<    "0"
<   ],
<   "X-B3-Spanid": [
<    "e781a8da28922b94"
<   ],
<   "X-B3-Traceid": [
<    "f6a68b128d224598e781a8da28922b94"
<   ],
<   "X-Echo-Set-Header": [
<    ""
<   ],
<   "X-Envoy-Attempt-Count": [
<    "1"
<   ],
<   "X-Envoy-Decorator-Operation": [
<    "infra-backend-v1.higress-conformance-infra.svc.cluster.local:8080/*"
<   ],
<   "X-Envoy-Internal": [
<    "true"
<   ],
<   "X-Forwarded-For": [
<    "192.168.65.1"
<   ],
<   "X-Forwarded-Proto": [
<    "http"
<   ],
<   "X-Real-Ip": [
<    "192.168.0.1"
<   ],
<   "X-Request-Id": [
<    "f886a0ff-9443-4153-affe-d25df45f73f3"
<   ]
<  },
<  "namespace": "higress-conformance-infra",
<  "ingress": "",
<  "service": "",
<  "pod": "infra-backend-v1-55b649759b-fzvbp"
< }

    http.go:263: Request passed
=== CONT  TestHigressConformanceTests/WasmPluginsIpRestriction
    apply.go:157: 🚮 Deleting ip-restriction WasmPlugin
    apply.go:157: 🚮 Deleting httproute-app-root Ingress
=== CONT  TestHigressConformanceTests
    apply.go:113: 🚮 Deleting tls-validity-checks-certificate 
    apply.go:113: 🚮 Deleting certificate 
    apply.go:157: 🚮 Deleting nacos-standlone-rc3-service Service
    apply.go:157: 🚮 Deleting nacos-standlone-rc3 Pod
    apply.go:157: 🚮 Deleting dubbo-demo-provider Pod
    apply.go:157: 🚮 Deleting httpbin Pod
    apply.go:157: 🚮 Deleting consul-service Service
    apply.go:157: 🚮 Deleting consul-standlone Pod
    apply.go:157: 🚮 Deleting web-backend Deployment
    apply.go:157: 🚮 Deleting web-backend Service
    apply.go:157: 🚮 Deleting higress-conformance-web-backend Namespace
    apply.go:157: 🚮 Deleting app-backend-v2 Deployment
    apply.go:157: 🚮 Deleting app-backend-v2 Service
    apply.go:157: 🚮 Deleting app-backend-v1 Deployment
    apply.go:157: 🚮 Deleting app-backend-v1 Service
    apply.go:157: 🚮 Deleting higress-conformance-app-backend Namespace
    apply.go:157: 🚮 Deleting infra-backend-v3 Deployment
    apply.go:157: 🚮 Deleting infra-backend-v3 Service
    apply.go:157: 🚮 Deleting infra-backend-v2 Deployment
    apply.go:157: 🚮 Deleting infra-backend-v2 Service
    apply.go:157: 🚮 Deleting infra-backend-v1 Deployment
    apply.go:157: 🚮 Deleting infra-backend-v1 Service
    apply.go:157: 🚮 Deleting higress-conformance-infra Namespace
--- PASS: TestHigressConformanceTests (23.40s)
    --- PASS: TestHigressConformanceTests/WasmPluginsIpRestriction (1.17s)
        --- PASS: TestHigressConformanceTests/WasmPluginsIpRestriction/WasmPlugins_ip-restriction (1.14s)
PASS
ok      command-line-arguments  23.832s
  1. test in k8s cluster locally
image
kubectl port-forward service/higress-gateway -n higress-system 1080:80 1443:443
Forwarding from 127.0.0.1:1080 -> 80
Forwarding from [::1]:1080 -> 80
Forwarding from 127.0.0.1:1443 -> 443
Forwarding from [::1]:1443 -> 443
Handling connection for 1080
Handling connection for 1080
Handling connection for 1080
curl http://localhost:1080/foo -H 'host: foo.bar.com' -H 'X-REAL-IP: 10.0.0.1'
foo
curl http://localhost:1080/foo -H 'host: foo.bar.com' -H 'X-REAL-IP: 10.0.3.0'
{"message":"Your IP address is not allowed."}%

Ⅴ. Special notes for reviews

@CLAassistant
Copy link

CLAassistant commented Jan 6, 2024

CLA assistant check
All committers have signed the CLA.

@Renz7
Copy link
Contributor Author

Renz7 commented Jan 7, 2024

#607

@WeixinX
Copy link
Collaborator

WeixinX commented Jan 9, 2024

@Renz7, @johnlanni 想请教一下为什么 IP 是通过请求头进行获取,而不是使用 proxywasm.GetProperty([]string{"source","address"})

@Renz7
Copy link
Contributor Author

Renz7 commented Jan 9, 2024

@Renz7 Renz7 marked this pull request as draft January 9, 2024 08:23
@johnlanni
Copy link
Collaborator

是的 应该用这个:
proxywasm.GetProperty([]string{"source","address"})

@johnlanni
Copy link
Collaborator

可以加个配置,允许用户配置ip来源:

  1. remote ip
  2. xff header
  3. 自定义header,例如 x-real-ip

@Renz7 Renz7 marked this pull request as ready for review January 23, 2024 05:29
@johnlanni
Copy link
Collaborator

cc @WeixinX

@johnlanni
Copy link
Collaborator

@SpecialYang 支持IP黑白名单的插件,有空一起review下

Copy link
Collaborator

@WeixinX WeixinX left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

其他的我认为没什么问题 ~

plugins/wasm-go/extensions/ip-restriction/main.go Outdated Show resolved Hide resolved
plugins/wasm-go/extensions/ip-restriction/utils.go Outdated Show resolved Hide resolved
@johnlanni
Copy link
Collaborator

@Renz7 请再按上述要求做一下代码调整,调整完成后我将代码合入

@Renz7
Copy link
Contributor Author

Renz7 commented Mar 3, 2024

@Renz7 请再按上述要求做一下代码调整,调整完成后我将代码合入

OK 我尽快

@Renz7
Copy link
Contributor Author

Renz7 commented Mar 5, 2024

@Renz7 请再按上述要求做一下代码调整,调整完成后我将代码合入

OK 我尽快

@johnlanni @WeixinX PTAL

Copy link
Collaborator

@johnlanni johnlanni left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@codecov-commenter
Copy link

codecov-commenter commented Mar 5, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 38.16%. Comparing base (cc6043d) to head (c297936).

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #759      +/-   ##
==========================================
+ Coverage   38.13%   38.16%   +0.02%     
==========================================
  Files          61       61              
  Lines       10436    10436              
==========================================
+ Hits         3980     3983       +3     
+ Misses       6156     6154       -2     
+ Partials      300      299       -1     

see 1 file with indirect coverage changes

@johnlanni johnlanni merged commit 3128df9 into alibaba:main Mar 12, 2024
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Implement ip black & white list plugin using TinyGo