Oplon ADC Content rewriting

Introduzione

Oplon ADC implementa il content rewriting in modalità nativa e come componente fondamentale nel governo dei servizi applicativi. Il sistema è stato studiato sia per un utilizzo di rewriting in senso stretto, rewriting di HTTP HEADER o HTTP BODY, sia come sistema di integrazione layer 7 e layer 4.

Da disegno progettuale è stata data la possibilità di utilizzare regole descritte con espressini regolari fino ad utilizzare il linguaggio di programmazione JAVA o linguaggi di scripting. Queste due modalità di rewriting possono essere utilizzate contemporaneamente.

Altro aspetto fondamentale di cui si è tenuto conto durante la progettazione è la facilità di utilizzo ed una "leggibilità intuitiva" nel tempo di quanto sviluppato sia nelle regole descrittive sia a livello di programmazione. Tutte le regole sono impostabili attraverso interfaccia WEB.

Questo documento tratta l'argomento rewriting utilizzando tantissimi esempi in modo da poter essere poi riutilizzati nei propri progetti.

Servizi academy.Oplon.net HTTP2/1.x

Oplon Networks mette a disposizione un servizio basato su TOMCAT per effettuare i test descritti in questo documento. All'indirizzo https://academy.oplon.net/.

All'URI https://academy.oplon.net/trainingw è a disposizione un servizio che evidenzia i risultati delle operazioni di content rewriting sia HEADER sia BODY http/s.

Il servizio è erogato nella porta 443 in http/2 in autosensing. L'autosensing http/2 di Oplon ADC è in grado di capire se il client è in grado di instaurare una comunicazione http/2 ed eventualmente commutare automaticamente in http/1.x.

Allo stesso indirizzo ma con porta 543, https://academy.oplon.net:443/ è possibile connettersi con i soli protocolli http/1.x.

Il servizio richiede un certificato digitale, NON OBBLIGATORIO, al solo scopo di eseguire gli esercizi per questo documento e per i corsi online in modo da poter verificare le funzionalità di "client certificate forwarding" verso le applicazioni. Il listener accetta qualsiasi tipo di certificato e all'indirizzo https://academy.oplon.net/trainingw è possibile apprezzare il forwarding del "client certifcate chain".

Enjoy!

Impostazione ADC per eseguire gli esercizi

Per poter agevolmente eseguire gli esercizi di questo manuale è sufficiente impostare l'ADC con i seguenti listener, copiati direttamente dai template al modulo Platform Edition, cambiando gli indirizzi su cui i listener ascoltano ed eventualmente la porta.

image1

image2 Come gruppo mantenere per i test http_https proposto dai template ed inserire un unico endpoint con il nome del dominio "academy.Oplon.net" porta 443 con indicazione della connessione SSL

Rewriting

Con l'argomento rewriting si identificano i processi che, filtrando i dati in transito attraverso un gateway, possono modificare i contenuti.

image3

In un processo di trasformazione di questo tipo risulta evidente che la pertinenza delle modifiche apportate deve essere molto rigorosa andando quest'ultima ad incidere non solo nei contenuti ma anche a livello di protocollo e quindi influenzando i comportamenti.

Il sistema di rewriting dovrà quindi fornire gli strumenti necessari per modificare i contenuti in maniera selettiva con semplicità.

Intervenire sul protocollo richiede ovviamente una certa consapevolezza delle modifiche che si vogliono apportare andando ad incidere sull'erogazione del servizio. Ciò nondimeno il sistema dovrà essere sufficientemente astratto da nascondere la complessità delle tecnologie assicurando all'utilizzatore il risultato finale.

Vista l'articolazione dell'argomento un altro aspetto da tenere in considerazione è la possibilità di intervenire attraverso semplici regole descrittive con regular expression lasciando la possibilità di intervenire anche attraverso estensioni di classi JAVA o di scripting con un vero e proprio linguaggio di programmazione.

Quest'ultimo aspetto, oltre al rewriting, permette di svolgere attività di integrazione con gli applicativi andando a gestire attività come il Single Sign On (SSO) oppure aspetti di attribuzione dell'utilizzo delle applicazioni per successiva fatturazione o suddivisione per centri di costo.

HTTP Rewriting

Oplon ADC implementa il rewriting del protocollo http/1.0/1.1/2.0 attraverso lo sviluppo di regole descrittive.

Le regole vengono etichettate con un nome in modo da poterle riutilizzare su diversi flussi informativi e a diversi livelli favorendo lo sviluppo di proprie librerie di regole.

In Oplon ADC con il protocollo http, possono essere descritte due tipi di regole, una relativa all'HEADER e l'altra relativa al BODY. Questi due elementi infatti contraddistinguono il messaggio http. Entrambe queste regole vengono implementate in maniera simile per diversificarsi solo per gli scopi di pertinenza.

Il sistema viene fornito dalla fabbrica già con un set di regole template che coprono la maggioranza dei casi di applicazione. I template vengono costantemente aggiornati e implementati.

Per accedere alla gestione delle regole di content rewriting attraverso Web Interface andare in

