Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Support admin API authentication with SSL certificates #1747

Merged
merged 38 commits into from
Jul 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
bc33857
Client-to-server authentication with HTTPS client certificates
johzchen Jun 20, 2020
1074440
test
johzchen Jun 20, 2020
844118c
fix: admin port
johzchen Jun 20, 2020
0a972c8
fix: https
johzchen Jun 20, 2020
408df70
test
johzchen Jun 20, 2020
ba41a01
test
johzchen Jun 20, 2020
32067b5
test
johzchen Jun 20, 2020
717f226
test
johzchen Jun 20, 2020
b9d2af9
fix lint error
johzchen Jun 20, 2020
73b311d
test
johzchen Jun 20, 2020
22cbe7d
test
johzchen Jun 20, 2020
ac1c52e
test
johzchen Jun 20, 2020
c67ec40
new cert
johzchen Jun 20, 2020
9ce5960
fix: domain
johzchen Jun 20, 2020
d349020
fix: domain
johzchen Jun 20, 2020
5addff3
config option
johzchen Jun 21, 2020
acf0d6c
Merge branch 'apisix/master' into cli-srv-auth
johzchen Jun 21, 2020
3421255
doc
johzchen Jun 21, 2020
03487a6
optimize
johzchen Jun 22, 2020
a71cd51
optimize
johzchen Jun 22, 2020
e57b026
optimize
johzchen Jun 22, 2020
f0c21b1
fix error
johzchen Jun 22, 2020
9104603
fix path error
johzchen Jun 22, 2020
beb4d3e
check http status after call mtls admin api
johzchen Jun 22, 2020
1ba44f1
remove useless config file
johzchen Jun 22, 2020
62b916f
set default path for mTLS certs
johzchen Jun 22, 2020
3219d85
fix text style
johzchen Jun 24, 2020
ac82691
fix: naming
johzchen Jun 24, 2020
586c1bc
more test cases
johzchen Jun 24, 2020
b9591f0
fix lint check
johzchen Jun 24, 2020
d479370
fix error
johzchen Jun 24, 2020
450e926
test
johzchen Jun 24, 2020
988253c
update doc for admin api mTLS
johzchen Jun 24, 2020
83a45b8
Merge branch 'master' into cli-srv-auth
johzchen Jul 16, 2020
473a59b
fix lint
johzchen Jul 16, 2020
a689132
fix etcd version
johzchen Jul 16, 2020
e256756
Merge branch 'master' into cli-srv-auth
johzchen Jul 17, 2020
b0838e8
run mTLS test cases with github ations
johzchen Jul 17, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
fail-fast: false
matrix:
platform: [ubuntu-18.04]
os_name: [linux_openresty, linux_tengine, linux_apisix_master_luarocks, linux_apisix_current_luarocks]
os_name: [linux_openresty, linux_tengine, linux_apisix_master_luarocks, linux_apisix_current_luarocks, linux_openresty_mtls]
include:
- platform: macos-latest
os_name: osx_openresty
Expand Down
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ addons:
homebrew:
update: true


cache:
directories:
- build-cache
Expand Down
182 changes: 182 additions & 0 deletions .travis/linux_openresty_mtls_runner.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
#!/usr/bin/env bash
#
# 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.
#

set -ex

export_or_prefix() {
export OPENRESTY_PREFIX="/usr/local/openresty-debug"
}

create_lua_deps() {
echo "Create lua deps cache"

make deps
luarocks install luacov-coveralls --tree=deps --local > build.log 2>&1 || (cat build.log && exit 1)

sudo rm -rf build-cache/deps
sudo cp -r deps build-cache/
sudo cp rockspec/apisix-master-0.rockspec build-cache/
}

before_install() {
sudo cpanm --notest Test::Nginx >build.log 2>&1 || (cat build.log && exit 1)
}

