Certificate

APISIX supports to load multiple SSL certificates by TLS extension Server Name Indication (SNI).

Single SNI

It is most common for an SSL certificate to contain only one domain. We can create an ssl object. Here is a simple case, creates a ssl object and route object.

  • cert: PEM-encoded public certificate of the SSL key pair.
  • key: PEM-encoded private key of the SSL key pair.
  • snis: Hostname(s) to associate with this certificate as SNIs. To set this attribute this certificate must have a valid private key associated with it.

We will use the Python script below to simplify the example:

  1. #!/usr/bin/env python
  2. # coding: utf-8
  3. # save this file as ssl.py
  4. import sys
  5. # sudo pip install requests
  6. import requests
  7. if len(sys.argv) <= 3:
  8. print("bad argument")
  9. sys.exit(1)
  10. with open(sys.argv[1]) as f:
  11. cert = f.read()
  12. with open(sys.argv[2]) as f:
  13. key = f.read()
  14. sni = sys.argv[3]
  15. api_key = "edd1c9f034335f136f87ad84b625c8f1"
  16. resp = requests.put("http://127.0.0.1:9080/apisix/admin/ssl/1", json={
  17. "cert": cert,
  18. "key": key,
  19. "snis": [sni],
  20. }, headers={
  21. "X-API-KEY": api_key,
  22. })
  23. print(resp.status_code)
  24. print(resp.text)
  1. # create SSL object
  2. ./ssl.py t.crt t.key test.com
  3. # create Router object
  4. curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -i -d '
  5. {
  6. "uri": "/hello",
  7. "hosts": ["test.com"],
  8. "methods": ["GET"],
  9. "upstream": {
  10. "type": "roundrobin",
  11. "nodes": {
  12. "127.0.0.1:1980": 1
  13. }
  14. }
  15. }'
  16. # make a test
  17. curl --resolve 'test.com:9443:127.0.0.1' https://test.com:9443/hello -vvv
  18. * Added test.com:9443:127.0.0.1 to DNS cache
  19. * About to connect() to test.com port 9443 (#0)
  20. * Trying 127.0.0.1...
  21. * Connected to test.com (127.0.0.1) port 9443 (#0)
  22. * Initializing NSS with certpath: sql:/etc/pki/nssdb
  23. * skipping SSL peer certificate verification
  24. * SSL connection using TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
  25. * Server certificate:
  26. * subject: CN=test.com,O=iresty,L=ZhuHai,ST=GuangDong,C=CN
  27. * start date: Jun 24 22:18:05 2019 GMT
  28. * expire date: May 31 22:18:05 2119 GMT
  29. * common name: test.com
  30. * issuer: CN=test.com,O=iresty,L=ZhuHai,ST=GuangDong,C=CN
  31. > GET /hello HTTP/1.1
  32. > User-Agent: curl/7.29.0
  33. > Host: test.com:9443
  34. > Accept: */*

wildcard SNI

Sometimes, one SSL certificate may contain a wildcard domain like *.test.com, that means it can accept more than one domain, eg: www.test.com or mail.test.com.

Here is an example, note that the value we pass as sni is *.test.com.

  1. ./ssl.py t.crt t.key '*.test.com'
  2. curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -i -d '
  3. {
  4. "uri": "/hello",
  5. "hosts": ["*.test.com"],
  6. "methods": ["GET"],
  7. "upstream": {
  8. "type": "roundrobin",
  9. "nodes": {
  10. "127.0.0.1:1980": 1
  11. }
  12. }
  13. }'
  14. # make a test
  15. curl --resolve 'www.test.com:9443:127.0.0.1' https://www.test.com:9443/hello -vvv
  16. * Added test.com:9443:127.0.0.1 to DNS cache
  17. * About to connect() to test.com port 9443 (#0)
  18. * Trying 127.0.0.1...
  19. * Connected to test.com (127.0.0.1) port 9443 (#0)
  20. * Initializing NSS with certpath: sql:/etc/pki/nssdb
  21. * skipping SSL peer certificate verification
  22. * SSL connection using TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
  23. * Server certificate:
  24. * subject: CN=test.com,O=iresty,L=ZhuHai,ST=GuangDong,C=CN
  25. * start date: Jun 24 22:18:05 2019 GMT
  26. * expire date: May 31 22:18:05 2119 GMT
  27. * common name: test.com
  28. * issuer: CN=test.com,O=iresty,L=ZhuHai,ST=GuangDong,C=CN
  29. > GET /hello HTTP/1.1
  30. > User-Agent: curl/7.29.0
  31. > Host: test.com:9443
  32. > Accept: */*

multiple domain

If your SSL certificate may contain more than one domain, like www.test.com and mail.test.com, then you can add them into the snis array. For example:

  1. {
  2. "snis": ["www.test.com", "mail.test.com"]
  3. }

multiple certificates for a single domain

If you want to configure multiple certificate for a single domain, for instance, supporting both the ECC and RSA key-exchange algorithm, then just configure the extra certificates (the first certificate and private key should be still put in cert and key) and private keys by certs and keys.

  • certs: PEM-encoded certificate array.
  • keys: PEM-encoded private key array.

APISIX will pair certificate and private key with the same indice as a SSL key pair. So the length of certs and keys must be same.