一、演示環境准備
1、nginx配置
[root@nginx conf.d]# pwd /etc/nginx/conf.d [root@nginx conf.d]# ls conf_bak kong_test.conf [root@nginx conf.d]# cat kong_test.conf server { listen 80; server_name 192.168.1.128; access_log /root/access.log main; location / { root /usr/share/nginx/html; index index.html index.htm; } } [root@nginx conf.d]# cd /usr/share/nginx/html/ [root@nginx html]# ls 404.html 50x.html index.html [root@nginx html]# mkdir test [root@nginx html]# cd test [root@nginx test]# echo "`hostname` , hello" > first.html [root@nginx test]# cat first.html nginx , hello
二、基本操作
1、添加 API
官網教程:https://getkong.org/docs/0.10.x/getting-started/adding-your-api/
提示:在查看官網文檔時默認會定向到最新的說明文檔,要留意下當前kong版本選擇對應的文檔。
[root@kong_server ~]# curl -i -X POST http://localhost:8001/apis/ -d "name=first_api" -d "uris=/first" -d "upstream_url=http://192.168.1.129/test/first.html" HTTP/1.1 201 Created Date: Thu, 05 Apr 2018 22:17:53 GMT Content-Type: application/json; charset=utf-8 Transfer-Encoding: chunked Connection: keep-alive Access-Control-Allow-Origin: * Server: kong/0.10.4 {"http_if_terminated":true,"id":"683c6d99-5766-4cdf-bd3f-5b6b1e3afe67","retries":5,"preserve_host":false,"created_at":1522966674000,"upstream_connect_timeout":60000,"upstream_url":"http:\/\/192.168.1.129\/test\/first.html","upstream_read_timeout":60000,"https_only":false,"upstream_send_timeout":60000,"strip_uri":true,"name":"first_api","uris":["\/first"]}
當然,此步驟也可以通過kong的桌面管理工具進行操作 或者 UI工具操作,安裝步驟見 API gateway 之 kong 安裝(二)
a、驗證是否已生效
[root@kong_server ~]# curl -i -X GET http://192.168.1.128:8000/first HTTP/1.1 200 OK Date: Thu, 05 Apr 2018 22:41:17 GMT Content-Type: text/html; charset=UTF-8 Content-Length: 14 Connection: keep-alive Server: nginx/1.10.2 Last-Modified: Sat, 13 Jan 2018 03:01:57 GMT ETag: "5a5976a5-e" Accept-Ranges: bytes X-Kong-Upstream-Latency: 1 X-Kong-Proxy-Latency: 0 Via: kong/0.10.4 nginx , hello
這樣,就添加了一個API,並通過kong代理請求到后端的nginx服務器上了,此時kong就是一個反向代理服務器,由於kong是api gateway,它支持很多安全、驗證、日志等插件功能,所以就可以在API上添加想要實現的功能對應的插件
2、啟用插件(basic auth)
basic auth插件作用就是當訪問某個API時,需要經過認證用戶名密碼通過后才能訪問。
官網教程:https://getkong.org/plugins/basic-authentication/?_ga=2.77732445.853990414.1523077059-1213803929.1523077059
a、關聯插件到需要認證的API上面
[root@kong_server ~]# curl -X POST http://localhost:8001/apis/first_api/plugins -d "name=basic-auth" -d "config.hide_credentials=true" {"api_id":"683c6d99-5766-4cdf-bd3f-5b6b1e3afe67","id":"61a6ebe0-677c-406e-b93f-a1da9b617db4","created_at":1522979304000,"enabled":true,"name":"basic-auth","config":{"hide_credentials":true,"anonymous":""}}
b、創建一個消費者(consumer)
注意:這里的consumer主要是指代表一種角色,它也可以是多個不同名字的consumer,假如這個API我允許通過哪些角色的consumer訪問,其他一律不允許,比如,jason, tom, jack等消費者角色,kong通常設置某些認證且只允許某個消費者來認證訪問,后面演示中還會用到。
[root@kong_server ~]# curl -i -X POST http://localhost:8001/consumers/ -d "username=Jason" HTTP/1.1 201 Created Date: Fri, 06 Apr 2018 02:09:49 GMT Content-Type: application/json; charset=utf-8 Transfer-Encoding: chunked Connection: keep-alive Access-Control-Allow-Origin: * Server: kong/0.10.4 {"username":"Jason","created_at":1522980590000,"id":"63d186fd-aa5c-449c-99d7-1f0cb7437e47"}
c、創建一個用戶信息,即basic auth認證需要用到的用戶名/密碼
[root@kong_server ~]# curl -X POST http://localhost:8001/consumers/Jason/basic-auth \ > --data "username=user1" \ > --data "password=password1" {"password":"0efeedcbcf5fbca03dc602dcd57fb77ea5c0d237","consumer_id":"63d186fd-aa5c-449c-99d7-1f0cb7437e47","id":"d38e51e0-7aef-4383-b9cb-cd5ff0b8eda2","username":"user1","created_at":1522980878000}
d、再次訪問加入basic auth認證后的 API
[root@kong_server ~]# curl -i -X GET http://localhost:8000/first --header "Authorization: Basic dXNlcjE6cGFzc3dvcmQx" HTTP/1.1 200 OK Date: Fri, 06 Apr 2018 02:27:40 GMT Content-Type: text/html; charset=UTF-8 Content-Length: 14 Connection: keep-alive Server: nginx/1.10.2 Last-Modified: Sat, 13 Jan 2018 03:01:57 GMT ETag: "5a5976a5-e" Accept-Ranges: bytes X-Kong-Upstream-Latency: 1 X-Kong-Proxy-Latency: 19 Via: kong/0.10.4 nginx , hello
這里要注意的是,dXNlcjE6cGFzc3dvcmQx 這個是對字符串 "user1:password1" 做base64編碼后的結果,即 echo -n "user1:password1" | base64,如果輸入錯誤編碼后的值,kong會返回403 Forbidden
[root@kong_server ~]# curl -i -X GET http://localhost:8000/first --header "Authorization: Basic hahaha" HTTP/1.1 403 Forbidden Date: Fri, 06 Apr 2018 02:33:07 GMT Content-Type: application/json; charset=utf-8 Transfer-Encoding: chunked Connection: keep-alive Server: kong/0.10.4 {"message":"Invalid authentication credentials"}
瀏覽器訪問效果
創建了這個basic auth用戶名、密碼后,可以把這個插件應用到其他的API上面,可以通過這個用戶名密碼登錄驗證。
3、key-auth 插件認證
官網教程:https://getkong.org/plugins/key-authentication/?_ga=2.44833389.853990414.1523077059-1213803929.1523077059
a、關聯插件至指定API
[root@kong_server ~]# curl -i -X POST \ > --url http://localhost:8001/apis/first_api/plugins/ \ > --data 'name=key-auth' HTTP/1.1 201 Created Date: Fri, 06 Apr 2018 03:42:46 GMT Content-Type: application/json; charset=utf-8 Transfer-Encoding: chunked Connection: keep-alive Access-Control-Allow-Origin: * Server: kong/0.10.4 {"api_id":"683c6d99-5766-4cdf-bd3f-5b6b1e3afe67","id":"51c396d9-6ae1-45fe-a760-bbb1735f77b6","created_at":1522986167000,"enabled":true,"name":"key-auth","config":{"hide_credentials":false,"anonymous":"","key_names":["apikey"],"key_in_body":false}}
此時已經向first_api這個API應用了2個插件,為了不影響,把basic-auth插件取消掉
b、驗證是否生效
[root@nginx html]# curl -i -X GET --url http://192.168.1.128:8000/first HTTP/1.1 401 Unauthorized Date: Fri, 06 Apr 2018 03:50:51 GMT Content-Type: application/json; charset=utf-8 Transfer-Encoding: chunked Connection: keep-alive WWW-Authenticate: Key realm="kong" Server: kong/0.10.4 {"message":"No API key found in request"}
c、自定義API key給consumer
[root@kong_server ~]# curl -i -X POST \ > --url http://localhost:8001/consumers/Jason/key-auth/ \ > --data 'key=test_api_key_jason' HTTP/1.1 201 Created Date: Fri, 06 Apr 2018 03:57:10 GMT Content-Type: application/json; charset=utf-8 Transfer-Encoding: chunked Connection: keep-alive Access-Control-Allow-Origin: * Server: kong/0.10.4 {"created_at":1522987031000,"consumer_id":"63d186fd-aa5c-449c-99d7-1f0cb7437e47","key":"test_api_key_jason","id":"fae89fb9-9e9b-4c98-bf7d-b393a81c297b"}
d、通過剛剛創建的API key訪問API
[root@nginx html]# curl -i -X GET --url http://192.168.1.128:8000/first --header "apikey: test_api_key_jason" HTTP/1.1 200 OK Date: Fri, 06 Apr 2018 03:58:30 GMT Content-Type: text/html; charset=UTF-8 Content-Length: 14 Connection: keep-alive Server: nginx/1.10.2 Last-Modified: Sat, 13 Jan 2018 03:01:57 GMT ETag: "5a5976a5-e" Accept-Ranges: bytes X-Kong-Upstream-Latency: 1 X-Kong-Proxy-Latency: 2 Via: kong/0.10.4 nginx , hello
瀏覽器訪問:
e、通過kong自定義生成apikey(推薦這種方式)
[root@kong_server ~]# curl -i -X POST --url http://localhost:8001/consumers/ --data "username=Tom" HTTP/1.1 201 Created Date: Fri, 06 Apr 2018 04:09:40 GMT Content-Type: application/json; charset=utf-8 Transfer-Encoding: chunked Connection: keep-alive Access-Control-Allow-Origin: * Server: kong/0.10.4 {"username":"Tom","created_at":1522987781000,"id":"665658e9-f88b-48a0-81c1-594df3bdf456"} [root@kong_server ~]# curl -i -X POST --url http://localhost:8001/consumers/Tom/key-auth/ -d "" HTTP/1.1 201 Created Date: Fri, 06 Apr 2018 04:10:04 GMT Content-Type: application/json; charset=utf-8 Transfer-Encoding: chunked Connection: keep-alive Access-Control-Allow-Origin: * Server: kong/0.10.4 {"created_at":1522987805000,"consumer_id":"665658e9-f88b-48a0-81c1-594df3bdf456","key":"d4661517c9a0463ebabcba7187d2ee0b","id":"16755308-0f55-427e-9cc6-c0d8de0897d4"}
也可以查詢某個consumer的API key
[root@kong_server ~]# curl -i -X GET --url http://localhost:8001/consumers/Tom/key-auth/ HTTP/1.1 200 OK Date: Fri, 06 Apr 2018 04:17:27 GMT Content-Type: application/json; charset=utf-8 Transfer-Encoding: chunked Connection: keep-alive Access-Control-Allow-Origin: * Server: kong/0.10.4 {"data":[{"created_at":1522987805000,"consumer_id":"665658e9-f88b-48a0-81c1-594df3bdf456","key":"d4661517c9a0463ebabcba7187d2ee0b","id":"16755308-0f55-427e-9cc6-c0d8de0897d4"}],"total":1} [root@kong_server ~]# [root@kong_server ~]# [root@kong_server ~]# curl -i -X GET --url http://localhost:8001/consumers/Jason/key-auth/ HTTP/1.1 200 OK Date: Fri, 06 Apr 2018 04:18:34 GMT Content-Type: application/json; charset=utf-8 Transfer-Encoding: chunked Connection: keep-alive Access-Control-Allow-Origin: * Server: kong/0.10.4 {"data":[{"created_at":1522987031000,"consumer_id":"63d186fd-aa5c-449c-99d7-1f0cb7437e47","key":"test_api_key_jason","id":"fae89fb9-9e9b-4c98-bf7d-b393a81c297b"}],"total":1}
f、訪問測試
[root@nginx html]# curl -i -X GET --url http://192.168.1.128:8000/first --header 'apikey: d4661517c9a0463ebabcba7187d2ee0b' HTTP/1.1 200 OK Date: Fri, 06 Apr 2018 04:15:02 GMT Content-Type: text/html; charset=UTF-8 Content-Length: 14 Connection: keep-alive Server: nginx/1.10.2 Last-Modified: Sat, 13 Jan 2018 03:01:57 GMT ETag: "5a5976a5-e" Accept-Ranges: bytes X-Kong-Upstream-Latency: 1 X-Kong-Proxy-Latency: 0 Via: kong/0.10.4 nginx , hello
瀏覽器訪問:
4、IP Restriction 插件
官網教程:https://getkong.org/plugins/ip-restriction/?_ga=2.44833389.853990414.1523077059-1213803929.1523077059
Linux nginx服務器IP:192.168.1.129
這里把192.168.1.129的IP加入黑名單進行測試
a、管理插件至指定API
[root@kong_server ~]# curl -i -X POST http://localhost:8001/apis/first_api/plugins \ > --data "name=ip-restriction" \ > --data "config.blacklist=192.168.1.129, 143.1.0.0/24" HTTP/1.1 201 Created Date: Fri, 06 Apr 2018 05:01:58 GMT Content-Type: application/json; charset=utf-8 Transfer-Encoding: chunked Connection: keep-alive Access-Control-Allow-Origin: * Server: kong/0.10.4 {"api_id":"683c6d99-5766-4cdf-bd3f-5b6b1e3afe67","id":"3bdc6ea8-0fca-41f3-b330-36b2ce71c9e2","created_at":1522990918000,"enabled":true,"name":"ip-restriction","config":{"blacklist":["192.168.1.129","143.1.0.0\/24"]}}
b、驗證是否生效
只啟用ip restriction插件
[root@nginx html]# curl -i -X GET --url http://192.168.1.128:8000/first HTTP/1.1 403 Forbidden Date: Fri, 06 Apr 2018 05:02:02 GMT Content-Type: application/json; charset=utf-8 Transfer-Encoding: chunked Connection: keep-alive Server: kong/0.10.4 {"message":"Your IP address is not allowed"}
5、Rate limiting 訪問速率限制
官網教程:https://getkong.org/plugins/rate-limiting/?_ga=2.85736144.853990414.1523077059-1213803929.1523077059
a、關聯至API
[root@kong_server ~]# curl -X POST http://localhost:8001/apis/first_api/plugins \ > --data "name=rate-limiting" \ > --data "config.second=2" \ > --data "config.hour=100" {"api_id":"683c6d99-5766-4cdf-bd3f-5b6b1e3afe67","id":"4135a8bf-13b6-4f6f-b006-f5afe65ae6cc","created_at":1522991450000,"enabled":true,"name":"rate-limiting","config":{"fault_tolerant":true,"limit_by":"consumer","policy":"cluster","redis_database":0,"second":2,"hour":100,"redis_timeout":2000,"redis_port":6379}}
config.second=2 表示每秒超過2次請求first_api接口時,將會被限制,提示限制信息
config.hour=100 表示一個小時內超過100次后就會被限制訪問,提示限制信息
提示:這里是可以指定只限制某個consumer,加上參數就可了 consumer_id=CONSUMER
b、效果測試
[root@nginx html]# for i in {1..3}; do curl -X GET --url http://192.168.1.128:8000/first ; done nginx , hello nginx , hello {"message":"API rate limit exceeded"}
瀏覽器快速刷新效果:
6、acl 訪問控制
In order to use this plugin, you need to properly have configured your Service or Route (or API) with anauthentication plugin so that the plugin can identify who is the client Consumer making the request.
要使用這個插件的話,我們必須先配置好認證插件,可以是basic-auth, key-auth, OAth 2.0,其實這個acl插件需要知道是那個consumer發起的請求,由於前面幾個認證插件都需要關聯consumer,acl需要借助認證插件。
a、應用插件至API
[root@kong_server ~]# curl -X POST http://localhost:8001/apis/first_api/plugins/ \ > --data "name=acl" \ > --data "config.blacklist=group1" {"api_id":"683c6d99-5766-4cdf-bd3f-5b6b1e3afe67","id":"3cfc5701-78f5-48d6-a475-28ac09b2fb9a","created_at":1522997186000,"enabled":true,"name":"acl","config":{"blacklist":["group1"]}}
b、關聯consumer
前面我們已經添加了 Jason, Tom 兩個consumer, 我們再添加Jerry, Bob兩個,以便分為2個組,然后讓acl控制一個組做黑名單或白名單
[root@kong_server ~]# curl -X POST http://localhost:8001/consumers/ -d "username=Jerry" {"username":"Jerry","created_at":1522998210000,"id":"98c8d417-1572-48fe-99ee-feab95cb788e"} [root@kong_server ~]# curl -X POST http://localhost:8001/consumers/ -d "username=Bob" {"username":"Bob","created_at":1522998223000,"id":"40fb4329-482c-432c-8a1c-101a3ddae328"} [root@kong_server ~]# curl -X POST http://localhost:8001/consumers/Jerry/key-auth/ -d "" {"created_at":1522998713000,"consumer_id":"98c8d417-1572-48fe-99ee-feab95cb788e","key":"d0baf3a09b074a65a14b66057ddd2f07","id":"417fd160-0282-483a-bdbf-6e7e183d0ff9"} [root@kong_server ~]# curl -X POST http://localhost:8001/consumers/Bob/key-auth/ -d "" {"created_at":1522998726000,"consumer_id":"40fb4329-482c-432c-8a1c-101a3ddae328","key":"4cea214e55024c4aba0aeb3e79472ebe","id":"940d1166-bb78-424e-bb2f-5b50b2751c63"} [root@kong_server ~]# curl -X POST http://localhost:8001/consumers/Jerry/acls/ -d "group=group1" {"group":"group1","consumer_id":"98c8d417-1572-48fe-99ee-feab95cb788e","created_at":1522998308000,"id":"5259a6c1-4ddc-402d-8572-2651d46555f4"} [root@kong_server ~]# curl -X POST http://localhost:8001/consumers/Bob/acls/ -d "group=group1" {"group":"group1","consumer_id":"40fb4329-482c-432c-8a1c-101a3ddae328","created_at":1522998321000,"id":"be2191d4-ecae-4638-ab5a-dd26c16d6002"}
c、驗證是否生效
注意:這個是需要開啟一個認證插件的,不然會報錯
[root@nginx html]# curl -X GET --url http://192.168.1.128:8000/first {"message":"Cannot identify the consumer, add an authentication plugin to use the ACL plugin"} [root@nginx html]# curl -X GET --url http://192.168.1.128:8000/first -H "apikey: test_api_key_jason" {"message":"Cannot identify the consumer, add an authentication plugin to use the ACL plugin"}
以key-auth插件作為認證插件,開啟key-auth插件,再測試
[root@nginx html]# curl -X GET --url http://192.168.1.128:8000/first -H "apikey: d0baf3a09b074a65a14b66057ddd2f07" # Jerry apikey {"message":"You cannot consume this service"} [root@nginx html]# curl -X GET --url http://192.168.1.128:8000/first -H "apikey: 4cea214e55024c4aba0aeb3e79472ebe" # Bob apikey {"message":"You cannot consume this service"} [root@nginx html]# curl -X GET --url http://192.168.1.128:8000/first -H "apikey: test_api_key_jason" # Jason 自定義apikey(不在黑名單組) nginx , hello
7、syslog 插件
把指定api的請求日志記錄到syslog日志
a、關聯syslog插件
我們直接通過桌面管理工具添加
b、驗證,訪問API時,tailf /var/log/message(kong服務器)
[root@nginx html]# curl -i -X GET --url http://192.168.1.128:8000/first HTTP/1.1 200 OK Date: Fri, 06 Apr 2018 07:37:14 GMT Content-Type: text/html; charset=UTF-8 Content-Length: 14 Connection: keep-alive Server: nginx/1.10.2 Last-Modified: Sat, 13 Jan 2018 03:01:57 GMT ETag: "5a5976a5-e" Accept-Ranges: bytes X-Kong-Upstream-Latency: 1 X-Kong-Proxy-Latency: 0 Via: kong/0.10.4 nginx , hello
系統日志
Apr 6 15:37:14 base kong[8109]: {"client_ip":"192.168.1.129","request":{"method":"GET","uri":"\/first","size":"176","request_uri":"http:\/\/192.168.1.128:8000\/first","querystring":{},"headers":{"host":"192.168.1.128:8000","accept":"*\/*","user-agent":"curl\/7.19.7 (x86_64-redhat-linux-gnu) libcurl\/7.19.7 NSS\/3.27.1 zlib\/1.2.3 libidn\/1.18 libssh2\/1.4.2"}},"response":{"status":200,"size":"335","headers":{"server":"nginx\/1.10.2","content-type":"text\/html; charset=UTF-8","connection":"close","content-length":"14","x-kong-proxy-latency":"0","last-modified":"Sat, 13 Jan 2018 03:01:57 GMT","x-kong-upstream-latency":"1","accept-ranges":"bytes","via":"kong\/0.10.4","etag":"\"5a5976a5-e\""}},"latencies":{"request":1,"kong":0,"proxy":1},"started_at":1523000234618,"tries":[{"ip":"192.168.1.129","port":80}],"api":{"uris":["\/first"],"id":"683c6d99-5766-4cdf-bd3f-5b6b1e3afe67","upstream_read_timeout":60000,"preserve_host":false,"created_at":1522966674000,"upstream_connect_timeout":60000,"upstream_url":"http:\/\/192.168.1.129\/test\/first.html","strip_uri":true,"https_only":false,"name":"first_api","http_if_terminated":true,"upstream_send_timeout":60000,"retries":5}}
更多插件應用:https://konghq.com/plugins/