mirror of
https://gitee.com/iresty/apisix.git
synced 2024-12-16 01:41:17 +08:00
174 lines
5.3 KiB
Markdown
174 lines
5.3 KiB
Markdown
<!--
|
|
#
|
|
# 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.
|
|
#
|
|
-->
|
|
|
|
[Chinese](zh-cn/https.md)
|
|
|
|
### HTTPS
|
|
|
|
`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:
|
|
|
|
```python
|
|
#!/usr/bin/env python
|
|
# coding: utf-8
|
|
# save this file as ssl.py
|
|
import sys
|
|
# sudo pip install requests
|
|
import requests
|
|
|
|
if len(sys.argv) <= 3:
|
|
print("bad argument")
|
|
sys.exit(1)
|
|
with open(sys.argv[1]) as f:
|
|
cert = f.read()
|
|
with open(sys.argv[2]) as f:
|
|
key = f.read()
|
|
sni = sys.argv[3]
|
|
api_key = "edd1c9f034335f136f87ad84b625c8f1"
|
|
resp = requests.put("http://127.0.0.1:9080/apisix/admin/ssl/1", json={
|
|
"cert": cert,
|
|
"key": key,
|
|
"snis": [sni],
|
|
}, headers={
|
|
"X-API-KEY": api_key,
|
|
})
|
|
print(resp.status_code)
|
|
print(resp.text)
|
|
```
|
|
|
|
```shell
|
|
# create SSL object
|
|
./ssl.py t.crt t.key test.com
|
|
|
|
# create Router object
|
|
curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -i -d '
|
|
{
|
|
"uri": "/hello",
|
|
"hosts": ["test.com"],
|
|
"methods": ["GET"],
|
|
"upstream": {
|
|
"type": "roundrobin",
|
|
"nodes": {
|
|
"127.0.0.1:1980": 1
|
|
}
|
|
}
|
|
}'
|
|
|
|
# make a test
|
|
|
|
curl --resolve 'test.com:9443:127.0.0.1' https://test.com:9443/hello -vvv
|
|
* Added test.com:9443:127.0.0.1 to DNS cache
|
|
* About to connect() to test.com port 9443 (#0)
|
|
* Trying 127.0.0.1...
|
|
* Connected to test.com (127.0.0.1) port 9443 (#0)
|
|
* Initializing NSS with certpath: sql:/etc/pki/nssdb
|
|
* skipping SSL peer certificate verification
|
|
* SSL connection using TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
|
|
* Server certificate:
|
|
* subject: CN=test.com,O=iresty,L=ZhuHai,ST=GuangDong,C=CN
|
|
* start date: Jun 24 22:18:05 2019 GMT
|
|
* expire date: May 31 22:18:05 2119 GMT
|
|
* common name: test.com
|
|
* issuer: CN=test.com,O=iresty,L=ZhuHai,ST=GuangDong,C=CN
|
|
> GET /hello HTTP/1.1
|
|
> User-Agent: curl/7.29.0
|
|
> Host: test.com:9443
|
|
> 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`.
|
|
|
|
```shell
|
|
./ssl.py t.crt t.key '*.test.com'
|
|
|
|
curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -i -d '
|
|
{
|
|
"uri": "/hello",
|
|
"hosts": ["*.test.com"],
|
|
"methods": ["GET"],
|
|
"upstream": {
|
|
"type": "roundrobin",
|
|
"nodes": {
|
|
"127.0.0.1:1980": 1
|
|
}
|
|
}
|
|
}'
|
|
|
|
# make a test
|
|
|
|
curl --resolve 'www.test.com:9443:127.0.0.1' https://www.test.com:9443/hello -vvv
|
|
* Added test.com:9443:127.0.0.1 to DNS cache
|
|
* About to connect() to test.com port 9443 (#0)
|
|
* Trying 127.0.0.1...
|
|
* Connected to test.com (127.0.0.1) port 9443 (#0)
|
|
* Initializing NSS with certpath: sql:/etc/pki/nssdb
|
|
* skipping SSL peer certificate verification
|
|
* SSL connection using TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
|
|
* Server certificate:
|
|
* subject: CN=test.com,O=iresty,L=ZhuHai,ST=GuangDong,C=CN
|
|
* start date: Jun 24 22:18:05 2019 GMT
|
|
* expire date: May 31 22:18:05 2119 GMT
|
|
* common name: test.com
|
|
* issuer: CN=test.com,O=iresty,L=ZhuHai,ST=GuangDong,C=CN
|
|
> GET /hello HTTP/1.1
|
|
> User-Agent: curl/7.29.0
|
|
> Host: test.com:9443
|
|
> 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:
|
|
|
|
```json
|
|
{
|
|
"snis": ["www.test.com", "mail.test.com"]
|
|
}
|
|
```
|
|
|
|
### multiple certificates for a single domain
|
|
|
|
If you want to configure multiple certificate for a single domain, for
|
|
instance, supporting both the
|
|
[ECC](https://en.wikipedia.org/wiki/Elliptic-curve_cryptography)
|
|
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.
|