Forum Discussion

muntae_kim's avatar
Feb 27, 2024

Can I set decryption in LTM config on a port other than 443?

hello. My name is Muntae Kim.

Due to the EoTS of the BIG-IP SW used by our client, we are inevitably unable to open the case and would like to ask for your assistance.

 

Customer information:

- Model name: BIG-IP I7800

- SW information: TMOS 14.1.5

  - License: LTM (Forward Proxy) + URL Filtering

  - Configuration information: Decryption of 443 traffic outbound from the internal PC to the outside.

 

Review requirements

- We would like to ask for your help as there is a request for technical review to determine whether decryption is technically possible for Custum Ports (ex. 8443, 7443, etc.) other than the HTTPS (TCP/443) port that the customer is currently decrypting.

- I will attach information about the currently configured Virtual Server and iRules.

 

We would like to ask for your feedback.

We have attached the iRule used by our customer, so please refer to it for your review.

thank you

#________________________________________________________________________________
#Virtual Server / 1.1.VS_443_Filter_SRCIP_config.txt
#________________________________________________________________________________
ltm virtual /Common/VS_443_Filter_253.10 {
    destination /Common/0.0.0.0:443
    ip-protocol tcp
    last-modified-time 2021-03-25:19:13:28
    mask any
    pool /Common/pool-fw1
    profiles {
        /Common/FastL4_Loose { }
    }
    rules {
        /Common/SSL_Filter_Rule
    }
    source 166.125.253.10/32
    translate-address disabled
    translate-port disabled
    vlans {
        /Common/in
    }
    vlans-enabled
}
#________________________________________________________________________________
#Pools
#________________________________________________________________________________
ltm pool /Common/pool-fw1 {
    members {
        /Common/166.125.0.2:0 {
            address 166.125.0.2
        }
    }
}
#________________________________________________________________________________
#iRules
#________________________________________________________________________________
ltm rule /Common/SSL_Filter_Rule {
when CLIENT_ACCEPTED {
           # DEBUG On/Off : 1/0
           set DEBUG 0
 
           # Check bypass or intercept
           # 1. Bypass-DIP for destination IP
           # 2. Bypass-SIP for source IP
           # 3. Intercept-DIP for destionation IP
           #  - trigger TCP::collect to extract SNI
           # 4. Intercept-SIP for source IP
           #  - trigger TCP::collectto extract SNI
           # 5. Bypass-Host for SNI (Only triggered after Intercept-SIP/DIP match)
           #   - SNI is matched from Bypass-Host datagroup -> bypass
           #   - SNI is matched from Intercept-Host datagroup -> intercetp
           #   - Otherwise intercept traffic
 
           if { $DEBUG } { log local0. "[IP::client_addr] -> [IP::local_addr]" }
           if { [class match -name -- [IP::local_addr] equals Bypass-DIP ] ne "" } {
                     if { $DEBUG } { log local0. "class match result : [class match -name -- [IP::local_addr] equals Bypass-DIP ]" }
                     if { $DEBUG } { log local0. "Run Destination IP bypass: Destination IP address is registered on bypass list" }
                     # log local0. "run client collect command_1"
                     #virtual VS_443_Proxy-1
           } elseif { [class match -name -- [IP::client_addr] equals Bypass-SIP ] ne "" } {
                     if { $DEBUG } { log local0. "class match result : [class match -name -- [IP::client_addr] equals Bypass-SIP ]" }
                     if { $DEBUG } { log local0. "Run Source IP bypass: Source IP address is registered on bypass list" }
           } elseif { [class match -name -- [IP::local_addr] equals Intercept-DIP ] ne "" } {
                     if { $DEBUG } { log local0. "Destionation IP address is registred on Intercept-DIP list" }
                     if { $DEBUG } { log local0. "class match result : [class match -name -- [IP::local_addr] equals Intercept-DIP ]" }
                     # log local0. "run client collect command_1"
                     virtual VS_443_Proxy-1
           } elseif { [class match -name -- [IP::client_addr] equals Intercept-SIP ] ne "" } {   
                     if { $DEBUG } { log local0. "Source IP address is registred on Intercept-SIP list" }
                     if { $DEBUG } { log local0. "class match result : [class match -name -- [IP::client_addr] equals Intercept-SIP ]" }
                     # run TCP collect to check SNI for bypass before intercept SSL traffic
                     # log local0. "run client collect command_2"
                     virtual VS_443_Proxy-1
           }
}
 
}
#________________________________________________________________________________
#Profiles
#________________________________________________________________________________
ltm profile fastl4 /Common/FastL4_Loose {
    app-service none
    defaults-from /Common/fastL4
    hardware-syn-cookie disabled
    loose-close enabled
    loose-initialization enabled
    reset-on-timeout disabled
    syn-cookie-enable disabled
}
 #________________________________________________________________________________
