diff --git a/apps/cli/e2e/assets/tls/ca.cer b/apps/cli/e2e/assets/tls/ca.cer new file mode 100755 index 00000000..70a23a31 --- /dev/null +++ b/apps/cli/e2e/assets/tls/ca.cer @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICqzCCAZMCFHJ1qdQ562AtZhnNb2g5RP964zFtMA0GCSqGSIb3DQEBCwUAMBEx +DzANBgNVBAMMBlJPT1RDQTAgFw0yNDA2MDYwNzExMzhaGA8yMTI0MDUxMzA3MTEz +OFowETEPMA0GA1UEAwwGUk9PVENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEAhWEhjd+3TF6tuGdEL1GD9VgaeEemXSYpjI2iaYs2MqtS6ge0QmUYmjgS +hikCkA+hOIwhLFB8Cy23BcsEIQFDGs53HThOBt+harW4+M1bz+rQb+DQNhS4LmqI +VbriMxR5ReLn76rJnc1SXVgjyuLQQrVDPESGpnqhvkPIDVR1xcjklE3iNVH7Dy7o +XH/xRO0h1RqW4JmBrW3z9IjeP80oTjZFpa/Vse3V64CBsR5VEB6Y0qs97PlTTsoM +u7/AIcvb6y4t+qMksKT3HUBsu+QGkRpbjFCcd3zacezRk2FcRU1njTuQaxwBQNBw +cQ25nMO9vbo1uKjrTen+68oQp0wR7QIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQAY +LYET3babzbqhw8OtrhdyON7GT1DqBeB+2PS1s+9glUCuk2Ov4lFwdXDklxVhYpFt +XNVlGqbYhI0ypTF/us2jKgrJGpusJt+xQ+03so1ysp49TfptfZPF3vaJsdzePn2V +yCK2Yj0O8JZcHWQEPQR+qbP6l3k+WkAQ2iCJhbXzafemNmixRxS/DpgYK6pe7XhF +emlTdRF4J0YMJPfkpaoSNCpp1gIYt+xbnDxOA+72sOJJN1BH2w5oAA+JLYFkAZSC +pMG8eWGt/+9PcF2LFN+D1vW7K8nshmsoqS6OrjFWEP7C68Mjj6XFfL0vzODWntph +1wIUTc09QrjQzMnTwxpw +-----END CERTIFICATE----- diff --git a/apps/cli/e2e/assets/tls/ca.csr b/apps/cli/e2e/assets/tls/ca.csr new file mode 100755 index 00000000..1586ce87 --- /dev/null +++ b/apps/cli/e2e/assets/tls/ca.csr @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIICVjCCAT4CAQAwETEPMA0GA1UEAwwGUk9PVENBMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAhWEhjd+3TF6tuGdEL1GD9VgaeEemXSYpjI2iaYs2MqtS +6ge0QmUYmjgShikCkA+hOIwhLFB8Cy23BcsEIQFDGs53HThOBt+harW4+M1bz+rQ +b+DQNhS4LmqIVbriMxR5ReLn76rJnc1SXVgjyuLQQrVDPESGpnqhvkPIDVR1xcjk +lE3iNVH7Dy7oXH/xRO0h1RqW4JmBrW3z9IjeP80oTjZFpa/Vse3V64CBsR5VEB6Y +0qs97PlTTsoMu7/AIcvb6y4t+qMksKT3HUBsu+QGkRpbjFCcd3zacezRk2FcRU1n +jTuQaxwBQNBwcQ25nMO9vbo1uKjrTen+68oQp0wR7QIDAQABoAAwDQYJKoZIhvcN +AQELBQADggEBABXzWtLjaZuxW/WweDb+HCwb5bYBrYfPqqjby1acjl68eYlo0ZFM +kZYPKHmxp+NVbtGORAXvFDmNt9Kfguk0IfZse9n1jsfTozpHM6hGTQJGjPIxA9Sh +l91PNPCODnFy/bg9J9BEQ6HKK7+pUn3cY6BA3JWQ9hJyV1kP8Dir/zhoinhs7aUK ++f+FS7YNWwezqQacBFkZKybomikxkhREWMyWaRk+aflDvGRvGLZ8Wa0ykruyzJV7 +3Hpl+d3RSP7xq+r0ETBsJQ4HYwjRc1glJv7+BVyxZoIbpuPK0oyKafezHSThn+Ro +tRIWwZAjRGHvqpcortiiNR3sL8cXMFCUw1w= +-----END CERTIFICATE REQUEST----- diff --git a/apps/cli/e2e/assets/tls/ca.key b/apps/cli/e2e/assets/tls/ca.key new file mode 100755 index 00000000..e0d13983 --- /dev/null +++ b/apps/cli/e2e/assets/tls/ca.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCFYSGN37dMXq24 +Z0QvUYP1WBp4R6ZdJimMjaJpizYyq1LqB7RCZRiaOBKGKQKQD6E4jCEsUHwLLbcF +ywQhAUMazncdOE4G36Fqtbj4zVvP6tBv4NA2FLguaohVuuIzFHlF4ufvqsmdzVJd +WCPK4tBCtUM8RIameqG+Q8gNVHXFyOSUTeI1UfsPLuhcf/FE7SHVGpbgmYGtbfP0 +iN4/zShONkWlr9Wx7dXrgIGxHlUQHpjSqz3s+VNOygy7v8Ahy9vrLi36oySwpPcd +QGy75AaRGluMUJx3fNpx7NGTYVxFTWeNO5BrHAFA0HBxDbmcw729ujW4qOtN6f7r +yhCnTBHtAgMBAAECggEACyvir2s3WJOuMZL2AI/vdrC4QtkezjrV4bpeiere5r6N +ICH2D1ZACca8MnV5NqTAfafVrXcDn2dm/CVlb/hBl8YG7wZvbp7zelMZ2Oj7vCia +6GFS6dIGx93PaSgmgwhqIe2Kkfs4ONng1gWoYHlqinPRMQPnp/D/NBxMQ2WOxGUw +tPo0NMwj7pKxNkXvACfbx3699DDnF9sLia2ZOn71MY2A7FHMN744eY6lOvzvJ/KT +m1Y0QPaiRUzJmY8w+jXTG/3Pcg/SPu+MiObgzeHkHBzNPLovFaMj1CJTJcuih/Od +4epcAliFtbHyrb/N1sl6X6z53bVEWOWXaGWC76efdwKBgQC5mqleNKzd24kEubp7 +DIvA7WuRmgKji7BHjBRE7ZRr85Fq+JkEH58S/4oY8uXpFC523s+t6CzVn7tgVGvV +ed6LcFeon6MUeEvNqpYow9ku/MbzPn+dOrasS9yEzI7ROoIpuHgdXd2s/Y7ukC4Z +gvVv4SGO3j1TeBO2pfUV6uXRjwKBgQC3964lPEUpot1L7R62fXTyJ+7wfoGibIps +jRcqV+EeZJt9LzBtthrMGqYOINfGWXVThjjfMX2H5Ig1CuUE5t2TLgW0jPWuE0/x +09KM77dclr9PVA3OKPNZoA1NTq/kVUJQeA9+vYfzitY5XR28Ak0qav6rQHjZ37Yi +jy5ARa5uwwKBgB79AZYm+U25X7EYSVhOCe9WNIWEzzf7FJ19d8ziVcuISRkxFGsp +1GdZnvb3Zwd5RSC3prkEcKfiGWjF75Me29cwFJKkxJegVheqiZOYz2QW9CicoLXh +nao6qEDL3nR0blME55kPmPlPBFQ0Yl4EDXJ2hiHSXS7Yd4IhR0A3jdNlAoGBAIcs +C978K+1t56BUOE7qW7VaNiyrJ2FK02LzQGQycgy866rNs43JUmNJ6V1UMHdjX9vh +MYR9frkM6C/hM2mooIH2PObu883WDtWnSHuZ32a+tQ76ubITUMs32M5G1OK26qTp +sqjzZiNCjilUC/cK0dwrBbibBLFBuTgncFp1WLe1AoGActRr0ocNGwchOLFcTwJ2 +hTVHlK0F7eoOgt+hBb7lPSW3jRJFxmJq65BUPTnYU2j+o34kHQnIt1reb5s5Lstu +e2h4xLO4vE8WMDp1WYwV6BgcEsVkbxAX5J/hsDzRPnGq49oVEz1uIup7uGZq9Bgr +xJ0fTr/SVy7uXF3T+zLZlAk= +-----END PRIVATE KEY----- diff --git a/apps/cli/e2e/assets/tls/client.cer b/apps/cli/e2e/assets/tls/client.cer new file mode 100755 index 00000000..a7198822 --- /dev/null +++ b/apps/cli/e2e/assets/tls/client.cer @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICqzCCAZMCFGtUTWJsSz7Li0uWX+lN/rHcDmg4MA0GCSqGSIb3DQEBCwUAMBEx +DzANBgNVBAMMBlJPT1RDQTAgFw0yNDA2MDYwNzExMzhaGA8yMTI0MDUxMzA3MTEz +OFowETEPMA0GA1UEAwwGQ0xJRU5UMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEAtRnzgCX/VsqbTqbDuVlzq2E30O01lzBMUpT6JAOao8nDs0euovUNh2QM +6CdElhNjeF3yWtVHgl4kAWRMbvdr9LarqiiVvHk6B5eO+tIhT8Nw7fuTbjpAtzjk +5Zk4yMjiy4voNzLKY6LuhCO2KtSF7Uo6krBb8RtSgW1kElkYrqBoX6q8Z0PmH+5w +jyjRpsOFVGYDVfIjiJyy0dAu1ifwSFvfgvikGLzkFg+QnUTtiGZ6jDSqHBgN+U4B +WDkIClzHlT3jJKZW/KSDMc68q8NTNTN2gKDU5Lo0wvQpNtmczEFVRImn6KXFn0fP +Ok4AI+NmSWwtAfs+2dm3gl/lHUoakQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQB/ +RgRCBM21IqfhyCmIf0E0KzTAuRFSo4wgk0MTXddl0w8XDOdLAP4T1IXwPYKkwAtA +6pEhNpYep6kAy32k8NcbirlLp/URzwI7C8Z8+3l1xyl8GV0ivDfE1WPVWk9uwDwn +qJfuqi+BZF+9P0wtzCvov5bXlbaK0Gf65S12dKKw5GRERFU52YcQXUexd+Gnrr9x +Xgoa7qJ+7MzVB8QBx7Jsdbks7fFa371S/450cp4vYTYVF0MAOPOxzXg1BBtp8I+/ +TryUg/G/u/7dnals+GmucCgJ4AqNFLqOPsVwpZBXErdqJBDgxFSRQUGJ1DRHR9lP +8cx9TgbbU7wYLWP+rjbL +-----END CERTIFICATE----- diff --git a/apps/cli/e2e/assets/tls/client.csr b/apps/cli/e2e/assets/tls/client.csr new file mode 100755 index 00000000..034bc7a7 --- /dev/null +++ b/apps/cli/e2e/assets/tls/client.csr @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIICVjCCAT4CAQAwETEPMA0GA1UEAwwGQ0xJRU5UMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAtRnzgCX/VsqbTqbDuVlzq2E30O01lzBMUpT6JAOao8nD +s0euovUNh2QM6CdElhNjeF3yWtVHgl4kAWRMbvdr9LarqiiVvHk6B5eO+tIhT8Nw +7fuTbjpAtzjk5Zk4yMjiy4voNzLKY6LuhCO2KtSF7Uo6krBb8RtSgW1kElkYrqBo +X6q8Z0PmH+5wjyjRpsOFVGYDVfIjiJyy0dAu1ifwSFvfgvikGLzkFg+QnUTtiGZ6 +jDSqHBgN+U4BWDkIClzHlT3jJKZW/KSDMc68q8NTNTN2gKDU5Lo0wvQpNtmczEFV +RImn6KXFn0fPOk4AI+NmSWwtAfs+2dm3gl/lHUoakQIDAQABoAAwDQYJKoZIhvcN +AQELBQADggEBAFWS8ymjbYN2dQU4KwlCvXwVqWgCLhP8T9TsUQwigmmbeX9ylv+j +Y8UkTitNmOSI+KxSFHP85rRS28pWDUU7FERljUxQSZcBZX6Ibgj9VaVZnIX6sGi+ +rzIWuaZEe5303MiGjxzlFdISfIGJP1zdsmpSg94EvuMLT7Wx329wU9XpY8/QXzZx +pDvsNlpEXkRErTjuxJrP8izdCM59ANXQ8FO5ADQOrtOcJzg3T9CN4deQ6erSF5lV +8NBcxPJM91pdXCwwWZsANMr1Hzb5nJYI25e5vn1DiFunrhtUDI6OCuz+TAkDwqID +W/37OxZ9SO22kDKP4KN7Lgax1i+Wym2t3P8= +-----END CERTIFICATE REQUEST----- diff --git a/apps/cli/e2e/assets/tls/client.key b/apps/cli/e2e/assets/tls/client.key new file mode 100755 index 00000000..8395a0b2 --- /dev/null +++ b/apps/cli/e2e/assets/tls/client.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC1GfOAJf9WyptO +psO5WXOrYTfQ7TWXMExSlPokA5qjycOzR66i9Q2HZAzoJ0SWE2N4XfJa1UeCXiQB +ZExu92v0tquqKJW8eToHl4760iFPw3Dt+5NuOkC3OOTlmTjIyOLLi+g3Mspjou6E +I7Yq1IXtSjqSsFvxG1KBbWQSWRiuoGhfqrxnQ+Yf7nCPKNGmw4VUZgNV8iOInLLR +0C7WJ/BIW9+C+KQYvOQWD5CdRO2IZnqMNKocGA35TgFYOQgKXMeVPeMkplb8pIMx +zryrw1M1M3aAoNTkujTC9Ck22ZzMQVVEiafopcWfR886TgAj42ZJbC0B+z7Z2beC +X+UdShqRAgMBAAECggEABPODboC7cSRDaDxTdA0PxkL3a3Ecyrghkg1sJFFr6Cfz +P4LJcb+Y4dd4qd0u+RppGQiagGS92oDX46jaFRuTGkLnQRTweRFoZn48hLt7eSqK ++xqqbnRNwiSeT2+nt4eUecOmsuGi2mQBOOAgEh4y1ii2Hr4PGXGpiQvUVVMVw2pn +8ult6mu701EiuvoG4nQ+tHwa0d4x6oY+PHx6CNIcw9wbAwG1NJRVzjU6Nr3LZ2GT +IjfkRbf/VNey/gnQ3lQkAZL1BUMOYoPwyUwtyRfX9Q4YDEV67hj6eQ3k4S9eQdVA +F6dkD+U7J4VPNer1G0EIQgLFuxl6MWpW0IebilpIxQKBgQDCxw2aKKq5s0xS6QEt +gO1ixl6YWFfSkNvPn5Q5M3kVSR7PYdTnELyJHjcBlVN0hZQSOitcj+PLyru0loXf +L7y8Dvbk6WLUBObfGK5Ya1Mkz20luv2TCjV/VhC23uFqGWruFakJTaqsXBta1xQb +hV1pmET2S23v3VRChdyTKIo9TQKBgQDuBm6m5D4ydCPOQ8hu9usmoTOhbkJe3fD/ +9AQ8CAiIxnagBr9WQvfVuqd0tdvy7ncJFjPz+9LzusPm2fHlXBIMfnXFlc0UzJ3q +N34ttIsI8UltHdw8hTK5EGUCh/DZHyMjgj+jPmPteGaJbfQhPYaXtR0bOkFBkkB8 +ZiVeUhLAVQKBgQCJYb7tWfu5SYbu/9vNzZ8iSUqVZ9Jh+bygwCza/7xK0C1EFvwF +Ep/4kvA3VKzthf4/sPm+qtsAdflZUcYQ+unDN0bbhOYpJ1/0QcNPKDwXvZp9v1t1 +qAC91OWrJp+Vp2HtlieJIVfdhIXi18sd8j5F6ZnSordjNRhmZ2aCAVkoDQKBgH4E +R8bx5f/+PwqwFkixT3PnOpeH8XmaVUKdZTSHKEWJlTpJ+DjqQZ4VMRz4P1eRatIT +wDO3KktBoP/yeT/uC9wzg5S1J5uQbTaYZKQ8BrQYUsCDY5tjBaS3ClNZt2isNIVT +Ku/5Uxxhdx/hZ7PFiCF/kMZehDf7/0odJkGWgDj1AoGBAIya8y+vrRJk0XeSlpFv +99tPPg9hQJThsc3JM+1XBXT0XkbiJAR4lKihuiJBm+CpsbAkLqfnz/EdE3YYC3UH +XYxu11VjQnEN1uhXMCqB35LHmnRHuiFxOaes/w889CGF2Ns4mvsLOq48QER0f3jH +1+Q6NOuao6xu5N9jypPt3ZIR +-----END PRIVATE KEY----- diff --git a/apps/cli/e2e/assets/tls/generate-mtls.sh b/apps/cli/e2e/assets/tls/generate-mtls.sh new file mode 100755 index 00000000..939cf217 --- /dev/null +++ b/apps/cli/e2e/assets/tls/generate-mtls.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +# For ROOT CA +openssl genrsa -out ca.key 2048 +openssl req -new -sha256 -key ca.key -out ca.csr -subj "/CN=ROOTCA" +openssl x509 -req -days 36500 -sha256 -extensions v3_ca -signkey ca.key -in ca.csr -out ca.cer + +# For server certificate +openssl genrsa -out server.key 2048 +openssl req -new -sha256 -key server.key -out server.csr -subj "/CN=localhost" +openssl x509 -req -days 36500 -sha256 -extensions v3_req -CA ca.cer -CAkey ca.key -CAserial ca.srl -CAcreateserial -in server.csr -out server.cer + +# For client certificate +openssl genrsa -out client.key 2048 +openssl req -new -sha256 -key client.key -out client.csr -subj "/CN=CLIENT" +openssl x509 -req -days 36500 -sha256 -extensions v3_req -CA ca.cer -CAkey ca.key -CAserial ca.srl -CAcreateserial -in client.csr -out client.cer + +chmod -R 777 . diff --git a/apps/cli/e2e/assets/tls/server.cer b/apps/cli/e2e/assets/tls/server.cer new file mode 100755 index 00000000..5b5d3d24 --- /dev/null +++ b/apps/cli/e2e/assets/tls/server.cer @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICrjCCAZYCFDvgCOozSi7reDVf+3IBVoi1pxg1MA0GCSqGSIb3DQEBCwUAMBEx +DzANBgNVBAMMBlJPT1RDQTAgFw0yNDA2MDYwNzExMzhaGA8yMTI0MDUxMzA3MTEz +OFowFDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEA8TTjrcxP1n+/Rh7f7S0WIG589Ne+toBi2MXO1maJ3/6iZGGfhAlu +ofOg59OpEfoz6WgCOiVdwQvPAEHs6XXw+mS5B3oEIB9/WMrU6P6Ew/zYNjVyxhT0 +dGQg1ug7SnqOdpieGRk7f+2qRDXt+j7TybeEGZ81lUXrDLqPnkC5sqJAQCbj1X2s +tEWMquROH56kp99lL/PF1swVwNa+pmoKnc+S3vhcMK2PvkfGKQ/HJAoVMvyF9rwR +Mr9cuEmXm0irqIMd/cy7y4Sfvk5snPfKzJ40HUl0tHkmxkQV2SvSO9soJH/4XmIm +YRDN2HvA2zZfGTxz4mzbnIMcI+xieleFKQIDAQABMA0GCSqGSIb3DQEBCwUAA4IB +AQBQVw/bIaFZx8JbdNqRwGy0ryZT7U/D5fdqKel1kWwjdTFMldtH1jX4LMuBR/LE +Iscsv2pXypGjuSPmPtHl9+fcg31d5VFFpg+SvLkifyP7iPZoe/cr5erK/ytoJD35 +64APQuYzz3+BzgLLHhOyv5wAr+Bb9cSweXGyyKHPB+zVp8LthYMOnmlIxXrKCnmi +skRtEmI3RPhMF/Vrkm44mkYB19P7cgzawuvxn3ooYHBjI0pLsoxRXyj5QJurJGsq +6Qkt2omsqNCZuz2r6m8jHXdtGMKjQm+KUww5ntDo68r2xHpftCMPgX5EKeUxvlAD +BT6Rk9y/p4Gz2jsFsJLfKjwu +-----END CERTIFICATE----- diff --git a/apps/cli/e2e/assets/tls/server.csr b/apps/cli/e2e/assets/tls/server.csr new file mode 100755 index 00000000..701dee4f --- /dev/null +++ b/apps/cli/e2e/assets/tls/server.csr @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIICWTCCAUECAQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEA8TTjrcxP1n+/Rh7f7S0WIG589Ne+toBi2MXO1maJ +3/6iZGGfhAluofOg59OpEfoz6WgCOiVdwQvPAEHs6XXw+mS5B3oEIB9/WMrU6P6E +w/zYNjVyxhT0dGQg1ug7SnqOdpieGRk7f+2qRDXt+j7TybeEGZ81lUXrDLqPnkC5 +sqJAQCbj1X2stEWMquROH56kp99lL/PF1swVwNa+pmoKnc+S3vhcMK2PvkfGKQ/H +JAoVMvyF9rwRMr9cuEmXm0irqIMd/cy7y4Sfvk5snPfKzJ40HUl0tHkmxkQV2SvS +O9soJH/4XmImYRDN2HvA2zZfGTxz4mzbnIMcI+xieleFKQIDAQABoAAwDQYJKoZI +hvcNAQELBQADggEBABtrExq53/Cq/gcowGU+eIlamO+JH5vpZDL1l80PxQ3qE2R2 +UZwN8ocldAvcvYs0YPcBGOkNhBdqrcHaHx28el1Xu3NbUwg+YK47sbj/zcOsQEYd +MvCXtmd1r7MGyvfrsqir3fAFHry5ppIlGj47/sr39/Nv+rNGFU3lYBkmukhvOLpz +JhC6sUwmjN+nn68feYrAOtr7EnCf/D0Y711IWmdw18D/KxCm2Cl8DHVH60Tzdj+2 +0vXm9sKrN+Xzg/l7849wEUIXTCQROHdQCLuJ8bkk3T5RsnTqePUJzwnnC0V6HfMN +cJNVmV1zuf5w/gxEGEilAmytlYbPYCSJPNTrSC4= +-----END CERTIFICATE REQUEST----- diff --git a/apps/cli/e2e/assets/tls/server.key b/apps/cli/e2e/assets/tls/server.key new file mode 100755 index 00000000..032a3674 --- /dev/null +++ b/apps/cli/e2e/assets/tls/server.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDxNOOtzE/Wf79G +Ht/tLRYgbnz01762gGLYxc7WZonf/qJkYZ+ECW6h86Dn06kR+jPpaAI6JV3BC88A +QezpdfD6ZLkHegQgH39YytTo/oTD/Ng2NXLGFPR0ZCDW6DtKeo52mJ4ZGTt/7apE +Ne36PtPJt4QZnzWVResMuo+eQLmyokBAJuPVfay0RYyq5E4fnqSn32Uv88XWzBXA +1r6magqdz5Le+FwwrY++R8YpD8ckChUy/IX2vBEyv1y4SZebSKuogx39zLvLhJ++ +Tmyc98rMnjQdSXS0eSbGRBXZK9I72ygkf/heYiZhEM3Ye8DbNl8ZPHPibNucgxwj +7GJ6V4UpAgMBAAECggEAALjT+PhfFs5xaqAmCHDgRj7pFdcy0Btd8GCAiCjCFI8P +umAxGN/pr7IUfbfRo5Gi/SRdZAIqSoJ4Cfv93bcHfnW1uL2B7Kdbe2RkCGyBRjro +BMWFL0LvIQ1kVxsBLm25JnFk1mtlFQgc6zEEIix0+CoZ9Z+sio1X25plWqe+m+Jv +SkfRQQ1GtQenjzc+WF+TZT0gP33c0eQwbY0AZSSE/FJtmczfRe19+GkZfHZfukIg +raLIp3HZFq7eDeZrO/lCsDdiwl8H/dA1gtMC1bwku+qVES4YtskL1c46x7Id8FdL +m1nWjUf/21NGEJns+OoTA3lZ2KlpCMHJKr/PGSHrWQKBgQD7PDGnIW9ir45Yf6Y9 +9fNVUNZLM8ecvKaMicesPsA/GmmSBGJFiY7QmyCPc2/eI1PXFNHCVlAoykaz07Nr +Y+nWf+QD5QciDSdCos9MYnbpa/whVnIlLeGCXJKM09kkaDQ4vN6ReEjpm96n3+xX +R9X99SXiUtKmnPKw4mLnwOlUzQKBgQD1yAEnjwp4mXM5/kJVZLcjpYaeEqX9fOF5 +5O9jIKbMzsRIVNuX5ItpyTvLLr0GaRWXYoMga1kov4eTOojygD2PlpSxk+8a7N2z +oTtGZ8WmypQswImVR9Ris/6jADzAzeiwWxZT0gV7bBE7O1iBfgAevWLtw+cqH1Y6 +RbNwXFERzQKBgQCK1GV/vJsnhml7f/ZmcN3pPEVewxtAAoNqT8y14usrM7Y4yRFg +6bWwkrh4bMrZjt4KkWekIzwifjx5rLeN1WVncb6XZFz/tRMH4J360MJzFIf8CCAF +aYgfGHanOX3Zf3e0DrJS4owwA0ETtUqNpJWcw3YOzcO37Cy0EDWlaVXG1QKBgQCk +HY3vzUrPpp9TXR0MCjlj2xZdnNQrxGSG0UCr71SRs4tLRSZwcVJKK+36SVY83pRl +RomKb0PUurebrt1dGBaDN6hIPyDM2NddJ879vzMyoVh53YLBJHqEAe6JBxKKJ7Q1 +dk0dYUL52/pRk9oQdYM9A3b4jvRfoxcfyAT+hRY5DQKBgHtMa6mn0vxUFd77INOP +DGG3Ostf6MwA7tS/TnVCnFNZoZnUb00y3fq3rOqBWA75Aqf3pCSl8kk1dHPeh1GU +zbGEtWFo20wendCJGim+vVs4GSp0RUV9rkT/eB3D4lPjLzVQA8AlGew9T2ZMqomo +jv5ta8/TiGiqpVLP62L2TKt2 +-----END PRIVATE KEY----- diff --git a/apps/cli/e2e/server/basic.e2e-spec.ts b/apps/cli/e2e/server/basic.e2e-spec.ts index b9ffd154..46eb0557 100644 --- a/apps/cli/e2e/server/basic.e2e-spec.ts +++ b/apps/cli/e2e/server/basic.e2e-spec.ts @@ -1,5 +1,9 @@ import * as ADCSDK from '@api7/adc-sdk'; import axios from 'axios'; +import { readFileSync } from 'node:fs'; +import * as http from 'node:http'; +import * as https from 'node:https'; +import { join } from 'node:path'; import { lastValueFrom } from 'rxjs'; import request from 'supertest'; @@ -29,8 +33,8 @@ describe('Server - Basic', () => { }, }); - expect(status).toBe(202); - expect(body.status).toBe('success'); + expect(status).toEqual(202); + expect(body.status).toEqual('success'); await expect(lastValueFrom(mockedBackend.dump())).resolves.toEqual({}); }); @@ -48,8 +52,8 @@ describe('Server - Basic', () => { }, }); - expect(status).toBe(500); - expect(body.message).toBe('Error: connect ECONNREFUSED 127.0.0.1:50000'); + expect(status).toEqual(500); + expect(body.message).toEqual('Error: connect ECONNREFUSED 127.0.0.1:50000'); }); it('test sync', async () => { @@ -74,8 +78,8 @@ describe('Server - Basic', () => { }, }); - expect(status).toBe(202); - expect(body.status).toBe('success'); + expect(status).toEqual(202); + expect(body.status).toEqual('success'); await expect(lastValueFrom(mockedBackend.dump())).resolves.toEqual(config); }); @@ -94,8 +98,155 @@ describe('Server - Basic', () => { config: {}, }, }); - expect(status).toBe(202); - expect(data.status).toBe('success'); + expect(status).toEqual(202); + expect(data.status).toEqual('success'); + + await server.stop(); + }); + + it('test server listen (with HTTPS, self-signed)', async () => { + const url = new URL(`https://127.0.0.1:48562`); + const server = new ADCServer({ + listen: url, + tlsCert: readFileSync( + join(__dirname, '../assets/tls/server.cer'), + 'utf-8', + ), + tlsKey: readFileSync( + join(__dirname, '../assets/tls/server.key'), + 'utf-8', + ), + }); + await server.start(); + + const { status, data } = await axios.put( + `${url.origin}/sync`, + { + task: { + opts: { + backend: 'mock', + server: 'http://1.1.1.1:3000', + token: 'mock', + }, + config: {}, + }, + }, + { httpsAgent: new https.Agent({ rejectUnauthorized: false }) }, + ); + expect(status).toEqual(202); + expect(data.status).toEqual('success'); + + await server.stop(); + }); + + it('test server listen (with HTTPS-mTLS, self-signed)', async () => { + const url = new URL(`https://127.0.0.1:48562`); + const readCert = (fileName: string) => + readFileSync(join(__dirname, '../assets/tls/', fileName), 'utf-8'); + const server = new ADCServer({ + listen: url, + tlsCert: readCert('server.cer'), + tlsKey: readCert('server.key'), + tlsCACert: readCert('ca.cer'), + }); + await server.start(); + + // without client cert/key, should fail + await expect( + axios.put( + `${url.origin}/sync`, + { + task: { + opts: { + backend: 'mock', + server: 'http://1.1.1.1:3000', + token: 'mock', + }, + config: {}, + }, + }, + { httpsAgent: new https.Agent({ rejectUnauthorized: false }) }, + ), + ).rejects.toThrow(/certificate required/); + + // with client cert/key, should succeed + const { status, data } = await axios.put( + `${url.origin}/sync`, + { + task: { + opts: { + backend: 'mock', + server: 'http://1.1.1.1:3000', + token: 'mock', + }, + config: {}, + }, + }, + { + httpsAgent: new https.Agent({ + rejectUnauthorized: false, + cert: readCert('client.cer'), + key: readCert('client.key'), + }), + }, + ); + expect(status).toEqual(202); + expect(data.status).toEqual('success'); + + await server.stop(); + }); + + it('test server listen (with UDS)', async () => { + const url = new URL(`unix:///tmp/adc-test.sock`); + const server = new ADCServer({ listen: url }); + await server.start(); + + const { status, data } = await new Promise<{ + status: number; + data: { status: string }; + }>((resolve, reject) => { + const req = http.request( + 'http://localhost/sync', + { + socketPath: url.pathname, + method: 'PUT', + headers: { + 'Content-Type': 'application/json', + }, + }, + (res) => { + let body = ''; + res.setEncoding('utf-8'); + res.on('data', (chunk) => { + body += chunk; + }); + res.on('end', () => { + expect(res.statusCode).toBe(202); + expect(JSON.parse(body).status).toBe('success'); + resolve({ + status: res.statusCode, + data: JSON.parse(body), + }); + }); + }, + ); + req.on('error', reject); + req.write( + JSON.stringify({ + task: { + opts: { + backend: 'mock', + server: 'http://1.1.1.1:3000', + token: 'mock', + }, + config: {}, + }, + }), + ); + req.end(); + }); + expect(status).toEqual(202); + expect(data.status).toEqual('success'); await server.stop(); }); diff --git a/apps/cli/src/command/helper.ts b/apps/cli/src/command/helper.ts index 323efc3d..4f098c67 100644 --- a/apps/cli/src/command/helper.ts +++ b/apps/cli/src/command/helper.ts @@ -88,12 +88,6 @@ export class BackendCommand< } private addBackendOptions() { - const processCertificateFile = (value: string, err: string) => { - const path = resolve(value); - if (!existsSync(path)) throw new Error(err); - return path; - }; - const parseResourceTypeFilter = ( cv: ADCSDK.ResourceType, pv: Array = [], @@ -217,6 +211,11 @@ export class BackendCommand< } } +export const processCertificateFile = (value: string, err: string) => { + const path = resolve(value); + if (!existsSync(path)) throw new InvalidArgumentError(err); + return path; +}; export const NoLintOption = new Option('--no-lint', 'disable lint check'); export const RequestConcurrentOption = new Option( '--request-concurrent ', diff --git a/apps/cli/src/command/ingress-server.command.ts b/apps/cli/src/command/ingress-server.command.ts index 98da6f61..f51fb632 100644 --- a/apps/cli/src/command/ingress-server.command.ts +++ b/apps/cli/src/command/ingress-server.command.ts @@ -1,10 +1,15 @@ -import commander from 'commander'; +import chalk from 'chalk'; +import commander, { Option } from 'commander'; +import { readFileSync } from 'node:fs'; import { ADCServer } from '../server'; -import { BaseCommand, BaseOptions } from './helper'; +import { BaseCommand, BaseOptions, processCertificateFile } from './helper'; type IngressServerOptions = { listen?: URL; + caCertFile?: string; + tlsCertFile?: string; + tlsKeyFile?: string; } & BaseOptions; export const IngressServerCommand = new BaseCommand( @@ -22,9 +27,61 @@ export const IngressServerCommand = new BaseCommand( }, new URL('http://127.0.0.1:3000'), ) - .handle(async ({ listen }) => { - await new ADCServer({ + .addOption( + new Option( + '--ca-cert-file ', + 'path to the CA certificate to verify the client', + ).argParser((value) => + processCertificateFile( + value, + 'The specified CA certificate file does not exist', + ), + ), + ) + .addOption( + new Option( + '--tls-cert-file ', + 'path to the TLS server certificate', + ).argParser((value) => + processCertificateFile( + value, + 'The specified TLS server certificate file does not exist', + ), + ), + ) + .addOption( + new Option( + '--tls-key-file ', + 'path to the TLS server key', + ).argParser((value) => + processCertificateFile( + value, + 'The specified TLS server key file does not exist', + ), + ), + ) + .handle(async ({ listen, tlsCertFile, tlsKeyFile, caCertFile }) => { + if (listen.protocol === 'https:' && (!tlsCertFile || !tlsKeyFile)) { + console.error( + chalk.red( + 'Error: When using HTTPS, both --tls-cert-file and --tls-key-file must be provided', + ), + ); + return; + } + + const server = new ADCServer({ listen, - }).start(); - console.log(`ADC server is running on: ${listen.origin}`); + tlsCert: readFileSync(tlsCertFile, 'utf-8'), + tlsKey: readFileSync(tlsKeyFile, 'utf-8'), + tlsCACert: caCertFile ? readFileSync(caCertFile, 'utf-8') : undefined, + }); + await server.start(); + console.log( + `ADC server is running on: ${listen.protocol === 'unix:' ? listen.pathname : listen.origin}`, + ); + process.on('SIGINT', () => { + console.log('Stopping, see you next time!'); + server.stop(); + }); }); diff --git a/apps/cli/src/server/index.ts b/apps/cli/src/server/index.ts index 9c7b4f41..b8d8966d 100644 --- a/apps/cli/src/server/index.ts +++ b/apps/cli/src/server/index.ts @@ -1,19 +1,22 @@ import express from 'express'; import type { Express } from 'express'; -import type { Server } from 'node:http'; +import * as fs from 'node:fs'; +import * as http from 'node:http'; +import * as https from 'node:https'; import { syncHandler } from './sync'; interface ADCServerOptions { listen: URL; + tlsCert?: string; + tlsKey?: string; + tlsCACert?: string; } export class ADCServer { private readonly express: Express; - private listen: URL; - private server?: Server; + private server?: http.Server | https.Server; - constructor(opts: ADCServerOptions) { - this.listen = opts.listen; + constructor(private readonly opts: ADCServerOptions) { this.express = express(); this.express.disable('x-powered-by'); this.express.use(express.json({ limit: '100mb' })); @@ -21,12 +24,42 @@ export class ADCServer { } public async start() { + switch (this.opts.listen.protocol) { + case 'https:': + this.server = https.createServer( + { + cert: this.opts.tlsCert, + key: this.opts.tlsKey, + ...(this.opts.tlsCACert + ? { + ca: this.opts.tlsCACert, + requestCert: true, + rejectUnauthorized: true, + } + : {}), + }, + this.express, + ); + break; + case 'http:': + case 'unix:': + default: + this.server = http.createServer(this.express); + break; + } return new Promise((resolve) => { - this.server = this.express.listen( - parseInt(this.listen.port), - this.listen.hostname, - () => resolve(), - ); + const listen = this.opts.listen; + if (listen.protocol === 'unix:') { + if (fs.existsSync(listen.pathname)) fs.unlinkSync(listen.pathname); + this.server.listen(listen.pathname, () => { + fs.chmodSync(listen.pathname, 0o660); + resolve(); + }); + } else { + this.server.listen(parseInt(listen.port), listen.hostname, () => + resolve(), + ); + } }); } diff --git a/tsconfig.json b/tsconfig.json index e4a67e82..061829b6 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -19,9 +19,6 @@ }, { "path": "./libs/sdk" - }, - { - "path": "./apps/cli-e2e" } ] }