upstream-mtls.t 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684
  1. #
  2. # Licensed to the Apache Software Foundation (ASF) under one or more
  3. # contributor license agreements. See the NOTICE file distributed with
  4. # this work for additional information regarding copyright ownership.
  5. # The ASF licenses this file to You under the Apache License, Version 2.0
  6. # (the "License"); you may not use this file except in compliance with
  7. # the License. You may obtain a copy of the License at
  8. #
  9. # http://www.apache.org/licenses/LICENSE-2.0
  10. #
  11. # Unless required by applicable law or agreed to in writing, software
  12. # distributed under the License is distributed on an "AS IS" BASIS,
  13. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. # See the License for the specific language governing permissions and
  15. # limitations under the License.
  16. #
  17. use t::APISIX;
  18. my $nginx_binary = $ENV{'TEST_NGINX_BINARY'} || 'nginx';
  19. my $version = eval { `$nginx_binary -V 2>&1` };
  20. if ($version !~ m/\/apisix-nginx-module/) {
  21. plan(skip_all => "apisix-nginx-module not installed");
  22. } else {
  23. plan('no_plan');
  24. }
  25. repeat_each(1);
  26. log_level('info');
  27. no_root_location();
  28. no_shuffle();
  29. add_block_preprocessor(sub {
  30. my ($block) = @_;
  31. });
  32. run_tests();
  33. __DATA__
  34. === TEST 1: tls without key
  35. --- config
  36. location /t {
  37. content_by_lua_block {
  38. local t = require("lib.test_admin")
  39. local json = require("toolkit.json")
  40. local ssl_cert = t.read_file("t/certs/mtls_client.crt")
  41. local data = {
  42. upstream = {
  43. scheme = "https",
  44. type = "roundrobin",
  45. nodes = {
  46. ["127.0.0.1:1983"] = 1,
  47. },
  48. tls = {
  49. client_cert = ssl_cert,
  50. }
  51. },
  52. uri = "/hello"
  53. }
  54. local code, body = t.test('/apisix/admin/routes/1',
  55. ngx.HTTP_PUT,
  56. json.encode(data)
  57. )
  58. if code >= 300 then
  59. ngx.status = code
  60. end
  61. ngx.print(body)
  62. }
  63. }
  64. --- request
  65. GET /t
  66. --- error_code: 400
  67. --- response_body
  68. {"error_msg":"invalid configuration: property \"upstream\" validation failed: property \"tls\" validation failed: failed to validate dependent schema for \"client_cert\": property \"client_key\" is required"}
  69. === TEST 2: tls with bad key
  70. --- config
  71. location /t {
  72. content_by_lua_block {
  73. local t = require("lib.test_admin")
  74. local json = require("toolkit.json")
  75. local ssl_cert = t.read_file("t/certs/mtls_client.crt")
  76. local data = {
  77. upstream = {
  78. scheme = "https",
  79. type = "roundrobin",
  80. nodes = {
  81. ["127.0.0.1:1983"] = 1,
  82. },
  83. tls = {
  84. client_cert = ssl_cert,
  85. client_key = ("AAA"):rep(128),
  86. }
  87. },
  88. uri = "/hello"
  89. }
  90. local code, body = t.test('/apisix/admin/routes/1',
  91. ngx.HTTP_PUT,
  92. json.encode(data)
  93. )
  94. if code >= 300 then
  95. ngx.status = code
  96. end
  97. ngx.print(body)
  98. }
  99. }
  100. --- request
  101. GET /t
  102. --- error_code: 400
  103. --- response_body
  104. {"error_msg":"failed to decrypt previous encrypted key"}
  105. --- error_log
  106. decrypt ssl key failed
  107. === TEST 3: encrypt key by default
  108. --- config
  109. location /t {
  110. content_by_lua_block {
  111. local t = require("lib.test_admin")
  112. local json = require("toolkit.json")
  113. local ssl_cert = t.read_file("t/certs/mtls_client.crt")
  114. local ssl_key = t.read_file("t/certs/mtls_client.key")
  115. local data = {
  116. upstream = {
  117. scheme = "https",
  118. type = "roundrobin",
  119. nodes = {
  120. ["127.0.0.1:1983"] = 1,
  121. },
  122. tls = {
  123. client_cert = ssl_cert,
  124. client_key = ssl_key,
  125. }
  126. },
  127. uri = "/hello"
  128. }
  129. local code, body = t.test('/apisix/admin/routes/1',
  130. ngx.HTTP_PUT,
  131. json.encode(data)
  132. )
  133. if code >= 300 then
  134. ngx.status = code
  135. ngx.say(body)
  136. return
  137. end
  138. local code, body, res = t.test('/apisix/admin/routes/1',
  139. ngx.HTTP_GET
  140. )
  141. if code >= 300 then
  142. ngx.status = code
  143. ngx.say(body)
  144. return
  145. end
  146. res = json.decode(res)
  147. ngx.say(res.value.upstream.tls.client_key == ssl_key)
  148. -- upstream
  149. local data = {
  150. scheme = "https",
  151. type = "roundrobin",
  152. nodes = {
  153. ["127.0.0.1:1983"] = 1,
  154. },
  155. tls = {
  156. client_cert = ssl_cert,
  157. client_key = ssl_key,
  158. }
  159. }
  160. local code, body = t.test('/apisix/admin/upstreams/1',
  161. ngx.HTTP_PUT,
  162. json.encode(data)
  163. )
  164. if code >= 300 then
  165. ngx.status = code
  166. ngx.say(body)
  167. return
  168. end
  169. local code, body, res = t.test('/apisix/admin/upstreams/1',
  170. ngx.HTTP_GET
  171. )
  172. if code >= 300 then
  173. ngx.status = code
  174. ngx.say(body)
  175. return
  176. end
  177. res = json.decode(res)
  178. ngx.say(res.value.tls.client_key == ssl_key)
  179. local data = {
  180. upstream = {
  181. scheme = "https",
  182. type = "roundrobin",
  183. nodes = {
  184. ["127.0.0.1:1983"] = 1,
  185. },
  186. tls = {
  187. client_cert = ssl_cert,
  188. client_key = ssl_key,
  189. }
  190. },
  191. }
  192. local code, body = t.test('/apisix/admin/services/1',
  193. ngx.HTTP_PUT,
  194. json.encode(data)
  195. )
  196. if code >= 300 then
  197. ngx.status = code
  198. ngx.say(body)
  199. return
  200. end
  201. local code, body, res = t.test('/apisix/admin/services/1',
  202. ngx.HTTP_GET
  203. )
  204. if code >= 300 then
  205. ngx.status = code
  206. ngx.say(body)
  207. return
  208. end
  209. res = json.decode(res)
  210. ngx.say(res.value.upstream.tls.client_key == ssl_key)
  211. }
  212. }
  213. --- request
  214. GET /t
  215. --- response_body
  216. false
  217. false
  218. false
  219. === TEST 4: hit
  220. --- upstream_server_config
  221. ssl_client_certificate ../../certs/mtls_ca.crt;
  222. ssl_verify_client on;
  223. --- request
  224. GET /hello
  225. --- response_body
  226. hello world
  227. === TEST 5: wrong cert
  228. --- config
  229. location /t {
  230. content_by_lua_block {
  231. local t = require("lib.test_admin")
  232. local json = require("toolkit.json")
  233. local ssl_cert = t.read_file("t/certs/apisix.crt")
  234. local ssl_key = t.read_file("t/certs/apisix.key")
  235. local data = {
  236. upstream = {
  237. scheme = "https",
  238. type = "roundrobin",
  239. nodes = {
  240. ["127.0.0.1:1983"] = 1,
  241. },
  242. tls = {
  243. client_cert = ssl_cert,
  244. client_key = ssl_key,
  245. }
  246. },
  247. uri = "/hello"
  248. }
  249. local code, body = t.test('/apisix/admin/routes/1',
  250. ngx.HTTP_PUT,
  251. json.encode(data)
  252. )
  253. if code >= 300 then
  254. ngx.status = code
  255. end
  256. ngx.say(body)
  257. }
  258. }
  259. --- request
  260. GET /t
  261. --- response_body
  262. passed
  263. === TEST 6: hit
  264. --- upstream_server_config
  265. ssl_client_certificate ../../certs/mtls_ca.crt;
  266. ssl_verify_client on;
  267. --- request
  268. GET /hello
  269. --- error_code: 400
  270. --- error_log
  271. client SSL certificate verify error
  272. === TEST 7: clean old data
  273. --- config
  274. location /t {
  275. content_by_lua_block {
  276. local t = require("lib.test_admin")
  277. assert(t.test('/apisix/admin/routes/1',
  278. ngx.HTTP_DELETE
  279. ))
  280. assert(t.test('/apisix/admin/services/1',
  281. ngx.HTTP_DELETE
  282. ))
  283. assert(t.test('/apisix/admin/upstreams/1',
  284. ngx.HTTP_DELETE
  285. ))
  286. }
  287. }
  288. --- request
  289. GET /t
  290. === TEST 8: don't encrypt key
  291. --- yaml_config
  292. apisix:
  293. node_listen: 1984
  294. data_encryption:
  295. keyring: null
  296. --- config
  297. location /t {
  298. content_by_lua_block {
  299. local t = require("lib.test_admin")
  300. local json = require("toolkit.json")
  301. local ssl_cert = t.read_file("t/certs/mtls_client.crt")
  302. local ssl_key = t.read_file("t/certs/mtls_client.key")
  303. local data = {
  304. upstream = {
  305. scheme = "https",
  306. type = "roundrobin",
  307. nodes = {
  308. ["127.0.0.1:1983"] = 1,
  309. },
  310. tls = {
  311. client_cert = ssl_cert,
  312. client_key = ssl_key,
  313. }
  314. },
  315. uri = "/hello"
  316. }
  317. local code, body = t.test('/apisix/admin/routes/1',
  318. ngx.HTTP_PUT,
  319. json.encode(data)
  320. )
  321. if code >= 300 then
  322. ngx.status = code
  323. ngx.say(body)
  324. return
  325. end
  326. local code, body, res = t.test('/apisix/admin/routes/1',
  327. ngx.HTTP_GET
  328. )
  329. if code >= 300 then
  330. ngx.status = code
  331. ngx.say(body)
  332. return
  333. end
  334. res = json.decode(res)
  335. ngx.say(res.value.upstream.tls.client_key == ssl_key)
  336. -- upstream
  337. local data = {
  338. scheme = "https",
  339. type = "roundrobin",
  340. nodes = {
  341. ["127.0.0.1:1983"] = 1,
  342. },
  343. tls = {
  344. client_cert = ssl_cert,
  345. client_key = ssl_key,
  346. }
  347. }
  348. local code, body = t.test('/apisix/admin/upstreams/1',
  349. ngx.HTTP_PUT,
  350. json.encode(data)
  351. )
  352. if code >= 300 then
  353. ngx.status = code
  354. ngx.say(body)
  355. return
  356. end
  357. local code, body, res = t.test('/apisix/admin/upstreams/1',
  358. ngx.HTTP_GET
  359. )
  360. if code >= 300 then
  361. ngx.status = code
  362. ngx.say(body)
  363. return
  364. end
  365. res = json.decode(res)
  366. ngx.say(res.value.tls.client_key == ssl_key)
  367. local data = {
  368. upstream = {
  369. scheme = "https",
  370. type = "roundrobin",
  371. nodes = {
  372. ["127.0.0.1:1983"] = 1,
  373. },
  374. tls = {
  375. client_cert = ssl_cert,
  376. client_key = ssl_key,
  377. }
  378. },
  379. }
  380. local code, body = t.test('/apisix/admin/services/1',
  381. ngx.HTTP_PUT,
  382. json.encode(data)
  383. )
  384. if code >= 300 then
  385. ngx.status = code
  386. ngx.say(body)
  387. return
  388. end
  389. local code, body, res = t.test('/apisix/admin/services/1',
  390. ngx.HTTP_GET
  391. )
  392. if code >= 300 then
  393. ngx.status = code
  394. ngx.say(body)
  395. return
  396. end
  397. res = json.decode(res)
  398. ngx.say(res.value.upstream.tls.client_key == ssl_key)
  399. }
  400. }
  401. --- request
  402. GET /t
  403. --- response_body
  404. true
  405. true
  406. true
  407. === TEST 9: bind upstream
  408. --- config
  409. location /t {
  410. content_by_lua_block {
  411. local t = require("lib.test_admin")
  412. local json = require("toolkit.json")
  413. local data = {
  414. upstream_id = 1,
  415. uri = "/server_port"
  416. }
  417. local code, body = t.test('/apisix/admin/routes/1',
  418. ngx.HTTP_PUT,
  419. json.encode(data)
  420. )
  421. if code >= 300 then
  422. ngx.status = code
  423. ngx.say(body)
  424. return
  425. end
  426. }
  427. }
  428. --- request
  429. GET /t
  430. === TEST 10: hit
  431. --- upstream_server_config
  432. ssl_client_certificate ../../certs/mtls_ca.crt;
  433. ssl_verify_client on;
  434. --- request
  435. GET /server_port
  436. --- response_body chomp
  437. 1983
  438. === TEST 11: bind service
  439. --- config
  440. location /t {
  441. content_by_lua_block {
  442. local t = require("lib.test_admin")
  443. local json = require("toolkit.json")
  444. local data = {
  445. service_id = 1,
  446. uri = "/hello_chunked"
  447. }
  448. local code, body = t.test('/apisix/admin/routes/1',
  449. ngx.HTTP_PUT,
  450. json.encode(data)
  451. )
  452. if code >= 300 then
  453. ngx.status = code
  454. ngx.say(body)
  455. return
  456. end
  457. }
  458. }
  459. --- request
  460. GET /t
  461. === TEST 12: hit
  462. --- upstream_server_config
  463. ssl_client_certificate ../../certs/mtls_ca.crt;
  464. ssl_verify_client on;
  465. --- request
  466. GET /hello_chunked
  467. --- response_body
  468. hello world
  469. === TEST 13: get cert by tls.client_cert_id
  470. --- config
  471. location /t {
  472. content_by_lua_block {
  473. local t = require("lib.test_admin")
  474. local json = require("toolkit.json")
  475. local ssl_cert = t.read_file("t/certs/mtls_client.crt")
  476. local ssl_key = t.read_file("t/certs/mtls_client.key")
  477. local data = {
  478. type = "client",
  479. cert = ssl_cert,
  480. key = ssl_key
  481. }
  482. local code, body = t.test('/apisix/admin/ssls/1',
  483. ngx.HTTP_PUT,
  484. json.encode(data)
  485. )
  486. if code >= 300 then
  487. ngx.status = code
  488. ngx.say(body)
  489. return
  490. end
  491. local data = {
  492. upstream = {
  493. scheme = "https",
  494. type = "roundrobin",
  495. nodes = {
  496. ["127.0.0.1:1983"] = 1,
  497. },
  498. tls = {
  499. client_cert_id = 1
  500. }
  501. },
  502. uri = "/hello"
  503. }
  504. local code, body = t.test('/apisix/admin/routes/1',
  505. ngx.HTTP_PUT,
  506. json.encode(data)
  507. )
  508. if code >= 300 then
  509. ngx.status = code
  510. ngx.say(body)
  511. return
  512. end
  513. }
  514. }
  515. --- request
  516. GET /t
  517. === TEST 14: hit
  518. --- upstream_server_config
  519. ssl_client_certificate ../../certs/mtls_ca.crt;
  520. ssl_verify_client on;
  521. --- request
  522. GET /hello
  523. --- response_body
  524. hello world
  525. === TEST 15: change ssl object type
  526. --- config
  527. location /t {
  528. content_by_lua_block {
  529. local t = require("lib.test_admin")
  530. local json = require("toolkit.json")
  531. local ssl_cert = t.read_file("t/certs/mtls_client.crt")
  532. local ssl_key = t.read_file("t/certs/mtls_client.key")
  533. local data = {
  534. type = "server",
  535. sni = "test.com",
  536. cert = ssl_cert,
  537. key = ssl_key
  538. }
  539. local code, body = t.test('/apisix/admin/ssls/1',
  540. ngx.HTTP_PUT,
  541. json.encode(data)
  542. )
  543. if code >= 300 then
  544. ngx.status = code
  545. ngx.say(body)
  546. return
  547. end
  548. }
  549. }
  550. --- request
  551. GET /t
  552. === TEST 16: hit, ssl object type mismatch
  553. --- upstream_server_config
  554. ssl_client_certificate ../../certs/mtls_ca.crt;
  555. ssl_verify_client on;
  556. --- request
  557. GET /hello
  558. --- error_code: 502
  559. --- error_log
  560. failed to get ssl cert: ssl type should be 'client'
  561. === TEST 17: delete ssl object
  562. --- config
  563. location /t {
  564. content_by_lua_block {
  565. local t = require("lib.test_admin")
  566. local json = require("toolkit.json")
  567. local code, body = t.test('/apisix/admin/ssls/1', ngx.HTTP_DELETE)
  568. if code >= 300 then
  569. ngx.status = code
  570. ngx.say(body)
  571. return
  572. end
  573. }
  574. }
  575. --- request
  576. GET /t
  577. === TEST 18: hit, ssl object not exits
  578. --- upstream_server_config
  579. ssl_client_certificate ../../certs/mtls_ca.crt;
  580. ssl_verify_client on;
  581. --- request
  582. GET /hello
  583. --- error_code: 502
  584. --- error_log
  585. failed to get ssl cert: ssl id [1] not exits