#Virtual Server / 1.2.VS_443_Proxy-1_config.txt
#________________________________________________________________________________
ltm virtual /Common/VS_443_Proxy-1 {
    destination /Common/0.0.0.0:443
    ip-protocol tcp
    mask any
    pool /Common/pool-fw1
    profiles {
        /Common/ClientSSL_Profiles {
            context clientside
        }
        /Common/ServerSSL_Profiles {
            context serverside
        }
        /Common/http { }
        /Common/tcp-lan-optimized { }
    }
    rules {
        /Common/SSL_Forward_Bypass_Rule_Debug_Complete_v2_Complete
    }
    source 0.0.0.0/0
    translate-address disabled
    translate-port disabled
    vlans-enabled
}
#________________________________________________________________________________
#Pools
#________________________________________________________________________________
ltm pool /Common/pool-fw1 {
    members {
        /Common/166.125.0.2:0 {
            address 166.125.0.2
        }
    }
}
#________________________________________________________________________________
#iRules
#________________________________________________________________________________
ltm rule /Common/SSL_Forward_Bypass_Rule_Debug_Complete_v2_Complete {
when RULE_INIT {
                       # you can add or remove Categories. See Access Policy - Secure Web Gateway - URL Categories for a list of options
           set static::airgap_ssl_bypass_categories {
                      /Common/Financial_Data_and_Services
           }
}
 
when CLIENT_ACCEPTED {
           ###set hsl [HSL::open -proto UDP -pool syslog_server_pool]
           # DEBUG On/Off : 1/0
           set DEBUG 0
           # disable client/serverside ssl profile by default
           HTTP::disable
           SSL::disable clientside
           SSL::disable serverside
 
           # Check bypass or intercept
           # 1. Bypass-DIP for destination IP
           # 2. Bypass-SIP for source IP
           # 3. Intercept-DIP for destionation IP
           #  - trigger TCP::collect to extract SNI
           # 4. Intercept-SIP for source IP
           #  - trigger TCP::collectto extract SNI
           # 5. Bypass-Host for SNI (Only triggered after Intercept-SIP/DIP match)
           #   - SNI is matched from Bypass-Host datagroup -> bypass
           #   - SNI is matched from Intercept-Host datagroup -> intercetp
           #   - Otherwise intercept traffic
 
           #if { $DEBUG } { log local0. "[IP::client_addr] -> [IP::local_addr]" }
           #if { [class match -name -- [IP::local_addr] equals Bypass-DIP ] ne "" } {
           #          if { $DEBUG } { HSL::send $hsl "class match result : [class match -name -- [IP::local_addr] equals Bypass-DIP ] --Bypass-DIP" }
           #          if { $DEBUG } { log local0. "Run Destination IP bypass: Destination IP address is registered on bypass list: [IP::local_addr]" }
           #} elseif { [class match -name -- [IP::client_addr] equals Bypass-SIP ] ne "" } {
           #           if { $DEBUG } { log local0. "class match result : [class match -name -- [IP::client_addr] equals Bypass-SIP ]" }
           #           if { $DEBUG } { log local0. "Run Source IP bypass: Source IP address is registered on bypass list: [IP::client_addr]" }
           #}
                        if { [class match -name -- [IP::local_addr] equals Intercept-DIP ] ne "" } {
                      #if { $DEBUG } { log local0. "Destionation IP address is registred on Intercept-DIP list" }
                      #if { $DEBUG } { log local0. "class match result : [class match -name -- [IP::local_addr] equals Intercept-DIP ]" }
                      # run TCP collect to check SNI for bypass before Intercept-DIP SSL traffic
                      # log local0. "run client collect command"
                      TCP::collect
                      set monitor_id [\
                      after 500 {
                                 TCP::release
                                 #if { $DEBUG } { log local0. "[IP::client_addr]:[TCP::client_port]-[IP::local_addr]:[TCP::local_port] -No Delayed Binding"}
                      }\
                      ]
 
           } elseif { [class match -name -- [IP::client_addr] equals Intercept-SIP ] ne "" } { 
                      #if { $DEBUG } { log local0. "Source IP address is registred on Intercept-SIP list" }
                      #if { $DEBUG } { log local0. "class match result : [class match -name -- [IP::client_addr] equals Intercept-SIP ]" }
                      # run TCP collect to check SNI for bypass before intercept SSL traffic
                      # log local0. "run client collect command"
 
                      TCP::collect
                      set monitor_id [\
                      after 500 {
                                 TCP::release
                                 #if { $DEBUG } { log local0. "[IP::client_addr]:[TCP::client_port]-[IP::local_addr]:[TCP::local_port] -No Delayed Binding"}
                      }\
                      ]
           }
}
 
when CLIENT_DATA {
           after cancel $monitor_id
           binary scan [TCP::payload] cSS tls_xacttype tls_version tls_recordlen
 
           if { ( $tls_xacttype == 23 ) or ( $tls_xacttype == 20 ) or ($tls_xacttype == 22)} {
                      set record_offset 43
                      binary scan [TCP::payload] @${record_offset}c tls_sessidlen
                      set record_offset [expr {$record_offset + 1 + $tls_sessidlen}]
                      binary scan [TCP::payload] @${record_offset}S tls_ciphlen
                      set record_offset [expr {$record_offset + 2 + $tls_ciphlen}]
                      binary scan [TCP::payload] @${record_offset}c tls_complen
                      set record_offset [expr {$record_offset + 1 + $tls_complen}]
 
                      if { ([TCP::payload length] > $record_offset) } {
                                 binary scan [TCP::payload] @${record_offset}S tls_extenlen
                                 set record_offset [expr {$record_offset + 2}]
                                 binary scan [TCP::payload] @${record_offset}a* tls_extensions
                                 for { set x 0 } { $x < $tls_extenlen } { incr x 4 } {
                                             set start [expr {$x}]
                                             binary scan $tls_extensions @${start}SS etype elen
                                             if { ($etype == "00") } {
                                                        set grabstart [expr {$start + 9}]
                                                        set grabend [expr {$elen - 5}]
                                                        binary scan $tls_extensions @${grabstart}A${grabend} tls_servername
                                                        set start [expr {$start + $elen}]
                                             } else {
 
                                                        # Bypass all other TLS extensions.
                                                        set start [expr {$start + $elen}]
                                             }
                                             set x $start
                                 }
                      }
 
                      if { ([info exists tls_servername]) } {
                                             #if { $DEBUG } { log local0. "[IP::client_addr]:[TCP::client_port] - [IP::local_addr]:[TCP::local_port] $tls_servername"}
                                 if { [class match $tls_servername contains Intercept-Host] } {
                                             if { $DEBUG } { log local0. "[IP::client_addr]:[TCP::client_port] -> [IP::local_addr] $tls_servername --Intercept-Host"}
                                                                                                                     ##1##if { $DEBUG } { HSL::send $hsl "[IP::client_addr]:[TCP::client_port] -> [IP::local_addr] $tls_servername --Intercept-Host"}
                                             #if { $DEBUG } { log local0. "class match result : [class match -name -- $tls_servername equals Intercept-Host ]" }
                                             #if { $DEBUG } { log local0. "RUN Intercept-Host: SNI is matched with Intercept-Host: $tls_servername" }
                                             virtual VS_443_Proxy-3
                                             ####SSL::enable clientside
                                             ####SSL::enable serverside
                                             ####HTTP::enable
                                 }
                                 elseif { [class match $tls_servername contains Bypass-Host] } {
                                             if { $DEBUG } { log local0. "[IP::client_addr]:[TCP::client_port] -> [IP::local_addr] $tls_servername --Bypass-Host"}
                                                                                                                     ##2##if { $DEBUG } { HSL::send $hsl "[IP::client_addr]:[TCP::client_port] -> [IP::local_addr] $tls_servername --Bypass-Host"}
                                             #if { $DEBUG } { log local0. "[IP::client_addr]:[TCP::client_port] -> [IP::local_addr] $tls_servername --Bypass-Host"}
                                             #if { $DEBUG } { log local0. "Run Bypass-Host: SNI is matched with Bypass-Host" }
                                 }
                                 else {
                                             set this_uri http://$tls_servername/
                                             set reply [getfield [CATEGORY::lookup $this_uri] " " 1]
                                             set decision [lsearch -exact $static::airgap_ssl_bypass_categories $reply]
                                             if {[lsearch -exact $static::airgap_ssl_bypass_categories $reply] >= 0}{
                                                        set ssl_bypass_mitm 1
                                                        if { $DEBUG } { log local0. "[IP::client_addr]:[TCP::client_port] -> [IP::local_addr] $tls_servername --Bypass-Category"}
                                                                                                                                                      ##3##if { $DEBUG } { HSL::send $hsl "[IP::client_addr]:[TCP::client_port] -> [IP::local_addr] $tls_servername --Bypass-Category"}
                                             } else {
                                                        set ssl_bypass_mitm 0
                                             }
                                             if { [info exists ssl_bypass_mitm] } {
                                                        if { $ssl_bypass_mitm } {
                                                                      #log local0. "$static::airgap_ssl_bypass_categories $reply"
                                                                      #log local0. "$reply"
                                                        } else {
                                                                   SSL::enable clientside
                                                                   SSL::enable serverside
                                                                   HTTP::enable
                                                        }
                                             }
                                 }
                      } else {
                                 #if { $DEBUG } { log local0. "No SNI exist -> Run Intercept by Intercept-SIP or Intercpet-DIP" }
                                 SSL::enable clientside
                                 SSL::enable serverside
                                 HTTP::enable
                      }
           }
           TCP::release
}
 
when CLIENTSSL_HANDSHAKE {
    if { $DEBUG } { log local0. "[IP::client_addr]:[TCP::client_port] -> [IP::local_addr] $tls_servername --Decryption"}
           ##4##if { $DEBUG } { HSL::send $hsl "[IP::client_addr]:[TCP::client_port] -> [IP::local_addr] $tls_servername --Decryption"}
           LB::detach
           SSL::disable serverside
           virtual VS_443_Proxy-2
}
}
#________________________________________________________________________________
#Profiles
#________________________________________________________________________________
ltm profile client-ssl /Common/ClientSSL_Profiles {
    app-service none
    cert /Common/default.crt
    cert-key-chain {
        CA_ {
            cert /Common/_.crt
            key /Common/_.key
            usage CA
        }
        default {
            cert /Common/default.crt
            key /Common/default.key
        }
    }
    cert-lifespan 365
    chain none
    defaults-from /Common/clientssl
    hostname-blacklist /Common/Intercept-Host
    hostname-whitelist /Common/Bypass-Host
    inherit-ca-certkeychain false
    inherit-certkeychain true
    key /Common/default.key
    passphrase none
    proxy-ca-cert /Common/_.crt
    proxy-ca-key /Common/_.key
    retain-certificate false
    ssl-forward-proxy enabled
    ssl-forward-proxy-bypass enabled
}
ltm profile server-ssl /Common/ServerSSL_Profiles {
    app-service none
    ca-file /Common/ca-bundle.crt
    cipher-group none
    ciphers ALL
    defaults-from /Common/serverssl
    secure-renegotiation request
    ssl-forward-proxy enabled
    ssl-forward-proxy-bypass enabled
}
# -Default Profile-
ltm profile http http {
    basic-auth-realm none
    lws-width 80
    oneconnect-transformations enabled
    oneconnect-status-reuse "200 206"
    proxy-type reverse
    enforcement {
        max-header-count 64
        max-header-size 32768
        pipeline allow
        unknown-method allow
    }
    request-chunking preserve
    response-chunking selective
}
# -Default Profile-
ltm profile tcp tcp-lan-optimized {
    ack-on-push enabled
    defaults-from /Common/tcp-legacy
    nagle disabled
    proxy-buffer-high 131072
    proxy-buffer-low 98304
    receive-window-size 65535
    send-buffer-size 65535
    slow-start disabled
}
 
