You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@apisix.apache.org by GitBox <gi...@apache.org> on 2020/12/30 09:52:19 UTC

[GitHub] [apisix] liyin37 commented on issue #3159: request help: when config one route,but post failed

liyin37 commented on issue #3159:
URL: https://github.com/apache/apisix/issues/3159#issuecomment-752395750


   不好意思,我仔细描述下:
   使用docker-compose启动apisix服务,其中
   docker-compose.yaml:
   version: "3"
   
   services:
     apisix:
       container_name: gistack-apisix
       image: registry.cn-beijing.aliyuncs.com/gisuni/apisix:1.5-alpine
       restart: always
       volumes:
         - $PWD/apisix/config.yaml:/usr/local/apisix/conf/config.yaml:ro
         - $PWD/apisix/debug.yaml:/usr/local/apisix/conf/debug.yaml:ro
         - $PWD/apisix/apisix_log:/usr/local/apisix/logs 
       depends_on:
         - etcd
       ports:
         - "9080:9080/tcp"
         - "9443:9443/tcp"
         - "9000:9000/tcp"
   
     etcd:
       container_name: gistack-etcd
       image: registry.cn-beijing.aliyuncs.com/gisuni/etcd:3.4.9
       user: root
       restart: always
       volumes:
         - $PWD/apisix/etcd_data:/etcd_data
       environment:
         ETCD_DATA_DIR: /etcd_data
         ETCD_ENABLE_V2: "true"
         ALLOW_NONE_AUTHENTICATION: "yes"
         ETCD_ADVERTISE_CLIENT_URLS: "http://0.0.0.0:2379"
         ETCD_LISTEN_CLIENT_URLS: "http://0.0.0.0:2379"
       ports:
         - "2379:2379/tcp"
   config.yaml 配置文件内容为:
   #
   # Licensed to the Apache Software Foundation (ASF) under one or more
   # contributor license agreements.  See the NOTICE file distributed with
   # this work for additional information regarding copyright ownership.
   # The ASF licenses this file to You under the Apache License, Version 2.0
   # (the "License"); you may not use this file except in compliance with
   # the License.  You may obtain a copy of the License at
   #
   #     http://www.apache.org/licenses/LICENSE-2.0
   #
   # Unless required by applicable law or agreed to in writing, software
   # distributed under the License is distributed on an "AS IS" BASIS,
   # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   # See the License for the specific language governing permissions and
   # limitations under the License.
   #
   apisix:
     node_listen: 9080              # APISIX listening port
     enable_admin: true
     enable_admin_cors: true         # Admin API support CORS response headers.
     enable_debug: false
     enable_dev_mode: false          # Sets nginx worker_processes to 1 if set to true
     enable_reuseport: true          # Enable nginx SO_REUSEPORT switch if set to true.
     enable_ipv6: true
     config_center: etcd             # etcd: use etcd to store the config value
                                     # yaml: fetch the config value from local yaml file `/your_path/conf/apisix.yaml`
   
     #proxy_protocol:                 # Proxy Protocol configuration
     #  listen_http_port: 9181        # The port with proxy protocol for http, it differs from node_listen and port_admin.
                                      # This port can only receive http request with proxy protocol, but node_listen & port_admin
                                      # can only receive http request. If you enable proxy protocol, you must use this port to
                                      # receive http request with proxy protocol
     #  listen_https_port: 9182       # The port with proxy protocol for https
     #  enable_tcp_pp: true           # Enable the proxy protocol for tcp proxy, it works for stream_proxy.tcp option
     #  enable_tcp_pp_to_upstream: true # Enables the proxy protocol to the upstream server
   
     proxy_cache:                     # Proxy Caching configuration
       cache_ttl: 10s                 # The default caching time if the upstream does not specify the cache time
       zones:                         # The parameters of a cache
       - name: disk_cache_one         # The name of the cache, administrator can be specify
                                      # which cache to use by name in the admin api
         memory_size: 50m             # The size of shared memory, it's used to store the cache index
         disk_size: 1G                # The size of disk, it's used to store the cache data
         disk_path: "/tmp/disk_cache_one" # The path to store the cache data
         cache_levels: "1:2"           # The hierarchy levels of a cache
     #  - name: disk_cache_two
     #    memory_size: 50m
     #    disk_size: 1G
     #    disk_path: "/tmp/disk_cache_two"
     #    cache_levels: "1:2"
   
     allow_admin:                  # http://nginx.org/en/docs/http/ngx_http_access_module.html#allow
       - 0.0.0.0/0                # If we don't set any IP list, then any IP access is allowed by default.
     #   - "::/64"
     # port_admin: 9180              # use a separate port
     # https_admin: true             # enable HTTPS when use a separate port for Admin API.
                                   # Admin API will use conf/apisix_admin_api.crt and conf/apisix_admin_api.key as certificate.
     admin_api_mtls:               # Depends on `port_admin` and `https_admin`.
       admin_ssl_cert: ""             # Path of your self-signed server side cert.
       admin_ssl_cert_key: ""         # Path of your self-signed server side key.
       admin_ssl_ca_cert: ""          # Path of your self-signed ca cert.The CA is used to sign all admin api callers' certificates.
   
     # Default token when use API to call for Admin API.
     # *NOTE*: Highly recommended to modify this value to protect APISIX's Admin API.
     # Disabling this configuration item means that the Admin API does not
     # require any authentication.
     admin_key:
       -
         name: "admin"
         key: edd1c9f034335f136f87ad84b625c8f1
         role: admin                 # admin: manage all configuration data
                                     # viewer: only can view configuration data
       -
         name: "viewer"
         key: 4054f7cf07e344346cd3f287985e76a2
         role: viewer
   
     delete_uri_tail_slash: false    # delete the '/' at the end of the URI
     router:
       http: 'radixtree_uri'         # radixtree_uri: match route by uri(base on radixtree)
                                     # radixtree_host_uri: match route by host + uri(base on radixtree)
       ssl: 'radixtree_sni'          # radixtree_sni: match route by SNI(base on radixtree)
     # stream_proxy:                 # TCP/UDP proxy
     #   tcp:                        # TCP proxy port list
     #     - 9100
     #     - 9101
     #   udp:                        # UDP proxy port list
     #     - 9200
     #     - 9211
     # dns_resolver:                   # If not set, read from `/etc/resolv.conf`
     #  - 1.1.1.1
     #  - 8.8.8.8
     dns_resolver_valid: 30          # valid time for dns result 30 seconds
     resolver_timeout: 5             # resolver timeout
     ssl:
       enable: true
       enable_http2: true
       listen_port: 9443
       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"
       key_encrypt_salt: "edd1c9f0985e76a2"    #  If not set, will save origin ssl key into etcd.
                                               #  If set this, must be a string of length 16. And it will encrypt ssl key with AES-128-CBC
                                               #  !!! So do not change it after saving your ssl, it can't decrypt the ssl keys have be saved if you change !!
   #  discovery: eureka               # service discovery center
   nginx_config:                     # config for render the template to genarate nginx.conf
     error_log: "logs/error.log"
     error_log_level: "debug"         # warn,error
     worker_rlimit_nofile: 20480     # the number of files a worker process can open, should be larger than worker_connections
     worker_shutdown_timeout: 240s     # timeout for a graceful shutdown of worker processes
     event:
       worker_connections: 10620
     http:
       access_log: "logs/access.log"
       keepalive_timeout: 60s         # timeout during which a keep-alive client connection will stay open on the server side.
       client_header_timeout: 60s     # timeout for reading client request header, then 408 (Request Time-out) error is returned to the client
       client_body_timeout: 60s       # timeout for reading client request body, then 408 (Request Time-out) error is returned to the client
       send_timeout: 10s              # timeout for transmitting a response to the client.then the connection is closed
       underscores_in_headers: "on"   # default enables the use of underscores in client request header fields
       real_ip_header: "X-Real-IP"    # http://nginx.org/en/docs/http/ngx_http_realip_module.html#real_ip_header
       real_ip_from:                  # http://nginx.org/en/docs/http/ngx_http_realip_module.html#set_real_ip_from
         - 127.0.0.1
         - 'unix:'
       #lua_shared_dicts:              # add custom shared cache to nginx.conf
       #  ipc_shared_dict: 100m        # custom shared cache, format: `cache-key: cache-size`
   
   etcd:
     host:                           # it's possible to define multiple etcd hosts addresses of the same etcd cluster.
       - "http://gistack-etcd:2379"     # multiple etcd address
     prefix: "/apisix"               # apisix configurations prefix
     timeout: 30                     # 30 seconds
     # user: root                     # root username for etcd
     # password: 5tHkHhYkjr6cQY        # root password for etcd
   #eureka:
   #  host:                           # it's possible to define multiple eureka hosts addresses of the same eureka cluster.
   #    - "http://127.0.0.1:8761"
   #  prefix: "/eureka/"
   #  fetch_interval: 30              # default 30s
   #  weight: 100                     # default weight for node
   #  timeout:
   #    connect: 2000                 # default 2000ms
   #    send: 2000                    # default 2000ms
   #    read: 5000                    # default 5000ms
   
   plugins:                          # plugin list
     - example-plugin
     - limit-req
     - limit-count
     - limit-conn
     - key-auth
     - basic-auth
     - prometheus
     - node-status
     - jwt-auth
     - zipkin
     - ip-restriction
     - grpc-transcode
     - serverless-pre-function
     - serverless-post-function
     - openid-connect
     - proxy-rewrite
     - redirect
     - response-rewrite
     - fault-injection
     - udp-logger
     - wolf-rbac
     - tcp-logger
     - kafka-logger
     - cors
     - consumer-restriction
     - syslog
     - batch-requests
     - http-logger
     - skywalking
     - echo
     - authz-keycloak
     - uri-blocker
     - request-validation
     - proxy-cache
     - proxy-mirror
     - ip-blacklist
   
   stream_plugins:
     - mqtt-proxy
   
   我们添加了一个黑白名单的插件ip-blacklist.lua到镜像的/usr/local/apisix/apisix/plugins目录下
   local ipairs    = ipairs
   local core      = require("apisix.core")
   local ipmatcher = require("resty.ipmatcher")
   local cjson = require ("cjson")
   local str_sub   = string.sub
   local str_find  = string.find
   local tonumber  = tonumber
   
   
   local schema = {
       type = "object",
       properties = {
           blacklist = {
               type = "array",
               items = {type = "array"},
               minItems = 1
           }
       },
       oneOf = {
           {required = {"blacklist"}}
       }
   }
   
   
   local plugin_name = "ip-blacklist"
   
   
   local _M = {
       version = 0.1,
       priority = 5000,        -- TODO: add a type field, may be a good idea
       name = plugin_name,
       schema = schema,
   }
   
   
   local function valid_ip(ip)
       local mask = 0
       local sep_pos = str_find(ip, "/", 1, true)
       if sep_pos then
           mask = str_sub(ip, sep_pos + 1)
           mask = tonumber(mask)
           if mask < 0 or mask > 128 then
               return false
           end
           ip = str_sub(ip, 1, sep_pos - 1)
       end
   
       if ipmatcher.parse_ipv4(ip) then
           if mask < 0 or mask > 32 then
               return false
           end
           return true
       end
   
       if mask < 0 or mask > 128 then
           return false
       end
       return ipmatcher.parse_ipv6(ip)
   end
   
   
   function _M.check_schema(conf)
       local ok, err = core.schema.check(schema, conf)
   
       if not ok then
           return false, err
       end
   
       if conf.blacklist and #conf.blacklist > 0 then
           for _, cidr in ipairs(conf.blacklist) do
               if not valid_ip(cidr[1]) then
                   return false, "invalid ip address: " .. cidr
               end
           end
       end
   
       return true
   end
   
   
   local function create_ip_mather(ip_list)
       local ip, err = ipmatcher.new(ip_list)
       if not ip then
           core.log.error("failed to create ip matcher: ", err,
                          " ip list: ", core.json.delay_encode(ip_list))
           return nil
       end
   
       return ip
   end
   
   
   function _M.access(conf, ctx)
      
       local servername = ""
       local uri = ctx.var.request_uri
       local sep_end = str_find(uri, "/", 2, true)
   
       if sep_end then
   	servername = str_sub(uri, 2, sep_end - 1)
       else 
   	servername = str_sub(uri, 2, string.len(uri))
       end
       if servername ~= "arcgis" then
   	ngx.header["Set-Cookie"] = {"server-site-location="..servername..";path=/"}
       end   
   
       local remote_addr = ctx.var.remote_addr
   
       if conf.blacklist and #conf.blacklist > 0 then
          -- core.log.warn(cjson.encode(conf.blacklist))
   	for i,cidr in pairs(conf.blacklist) do
   	   -- core.log.warn(cidr)
   	    local ip = cidr[1]
   	    local start_time = tonumber(cidr[2])
   	    local end_time = tonumber(cidr[3])
   	    local current_time = os.time()*1000;
   	    if remote_addr==ip and current_time >= start_time and current_time <= end_time then
   		 return 403, { message = "Sorry, Your IP address is not allowed!" } 
   	    end
          end 
      end
   end
   
   
   return _M
   
   现在开始测试黑白名单功能
   添加一条路由策略,代码如下:
   curl https://8.210.172.30:9443/apisix/admin/routes -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d ‘
   {
   	"uris": [
   		"/test/*"
   	],
   	"upstream": {
   		"nodes": {
   			"www.baidu.com:443": 1
   		},
   		"type": "roundrobin"
   	},
   	"desc": "test",
   	"plugins": {
   		"proxy-rewrite": {
   			"scheme": "https"
   		},
   		"ip-blacklist": {
   			"blacklist": [
   				["1.1.1.1","1609308000000","1609311600000"]
   			]
   		}
   	},
   	"priority": 0
   }’
   拦截的是1.1.1.1这个IP,但随便找一台客户机请求这条路由,都提示403 错误
   URL:https://8.210.172.30:9443/test/1
   ![image](https://user-images.githubusercontent.com/42507175/103343736-b6c14980-4ac7-11eb-88e1-ed9715a38bda.png)
   


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org