-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathf5.forward_proxy_v1_02102013.tmpl
2329 lines (2134 loc) · 108 KB
/
f5.forward_proxy_v1_02102013.tmpl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
cli admin-partitions {
update-partition Common
}
sys application template /Common/f5.forward_proxy {
actions {
definition {
html-help {
<p><b>Forward Proxy Template</b></p>
<p>For improved readability, we suggest you click the Launch button to view the Help in a separate, resizable window.</p>
<p>This template creates a complete configuration for using the BigIP LTM as an Forward (Explicit) Proxy. Before you start: </p>
<ul>
<li>Check System :: Resource Provisioning to ensure that LTM (local traffic manager) is
provisioned.</li>
<li>License and provision additional BIG-IP modules (if needed).</li>
<li>Ensure your BigIP system has interfaces on the protected network <i>and</i> on an external-facing network.</li>
<li>Ensure that the BigIP system's routing table has a default route that points towards the Internet through a router on the external-facing network.</li>
</ul>
<p><b>Device and/or Traffic Groups</b></p>
<p>If you select Advanced from the Template selection list, you can select a device group that synchronizes BIG-IP configuration data among devices and a traffic group of related objects that fail over to another device when the current device becomes unavailable.<br />
<b>Note:</b> To use Device and/or Traffic Groups, you must configure them before running this iApp.</p>
<p><b>Advanced Options</b></p>
<p>To enable advanced control features for your explicit proxy, select Yes from the list.</p>
<p>You will need to do this to access the following features:</p>
<ul>
<li>Proxy Autoconfiguration Support</li>
<li>Remote Logging Support</li>
<li>Large Proxy Population Support (SNAT Pools)</li>
</ul>
<p><b>Proxy Configuration</b><br />
<p><i>Virtual Server IP Address</i><br />
<p>Type the IP address clients will use to access the proxy. The system creates a virtual server using this address.</p>
<p><i>Type of Proxy</i><br />
<p>There are three proxy configuration options available to you:</p>
<ul>
<li><b>CONNECT Only</b></li>
</ul>
This proxy type directs all traffic to a web-based proxy and supports SSL transactions using the HTTP CONNECT method.
<ul>
<li><b>SOCKS Only</b></li>
</ul>
This proxy type uses a special method of tagging individual socket requests with a special key. This implementation supports SOCKS versions 4, 4A, and 5. Although SOCKSv5 supports UDP requests, this proxy implementation does not support that mode.
<ul>
<li><b>CONNECT+SOCKS</B></li>
</ul>
This provides both proxy types simultaneously, creating two distinct virtual servers.</p>
<p><i>Ports</i><br />
<p>The default port number for the CONNECT proxy is typically port 80, and for SOCKS is 1080. You should not need to change these values, but if it is required, you may set them here.</p>
<p><i>DNS Server</i><br />
<p>Proxies do need to sometimes resolve hostnames to IP addresses for request coming through. Enter the IP addresses of your resolvers here; they will be added to a pool and a virtual server will be created attached to the proxy to handle lookups. You can add multiple resolvers.<p>
<p><b>Note:</b> These resolvers need to be able to resolve external hostname records.<p>
<p><i>Large Proxy Population Support (Advanced)</i><br />
<p>If the proxy will be used by a large number of users, you will need to define additional addresses on your external network that can be used for address translation to the external network. This option creates a SNAT pool. By default, the proxy will use SNAT Automap, which will result in users' connections appearing to come from the BigIP's Self IP on the external-facing network.
<p><i>DNS Caching Lifetime (Advanced)</i><br />
<p>The proxy will attempt to cache hostnames for a short period of time to eliminate the need to repeatedly execute name resolution. This option is in <b>seconds</b>, and the default cache period is <b>60 seconds</b>.
<p><i>Proxy Debug (Advanced)</i><br />
<p>This option turns on logging of all proxy actions. Use with caution.</p>
<p><b>Security and Access Control</b></p>
<p><i>Network Control</i><br />
<p>By default, the proxy will supply service to any address that can connect to the created virtual server address.</p>
<p>If you wish to restrict which networks can access the external-facing network via the proxy, select this option and then configure the CIDR addresses of each network you wish to allow.</p>
<p><i>Port Control</i><br />
<p>The proxy will be configured to allow ports 80 (HTTP), 443 (HTTPS), and 21 (FTP) by default. The protocols spoken over these connections will be monitored and must match the expected content. Changes to this configuration are not recommended.</p>
<p>However - in some cases - it may be desirable to allow other alternate ports to be accessible through the proxy (e.g. port 8080 as an alternate HTTP port). If you wish to add recognized ports, select this option and add an entry to the desired section.</p>
<p><b>URL Filtering and Inspection</b></p>
<p>If you wish to integrate the proxy with Websense external URL filtering, enable this option.</p>
<p><i>Remote Websense Filtering Servers</i><br />
Supply the addresses of any Websense server configured to run the Filtering Engine. These addresses will be added to a pool which will be used to check all traffic traversing the proxy.</p>
<p><b>Proxy Autoconfiguration Support (Advanced)</b></p>
<p>Enabling this option will cause the proxy to generate a proxy autoconfiguration file to requesting browser clients using the configuration supplied.</p>
<p><i>Plain Names</i><br />
<p>Enabling this option forces browser clients who adopt the configuration to BYPASS the proxy when dealing with hostnames that are not fully-qualified domain names (e.g. "http://website/" rather than "http://www.website.com/").</p>
<p><i>URI Scheme Bypass</i><br />
<p>You may configure what network addresses or URL schemes will bypass the proxy and go directly to the discovered host.</p>
<p>The format of these addresses is in 'glob' style matching. This is represented as the FULL host and scheme portion of the URL being assessed.</p>
<p>For example, to make sure that all HTTPS accesses to in the 10.0.0.0/8 range bypass the proxy, you would enter 'https://10.*' below. To make the bypass occur independent of the scheme requested to the same network, you would enter '*://10.*'.</p>
<p><b>Note:</b> If you have enabled URL Filtering and Inspection support, then the addresses of all configured Websense filter hosts will be automatically added to this list.</p>
<p><i>Hostname Bypass</i><br />
<p>You may configure what hostnames or domains will bypass the proxy and go directly to the discovered host.</p>
<p>The format of these hostnames is in 'glob' style matching.</p>
<p>For example, to make sure that all requested hosts in the test.com domain bypass the proxy, enter '*.test.com'. You may also enter fully-qualified hostnames here as well (e.g., 'www.test.com').</p>
}
implementation {
#################################################################################
### FORWARD PROXY IAPP
### Version: 1.0 - F5 Networks
###
### Makes use of WISP API - Copyright 2013 Websense, Inc. All Rights Reserved.
### Functionality: Supports a generic, anonymous CONNECT or SOCKS proxy.
###
# IAPP SETUP
# Set up initial variables, subroutines and constants needed
# to execute this iApp.
tmsh::include "f5.app_utils"
tmsh::log_dest file
tmsh::log_level crit
set NO_ANSWER "No"
set YES_ANSWER "Yes"
set WAN_OPTION "WAN"
set EMPTY_STRING "EMPTY_STRING_NO_VALUE_PRESENT"
set ADDR_FIELD "addr"
set PORT_FIELD "port"
set RATIO_FIELD "ratio"
set CONNECTION_LIMIT_FIELD "connection_limit"
set HOST_FIELD "host"
set ONE_SPACE " "
set HTTP_11_VERSION_STRING "\"Version 1.1\""
proc tmsh_create { component arguments } {
regsub -all {\"} $arguments "\\\"" arguments
regsub -all {\[} $arguments "\\\[" arguments
regsub -all {\]} $arguments "\\\]" arguments
regsub -all {\$} $arguments "\\\$" arguments
tmsh::run_proc f5.app_utils:do_tmsh_create "\"$component\"" "\"$arguments\""
}
proc tmsh_modify { component arguments } {
regsub -all {\"} $arguments "\\\"" arguments
regsub -all {\[} $arguments "\\\[" arguments
regsub -all {\]} $arguments "\\\]" arguments
regsub -all {\$} $arguments "\\\$" arguments
tmsh::run_proc f5.app_utils:do_tmsh_modify "\"$component\"" "\"$arguments\""
}
proc setup_irules { } {
# PROXY IRULES
# This is the main functionality of the proxy support. There are three
# total iRules here:
# - Proxy Configuration: Contains global variables used to support
# the other iRules
# - Explicit Proxy: Supports a CONNECT-style proxy
# - SOCKS Proxy: Supports a SOCKS 4/4a/5-style proxy
if { [info exists ::proxy__proxy_enable_debug] } {
if { $::proxy__proxy_enable_debug == $::YES_ANSWER } {
set enable_debug 1
} else {
set enable_debug 0
}
} else {
set enable_debug 0
}
####################################################################################################################
###
### START OF PROXY CONFIGURATION SUPPORT IRULE
###
set config_code {
when RULE_INIT {
## HTTP Explicit Proxy - Websense Integrated - v1.0
##
## This iRule will act as a forward (or "explicit") proxy for HTTP requests.
##
## Set the virtual server that this iRule is connected to as the proxy
## server for your web browser. This can handle any HTTP request and also
## FTP and HTTPS requests through the CONNECT method.
##
## Remember to set a SNAT pool in addition to selecting "Address Translation"
## and "Port Translation" in your proxy VIP.
##
## CMP compatible: Yes
##
set static::proxy_brand_${tmsh::app_name} "iProxy-WISP"
set static::proxy_irule_version_${tmsh::app_name} 1.1
# ---------- LOGGING
# Activate debug logging for the proxy. This could fill up your local logs very
# quickly on an actively used proxy, so be careful.
set static::proxy_debug_${tmsh::app_name} ${enable_debug}
# Enable a syslog destination for proxied requests via high-speed logging. This
# should be the name of a pool.
set static::enable_logging_${tmsh::app_name} $::enable_logging
set static::log_destination_${tmsh::app_name} syslog_pool
set static::facility_${tmsh::app_name} 174
# ---------- NAME RESOLUTION
# Set a resolver IP address or a resolver VIP to use. Use the name of the virtual
# you create for you DNS resolver pool here if desired, or set a single IP address to use.
set static::resolver_ip_${tmsh::app_name} "$::resolver_virtual"
# This iRule will cache hostname lookups so the resolver doesn't need to be queried for
# successive accesses. This is independent of the DNS record's TTL, so a shorter time
# here is probably better. Value is in seconds.
set static::resolver_cache_lifetime_${tmsh::app_name} $::proxy_resolver_ttl
# ---------- WEB FILTERING
# Enable Websense filtering support. The WISP server pool must be an F5 pool.
# be an F5 pool. This allows us to use Oneconnect with the server integration
# and reduce the connection setup time to the Websense filter engine.
set static::support_websense_${tmsh::app_name} $::enable_websense
set static::wsp_wisp_pool_${tmsh::app_name} $::websense_server_pool
set static::wsp_wisp_port_${tmsh::app_name} "15868"
# Don't touch this. You have been warned.
set static::wsp_api_version_${tmsh::app_name} 0x0420
# ---------- SECURITY
# Specify a datagroup containing network locations that we do not proxy for. This is
# useful if you want the proxy not to be used to forward to internal networks.
set static::check_access_blocking_${tmsh::app_name} $::enable_acl
set static::block_access_datagroup_${tmsh::app_name} "$::proxy_acl_datagroup_name"
# Set the ports that you wish to allow for the various protocols spoken by this proxy.
# Without this, it's possible to use the CONNECT proxy to forward arbitrary connections
# on all ports, which is bad. It's best to select only well-known ports here.
set static::allow_http_to_ports_${tmsh::app_name} { $::http_ports }
set static::allow_https_to_ports_${tmsh::app_name} { $::https_ports }
set static::allow_ftp_to_ports_${tmsh::app_name} { $::ftp_ports }
# ---------- AUTHENTICATION (APM)
# Use an APM policy set to authenticate and create a session based on the user's
# supplied credentials to the proxy.
#
# If this is not enabled, the proxy will run without requesting authentication
# credentials. If it is enabled, successful logons will be supplied as data to
# both logging and web filtering integrations.
set static::support_apm_${tmsh::app_name} 0
set static::apm_transparent_${tmsh::app_name} 0
# ---------- PROXY AUTOCONFIGURATION
# When enabled, causes the proxy to be able to respond to PAC file requests for both
# standard PAC and WPAD .dat configurations. It builds the PAC file content dynamically
# based on user requirements.
#
# If your proxy setup has a registered hostname, then you should set it here --
# otherwise, you can safely use the IP address. Use of a hostname is valuable if you
# have multiple on-network proxies and want the user to select from the group.
set static::support_proxy_autoconfiguration_${tmsh::app_name} $::enable_pac
set static::proxy_name_${tmsh::app_name} "$::proxy__proxy_ip"
set static::plain_name_direct_${tmsh::app_name} $::enable_plainname
set static::direct_networks_${tmsh::app_name} { $::autoconfig_dn }
set static::direct_hostnames_${tmsh::app_name} { $::autoconfig_dh }
set static::proxy_autoconfig_base_${tmsh::app_name} {
function FindProxyForURL(url, host) {
\${plainname_section}
\${network_section}
\${hostname_section}
return "PROXY \$\{static::proxy_name_${tmsh::app_name}\}:\${proxy_port}";
}
}
# ---------- ERROR PAGES
# You can change these to suit your tastes, but do not change the variables
# contained within the page content.
#
# Error to display when the hostname lookup fails to resolve to an IP address.
set static::host_not_found_error_${tmsh::app_name} {
<!DOCTYPE html>
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Error: host not found.</title>
<style>
\$\{static::embedded_css_${tmsh::app_name}\}
</style>
</head><body id="pageBody">
<div style="clear: both; overflow: hidden; height=1px;"></div>
<!--\\\[if lt IE 7\\\]> <div style="width: 725px;"> <!\\\[endif\\\]-->
<div style="border: 1px solid #285EA6; width: 95%; max-width: 700px; overflow: hidden; margin-top: 1px; margin-left: 10px; background-color: #EEF2F7;">
<div id="openWindow">
<h1 class="error">Error: Host not found.</h1>
<p class="label">Reason:</p>
<p class="first-option" id="reason-text" style="display: block;">Your request has been cancelled because this system could not locate an address for the website you entered. Please check your website address and retry your request.</p> <div id="options">
<p class="label">URL/Host:</p>
<p id="url-text">\${host}</p>
<div id="options">
<p class="label">Options:</p>
<form class="first-option" name="BackForm" action="">
<p>Click <b>Go Back</b> or use the browser's Back button to return to the previous page. <input type="button" value=" Go Back " onClick="javascript:history.back()" name="ws-back"></p>
</form>
</div>
<div>
<address style="float: right; padding-top: 180px;"><font color="grey" size=-4>\$static::proxy_brand_${tmsh::app_name}/\$static::proxy_irule_version_${tmsh::app_name}</font></address>
</div>
</div>
</div>
<!--\\\[if lt IE 7\\\]> </div> <!\\\[endif\\\]-->
<div id="light" class="white_content"></div>
<div id="fade" class="black_overlay"></div>
<div style="clear: both;"></div>
</body></html>
}
# Error to display when the remote host does not appear to respond to the user's
# request.
set static::host_not_responding_error_${tmsh::app_name} {
<!DOCTYPE html>
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Error: host not responding.</title>
<style>
\$\{static::embedded_css_${tmsh::app_name}\}
</style>
</head><body id="pageBody">
<div style="clear: both; overflow: hidden; height=1px;"></div>
<!--\\\[if lt IE 7\\\]> <div style="width: 725px;"> <!\\\[endif\\\]-->
<div style="border: 1px solid #285EA6; width: 95%; max-width: 700px; overflow: hidden; margin-top: 1px; margin-left: 10px; background-color: #EEF2F7;">
<div id="openWindow">
<h1 class="error">Error: Host not responding.</h1>
<p class="label">Reason:</p>
<p class="first-option" id="reason-text" style="display: block;">Your request has been cancelled because this system could not connect to the website you entered. This could be due to network conditions or the site could be down. Please check your website address and retry your request.</p>
<p class="label">URL/Host:</p>
<p id="url-text">\${host}</p>
<div id="options">
<p class="label">Options:</p>
<form class="first-option" name="BackForm" action="">
<p>Click <b>Go Back</b> or use the browser's Back button to return to the previous page. <input type="button" value=" Go Back " onClick="javascript:history.back()" name="ws-back"></p>
</form>
</div>
<div>
<address style="float: right; padding-top: 180px;"><font color="grey" size=-4>\$static::proxy_brand_${tmsh::app_name}/\$static::proxy_irule_version_${tmsh::app_name}</font></address>
</div>
</div>
</div>
<!--\\\[if lt IE 7\\\]> </div> <!\\\[endif\\\]-->
<div id="light" class="white_content"></div>
<div id="fade" class="black_overlay"></div>
<div style="clear: both;"></div>
</body></html>
}
# Error to display if the request remote host is on the list of networks to
# disallow through the proxy.
set static::host_disallowed_error_${tmsh::app_name} {
<!DOCTYPE html>
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Error: host not allowed.</title>
<style>
\$\{static::embedded_css_${tmsh::app_name}\}
</style>
</head><body id="pageBody">
<div style="clear: both; overflow: hidden; height=1px;"></div>
<!--\\\[if lt IE 7\\\]> <div style="width: 725px;"> <!\\\[endif\\\]-->
<div style="border: 1px solid #285EA6; width: 95%; max-width: 700px; overflow: hidden; margin-top: 1px; margin-left: 10px; background-color: #EEF2F7;">
<div id="openWindow">
<h1 class="security">Error: Host not allowed.</h1>
<p class="label">Reason:</p>
<p class="first-option" id="reason-text" style="display: block;">Your request has been cancelled your network administrators do not allow connections from your network. Please check your configuration and if you feel you have reached this page in error, retry your request.</p>
<p class="label">URL/Host:</p>
<p id="url-text">\${host}</p>
<div id="options">
<p class="label">Options:</p>
<form class="first-option" name="BackForm" action="">
<p>Click <b>Go Back</b> or use the browser's Back button to return to the previous page. <input type="button" value=" Go Back " onClick="javascript:history.back()" name="ws-back"></p>
</form>
</div>
<div>
<address style="float: right; padding-top: 180px;"><font color="grey" size=-4>\$static::proxy_brand_${tmsh::app_name}/\$static::proxy_irule_version_${tmsh::app_name}</font></address>
</div>
</div>
</div>
<!--\\\[if lt IE 7\\\]> </div> <!\\\[endif\\\]-->
<div id="light" class="white_content"></div>
<div id="fade" class="black_overlay"></div>
<div style="clear: both;"></div>
</body></html>
}
# Error to display if the request remote host is on the list of networks to
# disallow through the proxy.
set static::port_disallowed_error_${tmsh::app_name} {
<!DOCTYPE html>
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Error: port not allowed.</title>
<style>
\$\{static::embedded_css_${tmsh::app_name}\}
</style>
</head><body id="pageBody">
<div style="clear: both; overflow: hidden; height=1px;"></div>
<!--\\\[if lt IE 7\\\]> <div style="width: 725px;"> <!\\\[endif\\\]-->
<div style="border: 1px solid #285EA6; width: 95%; max-width: 700px; overflow: hidden; margin-top: 1px; margin-left: 10px; background-color: #EEF2F7;">
<div id="openWindow">
<h1 class="security">Error: Port request not allowed.</h1>
<p class="label">Reason:</p>
<p class="first-option" id="reason-text" style="display: block;">Your request has been cancelled your network administrators do not allow connections via this port. Please check your configuration and/or website address and if you feel you have reached this page in error, retry your request.</p>
<p class="label">URL/Host:</p>
<p id="url-text">\${host}:\${port}</p>
<div id="options">
<p class="label">Options:</p>
<form class="first-option" name="BackForm" action="">
<p>Click <b>Go Back</b> or use the browser's Back button to return to the previous page. <input type="button" value=" Go Back " onClick="javascript:history.back()" name="ws-back"></p>
</form>
</div>
<div>
<address style="float: right; padding-top: 180px;"><font color="grey" size=-4>\$static::proxy_brand_${tmsh::app_name}/\$static::proxy_irule_version_${tmsh::app_name}</font></address>
</div>
</div>
</div>
<!--\\\[if lt IE 7\\\]> </div> <!\\\[endif\\\]-->
<div id="light" class="white_content"></div>
<div id="fade" class="black_overlay"></div>
<div style="clear: both;"></div>
</body></html>
}
# Error to display if the request remote host uses an unrecognized/unsupported
# method.
set static::unrecognized_method_error_${tmsh::app_name} {
<!DOCTYPE html>
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Error: host not allowed.</title>
<style>
\$\{static::embedded_css_${tmsh::app_name}\}
</style>
</head><body id="pageBody">
<div style="clear: both; overflow: hidden; height=1px;"></div>
<!--\\\[if lt IE 7\\\]> <div style="width: 725px;"> <!\\\[endif\\\]-->
<div style="border: 1px solid #285EA6; width: 95%; max-width: 700px; overflow: hidden; margin-top: 1px; margin-left: 10px; background-color: #EEF2F7;">
<div id="openWindow">
<h1 class="security">Error: Method not allowed.</h1>
<p class="label">Reason:</p>
<p class="first-option" id="reason-text" style="display: block;">Your request has been cancelled your network administrators do not allow this method to access remote sites. Please check your configuration and if you feel you have reached this page in error, retry your request.</p>
<p class="label">URL/Host:</p>
<p id="url-text">\${host}</p>
<div id="options">
<p class="label">Options:</p>
<form class="first-option" name="BackForm" action="">
<p>Click <b>Go Back</b> or use the browser's Back button to return to the previous page. <input type="button" value=" Go Back " onClick="javascript:history.back()" name="ws-back"></p>
</form>
</div>
<div>
<address style="float: right; padding-top: 180px;"><font color="grey" size=-4>\$static::proxy_brand_${tmsh::app_name}/\$static::proxy_irule_version_${tmsh::app_name}</font></address>
</div>
</div>
</div>
<!--\\\[if lt IE 7\\\]> </div> <!\\\[endif\\\]-->
<div id="light" class="white_content"></div>
<div id="fade" class="black_overlay"></div>
<div style="clear: both;"></div>
</body></html>
}
# CSS to be embedded in each error page. You can modify this to suit your environment.
# By default, it resembles the standard Websense block page.
set static::embedded_css_${tmsh::app_name} {
body { font-family: Arial, Helvetica, sans-serif; font-size: 12pt; padding: 0px;
background: #EEF2F7 5px 5px no-repeat; margin: 5px 7px;
}
h1 {
font-size: 1.2em;
border-bottom: 1px solid #8c8c8c;
padding-bottom: 6px;
margin: 0px 0px 15px 30px;
}
h1.security {
border: 0px;
background: #faf8c9 url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAMAAAAM7l6QAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAwBQTFRF/4xT3AEB/51q5Sga3R4e96CK3gsI9tWt9vb1/7SU84xk/ayS3hER/rqo/rKC+Om9/6t6+/v66GlU7u7q9XxK7KJ29MOe63pj/2pB6X5a+uzs82I57Yls3Csr5ubm872Z/VIl2tra/PDu6z4o60It6FY59XNF8Vgw5opl75x+/69+9dKq/66F/6Bq/7qi+NLN+q1+6GZT/4FP76GD/4tr+/Ty+ubk/Vkt8rOR/3RN/pFg/pdn9r6+62ZH7l9C7WFI/39M8ZWF81o4+e7B8q5/9Mul/o5d5pRv9czM7Y1zzc3N6nZe+7On9ql54x4V+IBO6WVS6mRN+vjJ/////6Z1/5NX/6d3/4dV/5lf+M/P+a6k/7uo/4xb/04f/76r+vXG/v7+/6Jw/5lg7pZ68a6N/4VP9+K3/4hR/Ipd/bio9c+o8bCP8reU8KmJ6WVQ/f38/3xK992z1dXV9+O49KCW/4JN9tiw0pub+/v7+6Rz656Q63pQ/6uI6o9i/6OD+M7H9+zq6GdT8Fs9+ad39Vst+tvU6K+i4uLiyLu78XZX+X9W/3lJ6Xlf8bq60dHR721K5Zxy7ZF272hN7qBz8JOI+fPF6G1t+OW675iN6cDA6+rn85+V72FE82hH8GtN72xQ+aqa9LKu5Ydm6YZm1Wdn7INr86Sk96uk8oVW9Kur9IFe5npf8I596XRU/YBb9LGx7IdZ9Ly28KeH7U028V9B48i+9m4//GE1/20991Il+aeN/1cp+YRT/oFR+vr65aB19c2m7qd591Yx/7Sf+5Jj/JVj/beo5Y9/7oNx/qV0+49e/ohZ/25H63Fx9q1+6WhS7Zdo6WtV7GpS/5h29JB09pR4+6h4+Jt72rGx5WZM75xu73lK83xV/31Z+HxM7mlH9rCA9/f34djR+qNz+6Bu8/Pz66l7+fHD96eZ/ryq8qye8pyK/YBO/4FM4jAw6+Xi6mZQ63197U0r51FR5l5e6Hpb84Vj73lc893b9Mii8Y1p/4ho76qq/4Zm81096mpNhgtE7AAAAFN0Uk5T/////////////////////////////////////////////////////////////////////////////////////////////////////////////wBmiX5ZAAACfElEQVR42mIIwgsYwCR/SpYzkIovs8hmfw5kOLNbpCGk2QOd7AINDQ0D7J2c7POAjDx7J3sxuLTmIZMz5rGxsQoSf39LKAAZu8/8VpCBScvPsYzGAHebsqHSS825X/JGAUHmSxDwAbKOvTy8MyAeLK1tbxn3clkkEKz0iYuLW24DZK3PjFtnJwaWNpa+rKf3Qj84ONisRE9vwcLg4IQfQEaduidYWnx7DScnt6NZfnDwRlbuKUrBHO9n7OLk5GwxjAdK83/YoQME1x1N84NN11ypDxacVXUVJKIWWAaUZp/UHQYCXK8qEoJbXwcHz2r7Bha4ZysGlHad5KALAkz9+oJA+4OFt94/Chbwt80BSovNM4oAA39VpYrgYI5HN0WSIiKSkpL8bS2A0gfmv2UIBQPpE0DN+45LQ3gMIv/lgdKFlwoKHEpT09MZPs0GGd7AvC09PbXUoUDtfxZQOr5xrxEYKH8ODn4IdN4fZjD3ze3z/CB/e3aFg4ATj1Kw3I2Z+4KDv6iA+HuqxcHBIt8ZAwSnmW2CnxbJyj6sCJZi+QcUWLE2FyztLGQFBMpng4MVlygrf3yYENzL7GZ1asPFYkiM5a6ytm56FxwsV86ckeHnATR+mrI1l2QyNEKnX7Q+wuPR7tXBMpeJacs7Ra++Itk7tRe1Yakl5fuTOX6MjGybE4FAhREIVC583YRIisZcj0+GIIHKWxqNUxHShZq/mgUQ4NpkDSFXpIQcVKYp42ugBQW+ohqNrsjpPCgozdh78jk+EDA4OGF1snYQqnRQUI7QYlGXBy7P9i8SSkHLJWDgbOHd4+6+WmhTcRA2aSDISp74Mx4zj+EEAAEGAGf5Qi4arzP2AAAAAElFTkSuQmCC) 5px 3px no-repeat;
margin: 5px 5px 15px 5px;
padding: 7px 7px;
text-indent: 33px;
}
h1.error {
border: 0px;
background: #ffffff url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAMAAAAM7l6QAAAAA3NCSVQICAjb4U/gAAAB5lBMVEX//////PH39/f38/Lw9Pj/8ufx8vXv8/ju8vfu8fTv7+/p7fHm5ub/4dbh4ePb4OTe3t7a3eD/0MTV2dzX2NnQ19rO19vV1tfO1djQ09T/wrfOz8/Izc7HzdDuwLbbxLv/ubD/taW8xMXRv7bAwcD/rKPHurK6vcC0vb24ur24urzjqJ+vs7X/mZn/lI2qq6ylqKf/j4mkpab2j4iapqacpKX+i4Swm5Ppi4T+g32VnZ6Ompnng37/fHXcg3zRhoCOlpaMlpbVgXv/dnDAhn+yioH/cmt+j4+Fi4t/jIuEior/Zmb/ZF51h4Z+gX9wgYD+WlR1e3p4eXf/U0//UExrdHOuYlxtcG+gYFr/REKjWFRmZmb/PDjlQT+QVVFkYFppXFb/MzO6RD+oSEOGUU1fWlVOXV5SW1nwMC2ES0X/KSZVVVVOVlKqPjqXQj7/IyGuNzRTUEqdOzb/Hxw5TE1TQz//EhGxJySHMCw2RUb1EA5FQDuGKig7OjU0OztLNDFnKCQpOTkrNjQzMzMgNjUrNDIhNDOgDw46JSEqKSUSLSwcKipZGhYxJB8nJCEWKCQfIyCOAQEnHhtKEg8XHBxEDw8QGBhmAABQBQVVAAATDw9KAAAAEhFDAAAaCgkRCAcHBwUAAAD4wBcmAAAACXBIWXMAAA50AAAOdAFrJLPWAAAAFnRFWHRDcmVhdGlvbiBUaW1lADA4LzIxLzA3cSoIoQAAABh0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzT7MfTgAABBF0RVh0WE1MOmNvbS5hZG9iZS54bXAAPD94cGFja2V0IGJlZ2luPSIgICAiIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNC4xLWMwMzQgNDYuMjcyOTc2LCBTYXQgSmFuIDI3IDIwMDcgMjI6Mzc6MzcgICAgICAgICI+CiAgIDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+CiAgICAgIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICAgICAgICAgIHhtbG5zOnhhcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyI+CiAgICAgICAgIDx4YXA6Q3JlYXRvclRvb2w+QWRvYmUgRmlyZXdvcmtzIENTMzwveGFwOkNyZWF0b3JUb29sPgogICAgICAgICA8eGFwOkNyZWF0ZURhdGU+MjAwNy0wOC0yNFQyMTo0Mzo1MVo8L3hhcDpDcmVhdGVEYXRlPgogICAgICAgICA8eGFwOk1vZGlmeURhdGU+MjAwNy0wOC0yNFQyMTo0NDoyN1o8L3hhcDpNb2RpZnlEYXRlPgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIj4KICAgICAgICAgPGRjOmZvcm1hdD5pbWFnZS9wbmc8L2RjOmZvcm1hdD4KICAgICAgPC9yZGY6RGVzY3JpcHRpb24+CiAgIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCOReQAAAAVBJREFUKJFj4MALGAhKN2MCFGkGdDBcpJnQAUnSzAggGa4CJJtZvAJZ4NJccMATVB0tycXVrFnbZ8WCKR0Ur5aQI8KV3RoRNsGEHU2azy9VnlGuNN2gKVNXL2+CPjs7OwM7O1w6qFCZVUpIu7Q/RdfS2bZmmg5ENw8UeBWa80opKtjHGZs5u/n01GmhSvM41roKqerq6lk6u3lPbhPnQJPm8ap1UdUzA8k2dMnAnMYHBzyhnU5gvRVzlNg5MKXT6m3MbN18fApm+cKlBWCAL63DwhCoNyAkpHy+Ozu6dGivjR5INjgyJqZ9lgNUWgQKonvtdJ3d3IqmxkYmZuVPnGaEmpCzm6PM3Nxyp7RMzcgqrppRKY2WDUwnJNsmLfAUbJtbXDa7hB8jl1hPqpnnz8Ym0ThzeqMYB4Y0h8fCUE4gJdvdL8qBRZrbQBhMq2tA+AAvEXlj6e+ckgAAAABJRU5ErkJggg==) 5px 3px no-repeat;
margin: 5px 5px 15px 5px;
padding: 7px 7px;
border-bottom: 1px solid #8c8c8c;
text-indent: 33px;
}
p {
font-size: 90%;
margin-top: 0;
margin-bottom: 10px;
margin-left: 5px;
text-indent: 2px;
}
span.warning {
background: #faf8c9;
border: 1px solid #c4c17b;
margin-left: 10px;
padding: 2px;
white-space: no-wrap;
}
#options {
width: 100%;
border-top: 1px solid #d7w1ec;
border-bottom: 1px solid #d7w1ec;
background: #ffffff;
padding: 6px 0px 6px 0px;
clear: both;
}
.first_option {padding-top: 1px; margin: 0px 5px 10px 100px;}
.label {display: block; float: left; height: 30px; width: 100px; font-weight: bold;}
.black_overlay {
display: none;
position: absolute;
top: 0%;
left: 0%;
width: 100%;
height: 100%;
background-color: black;
z-index:1001;
-moz-opacity:.80;
opacity:.80;
filter: alpha(opacity=80);
}
.white_content {
display: none;
position: absolute;
top: 25%
left: 25%;
width: 25%;
height: 260px;
background-color: white;
zindex:1002;
overflow: auto;
}
.header {
background: black;
color: white;
padding: 4px;
font-weight: bold;
}
}
}
}
###
### END OF PROXY CONFIGURATION SUPPORT IRULE
###
####################################################################################################################
####################################################################################################################
###
### START OF EXPLICIT PROXY SUPPORT IRULE
###
set explicit_proxy_code {
when CLIENT_ACCEPTED {
# Unset everything on a new client connection.
set is_connect 0
set is_http 0
set is_https 0
set error_occurred 0
set auth_holddown 0
set request_log_line ""
if { \$static::support_websense_${tmsh::app_name} } {
set disable_websense_lookups 0
foreach {a b c d} \[split \[IP::client_addr\] .\] break
set wsp_src_ip \[expr {(wide(\$a)<<24)+(\$b<<16)+(\$c<<8)+\$d}\]
if { \[active_members \$\{static::wsp_wisp_pool_${tmsh::app_name}\} ] > 0 } {
set wsp_list_cmd { set wsp_active_server_list \[active_members -list \$\{static::wsp_wisp_pool_${tmsh::app_name}\} \] }
eval \$wsp_list_cmd
set wsp_member_selection \[lindex \[lindex \$wsp_active_server_list \[expr { \[crc32 \[IP::client_addr\] \] % \[llength \$wsp_active_server_list\] } \] \] 0 \]
if { not \[catch {connect -timeout 100 -idle 30 -status wsp_conn_status \$\{wsp_member_selection\}:\$\{static::wsp_wisp_port_${tmsh::app_name}\}} wsp_conn\] == 0 && \$wsp_conn ne "" } {
if { \$static::proxy_debug_${tmsh::app_name} } { log local0. "Websense server not connecting." }
set disable_websense_lookups 1
}
} else {
set disable_websense_lookups 1
}
}
# Set up a logging handle for the context of this stream.
if { \$static::enable_logging_${tmsh::app_name} } {
set logging_handle \[HSL::open -proto UDP -pool \$\{static::log_destination_${tmsh::app_name}\} \]
}
}
when HTTP_REQUEST {
# If proxy autoconfig files are requested and we are configured to hand them out, use
# the predefined rules and generate a config file to hand out to the user.
if { \$static::support_proxy_autoconfiguration_${tmsh::app_name} } {
if { \[string tolower \[HTTP::uri\]\] equals "/proxy.pac" || \[string tolower \[HTTP::uri\]\] equals "/wpad.dat"} {
if { \$static::plain_name_direct_${tmsh::app_name} } {
set plainname_section " if (isPlainHostName(host))\\r\\n"
append plainname_section " return \\\"DIRECT\\\";\\r\\n"
} else {
set plainname_section ""
}
set network_section_length \[llength \$static::direct_networks_${tmsh::app_name}\]
set network_section_count 1
if { \$network_section_length > 0 } {
set network_section " if ("
foreach netitem \$static::direct_networks_${tmsh::app_name} {
append network_section "shExpMatch(url, \\"\$netitem\\")"
if { \$network_section_count == \$network_section_length } {
append network_section ")\\r\\n"
append network_section " return \\\"DIRECT\\\";\\r\\n"
} else {
append network_section " || \\r\\n "
incr network_section_count
}
}
} else {
set network_section ""
}
set hostname_section_length \[llength \$static::direct_hostnames_${tmsh::app_name}\]
set hostname_section_count 1
if { \$hostname_section_length > 0 } {
set hostname_section " if ("
foreach netitem \$static::direct_hostnames_${tmsh::app_name} {
append hostname_section "dnsDomainIs(host, \\"\$netitem\\")"
if { \$hostname_section_count == \$hostname_section_length } {
append hostname_section ")\\r\\n"
append hostname_section " return \\\"DIRECT\\\";\\r\\n\\r\\n"
} else {
append hostname_section " || \\r\\n "
incr hostname_section_count
}
}
} else {
set hostname_section ""
}
set proxy_port \[TCP::local_port\]
HTTP::respond 200 content \[subst \$static::proxy_autoconfig_base_${tmsh::app_name}\] Content-Type "application/x-ns-proxy-autoconfig" Connection "close" Pragma "no-cache"
HTTP::release
TCP::close
return
}
}
# Clear all previous HTTP request items.
set host ""
set port ""
set new_path ""
set prefix ""
if { \$static::support_websense_${tmsh::app_name} } {
set wsp_message_body ""
set wsp_message_out ""
set wsp_username ""
set wsp_username_length 0
set wsp_recv_message_length 0
set wsp_message_length 0
set wsp_uri_length 0
}
if { \$static::proxy_debug_${tmsh::app_name} } { log local0.info "HTTP::method: \[HTTP::method\]: HTTP::request : \[HTTP::request\]"}
# First check to see what method we're handling through the proxy.
# We need to process CONNECT a little differently than other HTTP proxy
# methods, and we need to discard requests that come through with
# unsupported methods.
# Coming out of this section will be:
# - \$host : hostname or bare IP address requested
# - \$port : port of the connection requested
# - \$new_path : normalized URI with the proxy format stripped
switch -- \[HTTP::method\] {
"CONNECT" {
set is_http 0
set is_https 0
set request_log_line ""
set original_request \[HTTP::uri\]
set host \[string tolower \[getfield \[HTTP::uri\] ":" 1\]\]
set port \[getfield \[HTTP::uri\] ":" 2\]
if {\$port eq ""}{
set port 443
}
set new_path \[HTTP::uri\]
HTTP::header remove "Proxy-Connection"
HTTP::cookie remove "MRHSession"
if { \$static::proxy_debug_${tmsh::app_name} } { log local0. "Connect request from \$host to \$port." }
set http_version \[HTTP::version\]
set is_connect 1
set is_https 1
}
"GET" -
"PUT" -
"POST" -
"HEAD" -
"PROPFIND" -
"PROPPATCH" -
"MKCOL" -
"DELETE" -
"COPY" -
"MOVE" -
"LOCK" -
"UNLOCK" {
set is_http 0
set is_https 0
set request_log_line ""
set original_request \[HTTP::uri\]
set scheme \[string tolower \[getfield \$original_request ":" 1\]\]
set host \[string tolower \[getfield \[findstr \$original_request "//" 2 "/"\] ":" 1\]\]
if { \$host contains "@" } {
set host_username ""
set host_username \[getfield \$host "@" 1\]
set host \[getfield \$host "@" 2\]
if { \$host_username contains ":" } {
set host_password \[getfield \$host_username ":" 1\]
set host_username \[getfield \$host_username ":" 2\]
}
}
#FIX
set port \[getfield \[findstr \$original_request "//" 2 "/"\] ":" 2\]
if { \$port eq "" } {
if { \[info exists host_username\] } {
set prefix "\$\{scheme\}://\$\{host_username\}@\$\{host\}"
} else {
set prefix "\$\{scheme\}://\$\{host\}"
}
} else {
if { \[info exists host_username\] } {
set prefix "\$\{scheme\}://\$\{host_username\}@\$\{host\}:\$\{port\}"
} else {
set prefix "\$\{scheme\}://\$\{host\}:\$\{port\}"
}
}
set new_path \[findstr \$original_request \$prefix \[string length \$prefix\] \]
if {\$port eq ""}{
set port 80
}
HTTP::uri \$new_path
HTTP::header remove "Proxy-Connection"
HTTP::cookie remove "MRHSession"
if { \$static::proxy_debug_${tmsh::app_name} } { log local0. "Get request from \$host to \$port. Altering from \$prefix to \$new_path" }
set http_version \[HTTP::version\]
set is_http 1
}
default {
set requested_method \[HTTP::method\]
set error_occurred 1
HTTP::respond 405 content \[subst \$static::unrecognized_method_error_${tmsh::app_name}\] Mime-Type "text/html"
return
}
}
# Check to see if the host provided by the browser client is an
# IP address or a hostname. If it's an IP address, we're going to
# forgo any DNS lookups.
if { ! \[catch {IP::addr \$host mask 255.255.255.255}\] } {
set _ipaddress \$host
set is_ipaddress 1
} else {
set _ipaddress \[table lookup \$host\]
switch -exact -- \$_ipaddress {
"" -
"NO_IP" {
set is_ipaddress 0
}
default {
set is_ipaddress 1
}
}
set is_ipaddress \[expr { (\$_ipaddress ne "") || (\$_ipaddress equals "NO_IP") }\]
}
# We don't want to arbitrarily allow any port through the proxy. If a request comes
# through that isn't on a list we expect to see for each mode (CONNECT vs. Normal),
# then abort and inform the user what they did.
if { (\$is_connect) } {
if { (\$is_https) && ( \[lsearch -exact \$static::allow_https_to_ports_${tmsh::app_name} \$port \] < 0 ) } {
set error_occurred 1
if { \$static::proxy_debug_${tmsh::app_name} } { log local0.info "Port request for \$host:\$port disallowed by ACL for HTTPS mode. Sending HTTP response error" }
if { \$static::enable_logging_${tmsh::app_name} } {
HSL::send \$logging_handle "<\$\{static::facility_${tmsh::app_name}\}> \[IP::client_addr\] -> \$host:\$port \\\"CONNECT \$new_path HTTP/\$http_version\\\" 403 -"
}
catch {TCP::respond "HTTP/1.1 403 Not Allowed\r\nMime-Type: text/html\\r\\nCache-Control: no-cache,no-store\\r\\nConnection: close\\r\\nContent-Length: \[string length \[subst \$static::port_disallowed_error_${tmsh::app_name}\]\]\\r\\n\\r\\n\[subst \$static::port_disallowed_error_${tmsh::app_name}\]\\r\\n\\r\\n"}
return
}
} else {
if { (\$is_http) && ( \[lsearch -exact \$static::allow_http_to_ports_${tmsh::app_name} \$port \] < 0 ) } {
set error_occurred 1
if { \$static::proxy_debug_${tmsh::app_name} } { log local0.info "Port request for \$host:\$port disallowed by ACL for HTTP mode. Sending HTTP response error" }
if { \$static::enable_logging_${tmsh::app_name} } {
HSL::send \$logging_handle "<\$\{static::facility_${tmsh::app_name}\}> \[IP::client_addr\] -> \$host:\$port \\\"\[HTTP::method\] \$new_path HTTP/\[HTTP::version\]\\\" 403 -"
}
HTTP::respond 403 content \[subst \$\{static::port_disallowed_error_${tmsh::app_name}\} \] Mime-Type text/html Cache-Control "no-cache,no-store"
return
}
}
# If we're handling a CONNECT request, we've got to pretend like the
# the connection is moving so the browser doesn't time out. This is less
# than ideal, but works even with poorly written clients.
#
# We zero out any TCP payload and disable HTTP processing because from this
# point forward we're basically letting the connection talk directly to
# the remote server. This response will only fire when the server connects.
if { \$is_connect } {
TCP::payload replace 0 \[TCP::payload length\] ""
TCP::collect
HTTP::disable discard
if { \$is_ipaddress } {
if { (\$static::check_access_blocking_${tmsh::app_name}) } {
if { not \[class match \[IP::client_addr\] equals \$static::block_access_datagroup_${tmsh::app_name}]\ } {
if { \$static::proxy_debug_${tmsh::app_name} } { log local0.info "ACL failed: \$host. Sending HTTP response error" }
catch {TCP::respond "HTTP/1.1 403 Not Allowed\r\nMime-Type: text/html\\r\\nCache-Control: no-cache,no-store\\r\\nConnection: close\\r\\nContent-Length: \[string length \[subst \$static::host_disallowed_error_${tmsh::app_name}\]\]\\r\\n\\r\\n\[subst \$static::host_disallowed_error_${tmsh::app_name}\]\\r\\n\\r\\n"}
return
} else {
node \$_ipaddress \$port
}
} else {
node \$_ipaddress \$port
}
} else {
if { \$static::proxy_debug_${tmsh::app_name} } { log local0.info "Got hostname: \$host, calling resolver..." }
set ips \[RESOLV::lookup @\$static::resolver_ip_${tmsh::app_name} -a \$host\]
if { \$static::proxy_debug_${tmsh::app_name} } {log local0.info "\$host NAME::response: \$ips"}
set _ipaddress \[lindex \$ips 0\]
if { (\$_ipaddress equals "") || (\$_ipaddress equals "NO_IP") } {
if { \$_ipaddress equals "" } {
set error_occurred 1
table add \$host "NO_IP" \$static::resolver_cache_lifetime_${tmsh::app_name}
if { \$static::proxy_debug_${tmsh::app_name} } { log local0.info "DNS resolution failed for hostname: \$host. Sending HTTPS response error" }
if { \$static::enable_logging_${tmsh::app_name} } {
HSL::send \$logging_handle "<\$\{static::facility_${tmsh::app_name}\}> \[IP::client_addr\] -> \$host:\$port \\\"CONNECT \$new_path HTTP/\$http_version\\\" 504 -"
}
catch {TCP::respond "HTTP/1.1 504 Not Allowed\\r\\nMime-Type: text/html\\r\\nCache-Control: no-cache,no-store\\r\\nConnection: close\\r\\nContent-Length: \[string length \[subst \$static::host_not_found_error_${tmsh::app_name}\]\]\\r\\n\\r\\n\[subst \$static::host_not_found_error_${tmsh::app_name}\]\\r\\n\\r\\n"}
return
} else {
set error_occurred 1
if { \$static::proxy_debug_${tmsh::app_name} } { log local0.info "DNS resolution failed for hostname (from cache): \$host. Sending HTTPS response error" }
if { \$static::enable_logging_${tmsh::app_name} } {
HSL::send \$logging_handle "<\$\{static::facility_${tmsh::app_name}\}> \[IP::client_addr\] -> \$host:\$port \\\"CONNECT \$new_path HTTP/\$http_version\\\" 504 -"
}
catch {TCP::respond "HTTP/1.1 504 Not Allowed\\r\\nMime-Type: text/html\\r\\nCache-Control: no-cache,no-store\\r\\nConnection: close\\r\\nContent-Length: \[string length \[subst \$static::host_not_found_error_${tmsh::app_name}\]\]\\r\\n\\r\\n\[subst \$static::host_not_found_error_${tmsh::app_name}\]\\r\\n\\r\\n"}
return
}
} else {
table add \$host \$_ipaddress \$static::resolver_cache_lifetime_${tmsh::app_name}
if { (\$static::check_access_blocking_${tmsh::app_name}) } {
if { not \[class match \[IP::client_addr\] equals \$static::block_access_datagroup_${tmsh::app_name}\] } {
if { \$static::proxy_debug_${tmsh::app_name} } { log local0.info "ACL failed: \$host. Sending HTTP response error" }
catch {TCP::respond "HTTP/1.1 403 Not Allowed\\r\\nMime-Type: text/html\\r\\nCache-Control: no-cache,no-store\\r\\nConnection: close\\r\\nContent-Length: \[string length \[subst \$static::host_disallowed_error_${tmsh::app_name}\]\]\\r\\n\\r\\n\[subst \$static::host_disallowed_error_${tmsh::app_name}\]\\r\\n\\r\\n"}
if { \$static::enable_logging_${tmsh::app_name} } {
HSL::send \$logging_handle "<\$\{static::facility_${tmsh::app_name}\}> \[IP::client_addr\] -> \$host:\$port \\\"CONNECT \$new_path HTTP/\$http_version\\\" 403 -"
}
return
} else {
set original_request "https://\[getfield \$\{original_request\} ":" 1\]"
if { \$static::support_websense_${tmsh::app_name} } {
if { not \$disable_websense_lookups } {
foreach {a b c d} \[split \$_ipaddress .\] break
set wsp_dst_ip \[expr {(wide(\$a)<<24)+(\$b<<16)+(\$c<<8)+\$d}\]
set wsp_url_length \[string length \$original_request\]
binary scan \[string range \[ md5 \[ expr { \[info cmdcount\] * rand() } \] \] 0 3 \] H8 wsp_message_id
set wsp_message_request_header "\[binary format SSSH8 \$static::wsp_api_version_${tmsh::app_name} 0x0089 0x0000 \$wsp_message_id\]"
set wsp_message_length \[expr { \[string length \$wsp_message_request_header\] + \[string length \$wsp_message_body\] + 2 } \]
set wsp_message_body "\[binary format SSIISa\$\{wsp_url_length\}Sa\$\{wsp_username_length\} 0x0002 0x0000 \$wsp_src_ip \$wsp_dst_ip \$wsp_url_length \$original_request \$wsp_username_length \$wsp_username\]"
send -timeout 1000 -status wsp_send_status \$wsp_conn \[binary format SSSSH8SSIISa\$\{wsp_url_length\}Sa\$\{wsp_username_length\} \$wsp_message_length \$static::wsp_api_version_${tmsh::app_name} 0x0089 0x0000 \$wsp_message_id 0x0002 0x0000 \$wsp_src_ip \$wsp_dst_ip \$wsp_url_length \$original_request \$wsp_username_length \$wsp_username\]
set wsp_recv_data \[recv -status wsp_recv_status -timeout 50 \$wsp_conn \]
binary scan \$wsp_recv_data SSSSH8SSSSa* wsp_recv_length wsp_recv_version wsp_recv_type wsp_recv_flags wsp_recv_message_id wsp_recv_lookup_code wsp_recv_lookup_desc wsp_recv_category wsp_recv_message_length wsp_recv_message
if {\$wsp_recv_message_length > 0 } { binary scan \$wsp_recv_message a\$\{wsp_recv_message_length\}S wsp_recv_message_out wsp_recv_null }
if { \[info exists wsp_recv_message_id\] } {
if { (\$wsp_message_id == \$wsp_recv_message_id) } {
if { \$wsp_recv_lookup_code > 0 } {
if { \[info exists wsp_recv_message_out\] } {
clientside {
catch {TCP::respond "HTTP/1.1 403 Not Allowed\\r\\nMime-Type: text/html\\r\\nCache-Control: no-cache,no-store\\r\\nConnection: close\\r\\nContent-Length: \[string length \[subst \$static::host_disallowed_error_${tmsh::app_name}\]\]\\r\\n\\r\\n\[subst \$static::host_disallowed_error_${tmsh::app_name}\]\\r\\n\\r\\n"}
}
}
}
}
}
}
}
node \$_ipaddress \$port
}
} else {
set original_request "https://\[getfield \$\{original_request\} ":" 1\]"
if { \$static::support_websense_${tmsh::app_name} } {
if { not \$disable_websense_lookups } {
foreach {a b c d} \[split \$_ipaddress .\] break
set wsp_dst_ip \[expr {(wide(\$a)<<24)+(\$b<<16)+(\$c<<8)+\$d}\]
set wsp_url_length \[string length \$original_request\]
binary scan \[string range \[ md5 \[ expr { \[info cmdcount\] * rand() } \] \] 0 3 \] H8 wsp_message_id
set wsp_message_request_header "\[binary format SSSH8 \$static::wsp_api_version_${tmsh::app_name} 0x0089 0x0000 \$wsp_message_id\]"
set wsp_message_length \[expr { \[string length \$wsp_message_request_header\] + \[string length \$wsp_message_body\] + 2 } \]
set wsp_message_body "\[binary format SSIISa\$\{wsp_url_length\}Sa\$\{wsp_username_length\} 0x0002 0x0000 \$wsp_src_ip \$wsp_dst_ip \$wsp_url_length \$original_request \$wsp_username_length \$wsp_username\]"
send -timeout 1000 -status wsp_send_status \$wsp_conn \[binary format SSSSH8SSIISa\$\{wsp_url_length\}Sa\$\{wsp_username_length\} \$wsp_message_length \$static::wsp_api_version_${tmsh::app_name} 0x0089 0x0000 \$wsp_message_id 0x0002 0x0000 \$wsp_src_ip \$wsp_dst_ip \$wsp_url_length \$original_request \$wsp_username_length \$wsp_username\]
set wsp_recv_data \[recv -status wsp_recv_status -timeout 50 \$wsp_conn \]
binary scan \$wsp_recv_data SSSSH8SSSSa* wsp_recv_length wsp_recv_version wsp_recv_type wsp_recv_flags wsp_recv_message_id wsp_recv_lookup_code wsp_recv_lookup_desc wsp_recv_category wsp_recv_message_length wsp_recv_message
if {\$wsp_recv_message_length > 0 } { binary scan \$wsp_recv_message a\$\{wsp_recv_message_length\}S wsp_recv_message_out wsp_recv_null }
if { \[info exists wsp_recv_message_id\] } {
if { (\$wsp_message_id == \$wsp_recv_message_id) } {
if { \$wsp_recv_lookup_code > 0 } {
if { \[info exists wsp_recv_message_out\] } {
clientside {
catch {TCP::respond "HTTP/1.1 403 Not Allowed\\r\\nMime-Type: text/html\\r\\nCache-Control: no-cache,no-store\\r\\nConnection: close\\r\\nContent-Length: \[string length \[subst \$static::host_disallowed_error_${tmsh::app_name}\]\]\\r\\n\\r\\n\[subst \$static::host_disallowed_error_${tmsh::app_name}\]\\r\\n\\r\\n"}
}
}
}
}
}
}
}
node \$_ipaddress \$port
}
}
}
} else {
# If we're not handling a CONNECT request, then we're going to strip out the
# FQDN and protocol from the fully-formed URI we just got.
#
# Along the way, we need to handle failures to resolve DNS, caching of DNS returns
# in a table for better performance, checking to see whether the browser client
# is restricted from proxy use, and logging error conditions. Only then do we set the
# node and port to the remote host system.
if { \$static::proxy_debug_${tmsh::app_name} } { log local0.info "Got hostname: \$host, calling resolver..." }
set ips \[RESOLV::lookup @\$static::resolver_ip_${tmsh::app_name} -a \$host\]
if { \$static::proxy_debug_${tmsh::app_name} } {log local0.info "\$host NAME::response: \$ips"}
set _ipaddress \[lindex \$ips 0\]
if { (\$_ipaddress equals "") || (\$_ipaddress equals "NO_IP") } {
if { \$_ipaddress equals "" } {
set error_occurred 1
table add \$host "NO_IP" \$static::resolver_cache_lifetime_${tmsh::app_name}
if { \$static::proxy_debug_${tmsh::app_name} } { log local0.info "DNS resolution failed for hostname: \$host. Sending HTTP response error" }
if { \$static::enable_logging_${tmsh::app_name} } {
HSL::send \$logging_handle "<\$\{static::facility_${tmsh::app_name}\}> \[IP::client_addr\] -> \$host:\$port \\\"\[HTTP::method\] \$new_path HTTP/\[HTTP::version\]\\\" 504 -"
}
HTTP::respond 504 content \[subst \$\{static::host_not_found_error_${tmsh::app_name}\} \] Mime-Type text/html Cache-Control "no-cache,no-store"
return
} else {
set error_occurred 1
if { \$static::proxy_debug_${tmsh::app_name} } { log local0.info "DNS resolution failed for hostname (from cache): \$host. Sending HTTP response error" }
if { \$static::enable_logging_${tmsh::app_name} } {
HSL::send \$logging_handle "<\$\{static::facility_${tmsh::app_name}\}> \[IP::client_addr\] -> \$host:\$port \\\"\[HTTP::method\] \$new_path HTTP/\[HTTP::version\]\\\" 504 -"
}
HTTP::respond 504 content \[subst \$\{static::host_not_found_error_${tmsh::app_name}\} \] Mime-Type text/html Cache-Control "no-cache,no-store"
return
}
} else {
table add \$host \$_ipaddress \$static::resolver_cache_lifetime_${tmsh::app_name}
if { (\$static::check_access_blocking_${tmsh::app_name}) } {
if { not \[class match \[IP::client_addr\] equals \$static::block_access_datagroup_${tmsh::app_name}\] } {
if { \$static::proxy_debug_${tmsh::app_name} } { log local0.info "ACL failed: \$host. Sending HTTP response error" }
HTTP::respond 403 content \[subst \$\{static::host_disallowed_error_${tmsh::app_name}\} \] Mime-Type text/html Cache-Control "no-cache,no-store"
if { \$static::enable_logging_${tmsh::app_name} } {
HSL::send \$logging_handle "<\$\{static::facility_${tmsh::app_name}\}> \[IP::client_addr\] -> \$host:\$port \\\"\[HTTP::method\] \$new_path HTTP/\[HTTP::version\]\\\" 403 -"
}
return
} else {
if { \$static::support_websense_${tmsh::app_name} } {
if { not \$disable_websense_lookups } {
foreach {a b c d} \[split \$_ipaddress .\] break
set wsp_dst_ip \[expr {(wide(\$a)<<24)+(\$b<<16)+(\$c<<8)+\$d}\]
set wsp_url_length \[string length \$original_request\]
binary scan \[string range \[ md5 \[ expr { \[info cmdcount\] * rand() } \] \] 0 3 \] H8 wsp_message_id
set wsp_message_request_header "\[binary format SSSH8 \$static::wsp_api_version_${tmsh::app_name} 0x0089 0x0000 \$wsp_message_id\]"
set wsp_message_length \[expr { \[string length \$wsp_message_request_header\] + \[string length \$wsp_message_body\] + 2 } \]
set wsp_message_body "\[binary format SSIISa\$\{wsp_url_length\}Sa\$\{wsp_username_length\} 0x0002 0x0000 \$wsp_src_ip \$wsp_dst_ip \$wsp_url_length \$original_request \$wsp_username_length \$wsp_username\]"
send -timeout 1000 -status wsp_send_status \$wsp_conn \[binary format SSSSH8SSIISa\$\{wsp_url_length\}Sa\$\{wsp_username_length\} \$wsp_message_length \$static::wsp_api_version_${tmsh::app_name} 0x0089 0x0000 \$wsp_message_id 0x0002 0x0000 \$wsp_src_ip \$wsp_dst_ip \$wsp_url_length \$original_request \$wsp_username_length \$wsp_username\]
set wsp_recv_data \[recv -status wsp_recv_status -timeout 50 \$wsp_conn \]
binary scan \$wsp_recv_data SSSSH8SSSSa* wsp_recv_length wsp_recv_version wsp_recv_type wsp_recv_flags wsp_recv_message_id wsp_recv_lookup_code wsp_recv_lookup_desc wsp_recv_category wsp_recv_message_length wsp_recv_message
if {\$wsp_recv_message_length > 0 } { binary scan \$wsp_recv_message a\$\{wsp_recv_message_length\}S wsp_recv_message_out wsp_recv_null }
if { \[info exists wsp_recv_message_id\] } {
if { (\$wsp_message_id == \$wsp_recv_message_id) } {
if { \$wsp_recv_lookup_code > 0 } {
if { \[info exists wsp_recv_message_out\] } {
clientside {
TCP::payload replace 0 0 ""
TCP::respond \$wsp_recv_message_out
TCP::close
}
}
}
}
}
}
}
node \$_ipaddress \$port
}
} else {
if { \$static::support_websense_${tmsh::app_name} } {
if { not \$disable_websense_lookups } {
foreach {a b c d} \[split \$_ipaddress .\] break
set wsp_dst_ip \[expr {(wide(\$a)<<24)+(\$b<<16)+(\$c<<8)+\$d}\]
binary scan \[string range \[ md5 \[ expr { \[info cmdcount\] * rand() } \] \] 0 3 \] H8 wsp_message_id
set wsp_message_request_header "\[binary format SSSH8 \$static::wsp_api_version_${tmsh::app_name} 0x0089 0x0000 \$wsp_message_id\]"
set wsp_url_length \[string length \$original_request\]
set wsp_message_length \[expr { \[string length \$wsp_message_request_header\] + \[string length \$wsp_message_body\] + 2 } \]
set wsp_message_body "\[binary format SSIISa\$\{wsp_url_length\}Sa\$\{wsp_username_length\} 0x0002 0x0000 \$wsp_src_ip \$wsp_dst_ip \$wsp_url_length \$original_request \$wsp_username_length \$wsp_username\]"
send -timeout 1000 -status wsp_send_status \$wsp_conn \[binary format SSSSH8SSIISa\$\{wsp_url_length\}Sa\$\{wsp_username_length\} \$wsp_message_length \$static::wsp_api_version_${tmsh::app_name} 0x0089 0x0000 \$wsp_message_id 0x0002 0x0000 \$wsp_src_ip \$wsp_dst_ip \$wsp_url_length \$original_request \$wsp_username_length \$wsp_username\]
set wsp_recv_data \[recv -status wsp_recv_status -timeout 50 \$wsp_conn \]
binary scan \$wsp_recv_data SSSSH8SSSSa* wsp_recv_length wsp_recv_version wsp_recv_type wsp_recv_flags wsp_recv_message_id wsp_recv_lookup_code wsp_recv_lookup_desc wsp_recv_category wsp_recv_message_length wsp_recv_message
if {\$wsp_recv_message_length > 0 } { binary scan \$wsp_recv_message a\$\{wsp_recv_message_length\}S wsp_recv_message_out wsp_recv_null }
if { \[info exists wsp_recv_message_id\] } {
if { (\$wsp_message_id == \$wsp_recv_message_id) } {
if { \$wsp_recv_lookup_code > 0 } {