ADC Settings -> Rewrite management. Rewrite management ha due ulteriori scelte per selezionare le regole di rewrite applicabili all'HEADER http o al BODY http. Per visualizzare i template selezionare "View template rewrite class"

image7

HTTP Rewriting HEADER esempio

Come primo esempio andremo a cambiare l'HEADER di RESPONSE http per anonimizzare la descrizione del server che sta rispondendo. Questo tipo di regola viene utilizzata normalmente per ragioni di sicurezza.

La regola verrà prima creata e poi, attraverso il suo nome, potrà essere utilizzata in più contesti.

Per creare una nuova regola per l'HEADER http procedere come di seguito:

ADC Settings -> Rewrite management -> Rewrite header rules -> [+]

Il Sistema chiederà su quale Application Delivery Controller creare la regola.

image8

Il passo successivo richiede di inserire il nome della regola, quando la regola sarà utilizzata, RESQUEST, RESPONSE o BOTH per entrambi i sensi. Potrà inoltre essere filtrata l'esecuzione per responseCode. L'ultimo parametro permette di disattivare la regola in modo da non renderla operativa anche se esistente.

image9

In questa immagine viene evidenziala la differenziazione del flusso di REQUEST e di RESPONSE:

image10

Appena premuto l'ok la regola viene creata e pronta per essere personalizzata attraverso il pulsante [edit]. È inoltre possibile esportare la regola su un file testo e importarla in un altro ADC non collegato direttamente.

image11

Entrando in edit è possibile impostare nel dettaglio tutte le condizioni, parametri ed eseguire qualsiasi tipo di verifica o modifica.

image12

Per modificare la porzione di header, che chiameremo "entity", espandere il pannello [Entities] e inserire nel nome l'entity name dell'header, in questo caso [Server] , selezionare l'azione, in questo caso [change] e inserire il valore che si vuole far apparire al posto del valore proveniente dal server, in questo caso digitare un valore di fantasia [DATA_NOT_AVAILABLE]

image13

Eseguire il [save] e il successivo [reinit] della regola.

image14

La regola è stata creata ed è anche stata salvata ma ancora non applicata in nessun contesto.

Verifichiamo il comportamento dell'applicazione senza l'utilizzo della regola. In questo caso il web server è un nginx versione 1.19.1:

image15

Applichiamo ora la regola a livello generale ADC e quindi verrà eseguita per tutti i servizi che transitano per l'ADC che andremo a selezionare tramite: ADC Settings->ADCs->Selezionare [edit] dell'ADC su cui si vuole applicare la regola...

image16

Nel pannello [Default rewrite header rules] impostare la regola precedentemente salvata.

image17

Eseguire il [save] e il successivo [reinit] della regola.

image14

Ricaricando la pagina con il browser si potrà verificare l'avvenuto cambiamento dell'HEADER.

image18

Solo come esercizio, proviamo ora a modificare la regola e cambiamo parte dell'entity header http da "nginx/1.19.1" in "SERVER_PHANTOM/...."lasciando inalterata la versione proposta da nginx anche nel caso venga aggiornata.

La prima cosa da fare è impostare una regex in grado di effettuare il cambiamento. Per ottenere velocemente questo risultato si può utilizzare il simulatore di regular expression direttamente dalla console web Oplon: Tools -> Regex helper

Expression: \^(.*)/(.*)\$

Questa espressione indica due insiemi divisi da una barra.

Replace To: SERVER_PHANTOM/\$2

Il replace con espressione regolare modifica la parte iniziale del primo insieme con una costante SERVER_PHANTOM seguita da una / e dal valore del secondo insieme indicato nella regolar expression.

In value: nginx/1.19.1

È il valore di test digitato per poter eseguire l'espressione regolare con l'helper.

image19

Modifichiamo la regola di rewrite nella seguente maniera:

Value: deve essere cancellato\ Find regexp: \^(.*)/(.*)\$

Questa espressione indica due insiemi divisi da una barra.

Replace regexp: SERVER_PHANTOM/\$2

Il replace con espressione regolare modifica la parte iniziale del primo insieme con una costante SERVER_PHANTOM seguita da una / e dal valore del secondo insieme indicato nella regolar expression.

image20

Il risultato che otterremo al refresh del richiamo sarà con la sostituzione del primo insieme a sinistra della / con la nostra costante SERVER_PHANTOM:

image21

HTTP HEADER Rewriting Conditions

L'esecuzione della regola può essere condizionata da insiemi di fattori come possono essere ad esempio l'indirizzo di provenienza, l'URI, alcuni parametri o un insieme di valori.

Per poter impostare delle condizioni è sufficiente aprire il pannello "Conditions" della regola. Se ad esempio vogliamo applicare la regola solamente se l'indirizzo di provenienza è un indirizzo particolare, nel nostro caso 192.168.56.131, possiamo scegliere tra i "From" -> "INNERVAR", cioè dei valori che il sistema mette a disposizione, scegliere su Value "REQUEST_CLIENT_ADDRESS" e quindi su "Find regexp" inserire l'espressione regolare che identifica l'indirizzo avendo cura di inserire prima della punteggiatura i le barre inverse come escape sequence:

Find regexp: 192\.168\.56\.131

image22

\

Risposte se l'indirizzo della richiesta del client non è 192.168.56.131

image23

Risposte se l'indirizzo del client è 192.168.56.131

image24

HTTP HEADER Rewriting REDIRECT

Altra possibilità a livello di HEADER è eseguire un redirect condizionato. Ovviamente questo sarebbe possibile modificando ENTITY per ENTITY l'HEADER. Essendo un'operazione molto utilizzata si è creato un valore dedicato, "redirectTo" per facilitare l'operazione.

Andiamo a creare una nuova regola di rewrite dell'header

image25

image26

Una volta creata la nuova regola entrare con edit per personalizzarla:

Nel personalizzare la regola andremo a impostare una "condizione rapida" che determinerà l'esecuzione della regola solo se il client eseguirà una GET durante la richiesta. Oltre alla condizione httpMethod, in request è possibile verificare prima dell'esecuzione anche l'URL richiesta, comprensiva di parametri e query string, attraverso una espressione regolare. In Response è possibile attivare la regola per un response code particolare. Queste "condizioni rapide" possono essere utilizzate con le più complete condizioni dell'apposito paragrafo "Conditions" mostrato in precedenza.

image27

Sul pannello "Routing" andremo a impostare a true "Enable redirection" e successivamente andremo a indicare "Redirectin URL" ed il codice che si vuole comunicare al client come ridirezione.

image28

In questo caso tutte le volte che verrà eseguita una richiesta con GET, il client verrà ridirezionato verso "http://www.Oplon.net/training?myParam=AAA" con response code 302.

Salvare la regola e quindi eseguire il reinit come indicato dal pannello in alto:

image14

Come per la volta precedente, una volta che la regola è stata creata, questa dovrà essere utilizzata nelle risorse in generale, per raggruppamento, per dominio o per singoli endpoint. In questo caso la attribuiremo all'unico endpoint della nostra macchina di test.

Selezionare [edit] dal modulo ADC interessato, in questo caso il modulo A01_LBLGoPlatform:

image29

Espandere il pannello "Endpoints Grouping" e selezionare [See details] per andare verso la gestione "Virtual domains"

image30

In maniera gerarchica dalla gestione domini scendere sulla gestione "endpoints" sempre con la scelta [See details]

image31

Scendere ulteriormente nel dettaglio dell'unico endpoint del nostro esercizio per applicare la regola precedentemente creata:

image32

Sull'endpoint aprire il pannello "Rewrite header rules" e selezionare la regola "RedirectToOplonNet".

image33

Salvare la modifica e quindi eseguire il reinit come indicato dal pannello in alto:

image14

Eseguire la richiesta ed il risultato sarà un redirect nella posizione indicata. Se avete utilizzato il dominio opon.net ci saranno poi ulteriori ridirezioni applicative ma come noterete il parametro rimarrà invariato come da nostra redirect:

image34

HTTP HEADER Rewriting with VARIABLES

L'utilizzo delle variabili è quanto di più sofisticato e potente sia stato realizzato per estrarre dei valori dai dati in transito, on-the-fly, e comporre nuovi valori da riutilizzare sugli stessi dati in transito. Le variabili, come le condizioni, possono essere utilizzate sia nelle regole di rewriting dell'HEADER sia nelle regole di rewriting del BODY.

Per variabile si intende un "nome simbolico" che sta ad indicare un valore in un determinato contesto in un determinato momento.

Nelle regole di rewriting le variabili sono utilizzate per memorizzare dei valori che possono derivare da diverse fonti precedentemente dichiarate, ivi comprese delle variabili stesse.

Il caso che vogliamo utilizzare per spiegare l'utilizzo delle variabili è lo stesso del redirect precedente dove però l'URL di ridirezione verrà popolata da valori costanti e con valori variabili provenienti dal flusso dati stesso.

Immaginiamo di voler eseguire un redirect con un parametro avente come valore il valore ricavato da un COOKIE se valorizzato.

A questo scopo copieremo la regola "redirectToOplonNet" sullo stesso modulo ADC e poi cambieremo il nome della regola copiata:

image35

Scegliamo se stesso come obiettivo della copia:

image36

Andiamo in [edit] della nuova regola per poterla modificare:

image37

...e cambiamo il nome della regola per poterla differenziare dalla regola di origine:

image38

Per poter gestire le variabili aprire il pannello "Variables" della regola e impostare il nome simbolico della variabile, come e da dove deve essere caricata la variabile ed il valore, che in questo caso è il contenuto del cookie LBLSESSIONID:

Name: MY_LBLSESSIONID

From: COOKIE

Value: LBLSESSIONID

image39

Dopo aver caricato la variabile MY_LBLSESSIONID andremo ad utilizzarla come valore del parametro del redirect:

Nel pannello routing indicare con il nome della variabile contrassegnato dai simboli % all'inizio e alla fine del nome variabile. Durante il runtime il nome verrà sostituito dal contenuto del cookie LBLSESSIONID...

image40

Assegnamo all'endpoint la nuova regola in sostituzione della precedente

image41

Salvare la modifica e quindi eseguire il reinit come indicato dal pannello in alto:

image14

Il risultato sarà un redirect con

image42

È possibile inoltre eseguire un export e un import di una regola in formato json

image43

Una volta salvata la regola in un file testo è possibile importarla in un altro ADC in un altro nodo che non è collegato al nodo dove è stata prodotta.

image44

Per completezza, nel parametro "from" possono essere indicati i seguenti elementi da cui trarre le informazioni:

INNERVAR=Valori precaricati da Oplon ADC per facilitare le operazioni

INNER VARIABLES

REQUEST_HTTP_URL=Request URL with params and query string

REQUEST_HTTP_URL_LAST_ELEMENT=only last element of the URL without params and\ query string

REQUEST_HTTP_URI_PATH=Only URI Path whithout parameters and query string

REQUEST_HTTP_HOST_NAME=hosname in entity \"Host\" (ATTENZIONE: L'utilizzo di questa

innervar può determinare la risoluzione del nome attraverso DNS.

Se il nome non è associato a nessun indirizzo il suo timeout può\ causare un forte rallentamento)

REQUEST_HTTP_HOST_PORT=port number in entity \"Host\"

REQUEST_HTTP_COOKIES_LIST=list of cookies names separated by \";\"

REQUEST_CLIENT_ADDRESS=TCP client address

RESPONSE_ENDPOINT_ADDRESS=TCP endpoint address\ SSL_CONNECTION_CLIENT = true se il client si connette in SSL con LBL\ SSL_CONNECTION_ENDPOINT = true se l'endpoint si connette in SSL con LBL\ SSL_CONNECTION_REENCRYPTION = true se viene eseguita la reencryption SSL\ (quindi Oplon fa la terminazione SSL e si connette verso l'endpoint in SSL)\ REQUEST_INCOMING_ADDRESS = indirizzo locale sul quale e' stata accettata la richiesta\ di servizio\ REQUEST_INCOMING_HOST_NAME = nome host o indirizzo locale sul quale e' stata accettata\ la richiesta di servizio (ATTENZIONE: L'utilizzo di questa

innervar può determinare la risoluzione del nome attraverso DNS.

Se il nome non è associato a nessun indirizzo il suo timeout può\ causare un forte rallentamento)\ REQUEST_HTTP_SCHEME = http o https in base al tipo di connessione del client verso LBL

HIGH_WATER_YELLOW_WARNING_REACHED = se true è stata superata la soglia Yellow

Warning. Indica quindi un carico rilevante ma non ancora

critico.

HIGH_WATER= number of connection requests in the queue in long format.

HIGH_WATER_LEVEL= % Of connection requests in the queue compared to the number of

tunnels contemporary settings, this is a float value.

TUNNEL_SESSIONS_ACTIVE= Instant active tunnels, int format.