do_install() {
export_or_prefix

wget -qO - https://openresty.org/package/pubkey.gpg | sudo apt-key add -
sudo apt-get -y update --fix-missing
sudo apt-get -y install software-properties-common
sudo add-apt-repository -y "deb http://openresty.org/package/ubuntu $(lsb_release -sc) main"
sudo add-apt-repository -y ppa:longsleep/golang-backports

sudo apt-get update
sudo apt-get install openresty-debug lua5.1 liblua5.1-0-dev

wget https://github.com/luarocks/luarocks/archive/v2.4.4.tar.gz
tar -xf v2.4.4.tar.gz
cd luarocks-2.4.4
./configure --prefix=/usr > build.log 2>&1 || (cat build.log && exit 1)
make build > build.log 2>&1 || (cat build.log && exit 1)
sudo make install > build.log 2>&1 || (cat build.log && exit 1)
cd ..
rm -rf luarocks-2.4.4

sudo luarocks install luacheck > build.log 2>&1 || (cat build.log && exit 1)


if [ ! -f "build-cache/apisix-master-0.rockspec" ]; then
create_lua_deps

else
src=`md5sum rockspec/apisix-master-0.rockspec | awk '{print $1}'`
src_cp=`md5sum build-cache/apisix-master-0.rockspec | awk '{print $1}'`
if [ "$src" = "$src_cp" ]; then
echo "Use lua deps cache"
sudo cp -r build-cache/deps ./
else
create_lua_deps
fi
fi

# sudo apt-get install tree -y
# tree deps

git clone https://github.com/iresty/test-nginx.git test-nginx
make utils

git clone https://github.com/apache/openwhisk-utilities.git .travis/openwhisk-utilities
cp .travis/ASF* .travis/openwhisk-utilities/scancode/

ls -l ./
}

