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 2021/09/24 08:47:22 UTC

[GitHub] [apisix] tzssangglass edited a comment on issue #5103: request help: Apache APISIX with Secured Websockets

tzssangglass edited a comment on issue #5103:
URL: https://github.com/apache/apisix/issues/5103#issuecomment-926456343


   @BoazDr, here's my demo
   
   1. The mock upstream websocket server is an openresty, configured as below:
   
   ```nginx
   master_process on;
   
   worker_processes 2;
   
   error_log logs/error.log warn;
   pid logs/nginx.pid;
   
   worker_rlimit_nofile 20480;
   
   events {
       accept_mutex off;
       worker_connections 10620;
   }
   
   worker_shutdown_timeout 3;
   
   http {
       server {
           listen 1983 ssl;
           ssl_certificate             /usr/local/Cellar/apisix/t/certs/apisix.crt;
           ssl_certificate_key         /usr/local/Cellar/apisix/t/certs/apisix.key;
           lua_ssl_trusted_certificate /usr/local/Cellar/apisix/t/certs/apisix.crt;
           server_tokens off;
   
           ssl_certificate_by_lua_block {
               local ngx_ssl = require "ngx.ssl"
               ngx.log(ngx.WARN, "Receive SNI: ", ngx_ssl.server_name())
           }
   
           location /websocket_handshake {
               content_by_lua_block {
                   local websocket = require "resty.websocket.server"
                   local wb, err = websocket:new()
                   if not wb then
                       ngx.log(ngx.ERR, "failed to new websocket: ", err)
                       return ngx.exit(400)
                   end
   
                   local bytes, err = wb:send_text("hello")
                   if not bytes then
                       ngx.log(ngx.ERR, "failed to send text: ", err)
                       return ngx.exit(444)
                   end
               }
   
               more_clear_headers Date;
           }
       }
   }
   ```
   
   use [websocat](https://github.com/vi/websocat) test this websocket server:
   
   ```shell
   websocat -t --ws-c-uri=wss://127.0.0.1:1983/websocket_handshake - ws-c:cmd:'socat - ssl:127.0.0.1:1983,verify=0,cafile=/usr/local/Cellar/apisix/t/certs/apisix.crt'
   hello
   ```
   
   2. start APISIX, and add route
   
   ```shell
   curl --location --request PUT 'http://127.0.0.1:9080/apisix/admin/routes/1' \
   --header 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' \
   --header 'Content-Type: application/json' \
   --data-raw '{
       "upstream": {
           "scheme": "https",
           "nodes": {
               "127.0.0.1:1983": 1
           },
           "type": "roundrobin"
       },
       "enable_websocket": true,
       "uri": "/websocket_handshake"
   }'
   ```
   
   3. add ssl
   
   ```
   curl --location --request PUT 'http://127.0.0.1:9080/apisix/admin/ssl/1' \
   --header 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' \
   --header 'Content-Type: application/json' \
   --data-raw '{
       "cert": "-----BEGIN CERTIFICATE-----
   MIIEojCCAwqgAwIBAgIJAK253pMhgCkxMA0GCSqGSIb3DQEBCwUAMFYxCzAJBgNV
   BAYTAkNOMRIwEAYDVQQIDAlHdWFuZ0RvbmcxDzANBgNVBAcMBlpodUhhaTEPMA0G
   A1UECgwGaXJlc3R5MREwDwYDVQQDDAh0ZXN0LmNvbTAgFw0xOTA2MjQyMjE4MDVa
   GA8yMTE5MDUzMTIyMTgwNVowVjELMAkGA1UEBhMCQ04xEjAQBgNVBAgMCUd1YW5n
   RG9uZzEPMA0GA1UEBwwGWmh1SGFpMQ8wDQYDVQQKDAZpcmVzdHkxETAPBgNVBAMM
   CHRlc3QuY29tMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAyCM0rqJe
   cvgnCfOw4fATotPwk5Ba0gC2YvIrO+gSbQkyxXF5jhZB3W6BkWUWR4oNFLLSqcVb
   VDPitz/Mt46Mo8amuS6zTbQetGnBARzPLtmVhJfoeLj0efMiOepOSZflj9Ob4yKR
   2bGdEFOdHPjm+4ggXU9jMKeLqdVvxll/JiVFBW5smPtW1Oc/BV5terhscJdOgmRr
   abf9xiIis9/qVYfyGn52u9452V0owUuwP7nZ01jt6iMWEGeQU6mwPENgvj1olji2
   WjdG2UwpUVp3jp3l7j1ekQ6mI0F7yI+LeHzfUwiyVt1TmtMWn1ztk6FfLRqwJWR/
   Evm95vnfS3Le4S2ky3XAgn2UnCMyej3wDN6qHR1onpRVeXhrBajbCRDRBMwaNw/1
   /3Uvza8QKK10PzQR6OcQ0xo9psMkd9j9ts/dTuo2fzaqpIfyUbPST4GdqNG9NyIh
   /B9g26/0EWcjyO7mYVkaycrtLMaXm1u9jyRmcQQI1cGrGwyXbrieNp63AgMBAAGj
   cTBvMB0GA1UdDgQWBBSZtSvV8mBwl0bpkvFtgyiOUUcbszAfBgNVHSMEGDAWgBSZ
   tSvV8mBwl0bpkvFtgyiOUUcbszAMBgNVHRMEBTADAQH/MB8GA1UdEQQYMBaCCHRl
   c3QuY29tggoqLnRlc3QuY29tMA0GCSqGSIb3DQEBCwUAA4IBgQAHGEul/x7ViVgC
   tC8CbXEslYEkj1XVr2Y4hXZXAXKd3W7V3TC8rqWWBbr6L/tsSVFt126V5WyRmOaY
   1A5pju8VhnkhYxYfZALQxJN2tZPFVeME9iGJ9BE1wPtpMgITX8Rt9kbNlENfAgOl
   PYzrUZN1YUQjX+X8t8/1VkSmyZysr6ngJ46/M8F16gfYXc9zFj846Z9VST0zCKob
   rJs3GtHOkS9zGGldqKKCj+Awl0jvTstI4qtS1ED92tcnJh5j/SSXCAB5FgnpKZWy
   hme45nBQj86rJ8FhN+/aQ9H9/2Ib6Q4wbpaIvf4lQdLUEcWAeZGW6Rk0JURwEog1
   7/mMgkapDglgeFx9f/XztSTrkHTaX4Obr+nYrZ2V4KOB4llZnK5GeNjDrOOJDk2y
   IJFgBOZJWyS93dQfuKEj42hA79MuX64lMSCVQSjX+ipR289GQZqFrIhiJxLyA+Ve
   U/OOcSRr39Kuis/JJ+DkgHYa/PWHZhnJQBxcqXXk1bJGw9BNbhM=
   -----END CERTIFICATE-----",
       "key": "-----BEGIN RSA PRIVATE KEY-----
   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
   -----END RSA PRIVATE KEY-----",
       "sni": "127.0.0.1"
   }'
   ```
   
   Note: The functions of the `sni` are explained below
   
   
   3. use websocat test this websocket server:
   
   ```shell
   websocat -t --tls-domain="127.0.0.1" --ws-c-uri=wss://127.0.0.1:9443/websocket_handshake - ws-c:cmd:'socat - ssl:127.0.0.1:9443,verify=0,cafile=/usr/local/Cellar/apisix/t/certs/apisix.crt'
   hello
   ```
   
   `--tls-domain="127.0.0.1"` specify domain for SNI when client do tlshandshake with APISIX, 
   
   Wireshake captures the following packet:
   
   ```
   Handshake Protocol: Client Hello
       Handshake Type: Client Hello (1)
       Length: 415
       Version: TLS 1.2 (0x0303)
       Random: 31959c15cb141a3b6493f35ec3fe97b26c7824aa9f2703aada7712d20229b5a2
       Session ID Length: 32
       Session ID: 30d9629faee10e4e4dc7b6feccaac46e64e7a9fccf1de32e8fd4d3dd1c09f804
       Cipher Suites Length: 150
       Cipher Suites (75 suites)
       Compression Methods Length: 1
       Compression Methods (1 method)
       Extensions Length: 192
       Extension: server_name (len=14)
           Type: server_name (0)
           Length: 14
           Server Name Indication extension
               Server Name list length: 12
               Server Name Type: host_name (0)
               Server Name length: 9
               Server Name: 127.0.0.1
       Extension: ec_point_formats (len=4)
       Extension: supported_groups (len=4)
       Extension: session_ticket (len=0)
       Extension: encrypt_then_mac (len=0)
       Extension: extended_master_secret (len=0)
       Extension: signature_algorithms (len=48)
       Extension: supported_versions (len=9)
       Extension: psk_key_exchange_modes (len=2)
       Extension: key_share (len=71)
   ****
   ```
   
   you can see that the `Server Name Indication extension` passes `127.0.0.1`, APISIX will look up the corresponding cert and key based on this SNI, then find the cert and key uploaded in step 2.
   
   finally, the wss protocol is completed from the client -> APISIX -> upstream 
   


-- 
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.

To unsubscribe, e-mail: notifications-unsubscribe@apisix.apache.org

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