TUNNEL_SESSIONS_COMMITTED= Instant tunnel committed, (subset of TUNNEL_SESSIONS_ACTIVE\"

Questi valori \"precaricati\" per essere utilizzati come modificatori (%xxx%) devono\ comunque essere caricati in una variabile locale alla regola.

ENTITY=caricamento della variabile descritta in varName con il valore dell'Entity\ dell'HEADER HTTP il cui nome è indicato in name.

URI_PARAM=caricamento della variabile descritta in varName con il valore del\ parametro o query string dell'HEADER HTTP il cui nome è indicato in\ name.

CONSTANT=caricamento della variabile descritta in varName con il valore del parametro

indicato in name. Solo in questo caso il valore contenuto in name può essere\ composto da un'altra variabile precedentemente caricata.

COOKIE=caricamento della variabile descritta in varName con il valore del Cookie

dell'HEADER HTTP il cui nome è indicato in name.

VARIABLE=caricamento della variabile descritta in varName con il valore di un'altra variabile il cui nome è indicato in name.

Una completa trattazione di tutti gli argomenti e parametri è disponibile sul manuale Oplon Reference Guide.

HTTP HEADER Analisi di una regola template di redirect

Oplon ADC contiene numerosi template di regole sia di Header sia di Body http. Di seguito analizzeremo una regola di ridirezione da https a http. Nel caso opposto, da http a https non è necessario utilizzare una regola, che comunque è presente nei template, ma è sufficiente impostare l'apposito flag predisposto nelle risorse da endpoints grouping, domain fino agli endpoint.

Selezioni disponibili per redirect http to https.

image45 ![](./images/image46.png image47

La regola di seguito, presente nei template, è httpsToHttp e si applica nel flusso di REQUEST:

image48

Come variabili sono state caricate l'host name e l'intera URL comprensiva di parametri e query string:

image49

Come condizione è stata verificata la tipologia di collegamento del client, in questo caso la condizione si verifica se il client si connette in SSL/TLS:

image50

Nelle regole di routing si utilizza il "redirection URL" mettendo una parte costante, "http://" concatenando le variabili precedentemente caricate con il nome dell'HOST e l'URL che era stata richiesta in origine comandando quindi il client a eseguire la stessa richiesta ma in http:

image51

Una trattazione più estesa delle variabili e la molteplicità di operazioni che si possono effettuare, può essere verificata sulla regola template che dimostra varie tipologie di assegnazione, variazione e composizione di valori da più variabili.

Template: testRedirectionWithVariables

image52

Questa regola dimostra le capacità di inspection, estrapolazione e composizione di nuovi valori derivati da dati di transito.

HTTP HEADER Rewriting with extended JAVA classes

Come visto in precedenza è possibile indicare in una regola l'utilizzo di una classe in JAVA definita e scritta dall'utilizzatore.

Questa funzionalità può essere utilizzata contemporaneamente a quanto visto fino ad ora in quanto la classe è una estensione di una classe appositamente creata in Oplon ADC a questo scopo. La classe mette a disposizione 6 momenti (metodi):

1-interceptorInit (richiamato una sola volta all'inizializzazione dell'oggetto)

2-interceptorEnd (richiamato una sola volta alla terminazione dell'oggetto)

3-doRequestHeaderBeforeReplace

4-doRequestHeaderAfterReplace

5-doResponseHeaderBeforeReplace

6-doResponseHeaderAfterReplace

Il ciclo di vita dei metodi è indicato nella sequenza sotto esposta, ovviamente se non sono state dichiarate via XML o comandate attraverso programma JAVA dei redirect. In quel caso alcuni di questi metodi non verranno richiamati.

image53 All'interno di ogni metodo viene messo a disposizione un oggetto che rappresenta il "frammento" consistente di quanto sta transitando.

Nell'esempio visto in precedenza, e disponibile da libreria Oplon ADC, all'interno di ogni metodo venivano eseguite alcune azioni come quella evidenziata di seguito:

* @Override
public void
doRequestHeaderBeforeReplace(LBLHTTPInterceptorHeaderStreamFragment
streamFragment) {
 logWarning(\"REQUEST HEADER BEFORE REPLACE\\n\"+
     streamFragment.getRequestRowImageStreamFragment());

 for (String varName: streamFragment.getVariables())
    logWarning(\"RQBR HEADER VarName:\"+varName+" value:\"+streamFragment.getVariable(varName));
}

La classe *LBLHTTPInterceptorHeaderAbstr* mette infatti a disposizione
alcuni metodi e tra questi la possibilità di effettuare il log
direttamente sul sistema di logging di *Oplon ADC*.

/**
* generazione di un messaggio con tipologia |ERROR|
* @param logMessage messaggio da persistere su file di log
*/

public void logError(String logMessage)
/**
* generazione di un messaggio con tipologia |WARNING|
* @param logMessage messaggio da persistere su file di log
*/
public void logWarning(String logMessage)
* generazione di un messaggio con tipologia |DEBUG| solo se
* definizione di lancio
* java -DDEBUG=true -DLBL_DEBUG_REWRITING=true
* @param logMessage messaggio da persistere su file di log
*/
public void logDebug(String logMessage)

In questo caso dal frammento di HEADER, passato come parametro al metodo, è possibile richiedere di elencare la lista delle variabili dichiarate e utilizzarne il valore:

for (String varName: streamFragment.getVariables())
    logWarning("REQUEST HEADER VarName:"+varName value:"+streamFragment.getVariable(varName));

Altri metodi di interrogazione e manipolazione dei dati sono disponibili sull'oggetto streamFragment come ad esempio quelli relativi alla gestione degli ENTITIES:

Un elenco completo dei metodi è disponibile nel manuale Oplon ADC Reference Guide.

La posizione delle classi è dipendente dal nome del package che verrà utilizzato e sarà relativo alla directory (vedere capitolo Create a JAVA extended class in questo manuale):

HTTP HEADER Rewriting displace endPointsGrouping

Con questa direttiva è possibile spiazzare in un altro EndPointsGrouping una richiesta proveniente da un listener afferente ad un EndPointsGrouping differente.

image54 Questa funzionalità si ottiene utilizzando le regole di rewriting dell'Header con un nuovo paragrafo che indica l'azione di spiazzamento.

Tutte le funzionalità presenti su interfaccia web sono utilizzabili attraverso classe interceptor sulla quale possono ovviamente essere effettuate anche operazioni logiche molo più complesse. In questo caso anche il displace e' possibile comandarlo anche da classe interceptor HEADER Java:

<rewriteHeaderRule enable="false" flow="REQUEST" name="setEndpGrouping"
    httpInterceptorClass="my_httprewriters.LBLDisplaceEndPointGroupingTemplate">
</rewriteHeaderRule>

HTTP BODY Rewriting

Il rewriting del BODY HTTP è attualmente quanto di più sofisticato si possa utilizzare in questo campo. È possibile utilizzare contemporaneamente sia regole descrittive sia estensioni di classi JAVA o di scripting. In entrambi i casi i dati vengono "passati" al rewriter con porzioni consistenti del body in base al mime type per poter applicare espressioni regolari di modificazione senza che la frammentazione TCP influisca nel rewriting. Le regole possono essere indifferentemente implementate sia su HTTP1.0, HTTP1.1 e HTTP2,

L'utilizzo delle regole di rewriting per il BODY è simile all'utilizzo delle regole di rewriting dell'HEADER e quindi una volta utilizzate le une o le altre si è rapidamente in grado di utilizzarle entrambe.

Costruiamo una regola per cambiare la descrizione del BODY del servizio di training. La regola cambierà le parole da "Hello Oplon" in "HELLO Oplon, THE BEST ADC IN THE UNIVERSE"

image55

Anche in questo caso i parametri iniziali sono identici al paragrafo dell'HEADER e prevedono una identificazione della regola attraverso un nome simbolico dichiarato sul parametro "name", una indicazione del flusso dati che si vuole intercettare, parametro "flow" in questo caso "RESPONSE" perché è il body di response che vogliamo modificare.

Dobbiamo inoltre istruire il motore di rewriting del tipo di mime type e come su quel mime type possono essere considerati consistenti blocchi di informazioni.

A esempio in un body con mime type "text/html" possono considerarsi parti consistenti tutte le informazioni comprese tra un carattere "\<" e un carattere ">".

image56

Questa associazione nel caso del rewriting del BODY non è facoltativa perché in base al mime type si identificano i blocchi di rewriting consistenti attraverso i parametro fragment Open text e fragment Close Text. E' importante stabilire il blocco consistente perchè il "frammentatore" del rewriter del BODY renderà disponibile alle espressioni regolari descritte o alla estensione della classe JAVA, solo porzioni modificabili e consistenti da un punto di vista logico.

image57

E' stata lasciata ampia libertà di scegliere la definizione di blocco consistente proprio per poter adattare al meglio la propria regola. Ovviamente le best practice indicano come blocco consistente per html e xml le parentesi angolari, "\<" ">", per i css le parentesi graffe, "{" "}", per i parametri all'interno di un body prodotto da una form HTTP (application/x-www-form-urlencoded) le "&" che suddividono i parametri con il loro nome=valore;

Senza la regola...

image58

Con la regola...

image59

HTTP BODY Rewriting

Anche con la funzionalità di rewriting del BODY è possibile contemporaneamente utilizzare il rewriting attraverso regole descritte sul file XML e associare anche una estensione di una classe JAVA appositamente resa disponibile dalla libreria con i seguenti metodi:

1-doRequestBodyBeforeReplace

2-doRequestBodyAfterReplace

3-doResponseBodyBeforeReplace

4-doResponseAfterAfterReplace

Da un punto di vista prettamente tecnologico il flusso dati http BODY (contenuti), verrà passato per "blocchi" consistenti per tipologia di mime-type e non per frammentazione tcp. Questo sarà assolutamente trasparente per coloro che si accingeranno a scrivere la regola di rewriting. È a cura del motore di rewriting mantenere consistente il frammento attraverso i caratteri descritti in fragmentOpen e fragmentClose.

Se vogliamo ad esempio modificare del testo presente nel BODY, esempio da "Hello Oplon !"

image60

image61

In "HELLO Oplon, THE BEST ADC IN THE UNIVERSE®!"

image62

Andare in ADC Settings->Rewrite management->Rewrite body rules, slezionare [+] e inserire la seguente regola:

Rewrite body rule

name: changeWords

flow: RESPONSE

Condition matcher for URL: /trainingw/OplonProjectTestServlet

Find regexp: Hello Oplon

Replace regexp: HELLO Oplon, THE BEST ADC IN THE UNIVERSE

Mime Type

Mime type: text/html

fragment Open text: \<

fragment Close text: \<

image63

Una volta creata la regola impostarla nel flusso desiderato, in questo caso la metteremo a livello di dominio:

image64

Il risultato al submit è il seguente!

image65

HTTP BODY Rewriting with extended JAVA classes

Sul BODY sono stati resi disponibili metodi differenti di interazione con il frammento, alcuni sono comuni altri sono ovviamente tipici per il trattamento del BODY. Forse uno tra i più interessanti è l'interazione con i valori contenuti in un BODY e forniti da una FORM HTML per poter interagire con quanto viene inviato dall'utente. In questo caso andremo ad aggiungere un parametro al form presente in https://academy.Oplon.net/trainingw. Se eseguiamo il form direttamente, senza passare per la vostra istanza ADC, il risultato sarà il seguente [submit]:

Nella sezione ==== Servlet Parameters ==== saranno presenti i parametri della form:

image66

Andiamo ora a creare una regola sul nostro ADC che aggiunge il parametro "MY_PARAM" con valore "My param value!" e dovremo ottenere il seguente risultato:

image67

La regola per inserire ad ogni POST HTTP il nuovo parametro sarà:

Rewrite body rule

name: addBodyFormParamTest

flow: REQUEST

httpInterceptorClass: rewriteclasses.LBLHTTPRewriteInterceptorBodyAddParam

Mime type

Mime type: application/x-www-form-urlencoded

fragment Open text: &

fragment Close text: &

image68

In questo caso l'azione di rewriting verrà interamente svolta dall'estensione della classe JAVA ed il risultato sarà un'aggiunta di un parametro al Form HTML esistente:

image69

Create JAVA extended class HTTP Interceptor

Per creare e compilare una estensione di classe JAVA in forma basilare è sufficiente andare in:

Files->Rewrite classes-Selezionare la classe da compilare [ ]->Premere il pulsante [compile]

image70

Per editare una classe, Files->Rewrite classes-Selezionare la classe da editare [ ]-> Premere il pulsante [edit] image71

Create JAVA extended class TCP Interceptor

L'utilizzo delle classi di rewriting nei flussi layer 4 TCP mettono a disposizione dell'implementatore uno strumento potentissimo in grado di verificare e/o modificare i valori che attraversano lo strado di instradamento e bilanciamento. Le classi di rewriting permettono anche di effettuare delle considerazioni sui contenuti e instradare in maniera coerente le informazioni.

Il principio su cui si basa l'implementazione delle classi di rewriting Layer 4 TCP è molto semplice. Alla dichiarazione del listener è possibile indicare una classe di rewriting che intercetterà l'innesco proveniente dal client e quindi lo stream bidirezionale full duplex. Di seguito un listener di esempio che si può trovare nel template messo a disposizione nella distribuzione nella directory: (LBL_HOME)/interceptors/rewriteclasses/ rewriteclasses.LBLTCPRWInterceptorSSLCatcher.java.

image72

..indicano la classe che verrà utilizzata nel rewriting.

Le classi di rewriting estendono la classe astratta con 6 metodi di controllo di flusso:

loadbalancer.rewriter.LBLTCPRewriteInterceptorAbstr

Il primo metodo viene richiamato dopo il primo innesco del client che intraprende la richiesta, il secondo metodo viene richiamato ad ogni pacchetto che transita dal client verso l'endpoint ed il terzo metodo viene richiamato ad ogni pacchetto che transita dall'endpoint verso il client. N.B.: I due metodi doPacketFromClient e doPacketFromEndpoint saranno utilizzati in concorrenza in quanto il flusso è full-duplex.

Al primo innesco (doPrimerFromClient), in dipendenza del protocollo, è possibile escludere la lettura del primo pacchetto proveniente dal client attraverso il parametro tcpInterceptorPrimerCapture="false". Questa funzionalità deve essere disabilitata in tutti i casi in cui si sta eseguendo il rewriting di protocolli che non prevedono un innesco da parte del client (es.: telnet). Il parametro tcpInterceptorPrimerCapture non ha alcun effetto se non viene esplicitamente utilizzata una classe di rewriting TCP.

LBLTCPRewriteInterceptorFragment tcpFragment

Il frammento passato nei metodi call-back permette di accede a diverse funzionalità di controllo e modifica di flusso. Di seguito un elenco di alcune delle funzioni messe a disposizione:

/**
* buffer stream getter
* @return buffer stream or null if error
*/
public byte\[\] getStream()

/**
* set a new stream buffer
* @param newBufferStream
* @throws IOException
*/
public void setStream(byte\[\] newBufferStream) throws IOException

/**
* return client host address
* @return client host address or null if not found
*/
public String getRequestClientAddress()

/**
* return incoming host address
* @return incoming host address or null if not found
*/
public String getRequestIncomingAddress()

/**
* return incoming socket
* @return incoming socket or null if not found
*/

public Socket getRequestIncomingSocket()
/**
* return incoming SSLSocket or null if not found or not SSL Socket
* @return incoming SSLSocket or null if not found or not SSL Socket
*/

public SSLSocket getRequestIncomingSSLSocket()
/**
* Session SSL socket connected to the incoming
* @return SSL session connected to the incoming socket,\
* or null if no SSL or non-existent socket
*/

public SSLSession getRequestIncomingSSLSession()
/**
* Peer certificates connected to the incoming socket
* @return Peer certificates connected to the incoming socket,
* or null if no SSL or non-existent socket
*/
public java.security.cert.Certificate[] getRequestIncomingSSLCertificates()

/**
* return incoming host name or address
* @return incoming host host name or address or null if not found
*/
public String getRequestIncomingHostName()

/**
* client ssl connection
* @return true if client ssl connection
*/
public String isSSLClientConnection()

/**
* return endpoint socket
* @return endpoint socket or null if not found
*/
public Socket getResponseEndpointSocket()

/**
* return endpoint SSLSocket or null if not found or not SSL Socket
* @return endpoint SSLSocket or null if not found or not SSL Socket
*/
public SSLSocket getResponseEndpointSSLSocket()

/**
* SSL session connected to the incoming socket endpoint
* @return SSL session endpoints connected to the socket,
* or null if the incoming non-SSL sockets or nonexistent
*/
public SSLSession getResponseEndpointSSLSession()

/**
* Peer certificates connected to the socket endpoint
* @return Peer certificates connected to the socket endpoint,
* or null if no SSL or non-existent socket
*/
public java.security.cert.Certificate[] getResponseEndpointSSLCertificates()

/**
* return endpoint host address
* @return endpoint host address or null if not found
*/
public String getResponseEndpointAddress()

/**
* endpoint ssl connection
* @return true if endpoint ssl connection
*/
public String isSSLEndpointConnection()

/**
* ssl reencryption
* @return true if in ssl reencryption
*/

public String isSSLReencryptionConnection()

Create JAVA extended class UDP Interceptor

L'utilizzo di classi di rewriting nel forwarding dei pacchetti UDP è possibile impostando nel listener il riferimento alla classe di rewriting che si intende utilizzare.

La modalità è simile al rewriting TCP e l'impostazione della classe nel file parametri avviene nella seguente modalità. La classe impostata nell'esempio è compresa nella distribuzione in modalità sorgente nella directory:

(LBL_HOME)/interceptors/rewriteclasses/LBLUDPRewriteInterceptorLogging

image73

Anche con l'UDP è possibile impostare l'affinità di sessione, come da esempio.

image74

Le classi di rewriting UDP estendono la classe con i seguenti metodi da implementare:

loadbalancer.rewriter.LBLUDPRewriteInterceptorAbstr

Dall'oggetto che viene passato come parametro delle funzioni è possibile ispezionare e variare sia i pacchetti che transitano sia variarne la loro destinazione.

Di seguito alcuni metodi messi a disposizione dall'oggetto che viene passato durante l'attraversamento del pacchetto.

/**
* input buffer. This is not a copy of buffer.
* Remind to setPacketLength after used the array.
* @return input buffer
*/
public byte\[\] getPacketByteArray()

/**
* Write pointer of the array
* @return Write pointer of the array
*/
public int getPacketLength()

/**
* Set a write pointer of the array
* @param wp write pointer
*/
public void setPacketLength(int wp)

/**
* endpoint address before rewriting
* @return the endpointAddress
*/
public InetAddress getEndPointAddress()

/**
* endpoint address before rewriting
* @param endPointAddress the endpointAddress to set
*/
public void setEndPointAddress(InetAddress endPointAddress)

/**
* Return a local incoming port
* @return local incoming port
*/
public int getLocalIncomingPort()

/**
* Return a local incoming Inet Address
* @return local incoming Inet Address
*/

public InetAddress getLocalIncomingInetAddress()
/**
* Return the host inet address of the client that sent the packet
* @returnhost inet address of the client that sent the packet
*/

public InetAddress getClientHostAddress()

Oplon ADC: Sviluppo di regole integrato

image75 image76 Attraverso l'interfaccia grafica HTML 5 è possibile gestire l'intero ciclo di sviluppo delle regole evolute. Da interfaccia grafica è possibile eseguire l'editazione, la compilazione, l'import, l'export del codice mantenendo coerenza in caso di installazioni in cluster su più nodi.

Oplon VAPP Developer: Sviluppo di regole integrato

Per uno sviluppo avanzato di regole è disponibile il download gratuito di un ambiente virtuale che permette di sviluppare e provare regole di rewriting prima di applicarle in produzione.

Il sistema è stato concepito per ambienti Enterprise e può essere configurato per supportare processi di certificazione delle regole sviluppate fino alla creazione di ambienti di software versioning, test, stage, e rilascio.

image77

Con Oplon Developer è possibile accentrare politiche di security, sistemi di SSO, integrazioni di terze parti in modo semplice, verificabile passo passo, riproducibile e visuale.

ENABLE REWRITING TRACE

L'abilitazione del trace delle funzionalità di rewriting è possibile attraverso due definizioni allo start della JVM.

E' possibile tracciare solo gli eventi, come il caricamento delle variabili e la verifica delle condizioni, oppure eseguire anche il trace delle trasformazioni apportate.

Per attivare i due trace è possibile utilizzare le seguenti definizioni di start:

-DLBL_DEBUG_REWRITING (abilita il trace del rewriting durante i test delle\ condizioni e il caricamento delle variabili)

-DLBL_DEBUG_ROW_REWRITING (abilita il trace del rewriting dei frammenti di

stream prima e dopo le modifiche

ATTENZIONE: questo flag se abilitato

esegue un log molto voluminoso,

abilitare in fase di debug delle regole)

Per poterli attivare e' necessario in fase di lancio impostare il processo in debug con la definizione -DDEBUG=true eseguire ad es.:

java -server \.... -DDEBUG=true -DLBL_DEBUG_REWRITING=true
-DLBL_DEBUG_ROW_REWRITING=true

Conclusione

Le funzionalità di rewriting implementate in Oplon ADC sono tra le più complete per un mercato professionale. Questo documento, assieme al documento Oplon ADC Reference Guide, danno un'idea della potenza applicabile in diverse situazioni e contesti mantenendo contemporaneamente controllo ed auto documentando quanto sviluppato attraverso la raffinata espressività del paradigma XML o del linguaggio Java.