Azure Private Link Service with NGINX Plus to decode Proxy Protocol TLV linkIdentifier

Published Jul 26 2022 09:02 AM 748 Views

In this video, we look at how to use NGINX Plus to get the TCP Proxy Protocol v2 TLV from the Azure Private Link Service and extract and decode the numeric linkIdentifier (aka LINKID) of the private endpoint connection.


We use NGINX Plus features such as $proxy_protocol_tlv_0x__ and the NGINX JavaScript module.


Prior to watching this deep dive video, I recommend to review Azure Private Link Service explanation and demos from provider (SaaS ISV) and consumer perspectives and TCP Proxy Protocol v2 with Azure Private Link Service — Deep Dive.


Video Walkthrough

Tip: Play the video full screen or on YouTube to see all of the details.



Video Chapters

00:00 Introduction
03:05 NGINX Plus
07:15 $proxy_protocol_tlv_0xEE
09:25 NGINX JavaScript
13:15 Decoding TLV
18:20 Seeing the linkIdentifier




Code snippets for NGINX Plus


azure_privatelink.js in /etc/nginx directory (Gist)



function hello_world(r) {
    return "Hello World from NGINX JavaScript module!";

function convert_tlv_to_hex(r) {
    var tlv_value = r.variables.proxy_protocol_tlv_0xEE;
    var hex = '';
    for (var i=0; i<tlv_value.length; i++) {
        hex += '0x' + tlv_value.charCodeAt(i).toString(16).padStart(2, '0') + ' ';
    return hex;

function convert_tlv_to_dec(r) {
    var tlv_value = r.variables.proxy_protocol_tlv_0xEE;
    var dec = '';
    for (var i=0; i<tlv_value.length; i++) {
        dec += tlv_value.charCodeAt(i) + ' ';
    return dec;

function convert_tlv_to_azurelinkid(r) {
    var tlv_value = r.variables.proxy_protocol_tlv_0xEE;
    var linkid = 0;
    // LINKID is little-endian encoded so the most significant byte is at the end, so we process the string in reverse order
    // First byte is always 0x01 and is not part of the LINKID, so we do not process i=0
    for (var i=tlv_value.length-1; i>=1; i--) {
        linkid = linkid * 256;
        linkid = linkid + tlv_value.charCodeAt(i)
    return linkid;

export default {hello_world, convert_tlv_to_hex, convert_tlv_to_dec, convert_tlv_to_azurelinkid}




 nginx.conf in /etc/nginx directory (Gist)



load_module modules/;
load_module modules/;

events { }
http {
    js_import main from azure_privatelink.js;
    js_set $hello_world main.hello_world;
    js_set $proxy_protocol_tlv_0xEE_hex main.convert_tlv_to_hex;
    js_set $proxy_protocol_tlv_0xEE_dec main.convert_tlv_to_dec;
    js_set $proxy_protocol_tlv_azurelinkid main.convert_tlv_to_azurelinkid;
    server {
        listen 80 proxy_protocol;
        location / {
            add_header Content-Type text/html;
            return 200 



Originally published at on April 5, 2022.






Version history
Last update:
‎Jul 26 2022 09:59 AM
Updated by: