Forum Discussion
Extract SAN from Client SSL Certificate & Insert into HTTP Header
- Aug 28, 2019
When I apply that iRule my test cert works. Not sure why your environment is different. Here's an alternate iRule you could try.
when HTTP_REQUEST { if {[SSL::cert 0] ne ""}{ set tmpcn [X509::subject [SSL::cert 0]] set cn [findstr $tmpcn "CN=" 3] HTTP::header replace X-Client-Certificate-SAN $cn } else { HTTP::header remove X-Client-Certificate-SAN } }
My test results.
curl -k --cert ./platform-tls-client.slack.com.crt --key ./platform-tls-client.slack.com.key https://192.168.1.200:8443/headers.json {"User-Agent":"curl/7.29.0","Host":"192.168.1.200:8443","Accept":"*/*","X-Client-Certificate-SAN":"platform-tls-client.slack.com"}
Here's what my config looks like.
ltm virtual test_vs { creation-time 2019-08-27:10:03:53 destination 192.168.1.200:pcsync-https ip-protocol tcp last-modified-time 2019-08-27:10:20:58 mask 255.255.255.255 pool slack_pool profiles { http { } mtls_clientssl { context clientside } tcp { } } rules { slack2 } source 0.0.0.0/0 source-address-translation { type automap } translate-address enabled translate-port enabled vs-index 3 } ltm profile client-ssl mtls_clientssl { app-service none authenticate-depth 0 ca-file f5ca cert-key-chain { default { cert default.crt key default.key } } defaults-from clientssl inherit-ca-certkeychain true inherit-certkeychain true peer-cert-mode require } ltm rule slack2 { when HTTP_REQUEST { if {[SSL::cert 0] ne ""}{ # extract SAN set santemp [findstr [X509::extensions [SSL::cert 0]] "Subject Alternative Name" 32 ","] # remove DNS: prefix set san [findstr $santemp "DNS" 4] # insert X-Client-Certificate-SAN header HTTP::header replace X-Client-Certificate-SAN $san } else { HTTP::header remove X-Client-Certificate-SAN } } }
I created the following codeshare example that does what is required to generate the X-Client-Certificate-SAN: https://devcentral.f5.com/s/articles/Slack-Mutual-TLS-Recipe-Adding-X-Client-Certificate-SAN-header-from-client-certificate
Hi Eric,
Our application owners have finally gotten around to testing this and we are running into a slight problem. The header is getting inserted, but is including this full value which seems to be breaking things:
platform-tls-client.slack.com X509v3 Key Usage: critical Digital Signature
...do have any suggestions on how to remove the extra info in the value?
Thanks!
- Eric_ChenAug 27, 2019
Employee
Can you send me a sample of your iRule? It is "weird" that it is grabbing that extra information. If you have a way to dump a copy of the Slack cert it would help. Here's my "test" cert that I have been using.
-----BEGIN CERTIFICATE----- MIIDujCCAqKgAwIBAgIUWzmeqJiZXLywAc2KXLDkQpdGX1wwDQYJKoZIhvcNAQEL BQAwWTELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcT B1NlYXR0bGUxFDASBgNVBAoTC0Y1IE5ldHdvcmtzMQ0wCwYDVQQLEwREZW1vMB4X DTE5MDcxMDE2MjUwMFoXDTI0MDcwODE2MjUwMFowKDEmMCQGA1UEAxMdcGxhdGZv cm0tdGxzLWNsaWVudC5zbGFjay5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw ggEKAoIBAQCzuteu/69oCkhHe7gmyqo+m3BIs73WN419bKt0piYL/qkq6jkZydjq 5cq0Ne/6og9tXvzwX/B00+kyuccq0kv+lBFXSvO6N4mx5CZCWBmGGcEqCQ82lTwZ B9SE7vsk1kG9WxxMR3M65fEC6mzPNpy7SDj33pGnkpwkmDbvGY45uqYWG8oRxUEV wfU+HkjkuK6Ny9Ag5n+2naDblkpVfebEXaFqzjdUyuRL8ACpX2u9TW9H6crt08Gc rNctNwS5HWuntf9XaMFUQeesnCTggfCRvQkFr4D3AalpZGEuBC7mp8CJhG7gFLbz zzwdK+i+q9Q/FDMts3F067Rb9/AYi7CfAgMBAAGjgaowgacwDgYDVR0PAQH/BAQD AgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAMBgNVHRMBAf8EAjAA MB0GA1UdDgQWBBT19sITL/5oD6wi+PTEI/XSA0dwnDAfBgNVHSMEGDAWgBRkzB44 eEQlLGaY1CwbuiVRM/cPijAoBgNVHREEITAfgh1wbGF0Zm9ybS10bHMtY2xpZW50 LnNsYWNrLmNvbTANBgkqhkiG9w0BAQsFAAOCAQEADPscLML2jmY6byf306FVmtUV YT/2COAEySdGbmXm2rAeuINyFCOypNg/RhBIi9WyicicHVFjpskVizli+Qaom90h L1g7MbMhqGL6jUGp81+L4ZJDlQXeJSDu9/KPg1FdiJdK/fe0kQoFFU7ENAjUpclt 7tYtlSQ6idVESZOzPk1Fu7/YCMtiWKNBPnF13fic4rF9Rg/wnX/Ct2Ji/WUSiQ/2 9gZX+YHPm3qm4DFn2fJV6gFKurWyClIai0AX1/+C4rpUJvWi2U/CElAcy4YNm7Vv ON34sdFIMmfwLksKvA5AuNXFLefc7x/5PaBsDF26syv+NkVcyMjoiQ2T9QtoAQ== -----END CERTIFICATE-----
and my test CA
-----BEGIN CERTIFICATE----- MIIDpjCCAo6gAwIBAgIUSpuabxnXu19oLF0fLKu17PNAtqEwDQYJKoZIhvcNAQEL BQAwWTELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcT B1NlYXR0bGUxFDASBgNVBAoTC0Y1IE5ldHdvcmtzMQ0wCwYDVQQLEwREZW1vMB4X DTE4MDQyMDA2NDMwMFoXDTIzMDQxOTA2NDMwMFowWTELMAkGA1UEBhMCVVMxEzAR BgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1NlYXR0bGUxFDASBgNVBAoTC0Y1 IE5ldHdvcmtzMQ0wCwYDVQQLEwREZW1vMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A MIIBCgKCAQEA5B7v5d/xsEWcmLfhtHDZAE8vAn3qmiEMLT5lFSdxzCg6h0JkqeDF iv50OGW00h2almjgEDMW+ldmjW+bSlWz5kpqdmzTXLnmw6/UN4Da+8odsw0abplS 6DNz/xjWcdw4YiLFY167AmtDUNXaJ/jTBAgWGYJy/rl2u1vpi1CWiJozpR/g/Jsb bAxPXG54ZZi2yUbCVh12DmjAqBfU3LFCvvOQHYyjCon76sLnXifrWSjb8EOVJZc8 Vw3IdRq0vf74Q62RgQXNAd1G5hme7kl/RdrrWqxlxCK8XXU2RSVnAX5baVxY/HC0 lvXKsfFbJec+DkTAaZLZN4KJLfkvoylLXQIDAQABo2YwZDAOBgNVHQ8BAf8EBAMC AQYwEgYDVR0TAQH/BAgwBgEB/wIBAjAdBgNVHQ4EFgQUZMweOHhEJSxmmNQsG7ol UTP3D4owHwYDVR0jBBgwFoAUZMweOHhEJSxmmNQsG7olUTP3D4owDQYJKoZIhvcN AQELBQADggEBAN0914undNu7bLOk+wVOTvfkL14jAoRCmv/rQBwvJoWNuU7d7TKk D0SZ/GME8kNg9RIAY/POCTiISrORIkoMwt4eLv0bDejualvJ7MwqOvgdFby6BuGg 5dVioFfcwQA/i4L0smHX8QY+w8+RlD7DZnHKcx/C7sPHCkrqmLYLDQSalvv8KgwF mBB/SBS/yACKpaJPCC3Vlj7aPt5aS6GmH25LpAeDM7LLrDHLj+osLbhkGou0ifYy 8RelfbJlI37NjVMJRWF1EsuSG0xYJPFg9/nqM6UPUHxLx+MmSJ6ibBj6MF6cYkKQ 5Okq/kt3E65/mPltGVmGYPFzwfqLIJFx13E= -----END CERTIFICATE-----
- alanjohnson7467Aug 27, 2019
Cirrus
Certainly. Here's the iRule:
when HTTP_REQUEST { if {[SSL::cert 0] ne ""}{ # extract SAN set santemp [findstr [X509::extensions [SSL::cert 0]] "Subject Alternative Name" 32 ","] # remove DNS: prefix set san [findstr $santemp "DNS" 4] # insert X-Client-Certificate-SAN header HTTP::header replace X-Client-Certificate-SAN $san } else { HTTP::header remove X-Client-Certificate-SAN } }
...and here's the cert:
-----BEGIN CERTIFICATE----- MIIGxDCCBaygAwIBAgIQBTuMAryoimCObRlbLqMDMDANBgkqhkiG9w0BAQsFADBN MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMScwJQYDVQQDEx5E aWdpQ2VydCBTSEEyIFNlY3VyZSBTZXJ2ZXIgQ0EwHhcNMTkwNjI3MDAwMDAwWhcN MjEwNzAxMTIwMDAwWjCBjzELMAkGA1UEBhMCVVMxETAPBgNVBAgTCENvbG9yYWRv MREwDwYDVQQHEwhMYWtld29vZDEiMCAGA1UEChMZRmlyc3RCYW5rIEhvbGRpbmcg Q29tcGFueTEXMBUGA1UECxMOV2ViIE9wZXJhdGlvbnMxHTAbBgNVBAMTFHNsYWNr LmVmaXJzdGJhbmsuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA wn4vUEkwwaXq5pkCUKlsZpCvucrBG9ut8zL4StVWwbFAx4nkdCR7VYusUAhgr4Sl z16iRk/CC9haT3lJO8QpxY32Fy+F0i4DE2sTRu3zYy5pxV68yr1VNh2tKbkaqSQD TVwid+/PYjo1z7eoB85qH51CZKTkqf0qKPaDNnXytvmmoMSOTNiA47nmAS9Ho2ph TQxO4lQ/aYV2pLJxflx5zEHf0gWmej727ayT/bbFWQHo46MCm/e9ATT0hBFB/1FC wwyOsgG+zZoMvatoGiwD3szVaSdqaf5gl3egjZdpIgGzUePmPeVrNlDIfdYL7da5 kFRusukJ3tWWOWqwPd5tMwIDAQABo4IDWzCCA1cwHwYDVR0jBBgwFoAUD4BhHIIx YdUvKOeNRji0LOHG2eIwHQYDVR0OBBYEFBorhc2cX34dOGaQ+ywCAMC684IlMB8G A1UdEQQYMBaCFHNsYWNrLmVmaXJzdGJhbmsuY29tMA4GA1UdDwEB/wQEAwIFoDAd BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwawYDVR0fBGQwYjAvoC2gK4Yp aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL3NzY2Etc2hhMi1nNi5jcmwwL6AtoCuG KWh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9zc2NhLXNoYTItZzYuY3JsMEwGA1Ud IARFMEMwNwYJYIZIAYb9bAEBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRp Z2ljZXJ0LmNvbS9DUFMwCAYGZ4EMAQICMHwGCCsGAQUFBwEBBHAwbjAkBggrBgEF BQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEYGCCsGAQUFBzAChjpodHRw Oi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRTSEEyU2VjdXJlU2VydmVy Q0EuY3J0MAwGA1UdEwEB/wQCMAAwggF8BgorBgEEAdZ5AgQCBIIBbASCAWgBZgB2 ALvZ37wfinG1k5Qjl6qSe0c4V5UKq1LoGpCWZDaOHtGFAAABa5nKiZgAAAQDAEcw RQIhAMX3+WUefc7OLTV2KfybQJC+rrtS75LvMcOdxerfLNfmAiBYGbDiTmGMnADn GReei6G26xhrkbonnEoM8D2BCgIHSwB1AId1v+dZfPiMQ5lfvfNu/1aNR1Y2/0q1 YMG06v9eoIMPAAABa5nKhcEAAAQDAEYwRAIgDgInNAmwRJYX5BxQwCrduwtdC9rt EkVCupV/qUBZWJACIA0/Y61nvK1RxM74vGKKNU5iCl3ty5O26GCnmkBZvCl1AHUA RJRlLrDuzq/EQAfYqP4owNrmgr7YyzG1P9MzlrW2gagAAAFrmcqE1QAABAMARjBE AiBXCan4X5ODJdgTBG/zPgK4/YqJAW/IC8Sb3oskOkUwkgIgEF9bbej6NUMc26aA KZVMza8zyKmgO+P0SRm8L34ZNpgwDQYJKoZIhvcNAQELBQADggEBALCU8N/sGGei poeCutDWeSFUwUpPg1fWFgHmhLsCs+2BfSFyn/5fnyL+2JkM/haNpllyiiKBOwuw tVAuXLIljyXmVtmTnTzWiWOeGgAS2q8DhzBDMgiOmrbKP4HW95a8LQQD8b95QMvF D59+q77piBxwH8Qa3BQVMlI34/ATrWz3XSgJR7BPx7BH3unfSkV+KHqWVd1dIMyZ 3RcMdBwK/Fn2dDDaLyjubzGPJcnMQWP6CbC5iyGR/kzrtAzTfvplBzJ/f1+VHLL2 F3H/rajvB2ZCNO9OPrwpXuj1AWlXixKU6F9OLVObdyuz5SLex7SZnhjUayfkgjLH f/SROV7gsGs= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIElDCCA3ygAwIBAgIQAf2j627KdciIQ4tyS8+8kTANBgkqhkiG9w0BAQsFADBh MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD QTAeFw0xMzAzMDgxMjAwMDBaFw0yMzAzMDgxMjAwMDBaME0xCzAJBgNVBAYTAlVT MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxJzAlBgNVBAMTHkRpZ2lDZXJ0IFNIQTIg U2VjdXJlIFNlcnZlciBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB ANyuWJBNwcQwFZA1W248ghX1LFy949v/cUP6ZCWA1O4Yok3wZtAKc24RmDYXZK83 nf36QYSvx6+M/hpzTc8zl5CilodTgyu5pnVILR1WN3vaMTIa16yrBvSqXUu3R0bd KpPDkC55gIDvEwRqFDu1m5K+wgdlTvza/P96rtxcflUxDOg5B6TXvi/TC2rSsd9f /ld0Uzs1gN2ujkSYs58O09rg1/RrKatEp0tYhG2SS4HD2nOLEpdIkARFdRrdNzGX kujNVA075ME/OV4uuPNcfhCOhkEAjUVmR7ChZc6gqikJTvOX6+guqw9ypzAO+sf0 /RR3w6RbKFfCs/mC/bdFWJsCAwEAAaOCAVowggFWMBIGA1UdEwEB/wQIMAYBAf8C AQAwDgYDVR0PAQH/BAQDAgGGMDQGCCsGAQUFBwEBBCgwJjAkBggrBgEFBQcwAYYY aHR0cDovL29jc3AuZGlnaWNlcnQuY29tMHsGA1UdHwR0MHIwN6A1oDOGMWh0dHA6 Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEdsb2JhbFJvb3RDQS5jcmwwN6A1 oDOGMWh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEdsb2JhbFJvb3RD QS5jcmwwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8v d3d3LmRpZ2ljZXJ0LmNvbS9DUFMwHQYDVR0OBBYEFA+AYRyCMWHVLyjnjUY4tCzh xtniMB8GA1UdIwQYMBaAFAPeUDVW0Uy7ZvCj4hsbw5eyPdFVMA0GCSqGSIb3DQEB CwUAA4IBAQAjPt9L0jFCpbZ+QlwaRMxp0Wi0XUvgBCFsS+JtzLHgl4+mUwnNqipl 5TlPHoOlblyYoiQm5vuh7ZPHLgLGTUq/sELfeNqzqPlt/yGFUzZgTHbO7Djc1lGA 8MXW5dRNJ2Srm8c+cftIl7gzbckTB+6WohsYFfZcTEDts8Ls/3HB40f/1LkAtDdC 2iDJ6m6K7hQGrn2iWZiIqBtvLfTyyRRfJs8sjX7tN8Cp1Tm5gr8ZDOo0rwAhaPit c+LJMto4JQtV05od8GiG7S5BNO98pVAdvzr508EIDObtHopYJeS4d60tbvVS3bR0 j6tJLp07kzQoH3jOlOrHvdPJbRzeXDLz -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG 9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97 nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt 43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4 gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg 06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= -----END CERTIFICATE-----
- Eric_ChenAug 28, 2019
Employee
When I apply that iRule my test cert works. Not sure why your environment is different. Here's an alternate iRule you could try.
when HTTP_REQUEST { if {[SSL::cert 0] ne ""}{ set tmpcn [X509::subject [SSL::cert 0]] set cn [findstr $tmpcn "CN=" 3] HTTP::header replace X-Client-Certificate-SAN $cn } else { HTTP::header remove X-Client-Certificate-SAN } }
My test results.
curl -k --cert ./platform-tls-client.slack.com.crt --key ./platform-tls-client.slack.com.key https://192.168.1.200:8443/headers.json {"User-Agent":"curl/7.29.0","Host":"192.168.1.200:8443","Accept":"*/*","X-Client-Certificate-SAN":"platform-tls-client.slack.com"}
Here's what my config looks like.
ltm virtual test_vs { creation-time 2019-08-27:10:03:53 destination 192.168.1.200:pcsync-https ip-protocol tcp last-modified-time 2019-08-27:10:20:58 mask 255.255.255.255 pool slack_pool profiles { http { } mtls_clientssl { context clientside } tcp { } } rules { slack2 } source 0.0.0.0/0 source-address-translation { type automap } translate-address enabled translate-port enabled vs-index 3 } ltm profile client-ssl mtls_clientssl { app-service none authenticate-depth 0 ca-file f5ca cert-key-chain { default { cert default.crt key default.key } } defaults-from clientssl inherit-ca-certkeychain true inherit-certkeychain true peer-cert-mode require } ltm rule slack2 { when HTTP_REQUEST { if {[SSL::cert 0] ne ""}{ # extract SAN set santemp [findstr [X509::extensions [SSL::cert 0]] "Subject Alternative Name" 32 ","] # remove DNS: prefix set san [findstr $santemp "DNS" 4] # insert X-Client-Certificate-SAN header HTTP::header replace X-Client-Certificate-SAN $san } else { HTTP::header remove X-Client-Certificate-SAN } } }
- alanjohnson7467Sep 17, 2019
Cirrus
Hi Eric,
Apologies for the delayed response. We used the alternate rule you provided and it is working perfectly. Thank you so much for all your help!
- Eric_ChenSep 17, 2019
Employee
Excellent! FYI, I used your question for an article: https://devcentral.f5.com/s/articles/Verifying-Slack-Requests-with-Mutual-TLS
Recent Discussions
Related Content
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com