#________________________________________________________________________________
#Virtual Server / 1.3.VS_443_Proxy-2_config.txt
#________________________________________________________________________________
ltm virtual /Common/VS_443_Proxy-2 {
    clone-pools {
        /Common/pool-mirroring {
            context clientside
        }
    }
    destination /Common/0.0.0.0:443
    ip-protocol tcp
    mask any
    pool /Common/pool-fw1
    profiles {
        /Common/ServerSSL_Insecure_Profiles {
            context serverside
        }
        /Common/http { }
        /Common/tcp-lan-optimized { }
    }
    rules {
        /Common/SSL_Forward_Proxy-2_Rule
    }
    source 0.0.0.0/0
    translate-address disabled
    translate-port disabled
    vlans-enabled
}
#________________________________________________________________________________
#Pools
#________________________________________________________________________________
ltm pool /Common/pool-fw1 {
    members {
        /Common/166.125.0.2:0 {
            address 166.125.0.2
        }
    }
}
ltm pool /Common/pool-mirroring {
    members {
        /Common/10.10.10.21:0 {
            address 10.10.10.21
        }
    }
}
#________________________________________________________________________________
#iRules
#________________________________________________________________________________
ltm rule /Common/SSL_Forward_Proxy-2_Rule {
#
# Add server_name extension in server-side's Client Hello using client-side's HTTP host header
#
when HTTP_REQUEST {
  set name [HTTP::host]
}
when SERVERSSL_CLIENTHELLO_SEND {
  set name_len [string length $name]
  set name_list_len [expr {$name_len + 3}]
  set name_type 0
  set ext_type 0
  set ext_len [expr {$name_len + 5}]
 
  SSL::extensions insert [binary format S1S1S1cS1a* $ext_type $ext_len $name_list_len $name_type $name_len $name]
 
}
 
}
#________________________________________________________________________________
#Profiles
#________________________________________________________________________________
ltm profile server-ssl /Common/ServerSSL_Insecure_Profiles {
    app-service none
    cipher-group none
    ciphers ALL
    defaults-from /Common/serverssl-insecure-compatible
    retain-certificate false
}
# -Default Profile-
ltm profile http http {
    basic-auth-realm none
    lws-width 80
    oneconnect-transformations enabled
    oneconnect-status-reuse "200 206"
    proxy-type reverse
    enforcement {
        max-header-count 64
        max-header-size 32768
        pipeline allow
        unknown-method allow
    }
    request-chunking preserve
    response-chunking selective
}
# -Default Profile-
ltm profile tcp tcp-lan-optimized {
    ack-on-push enabled
    defaults-from /Common/tcp-legacy
    nagle disabled
    proxy-buffer-high 131072
    proxy-buffer-low 98304
    receive-window-size 65535
    send-buffer-size 65535
    slow-start disabled
}
#________________________________________________________________________________
#Virtual Server / 1.4.VS_443_Proxy-3_config.txt
#________________________________________________________________________________
ltm virtual /Common/VS_443_Proxy-3 {
    creation-time 2022-09-28:15:50:34
    destination /Common/0.0.0.0:443
    ip-protocol tcp
    last-modified-time 2022-09-28:15:53:45
    mask any
    pool /Common/pool-fw1
    profiles {
        /Common/ClientSSL_Profiles_nobypass {
            context clientside
        }
        /Common/ServerSSL_Profiles {
            context serverside
        }
        /Common/http { }
        /Common/tcp-lan-optimized { }
    }
    rules {
        /Common/SSL_Forward_Proxy-3_Rule
    }
    source 0.0.0.0/0
    translate-address disabled
    translate-port disabled
    vlans-enabled
}
#________________________________________________________________________________
#Pools
#________________________________________________________________________________
ltm pool /Common/pool-fw1 {
    members {
        /Common/166.125.0.2:0 {
            address 166.125.0.2
        }
    }
}
#________________________________________________________________________________
#iRules
#________________________________________________________________________________
ltm rule /Common/SSL_Forward_Proxy-3_Rule {
when CLIENTSSL_HANDSHAKE {
###if { $DEBUG } { log local0. "[IP::client_addr]:[TCP::client_port] -> [IP::local_addr] $tls_servername --Decryption"}
###if { $DEBUG } { HSL::send $hsl "[IP::client_addr]:[TCP::client_port] -> [IP::local_addr] $tls_servername --Decryption"}
           LB::detach
           SSL::disable serverside
           virtual VS_443_Proxy-2
}
}
#________________________________________________________________________________
#Profiles
#________________________________________________________________________________
ltm profile client-ssl /Common/ClientSSL_Profiles_nobypass {
    app-service none
    cert-key-chain {
        __1 {
            cert /Common/_.crt
            key /Common/_.key
            usage CA
        }
        default {
            cert /Common/default.crt
            key /Common/default.key
        }
    }
    cert-lifespan 365
    defaults-from /Common/clientssl
    hostname-whitelist none
    inherit-ca-certkeychain false
    inherit-certkeychain true
    ssl-forward-proxy enabled
    ssl-forward-proxy-bypass enabled
}
ltm profile server-ssl /Common/ServerSSL_Profiles {
    app-service none
    ca-file /Common/ca-bundle.crt
    cipher-group none
    ciphers ALL
    defaults-from /Common/serverssl
    secure-renegotiation request
    ssl-forward-proxy enabled
    ssl-forward-proxy-bypass enabled
}
# -Default Profile-
ltm profile http http {
    basic-auth-realm none
    lws-width 80
    oneconnect-transformations enabled
    oneconnect-status-reuse "200 206"
    proxy-type reverse
    enforcement {
        max-header-count 64
        max-header-size 32768
        pipeline allow
        unknown-method allow
    }
    request-chunking preserve
    response-chunking selective
}
# -Default Profile-
ltm profile tcp tcp-lan-optimized {
    ack-on-push enabled
    defaults-from /Common/tcp-legacy
    nagle disabled
    proxy-buffer-high 131072
    proxy-buffer-low 98304
    receive-window-size 65535
    send-buffer-size 65535
    slow-start disabled
}
  • muntae_kim You can absolutely perform SSL termination on other ports than 443. Please keep in mind that the client has to be using the HTTPS protocol over that other port so this wouldn't work on lets say port 21 because that is for FTP or 22 because that is SSH without some fiddling with the client side of the connection. You would most likely use some free port that isn't reserved for a specific protocol.

  • Thank you for answer. I would like to ask additional questions because I do not understand your answer.

    Based on the current settings, the customer only wants to decrypt port 443, and is considering additional decryption of port 4430.

    To make this possible, please review the following settings.

    1. Add 4430 port Virtual Servers separately so that traffic flowing into 4430 port can be decrypted to the Virtual Servers that are currently set to port 443 only.
    2. Modify and apply iRules to operate on a newly added Virtual Server

    The conclusion is that when TCP 443 is set to 4430, a custom port, it is designated as Other, and whether it operates the same as 443.

    If anyone has any clarity on this part, please respond.

    thank you

    • Paulius's avatar
      Paulius
      Icon for MVP rankMVP

      muntae_kim You would configure a new virtual server listening on 4430 with an SSL profile and then send that decrypted traffic to your pool of choice. You do not have to send decrypted traffic back around to the virtual server listening on 443.