slack
2 TopicsSlack Mutual TLS Recipe: Adding X-Client-Certificate-SAN header from client certificate
Problem this snippet solves: The following is based on the documentation from Slack of how to authenticate requests from Slack via mutual TLS and pass along the information to a service that is not capable of mutual TLS via a X-Client-Certificate-SAN header. Adapted from: https://api.slack.com/docs/verifying-requests-from-slack#mutual_tls Based on question from: https://devcentral.f5.com/s/question/0D51T00006n6YltSAE/extract-san-from-client-ssl-certificate-insert-into-http-header How to use this snippet: Attach to Virtual Server that has both a HTTP and clientssl profile. The clientssl profile must be configured for "require" or "request" to process the client certificate and use a CA certificate that verifies that it is a trusted certificate. The iRule will replace any headers that are sent by the client. Code : 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 } } Tested this on version: 11.51.2KViews1like3CommentsSample Slack App for testing Mutual TLS with BIG-IP
Problem this snippet solves: This Slack App was used with the following Code Snippet to test Mutual TLS. This code was adapted from: https://api.slack.com/tutorials/tunneling-with-ngrok How to use this snippet: npm install express npm install request node index.js (or whatever you name it) Create a pool that points to the IP:Port where it is running (defaults to listening on 4390). Once you add the app (follow the tutorial from above, but use a different command name like /mtls). Unlike the tutorial you will cover a "real" SSL certificate on the BIG-IP (must be publicly accessible from Slack's servers). Follow-up article with more details will be posted in the future. Code : // Import express and request modules require('dotenv').config() var express = require('express'); var request = require('request'); var querystring = require('querystring'); // Instantiates Express and assigns our app variable to it var app = express(); //app.use(express.json()); app.use(express.urlencoded({ extended: true })); // Again, we define a port we want to listen to const PORT=4390; // Lets start our server app.listen(PORT, function () { //Callback triggered when server is successfully listening. Hurray! console.log("Example app listening on port " + PORT); }); // This route handles GET requests to our root demo address and responds with the same "Demo is working message" we used before app.get('/', function(req, res) { res.send('Demo is working! Path Hit: ' + req.url); }); // This route handles get request to a /oauth endpoint. We'll use this endpoint for handling the logic of the Slack oAuth process behind our app. app.get('/oauth', function(req, res) { // When a user authorizes an app, a code query parameter is passed on the oAuth endpoint. If that code is not there, we respond with an error message if (!req.query.code) { res.status(500); res.send({"Error": "Looks like we're not getting code."}); console.log("Looks like we're not getting code."); } else { // If it's there... // We'll do a GET call to Slack's `oauth.access` endpoint, passing our app's client ID, client secret, and the code we just got as query parameters. request({ url: 'https://slack.com/api/oauth.access', //URL to hit qs: {code: req.query.code, client_id: process.env.CLIENT_ID, client_secret: process.env.CLIENT_SECRET}, //Query string data method: 'GET', //Specify the method }, function (error, response, body) { if (error) { console.log(error); } else { res.json(body); } }) } }); // Route the endpoint that our slash command will point to and send back a simple response to indicate that ngrok is working app.post('/command', function(req, res) { var certSan = req.get('X-Client-Certificate-SAN'); if(certSan) { var cert = req.get('X-Client-Certificate'); var formattedCert = ''; for(i=0;i Tested this on version: 13.0523Views0likes0Comments