script() {
export_or_prefix
export PATH=$OPENRESTY_PREFIX/nginx/sbin:$OPENRESTY_PREFIX/luajit/bin:$OPENRESTY_PREFIX/bin:$PATH
openresty -V
sudo service etcd stop
mkdir -p ~/etcd-data
/usr/bin/etcd --listen-client-urls 'http://0.0.0.0:2379' --advertise-client-urls='http://0.0.0.0:2379' --data-dir ~/etcd-data > /dev/null 2>&1 &
etcd --version
sleep 5


# enable mTLS
sed -i 's/\# port_admin: 9180/port_admin: 9180/' conf/config.yaml
sed -i 's/\# https_admin: true/https_admin: true/' conf/config.yaml
sed -i 's/mtls_enable: false/mtls_enable: true/' conf/config.yaml
sed -i 's#admin_ssl_ca_cert: ""#admin_ssl_ca_cert: "../t/certs/mtls_ca.crt"#' conf/config.yaml
sed -i 's#admin_ssl_cert_key: ""#admin_ssl_cert_key: "../t/certs/mtls_server.key"#' conf/config.yaml
sed -i 's#admin_ssl_cert: ""#admin_ssl_cert: "../t/certs/mtls_server.crt"#' conf/config.yaml

./bin/apisix help
./bin/apisix init
./bin/apisix init_etcd
./bin/apisix start

sleep 1
cat logs/error.log


echo "127.0.0.1 admin.apisix.dev" | sudo tee -a /etc/hosts

# correct certs
code=$(curl -i -o /dev/null -s -w %{http_code} --cacert ./t/certs/mtls_ca.crt --key ./t/certs/mtls_client.key --cert ./t/certs/mtls_client.crt -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' https://admin.apisix.dev:9180/apisix/admin/routes)
nic-chen marked this conversation as resolved.
Show resolved Hide resolved
nic-chen marked this conversation as resolved.
Show resolved Hide resolved
if [ ! $code -eq 200 ]; then
echo "failed: failed to enabled mTLS for admin"
exit 1
fi

# # no certs
# code=$(curl -i -o /dev/null -s -w %{http_code} -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' https://admin.apisix.dev:9180/apisix/admin/routes)
# if [ ! $code -eq 000 ]; then
# echo "failed: failed to enabled mTLS for admin"
# exit 1
# fi

# # no ca cert
# code=$(curl -i -o /dev/null -s -w %{http_code} --key ./t/certs/mtls_client.key --cert ./t/certs/mtls_client.crt -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' https://admin.apisix.dev:9180/apisix/admin/routes)
# if [ ! $code -eq 000 ]; then
# echo "failed: failed to enabled mTLS for admin"
# exit 1
# fi

# # error key
# code=$(curl -i -o /dev/null -s -w %{http_code} --cacert ./t/certs/mtls_ca.crt --key ./t/certs/mtls_server.key --cert ./t/certs/mtls_client.crt -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' https://admin.apisix.dev:9180/apisix/admin/routes)
# if [ ! $code -eq 000 ]; then
# echo "failed: failed to enabled mTLS for admin"
# exit 1
# fi

# skip
code=$(curl -i -o /dev/null -s -w %{http_code} -k -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' https://admin.apisix.dev:9180/apisix/admin/routes)
if [ ! $code -eq 400 ]; then
echo "failed: failed to enabled mTLS for admin"
exit 1
fi

./bin/apisix stop
sleep 1

make lint && make license-check || exit 1
}

after_success() {
cat luacov.stats.out
luacov-coveralls
}

case_opt=$1
shift

case ${case_opt} in
before_install)
before_install "$@"
;;
do_install)
do_install "$@"
;;
script)
script "$@"
;;
after_success)
after_success "$@"
;;
esac
14 changes: 13 additions & 1 deletion bin/apisix
Original file line number Diff line number Diff line change
Expand Up @@ -289,13 +289,25 @@ http {
server {
{%if https_admin then%}
listen {* port_admin *} ssl;

{%if admin_api_mtls and admin_api_mtls.admin_ssl_cert and admin_api_mtls.admin_ssl_cert ~= "" and
admin_api_mtls.admin_ssl_cert_key and admin_api_mtls.admin_ssl_cert_key ~= "" and
admin_api_mtls.admin_ssl_ca_cert and admin_api_mtls.admin_ssl_ca_cert ~= ""
then%}
ssl_verify_client on;
ssl_certificate {* admin_api_mtls.admin_ssl_cert *};
ssl_certificate_key {* admin_api_mtls.admin_ssl_cert_key *};
ssl_client_certificate {* admin_api_mtls.admin_ssl_ca_cert *};
nic-chen marked this conversation as resolved.
Show resolved Hide resolved
{% else %}
ssl_certificate cert/apisix_admin_ssl.crt;
ssl_certificate_key cert/apisix_admin_ssl.key;
ssl_session_cache shared:SSL:20m;
{%end%}

ssl_session_cache shared:SSL:20m;
ssl_protocols {* ssl.ssl_protocols *};
ssl_ciphers {* ssl.ssl_ciphers *};
ssl_prefer_server_ciphers on;

{% else %}
listen {* port_admin *};
{%end%}
Expand Down
6 changes: 5 additions & 1 deletion conf/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,11 @@ apisix:
# - "::/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 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.
Expand Down
62 changes: 62 additions & 0 deletions doc/mtls.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<!--
#
# 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/mtls.md)

## Mutual TLS authentication

### Why use it

Mutual TLS authentication provides a better way to prevent unauthorized access to APISIX.

The clients will provide their certificates to the server and the server will check whether the cert is signed by the supplied CA and decide whether to serve the request.

### How to enable

nic-chen marked this conversation as resolved.
Show resolved Hide resolved
1. Generate self-signed key pairs, including ca, server, client key pairs.

2. Modify configuration items in `conf/config.yaml`:

```yaml
port_admin: 9180
https_admin: true

mtls:
enable: true # Enable or disable mTLS. Enable depends on `port_admin` and `https_admin`.
ca_cert: "/data/certs/mtls_ca.crt" # Path of your self-signed ca cert.
server_key: "/data/certs/mtls_server.key" # Path of your self-signed server side cert.
server_cert: "/data/certs/mtls_server.crt" # Path of your self-signed server side key.
```

3. Run command:

```shell
membphis marked this conversation as resolved.
Show resolved Hide resolved
apisix init
apisix reload
```

### How client calls

Please replace the following certificate paths and domain name with your real ones.

* Note: The same CA certificate as the server needs to be used *

```shell
curl --cacert /data/certs/mtls_ca.crt --key /data/certs/mtls_client.key --cert /data/certs/mtls_client.crt https://admin.apisix.dev:9180/apisix/admin/routes -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1'
```
60 changes: 60 additions & 0 deletions doc/zh-cn/mtls.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<!--
#
# 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.
#
-->

[English](../mtls.md)

## 双向认证

### 为什么使用

双向认证可以更好的防止未经授权访问 APISIX ,客户端将向服务器提供其证书,服务器将检查证书是否由提供的 CA 签名并决定是否响应请求。

### 如何开启

1. 生成自签证书对,包括 ca、server、client 证书对。

2. 修改 `conf/config.yaml` 中的配置项:

```yaml
port_admin: 9180
https_admin: true

mtls:
enable: true # Enable or disable mTLS. Enable depends on `port_admin` and `https_admin`.
ca_cert: "/data/certs/mtls_ca.crt" # Path of your self-signed CA cert.
server_key: "/data/certs/mtls_server.key" # Path of your self-signed server side cert.
server_cert: "/data/certs/mtls_server.crt" # Path of your self-signed server side key.
```

3. 执行命令:

```shell
apisix init
apisix reload
```

### 客户端如何调用

请将以下证书及域名替换为您的真实内容。

* 注意:需要和服务器使用相同的 CA 证书 *

```shell
curl --cacert /data/certs/mtls_ca.crt --key /data/certs/mtls_client.key --cert /data/certs/mtls_client.crt https://admin.apisix.dev:9180/apisix/admin/routes -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1'
```
20 changes: 20 additions & 0 deletions t/certs/mtls_ca.crt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
-----BEGIN CERTIFICATE-----
MIIDSjCCAjICCQDmBdlKmGaJITANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJj
bjESMBAGA1UECAwJR3VhbmdEb25nMQ8wDQYDVQQHDAZaaHVIYWkxDTALBgNVBAoM
BGFwaTcxDDAKBgNVBAsMA29wczEWMBQGA1UEAwwNY2EuYXBpc2l4LmRldjAeFw0y
MDA2MjAxMzEzNDFaFw0zMDA2MTgxMzEzNDFaMGcxCzAJBgNVBAYTAmNuMRIwEAYD
VQQIDAlHdWFuZ0RvbmcxDzANBgNVBAcMBlpodUhhaTENMAsGA1UECgwEYXBpNzEM
MAoGA1UECwwDb3BzMRYwFAYDVQQDDA1jYS5hcGlzaXguZGV2MIIBIjANBgkqhkiG
9w0BAQEFAAOCAQ8AMIIBCgKCAQEAun+Gq/bp7CcZ9i5ZdjuCvyZVXsiAaBELVi/Q
QQtC90z5aQyWudTPB1Lcpk5HosbT73eHh03hFCRMFv6Miase1T59KJ4zGSFKoFEr
j2cbNmWFJEhTGce1pn52zMzZrXERYhKBA0n4bwHK/IND0XeEZ2RQPtGnGBqj3vKL
3px+mOzIeMy4VMSkIkL2jlgo5jN0IjQIsvHRSrhIWzFhr6qtIJhuh0oI6gs+/yvA
vspGeVFtIg/1PY3bOgFfhJg08/Aw7vgMjmADypEbBabLaWOZ8RZ3Ci2is6cL/1wX
Sr8OIIBXTmTGmXEuSsMsBgC7BFwEY4XEsGx8QQJsrh1dSf2t0QIDAQABMA0GCSqG
SIb3DQEBBQUAA4IBAQCKC98wWieC66NHAYb9ICOwr+XTmoFABpFNaM4bPXMD4IUq
BaMGfBh92e4ANz2bm1D3J0ZNH3TVC7OhF2ymi6wSMde/Ygkh5xu2HgTEX2QTDQVd
J27jwEIe45VLdvuu33jvE/iNNQHI6J6zP45gs/FS+CwMoYRnNcC+428YUf9XMcgM
UkeMOnnkhw1OUzmoACY705hAEAPFbb7KkQ109lgbh6cucMy7Nw/N1t6Pyuxlqteg
d8Wy6VFYPRRK43dYoA9B0yvsZCERvxgR1IrDjo0B2wIDzM4eM6ldLfnr8pPnBFfS
g/Pdo6VZsXeSv3o00lBEY/25Vqxn3sPBK4E7a+mX
-----END CERTIFICATE-----
Loading