Skip to content

Commit c6b9f99

Browse files
Revolyssupstarszshreemaan-abhishek
authored
feat: autogenerate admin api key if not passed (#11080)
Signed-off-by: Ashish Tiwari <[email protected]> Co-authored-by: Peter Zhu <[email protected]> Co-authored-by: Abhishek Choudhary <[email protected]>
1 parent 4df549c commit c6b9f99

File tree

262 files changed

+3269
-879
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

262 files changed

+3269
-879
lines changed

.github/workflows/source-install.yml

+18-11
Original file line numberDiff line numberDiff line change
@@ -88,17 +88,24 @@ jobs:
8888
8989
- name: Test apisix
9090
run: |
91-
curl http://127.0.0.1:9180/apisix/admin/routes/1 \
92-
-H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
93-
{
94-
"uri": "/get",
95-
"upstream": {
96-
"type": "roundrobin",
97-
"nodes": {
98-
"127.0.0.1:8088": 1
99-
}
100-
}
101-
}'
91+
wget https://github.com/mikefarah/yq/releases/download/3.4.1/yq_linux_amd64 -O /usr/bin/yq && sudo chmod +x /usr/bin/yq
92+
get_admin_key() {
93+
local admin_key=$(yq '.deployment.admin.admin_key[0].key' conf/config.yaml)
94+
echo "$admin_key"
95+
}
96+
export admin_key=$(get_admin_key); echo $admin_key
97+
cat conf/config.yaml
98+
curl -v http://127.0.0.1:9180/apisix/admin/routes/1 \
99+
-H "X-API-KEY: $admin_key" -X PUT -d '
100+
{
101+
"uri": "/get",
102+
"upstream": {
103+
"type": "roundrobin",
104+
"nodes": {
105+
"127.0.0.1:8088": 1
106+
}
107+
}
108+
}'
102109
result_code=`curl -I -m 10 -o /dev/null -s -w %{http_code} http://127.0.0.1:9080/get`
103110
if [[ $result_code -ne 200 ]]; then
104111
printf "result_code: %s\n" "$result_code"

Makefile

+2
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ ENV_DOCKER_COMPOSE ?= docker-compose --project-directory $(CURDIR) -p $(proj
4141
ENV_NGINX ?= $(ENV_NGINX_EXEC) -p $(CURDIR) -c $(CURDIR)/conf/nginx.conf
4242
ENV_NGINX_EXEC := $(shell command -v openresty 2>/dev/null || command -v nginx 2>/dev/null)
4343
ENV_OPENSSL_PREFIX ?= /usr/local/openresty/openssl3
44+
ENV_LIBYAML_INSTALL_PREFIX ?= /usr
4445
ENV_LUAROCKS ?= luarocks
4546
## These variables can be injected by luarocks
4647
ENV_INST_PREFIX ?= /usr
@@ -131,6 +132,7 @@ deps: install-runtime
131132
mkdir -p ~/.luarocks; \
132133
$(ENV_LUAROCKS) config $(ENV_LUAROCKS_FLAG_LOCAL) variables.OPENSSL_LIBDIR $(addprefix $(ENV_OPENSSL_PREFIX), /lib); \
133134
$(ENV_LUAROCKS) config $(ENV_LUAROCKS_FLAG_LOCAL) variables.OPENSSL_INCDIR $(addprefix $(ENV_OPENSSL_PREFIX), /include); \
135+
$(ENV_LUAROCKS) config $(ENV_LUAROCKS_FLAG_LOCAL) variables.YAML_DIR $(ENV_LIBYAML_INSTALL_PREFIX); \
134136
$(ENV_LUAROCKS) install apisix-master-0.rockspec --tree deps --only-deps $(ENV_LUAROCKS_SERVER_OPT); \
135137
else \
136138
$(call func_echo_warn_status, "WARNING: You're not using LuaRocks 3.x; please remove the luarocks and reinstall it via https://raw.githubusercontent.com/apache/apisix/master/utils/linux-install-luarocks.sh"); \

apisix-master-0.rockspec

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ description = {
3232

3333
dependencies = {
3434
"lua-resty-ctxdump = 0.1-0",
35+
"lyaml = 6.2.8",
3536
"api7-lua-resty-dns-client = 7.0.1",
3637
"lua-resty-template = 2.0",
3738
"lua-resty-etcd = 1.10.5",

apisix/admin/init.lua

+1-1
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ local function set_ctx_and_check_token()
117117
local ok, err = check_token(api_ctx)
118118
if not ok then
119119
core.log.warn("failed to check token: ", err)
120-
core.response.exit(401, { error_msg = "failed to check token" })
120+
core.response.exit(401, { error_msg = "failed to check token", description = err })
121121
end
122122
end
123123

apisix/cli/ops.lua

+2-5
Original file line numberDiff line numberDiff line change
@@ -221,12 +221,9 @@ Please modify "admin_key" in conf/config.yaml .
221221
end
222222

223223
if admin.key == "" then
224-
util.die(help:format("ERROR: missing valid Admin API token."), "\n")
225-
end
226-
227-
if admin.key == "edd1c9f034335f136f87ad84b625c8f1" then
228224
stderr:write(
229-
help:format([[WARNING: using fixed Admin API token has security risk.]]),
225+
help:format([[WARNING: using empty Admin API.
226+
This will trigger APISIX to automatically generate a random Admin API token.]]),
230227
"\n"
231228
)
232229
end

apisix/core/id.lua

+72-7
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,19 @@
2121

2222
local fetch_local_conf = require("apisix.core.config_local").local_conf
2323
local try_read_attr = require("apisix.core.table").try_read_attr
24+
local profile = require("apisix.core.profile")
2425
local log = require("apisix.core.log")
25-
local uuid = require('resty.jit-uuid')
26+
local uuid = require("resty.jit-uuid")
27+
local lyaml = require("lyaml")
2628
local smatch = string.match
2729
local open = io.open
28-
29-
30-
local prefix = ngx.config.prefix()
30+
local type = type
31+
local ipairs = ipairs
32+
local string = string
33+
local math = math
34+
local prefix = ngx.config.prefix()
35+
local pairs = pairs
36+
local ngx_exit = ngx.exit
3137
local apisix_uid
3238

3339
local _M = {version = 0.1}
@@ -62,18 +68,77 @@ local function write_file(path, data)
6268
end
6369

6470

71+
local function generate_yaml(table)
72+
-- By default lyaml will parse null values as []
73+
-- The following logic is a workaround so that null values are parsed as null
74+
local function replace_null(tbl)
75+
for k, v in pairs(tbl) do
76+
if type(v) == "table" then
77+
replace_null(v)
78+
elseif v == nil then
79+
tbl[k] = "<PLACEHOLDER>"
80+
end
81+
end
82+
end
83+
84+
-- Replace null values with "<PLACEHOLDER>"
85+
replace_null(table)
86+
local yaml = lyaml.dump({ table })
87+
yaml = yaml:gsub("<PLACEHOLDER>", "null"):gsub("%[%s*%]", "null")
88+
return yaml
89+
end
90+
91+
6592
_M.gen_uuid_v4 = uuid.generate_v4
6693

6794

95+
--- This will autogenerate the admin key if it's passed as an empty string in the configuration.
96+
local function autogenerate_admin_key(default_conf)
97+
local changed = false
98+
-- Check if deployment.role is either traditional or control_plane
99+
local deployment_role = default_conf.deployment and default_conf.deployment.role
100+
if deployment_role and (deployment_role == "traditional" or
101+
deployment_role == "control_plane") then
102+
-- Check if deployment.admin.admin_key is not nil and it's an empty string
103+
local admin_keys = try_read_attr(default_conf, "deployment", "admin", "admin_key")
104+
if admin_keys and type(admin_keys) == "table" then
105+
for i, admin_key in ipairs(admin_keys) do
106+
if admin_key.role == "admin" and admin_key.key == "" then
107+
changed = true
108+
admin_keys[i].key = ""
109+
for _ = 1, 32 do
110+
admin_keys[i].key = admin_keys[i].key ..
111+
string.char(math.random(65, 90) + math.random(0, 1) * 32)
112+
end
113+
end
114+
end
115+
end
116+
end
117+
return default_conf,changed
118+
end
119+
120+
68121
function _M.init()
122+
local local_conf = fetch_local_conf()
123+
124+
local local_conf, changed = autogenerate_admin_key(local_conf)
125+
if changed then
126+
local yaml_conf = generate_yaml(local_conf)
127+
local local_conf_path = profile:yaml_path("config")
128+
local ok, err = write_file(local_conf_path, yaml_conf)
129+
if not ok then
130+
log.error("failed to write updated local configuration: ", err)
131+
ngx_exit(-1)
132+
end
133+
end
134+
135+
--allow user to specify a meaningful id as apisix instance id
69136
local uid_file_path = prefix .. "/conf/apisix.uid"
70137
apisix_uid = read_file(uid_file_path)
71138
if apisix_uid then
72139
return
73140
end
74141

75-
--allow user to specify a meaningful id as apisix instance id
76-
local local_conf = fetch_local_conf()
77142
local id = try_read_attr(local_conf, "apisix", "id")
78143
if id then
79144
apisix_uid = local_conf.apisix.id
@@ -89,6 +154,7 @@ function _M.init()
89154
end
90155
end
91156

157+
92158
---
93159
-- Returns the instance id of the running APISIX
94160
--
@@ -100,5 +166,4 @@ function _M.get()
100166
return apisix_uid
101167
end
102168

103-
104169
return _M

benchmark/run.sh

+4-4
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,8 @@ sleep 3
7474

7575
#############################################
7676
echo -e "\n\napisix: $worker_cnt worker + $upstream_cnt upstream + no plugin"
77-
78-
curl http://127.0.0.1:9180/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
77+
admin_key=$(yq '.deployment.admin.admin_key[0].key' conf/config.yaml | sed 's/"//g')
78+
curl http://127.0.0.1:9180/apisix/admin/routes/1 -H "X-API-KEY: $admin_key" -X PUT -d '
7979
{
8080
"uri": "/hello",
8181
"plugins": {
@@ -100,8 +100,8 @@ sleep 1
100100

101101
#############################################
102102
echo -e "\n\napisix: $worker_cnt worker + $upstream_cnt upstream + 2 plugins (limit-count + prometheus)"
103-
104-
curl http://127.0.0.1:9180/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
103+
admin_key=$(yq '.deployment.admin.admin_key[0].key' conf/config.yaml | sed 's/"//g')
104+
curl http://127.0.0.1:9180/apisix/admin/routes/1 -H "X-API-KEY: $admin_key" -X PUT -d '
105105
{
106106
"uri": "/hello",
107107
"plugins": {

ci/centos7-ci.sh

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ install_dependencies() {
2929
cpanminus perl \
3030
openssl-devel
3131

32+
yum install -y libyaml-devel
3233
# install newer curl
3334
yum makecache
3435
yum install -y libnghttp2-devel

ci/common.sh

+3
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ export_version_info() {
2323

2424
export_or_prefix() {
2525
export OPENRESTY_PREFIX="/usr/local/openresty"
26+
2627
export PATH=$OPENRESTY_PREFIX/nginx/sbin:$OPENRESTY_PREFIX/luajit/bin:$OPENRESTY_PREFIX/bin:$PATH
2728
export OPENSSL_PREFIX=$OPENRESTY_PREFIX/openssl3
2829
export OPENSSL_BIN=$OPENSSL_PREFIX/bin/openssl
@@ -178,6 +179,8 @@ GRPC_SERVER_EXAMPLE_VER=20210819
178179
linux_get_dependencies () {
179180
apt update
180181
apt install -y cpanminus build-essential libncurses5-dev libreadline-dev libssl-dev perl libpcre3 libpcre3-dev libldap2-dev
182+
apt-get install -y libyaml-dev
183+
wget https://github.com/mikefarah/yq/releases/download/3.4.1/yq_linux_amd64 -O /usr/bin/yq && sudo chmod +x /usr/bin/yq
181184
}
182185

183186
function start_grpc_server_example() {

ci/redhat-ci.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ install_dependencies() {
2626
wget tar gcc gcc-c++ automake autoconf libtool make unzip git sudo openldap-devel hostname patch \
2727
which ca-certificates pcre pcre-devel xz \
2828
openssl-devel
29-
29+
yum install -y libyaml-devel
3030
yum install -y --disablerepo=* --enablerepo=ubi-8-appstream-rpms --enablerepo=ubi-8-baseos-rpms cpanminus perl
3131

3232
# install newer curl

conf/config-default.yaml

+5-3
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,8 @@ nginx_config: # Config for render the template to generate n
170170
stream:
171171
enable_access_log: false # Enable stream proxy access logging.
172172
access_log: logs/access_stream.log # Location of the stream access log.
173-
access_log_format: "$remote_addr [$time_local] $protocol $status $bytes_sent $bytes_received $session_time" # Customize log format: http://nginx.org/en/docs/varindex.html
173+
access_log_format: |
174+
"$remote_addr [$time_local] $protocol $status $bytes_sent $bytes_received $session_time" # Customize log format: http://nginx.org/en/docs/varindex.html
174175
access_log_format_escape: default # Escape default or json characters in variables.
175176
lua_shared_dict: # Nginx Lua shared memory zone. Size units are m or k.
176177
etcd-cluster-health-check-stream: 10m
@@ -208,7 +209,8 @@ nginx_config: # Config for render the template to generate n
208209
enable_access_log: true # Enable HTTP proxy access logging.
209210
access_log: logs/access.log # Location of the access log.
210211
access_log_buffer: 16384 # buffer size of access log.
211-
access_log_format: "$remote_addr - $remote_user [$time_local] $http_host \"$request\" $status $body_bytes_sent $request_time \"$http_referer\" \"$http_user_agent\" $upstream_addr $upstream_status $upstream_response_time \"$upstream_scheme://$upstream_host$upstream_uri\""
212+
access_log_format: |
213+
"$remote_addr - $remote_user [$time_local] $http_host \"$request\" $status $body_bytes_sent $request_time \"$http_referer\" \"$http_user_agent\" $upstream_addr $upstream_status $upstream_response_time \"$upstream_scheme://$upstream_host$upstream_uri\""
212214
# Customize log format: http://nginx.org/en/docs/varindex.html
213215
access_log_format_escape: default # Escape default or json characters in variables.
214216
keepalive_timeout: 60s # Set the maximum time for which TCP connection keeps alive.
@@ -643,7 +645,7 @@ deployment: # Deployment configurations
643645
admin_key:
644646
-
645647
name: admin # admin: write access to configurations.
646-
key: edd1c9f034335f136f87ad84b625c8f1 # Set API key for the admin of Admin API.
648+
key: '' # Set API key for the admin of Admin API.
647649
role: admin
648650
-
649651
name: viewer # viewer: read-only to configurations.

conf/config.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -59,5 +59,5 @@ deployment:
5959
admin:
6060
admin_key:
6161
- name: admin
62-
key: edd1c9f034335f136f87ad84b625c8f1 # using fixed API token has security risk, please update it when you deploy to production environment
62+
key: '' # using fixed API token has security risk, please update it when you deploy to production environment. If passed empty then will be autogenerated by APISIX and will be written back here. Recommended is to use external mechanism to generate and store the token.
6363
role: admin

docs/en/latest/FAQ.md

+18-9
Original file line numberDiff line numberDiff line change
@@ -120,10 +120,19 @@ Let's take an example query `foo.com/product/index.html?id=204&page=2` and consi
120120

121121
There are two different ways to achieve this in Apache APISIX:
122122

123+
:::note
124+
You can fetch the `admin_key` from `config.yaml` and save to an environment variable with the following command:
125+
126+
```bash
127+
admin_key=$(yq '.deployment.admin.admin_key[0].key' conf/config.yaml | sed 's/"//g')
128+
```
129+
130+
:::
131+
123132
1. Using the `vars` field in a [Route](terminology/route.md):
124133

125134
```shell
126-
curl -i http://127.0.0.1:9180/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
135+
curl -i http://127.0.0.1:9180/apisix/admin/routes/1 -H "X-API-KEY: $admin_key" -X PUT -d '
127136
{
128137
"uri": "/index.html",
129138
"vars": [
@@ -136,7 +145,7 @@ curl -i http://127.0.0.1:9180/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335
136145
}
137146
}'
138147

139-
curl -i http://127.0.0.1:9180/apisix/admin/routes/2 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
148+
curl -i http://127.0.0.1:9180/apisix/admin/routes/2 -H "X-API-KEY: $admin_key" -X PUT -d '
140149
{
141150
"uri": "/index.html",
142151
"vars": [
@@ -163,7 +172,7 @@ Apache APISIX provides several different ways to achieve this:
163172
1. Setting `http_to_https` to `true` in the [redirect](plugins/redirect.md) Plugin:
164173

165174
```shell
166-
curl http://127.0.0.1:9180/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
175+
curl http://127.0.0.1:9180/apisix/admin/routes/1 -H "X-API-KEY: $admin_key" -X PUT -d '
167176
{
168177
"uri": "/hello",
169178
"host": "foo.com",
@@ -178,7 +187,7 @@ curl http://127.0.0.1:9180/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f1
178187
2. Advanced routing with `vars` in the redirect Plugin:
179188

180189
```shell
181-
curl -i http://127.0.0.1:9180/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
190+
curl -i http://127.0.0.1:9180/apisix/admin/routes/1 -H "X-API-KEY: $admin_key" -X PUT -d '
182191
{
183192
"uri": "/hello",
184193
"host": "foo.com",
@@ -201,7 +210,7 @@ curl -i http://127.0.0.1:9180/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f03433
201210
3. Using the `serverless` Plugin:
202211

203212
```shell
204-
curl -i http://127.0.0.1:9180/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
213+
curl -i http://127.0.0.1:9180/apisix/admin/routes/1 -H "X-API-KEY: $admin_key" -X PUT -d '
205214
{
206215
"uri": "/hello",
207216
"plugins": {
@@ -392,7 +401,7 @@ deployment:
392401
2. Add a proxy Route for the Apache APISIX dashboard:
393402

394403
```shell
395-
curl -i http://127.0.0.1:9180/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
404+
curl -i http://127.0.0.1:9180/apisix/admin/routes/1 -H "X-API-KEY: $admin_key" -X PUT -d '
396405
{
397406
"uris":[ "/*" ],
398407
"name":"apisix_proxy_dashboard",
@@ -416,7 +425,7 @@ curl -i http://127.0.0.1:9180/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f03433
416425
You can use the `vars` field in a Route for matching regular expressions:
417426

418427
```shell
419-
curl -i http://127.0.0.1:9180/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
428+
curl -i http://127.0.0.1:9180/apisix/admin/routes/1 -H "X-API-KEY: $admin_key" -X PUT -d '
420429
{
421430
"uri": "/*",
422431
"vars": [
@@ -452,7 +461,7 @@ For more info on using `vars` refer to [lua-resty-expr](https://github.com/api7/
452461
Yes. The example below shows configuring the FQDN `httpbin.default.svc.cluster.local` (a Kubernetes service):
453462

454463
```shell
455-
curl http://127.0.0.1:9180/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
464+
curl http://127.0.0.1:9180/apisix/admin/routes/1 -H "X-API-KEY: $admin_key" -X PUT -d '
456465
{
457466
"uri": "/ip",
458467
"upstream": {
@@ -554,7 +563,7 @@ You can check [this post](https://juejin.cn/post/6965778290619449351) for a more
554563
To strip a prefix from a path in your route, like to take `/foo/get` and strip it to `/get`, you can use the [proxy-rewrite](plugins/proxy-rewrite.md) Plugin:
555564

556565
```shell
557-
curl -i http://127.0.0.1:9180/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
566+
curl -i http://127.0.0.1:9180/apisix/admin/routes/1 -H "X-API-KEY: $admin_key" -X PUT -d '
558567
{
559568
"uri": "/foo/*",
560569
"plugins": {

0 commit comments

Comments
 (0)