Orenosp User's Guide for version 1.1.0 or later Table of Contents - HTTP/HTTPS Reverse Proxy Basics - Examples - Absolute URLs in Contents - Load-Balancing HTTP/HTTPS Servers - Enabling Various SSL-related Features - Virtual hosts and SSL server certificate - HTTP Compression - Various Built-in Security Filters - Nimda Filters - Referer Checking - Request Policing - Access and Performance Logging - User Authentication - Passing Through Authentication to Backend - Authenticating and Authorizing at Reverse Proxy - HTTP Basic Authentication - Form Based Authentication - SSL Client Certificate Authentication - External Authentication Services - HTTP/HTTPS Basic Auth Server - File-based authentication - PAM authentication - LDAP authentication - RADIUS authentication - Client Certificate Mapping and Authorization - Steps - Certificate Mapping Rules - IP-based Access Control - Monitoring Module - Bandwidth Control - Local File Serving for Menu Pages - Processing Order - IPv4 <-> IPv6 - Proxy-Backend Communication - Adding Arbitrary Request/Response Headers - Simple Content Rewrite - Regular Expression Based Content Rewrite - Response Headers Rewrite - Cookie Attribute Translation - Advanced Reverse Proxy Configurations - Outlook Web Access (OWA) - Quick Configurations - Basics - OWA's use of WebDAV - Alternative Reverse Proxy Configuration - User Authentication and Authorization - Implementing Idle Session Timeout - About Logging Out - Multiple OWA Servers - Windows SharePoint Services (WSS) - Interoperability Tips with IIS - Miscellaneous Parameters - SSL Client Authentication - SSL Profiles - Appendice - Setting Up a Simple Windows RAIDUS Server (IAS) For Secure Port Forwarding (SSL Tunneling), see SSL Tunneling Guide (tunnel/ssltunnel_en.txt). [Some sections are not yet translated to English] HTTP/HTTPS Reverse Proxy Basics =============================== Examples -------- [Example-1 and 2 are skipped for now] See "Advanced Reverse Proxy Configurations" section for more complex examples. Example-3 Publish internal servers via multiple virtual hostnames. The internal servers are really virtual servers hosted on localhost. external port/hostname internal vhostname web page (Orenosp) (internal http server) ---------------------------------------------------------------------------- 443 https : spub1.example.com --> secure-pub-1 http secure public web page 1 443 https : spub2.example.com --> secure-pub-2 http secure pulibc web page 2 443 https : sadmin.example.com --> secure-admin http admin web page --- sproxy.conf --- # define only one listen port # proxy_listen_name = lis-ssl 0.0.0.0@443 https # The backend server to forward the request to is determined by Host: # header in the original request. When forwarding it to the backend, # send vhostname specified with -hh option as Host: header. # # proxy_pass_by = vhost spub1.example.com http://localhost -hh=unsecure-pub proxy_pass_by = vhost spub2.example.com http://localhost -hh=secure-pub proxy_pass_by = vhost sadmin.example.com http://localhost -hh=secure-admin --- internal web server configuration --- - listen on port 80 - publish secure public web page 1 via vhostname secure-pub-1 - publish secure public web page 2 via vhostname secure-pub-2 - publish admin web page 1 via vhostname secure-admin - in all vhosts, restrict access to those from Orenosp using IP address restriction. --- notes when using this method for HTTPS --- see "Virtual hosts and SSL server certificate" section. Example-4 Publish, via a single hostname, multiple applications scattered over multiple servers. App1 and App2 exist under /app1/ on appserver1 and /app2/ on appserver2 respectively. https://appserver1/app1/ Application-1 http://appserver2/app2/ Application-2 We want to publish these apps via a single external proxy of https://mine.example.com/. https://mine.example.com/app1/ --> https://appserver1/app1/ https://mine.example.com/app2/ --> http://appserver2/app2/ --- sproxy.conf --- # define only one listen port # proxy_listen_name = lis-ssl 0.0.0.0@443 https # forward all requests received at lis-ssl and having paths of /app1/* # to https://appserver1/app1/. # forward all requests received at lis-ssl and having paths of /app2/* # to http://appserver2/app2/. # all other requests are denied as errors. # proxy_pass_by = url lis-ssl://*/app1/ https://appserver1/app1/ proxy_pass_by = url lis-ssl://*/app2/ http://appserver2/app2/ --- internal web server configurations --- As done in the example, if you can use the same path for external url and internal url, there is not much application or configuration changes. However, if you can't use the same path, either application must be changed to use relative paths or you must use Orenosp's content rewrite to rewrite paths in HTML pages. Some applications cannot be published in this way due to their content. Example-5 Sending a fixed authentication info to backend server that requires HTTP basic authentication. Orenosp allows client and backend to transparently exchange any authentication information. You can also configure the proxy to send a fixed basic auth credential to a backend server. proxy_pass_by = lis lis-ssl http://username:password@localhost:10001 See also "Advanced Reverse Proxy Configurations" section for more complex examples. Absolute URLs in Contents ------------------------- Generally if a web application is put behind a reverse proxy, its contents shouldn't have absolute URLs in them. But if you already have such an application, then there are two options: 1) Contents that use $SERVER_NAME and friends to achieve site-name independence -> specify -hh="_self_" 2) Contents that have literal absolute URLs -> specify -rw_url=on (automatic URL rewriting in content) e.g., proxy_pass_by = url lis-ssl://*/app1/ \ https://appserver1/app1/ -rw_url=on If you have an application that spans multiple web servers and has pages that link to one another, the automatic URL rewriting (-rw_url) won't solve the problem. In this case, you need to manually configure content rewrite rules. (See Content Rewrite) Load-Balancing HTTP/HTTPS Servers ================================= With load-balancing, you can distribute HTTP request processing among multiple equivalently configured backend servers. In the basic reverse proxy mode, destinations of requests are specified as a regular HTTP or HTTPS URLs. To use multiple servers for load-balancing you will instead need to define a load-balancing group (LB group) and specify the defined LB group as the destination in proxy_pass_by rules. proxy_lbgroup_define = lbhost1 http nodes="server1,server2:8890,server3:8888" ... proxy_pass_by = vhost www.example.com lbgrp://lbhost1 -hh="..." nodes= option specifies a list of servers that will share the request processing load. A node should be specified with its hostname and an optional port number. (Note: do not specify http and https default port numbers, 80 and 443). -hh option in proxy_pass_by, if specified, applies to all the nodes in a group equally. Session Binding --------------- By default, once an HTTP session is assigned to a particular LB node, all requests from that session will go to the same LB node. This is accomplished by using an HTTP cookie ("orenosp-lbg-"). Session binding modes supported: cookie insert mode : the only one supported now other modes that may be supported in future: backend cookie mode : uses backend-supplied cookie client IP range mode : uses client IP address Load-Balancing Algorithm ------------------------ Currently Orenosp does a simple round-robin. High Availability ----------------- Orenosp proactively health-check all nodes in LB groups. In every 5 seconds, it "pings" all nodes using ICMP echo requests. If a node fails to respond to this ping request, it is considered Non-Existent (NOEX). For all other nodes that responded to pings, Orenosp sends a HTTP request: GET http-or-https://node-hostname[:port]/ If the node returns a bad status or fails to respond, it is considered Service-Down (DOWN). Otherwise, the node is considered Service-UP (UP). HTTP status codes that are considered bad are 500 (internal server error), 502 (bad gateway), 503 (service unavailable) and 504 (gateway time out). If the node's state is not UP, it is considered as dead and is temporarily evicted from its LB group. When the node's state becomes UP, it is allowed to join back to the LB group. To rephrase, Orenosp does two periodic checks: (1) Ping check : all nodes (2) HTTP check : all non-NOEX nodes (DOWN and UP nodes) Apart from the peridic checks, Orenosp also retries to send the client HTTP request to another node if the first request fails. If you want to take a node into maintenance, you can just shutdown its HTTP service, shutdown the OS, or just remove the node from the network. After the maintenance, you can start the HTTP service or plug-in the network again. --- Tunables --- You can configure the HTTP check to be applied only for DOWN nodes. This way, you can avoid periodic HTTP check on UP nodes. You still get a similar level of high availability. proxy_lb_hcheck_downonly = 1 Monitoring ---------- You can configure Orenosp monitoring module and check status of LB groups. See "Monitoring Module" later in this guide. Enabling Various SSL-related Features ===================================== 1) Enabling Basic SSL Proxy Follow "Basic Configuration and SSL certificate Setup" in readme_en.txt 2) Enabling Proxy That Requests Client Certificates Follow "SSL Client Authentication" in this Orenosp Users Guide. 3) Configuring Certificate Based Access Control Follow "Client Certificate Mapping and Authorization" in this Orenosp Users Guide. 4) Passing Certificate Information to Backend Servers See "Passing Client Certificate Information to Backend Servers" subsection of "Proxy-Backend Communication" section in this Orenosp Users Guide. 5) Using Multiple SSL Profiles See "SSL Profiles" section in tihs Orenosp Users Guide. Virtual hosts and SSL server certificate ======================================== Notes when publishing multiple virtual hostnames on a single SSL listen port (IP address + port). A client browser will warn the user if the hostname included in the server certificate does not match with the actual hostname that the user is accessing. In order to avoid this, you need to create a server certificate using either of the following methods. 1) Put multiple vhost names in the server certificate (subjectAltName) vhost1 : myweb1.example.com vhost2 : myweb2.example.com vhost3 : myadmin.example.com subjectAltName in certificate: DNS:myweb1.example.com, DNS:myweb2.example.com, DNS:admin.example.com If using gencert, start "gencert -gen -1" and answer Y to "Do you want to put multitple DNS names?(y/n)", and put the next line: myweb1.example.com, myweb2.example.com, admin.example.com This way, you can have a certificate with multiple hostnames. 2) Put a wildcard hostname in CN of the certificate (wildcard certificate) vhost1 : www.myexample.com vhost2 : www2.myexample.com vhost3 : admin.myexample.com CN in certificate : *.myexample.com HTTP Compression ================ In sproxy.conf, find the following lines and uncomment them. #proxy_filter_define = comp-txtonly mod_filt_zlib mtype="text/" #proxy_filter_assign = * comp-txtonly Configured this way, all respose bodies (content) that statisfies all of the following conditions will be sent in compressed form to the client: - HTTP status is 200 (HTTP_OK) - are text files (their MIME type name begins with "text/") - the client (requester) can accept HTTP compressed response See Also Orenosv's users guide and config files. http://hp.vector.co.jp/authors/VA027031/orenosv/guide_en.txt http://hp.vector.co.jp/authors/VA027031/orenosv/http_dflt.txt Various Built-in Security Filters ================================= Nimda Filters ------------- See sproxy_full.txt Referer Checking ---------------- See sproxy_full.txt Request Policing ---------------- See sproxy_full.txt Access and Performance Logging ============================== - Access Logging See proxy_log_access_XXX parameters in sproxy_full.txt - Performance Logging You can add request's response time access logs by specifying 0004 flag to proxy_log_access_flags. The reponse time is defined as the time in seconds from when the request is received from the client and when the proxy has finished sending the last byte of the content. You can also have another dedicated performance logging for tracking backend response times. proxy_perf_logio = single perf.log Format for performance log files time: time when the front request is received from client hmethod: HTTP verb in backend request url: request URL to backend (enclosed by "") hstatus: HTTP status from backend inbytes: bytes sent to backend (sizeof request body) outbytes: bytes received from backend (size of response body) tm_connect: (2-1) time(msec) to connect tm_sendreq: (3-2) time(msec) to send request including req body tm_waitres: (4-3) time(msec) to wait for response headers tm_recvbody (5-4) time(msec) to receive all response body As of version 0.4.2, inbytes are not yet correctly reflected in the log. Because backend connections are cached, if Orenosp can use a cached connection, tm_connect will be very small in that case. - Remote Logging You can direct Orenosp to send log records to a Logging Service running on another PC. This function is applicable to the following logs: proxy_log_access_io, proxy_perf_logio, proxy_nimda_logio, proxy_htrace_logio Syntax of proxy_log_access_io: proxy_log_access_io = remote hostname:port { ssl | tcp } label hostname:port : log service's hostname and TCP port { ssl | tcp } Specify "ssl" to connect over SSL. SSL profile "cldflt" is used for the SSL operations. Specify "tcp" (or its synonym "raw") to connect over TCP. Note that logging communication including username and password will not be encrypted. label : any string that the log service requires -u=username:password : username and password to connect to the log service example proxy_log_access_io = remote host1:13000 ssl /host1/proxy \ -u=logadmin:passwd [Developing a compatible network log service] Please see remote_log_spec.txt. User Authentication =================== You have two options regarding authentication and authorization of access to internal servers. One is to let all requests through, and let each backend server do its authentication and authorization. The other option is to have the reverse proxy to authenticate and authorize these requests. There are three methods for authenticating and authorizing users on client (front) connections. You can combine any of them. Passing Through Authentication to Backend ----------------------------------------- By default Orenosp will relay HTTP basic, HTTP digest and any types of cookie-based authentication/authorization requests from/to backend servers. Windows Integrated Authentication: By default Orenosp will not pass through Microsoft-proprietary HTTP authentication methods. These include MS NTLM authentication and MS Negotiate authentication. When orenosp finds response headers requesting one of these auth methods, it will silently drops that response header. See proxy_auth_disable_XXX parameters in sproxy_full.txt. Set the following parameter to enable these auth methods. proxy_auth_disable_ntlm = 0 proxy_auth_disable_negotiate = 0 Authenticating and Authorizing at Reverse Proxy ----------------------------------------------- 1) HTTP Basic Authentication This is the most simple and easy method. If your backend server also enforces HTTP Basic Authentication, it won't work because each of the reverse proxy (front-end) and the backnd will request a basic authentication. There are three options: - Use a form based authentication at the proxy. - Specify a fixed username and password in backend specifier in proxy_pass_by parameter. (uname:passwd@backend:8888). - Have the proxy to pass username and password received to the backend. The latter only works if your proxy and backend server uses the same authentication database. (You need to set "proxy_auth_pass_to_backend = 1") 2) Form Based Authentication This is probably the most prefered method by users and server admins. Form Based Authentication provides you with a set of customizable HTML pages for authentication process. Another advantage is that it can coexist with backend's basic or form-based authentication because it uses a cookie named 'orenosp-authck-XXX'. You can also pass username and password received to the backend as an HTTP basic auth information. (You need to set "proxy_authck_pass_to_backend = 1") 3) SSL Client Certificate Authentication See section "Client Certificate Mapping and Authorization". HTTP Basic Authentication ------------------------- #proxy_auth_url = [options] proxy_auth_url = lis-ssl://*/* -u="user1:pass1" -rlm="Local Server" proxy_auth_url = lis-ssl2://*/* -u="user2:pass2" -rlm="Note Server" # [optional] pass user credential to backend's basic auth proxy_auth_pass_to_backend = 1 Form Based Authentication ------------------------- - make a directory /_formauth - copy all files from /padmin/_formauth to /_formauth. You can do this with a single command in a command prompt: > cd > xcopy padmin\_formauth _formauth\ [Linux/Mac]$ cp -R padmin/_formauth _formauth Edit sproxy.conf - enable Form Based Authentication proxy_authck_enable = 1 - [optional] # pass user credential to backend's basic auth proxy_authck_pass_to_backend = 1 - define authentication type(s) (protection realm) proxy_authck_define = noone -u="" -rlm="nobody allowed" proxy_authck_define = fmauth1 -u="user1:passwd1,user2:passwd2" \ -rlm="Restricted Area" -u specifies list of users and their passwords. You can set empty passwords to direct the proxy to use an external authentication server. e.g., -u="user1:,user2:" (you must put ':' even if no password is specified). see External Authentication Servers for details. -rlm specifies the name of the protection realm. If omitted, the name of the authentication type is used ("fmauth1" in the example). -tmo= : idle login timeout in minutes (must be >= 2) default is 30 (minutes). -ckdomain="domain-name" : specifies "domain" name in the ticket cookie. if you have two vhosts, www.example.com and www2.example.com, you could set -ckdomain=".example.com" (notice the leading dot) so that a user could be authenticated just once for all vhosts in *.example.com. - map virtual paths or URL space to protection realms defined proxy_authck_assign = * fmauth1 or if you only want to protect URL space in vhost1, do: proxy_authck_assign = *://vhost1.example.com/* fmauth1 NOTE: By default, access to any vpath space is unrestricted. If you want access restriction for all possible vpath space, be sure to include the following parameter BEFORE any other "proxy_authck_assign" parameters: # for all others, deny any access proxy_authck_assign = * noone - OPTIONAL: add authorization list The protection domain defined by proxy_authck_define is really a user authentication domain. Additionally, for each URL space, you can specify a list of users who should be allowed access. # anyone who are successfully authenticated can access. proxy_authck_assign = *://vhost1.example.com/* fmauth1 # for /private/* space, only user "admin1" and users in "admin" group # will be allowed access. proxy_authck_assign = *://vhost1.example.com/private/* fmauth1 \ -allow="admin1,@admins" User grouping information is stored in /grpdb.txt. Access protected pages When you access any protected pages, you will be redirected to "/_formauth/login.html". When the proxy redirects you, it also sends a cookie that specifies the protection realm for the access-attemped page. (In the above example, "Restricted Area" is the realm.) The proxy will use this realm name to look up an appropriate authck type with which to authenticate the user. Note that if you acess "/_formauth/login.html" directly without being redirected, the proxy will not have a realm name. In such a case the proxy will default to use the last authck type defined in the config file. This is a change from versrion 0.4.1 or earlier, where authentication would simply fail without a proper realm name cookie. The new behavior is preferable in cases where users tend to bookmark login pages. Customizing form-based authentication pages By enabling the form based authentication, any virtual paths that begin with "/_formauth/": - are intercepted by the proxy - will be accessible without __any form-based authentication__ - any files in $ORENOSP_HOME/_formauth directory are sent by the proxy. Therefore you can embed any files that exist in the same directory in the authenticating pages. The following are the special files accessed by the form-based auth module: /_formauth/validate : virtual path for builtin password validator (not customizable) /_formauth/login.html : login page in HTML /_formauth/loginerror.html : login error page in HTML /_formauth/loginsuccess.html : Success report page in HTML /_formauth/denied.html : access denied error page in HTML You can place other html files, icon files, javascript files, or any other type of files in this directory. Coordinating form-based authentication and IP-based access control You can configure the system so that form-based authentication will control any of the IP-based access control methods in Orenosp. Example o Orenosp listens on port 3339 for relayed TCP connections to a Remote Desktop in the LAN. Initially the tunneling listen port is restricted by IP-based access control so that no machine can connect. o When a client first connects to the HTTPS reverse proxy, the client will authenticate himself with Orenosp's form-based authentication. Then, the tunneling listen port will be "opened" for the IP address of that client. o When 60 minutes pass, the tunneling listen port will be "closed" for the client's IP. - create an empty text file "ipacl_rawrdp.txt" in ORENOSP_HOME directory. - add the following parameters: tunnel_listen_name = rdp-raw 0.0.0.0@3391 raw -ip_allow="@ipacl_rawrdp.txt" \ -ip_order=allow-deny proxy_authck_define = fmusers -u="_valid_:" -rlm="Our Users" -tmo=90 \ -onlogin=ipacl_add:ipacl_rawrdp.txt -onlogin=ipacl_tmo:60 end of example You can use any IP-based access control methods (proxy listen port, proxy_authip_url, or tunneling listen port) External Authentication Services ================================ Both the form-based authentication and HTTP basic authentication support external authentication services to verify user passwords. You can direct these auth modules to call the designated authentication service by putting an empty password in the user-password-list. An empty password can be specifed as "username:" (you have to put ':'). You can also use a special username "_valid_" to allow any user who is successfully authenticated by the backend server. e.g., -u="_valid_:" Currently there are four types of external authentication services supported: - HTTP/HTTPS basic auth server Send HEAD request along with username and password to . If it returns status 200, the user is authenticated. Details of actual behavior: send HEAD request first without user auth info and see if designated server actually requires authentication. If so, then send another HEAD request this time with authentication info and see if the server returns 200 status. Only then the user is authenticated. For all other cases, the user is not authenticated. - File-based authentication Authenticates username and password against "passwd.txt" file which usually resides in . Also, when using this method, you can authenticate users against the OS's native authentication mechanism (os_acl option). See Orenosv Users Guide for detail for this. - PAM authentication (Linux and Mac OS X versions only) Authenticate username and password using a PAM rule specified by "orenosp". You need to create /etc/pam.d/orenosp, possibly by copying another entry like "login" or "system-auth". - LDAP authentication (ActiveDirectory) Authenticate username and password by executing LDAP bind to the LDAP server. Currently, the LDAP server is assumed to be an Active Directory. - RADIUS authentication Authenticate user using username and passwod against a RADIUS server. Currently, PAP and CHAP (not MS-CHAP) are supported as authentication methods. For setting up a simple Windows IAS (RADIUS server), see the one of the appendice in this guide. To specify HTTP server auth service: - Prepare a web server that requires HTTP basic authentication. Say, "https://authserver1". (You can use either http or https web server) - for Form Based Authentication proxy_authck_authsrv_url = https://authserver1/ - for HTTP Basic Authentication proxy_auth_authsrv_url = https://authserver1/ To specify file-based auth service: - for Form Based Authentication proxy_authck_authsrv_file = passwd.txt - for HTTP Basic Authentication proxy_auth_authsrv_file = passwd.txt To specify PAM auth service: - for Form Based Authentication proxy_authck_authsrv_pam = svcname=orenosp - for HTTP Basic Authentication proxy_auth_authsrv_pam = svcname=orenosp To specify LDAP auth service: - for Form Based Authentication proxy_authck_authsrv_ldap = - for HTTP Basic Authentication proxy_auth_authsrv_ldap = are ldap_server= IP Address or hostname of LDAP server. Note that default TCP port number (389) is used. upn_domain= Active Directory's domain name (e.g., example.com). Client's username and this domain name are concatanated with '@', then used as LDAP authentication username. (user1@example.com) user_dn= An alternative for upn_domain. e.g., user_dn="cn=%s ,cn=Users,dc=example,dc=com" To specify RADIUS auth service: - for Form Based Authentication proxy_authck_authsrv_radius = - for HTTP Basic Authentication proxy_auth_authsrv_radius = are conf= The default is "radius.conf" under . auth={pap|chap} RADIUS auth metho to use. The default is "pap". A sample "radius.conf" file is included as /padmin/doc/radius.conf. Note if there are more than one type of parameters in sproxy.conf, the following order of precedence exists: url -> file -> pam -> ldap -> radius Note when using HTTP basic authentication (proxy_auth_xxx), user's password must be verified on every request to protected pages. In order to reduce authentication queries to auth services, the proxy caches both positive and negative query results in memory. These caches time out in 3 minutes. Client Certificate Mapping and Authorization ============================================ You can use SSL client certificates to authenticate users and enforce access contol based on them. First you enable SSL Client Authentication, then you use Client Certificate Mapping for two purposes. 1) Authorize access based on certain certificate attributes. 2) Establish mappings between certificates and usernames which will be used in subsequent authentication/authorization mechanisms (like basic auth and form-based auth). In 1) usage, you can protect a certain URL space by restricting access to those clients who have certficates with certain attributes. Let's say you want to restrict access to clients having certificates with "O=Tange Kentou Club". Then map all clients with Tange Kentou Club to a single username "tange-club", and restrict access to that user. In 2) usage, you don't really protect URL spaces, but just specify certificate to username mapping rules for URL spaces. You also need to specify other authentication/authorization rules (like basic auth and/or form-based auth), which would require the client to use the mapped username. For example, if a client having a certificate with "CN=Joe Yabuki" is mapped to "jyabuki", then the client will be required to use "jyabuki" as username for subsequent basic auth and/or form-based auth. Parameters used (see sproxy_full.txt for complete list of options): proxy_authcert_define = ... proxy_authcert_assign = Steps - Enable SSL Client Authentication by following "SSL Client Authentication" section. You need to set proxy_ssl_clauth to either "require" or "optional". proxy_ssl_clauth = require or proxy_ssl_clauth = optional If you choose "require" your users will need to present a valid certificate upon connecting your proxy. If they don't, an HTTPS connection will not be established. If you choose "optional" your users will not be required to present a valid certificate but offered a chance to present one upon connecting your proxy. So "optional" allows both users with a certificate and without a certificate to connect. Interoperability Note: Using "optional" will cause very old browsers to stop connecting if the user can't supply a valid certificate. So make sure all browsers you support don't have this kind of problem. - Define certificate mapping and authorization rules A) Restrict access to users with "O=Shiraki Corporation, OU=Boxing Gym" --- certmap.txt --- shiraki-boxing Subject O=Shiraki Corporation, OU=Boxing Gym --- end --- --- sproxy.conf --- # allow certificate-mapped users user1 and user2 proxy_authcert_define = shiraki -u="shiraki-boxing" -cmap=certmap.txt proxy_authcert_assign = * shiraki B) Map certificate to a username and require that username in subsequent basic or form-based authentication / authorization The key option here is "-set_username=1". --- certmap.txt --- jyabuki Subject CN=Joe Yabuki, O=Tange Kentou Club tange Subject CN=Tange, O=Tange Kentou Club --- end --- # establish mapped username to be required in subquent other auths. # That is, Joe needs to log in as "jyabuki" for subsequent form-based auth, # and Tange needs to log in as "tange" for subsequent form-based auth. proxy_authcert_define = tange -u="_valid_" -set_username=1 -cmap=certmap.txt proxy_authcert_assign = * tange # use mapped username in form-based auth proxy_authck_define = ... -u="jyabuki,tange" Certificate Mapping Rules ------------------------- The default filename used for storing certificate mapping rules is /certmap.txt. You can specify a different file with -cmap= option. Modification to the specified file is monitored by Orenosp and the file is re-read as necessary. You don't have to restart Orenosp to reflect changes. Syntax : username to mapp to Subject ,,... Hash_SHA1 If you need other matching method, please request to the auther. DN-Pattern : the following attribute names are recognized: CN : Common Name O : Organization Name OU : Organization Unit Name L : Locality Name C : Country Name E : EmailAddress - the following can be used in subject DN matching only (not for issuer DN) NOT YET IMPLEMENTED altDNSName : subject alternative name - DNS name (hostname) altEmail : subject alternative name - Email address If an attribute value contains a ',', it must be prefixed by '\'. O=Shiraki Corporation\, Inc., OU=Boxing Gym certificate-fingerprint-in-SHA1-in-hex : can accept two forms ':'-separated: 57:E7:BB:5D:20:D3:61:49:B9:F1:5E:18:14:6D:43:84:85:75:88:BB ' '-separated: 57 e7 bb 5d 20 d3 61 49 b9 f1 5e 18 14 6d 43 84 85 75 88 bb IP-based Access Control ======================= IP-based Access Control can be enforced in two ways: - per connection basis (specified in proxy_listen_name and tunnel_listen_name) - per request basis (specified by proxy_authip_url) Per-connection access control is more effective because it checks client's IP before establishing an SSL / HTTP connection, thereby thwarting SSL handshake DoS attacks. Per-request access control gives you more flexibility by giving finer control over URL space that a user is allowed to access. Both methods can use either the same access control list or separate ones. That is, you can specify a text-based IP pattern file to both modules. The IP pattern file can be edited while the service is running. Orenosp will detects file modification and reloads patterns from the file. There's no limit on the number of IP patterns in a file. --- a sample IP pattern file --- # you can comment out a line with '#' 123.123.0.0/16 123.234.0.0/16 234.123.123.128 --- end --- Refer to sproxy_full.txt for more details - "ip_allow/ip_deny/ip_order" options in proxy_listen_name - "IP-based Access Authorization" (proxy_authip_url) Monitoring Module ================= The monitoring module can be set up to display list of current connections and other various internal states within the Orenosp process. See Monitoring Module in sproxy_full.txt for list of parameters. Network Mappter --------------- Network Mappter is part of the monitoring module. You can use it to browse PCs within the LAN and possibly wake up a wake-up-enabled PC. See Monitoring Module - Network Map in sproxy_full.txt for list of parameters. Bandwidth Control (Throttling) ============================== See sproxy_full.txt for actual parameters. IMPORTANT : current limitations - Only the SEND direction (reverse proxy sending out contents) is currently supported. - BW control works over data that have not been processed by output filters. This means that the amount of data that's subjected to the bandwidth control will differ from the actual amount of data that goes over the wire. For example, if the HTTP compression filter reduces a 1MB content by 90%, the bandwidth control will see it as 1MB of data even though only the 100KB of data is actually sent over the wire. A work around would be to let the backend server to compress the contents and let them through the reverse proxy. Of course, it won't be possible to rewrite contents with this way. Local File Serving for Menu Pages ================================= If you have multiple servers/services through the proxy, you may want to have a "welcome" menu page. Usually one of the backend servers will host such a page. However, in case you can't place such a page on your backend server for some reason (say all of your http servers are devices), orenosp has a simple local file serving capability. If you set proxy_lfile_enable = 1 then, any files under /_intmenu/ directory will be available to the client with URLs of /_intmenu/XXX. Note that the request for such files are subject to regular authentication and authorization check done by the proxy, namely either by Simple basic auth or Form based auth. You should also set up a redirect from top url ("/") to "/_intmenu/menu.html" to guide users to the menu page. # redirect "/" to /_intmenu/menu.html (note "-s" option) proxy_redirect_by = url lis-ssl://host.com/ https://host.com/_intmenu/menu.html -s Processing Order ================ - [On connect only] Per-Connection IP-based Access Control - Request policing (proxy_plc_xxx) - Check for nimda requests - Per-Request IP-based Access Control - Certificate Mapping and Authorization - Redirect if matched with proxy_redirect_by - Simple basic authentication - Form based authentication - Switch to tunneling if SSLVPN - Redirect if matched with proxy_redirect_by (when "-2" is used) - Serve local files if "/_intmenu/xxx" - Serve monitoring request - Reverse-proxy request to backend if matched with proxy_pass_by IPv4 <-> IPv6 ============= You need a separate binary of Orenosp to use IPv6 (orenospXXXi6.exe). Limitations in the Current Release ---------------------------------- These will be addressed in future release as demand for IPv6 grows. - SSL Portforwarding over IPv6 is not supported Especially, tnapplet (Java) is not IPv6-enabled. Other components may work but not tested yet. - Load-Balancing to IPv6 backend servers is not supported This is because the load-balancing feature requires ping (ICMPv6) functionality but it is not quite implemented yet. Publish HTTP Servers within a IPv4-LAN to IPv6 network ------------------------------------------------------ # proxy_listen_name = lis-ipv6 ::@80 http # proxy_pass_by = lis lis-ipv6 127.0.0.1 Publish HTTP Servers within a IPv6-LAN to IPv4 network ------------------------------------------------------ # proxy_listen_name = lis-ipv4 0.0.0.0@80 http # proxy_pass_by = lis lis-ipv4 [::1] -hh=127.0.0.1 The notation of "[]" is used to specify an IPv6 address in the host part of a URL. URL Orenosp http://[fe80::203:2fff:fe02:c640]/ -> [fe80::203:2fff:fe02:c640] http://[fe80::203:2fff:fe02:c640]:81/ -> [fe80::203:2fff:fe02:c640]:81 Name Resolution - About DNS setup --------------------------------- To pulish an IPv6 server to IPv4 network DNS entries IP addresses(A) host1.mycompany.com host2.mycompany.com Set up this way, Orenosp is able to route requests based on virtual hostnames. To pulish an IPv4 server to IPv6 network DNS entries IP addresses(AAAA) host1.mycompany.com host2.mycompany.com Set up this way, Orenosp is able to route requests based on virtual hostnames. To accept requests from both IPv6 and IPv4 networks host1.mycompany.com A host1.mycompany.com AAAA host2.mycompany.com A host2.mycompany.com AAAA Also you need to add PTR records for IPv6, but it's out of scope of this document. Misc ---- - Note about "localhost" When you install IPv6 stack on Windows XP or Windows 2003, it seems like that the first IP address that the OS returns for "localhost" is IPv6 loop back address (::1), not IPv4 loop back address (127.0.0.1), even though "127.0.0.1 localhost" is in etc/hosts file. You can try "ping localhost" to see which address it's pinging. This will cause many problems including Orenosv. Use 127.0.0.1 instead of "localhost" whenever you have a strange problem. - To specify a link-local address as a listen port, append interface number as scope-id: # in case of IPv6 link-local address, append interface number # following '%'. proxy_listen_name = lis-ipv6 fe80::203:2fff:fe02:c640%3@8888 http # ^^ You can obtain the interface number by either of the commands: >ipv6 if (XP SP0) >netsh ??? (XP SP1 or higher, Win2003) - To specify a link-local address as a connect address (URL), do NOT specify the interface number: [fe80::203:2fff:fe02:c640%3]:81 ^^ DON'T DO THIS Proxy-Backend Communication =========================== Passing Client IP Addresses to Backend Servers ---------------------------------------------- Many HTTP reverse proxies including Orenosp will add the following headers to client request: X-Forwarded-For: X-Forwarded-Host: X-Forwarded-Proto: <"http"-or-"https"-of-client-request> If you are using Apache as a backend server, you can use a module called "mod_rpaf" to make the Apache server to 1) accept X-Forwarded-For:'s IP address as real client's IP address, 2) accept X-Forwarded-Host:'s value as real virtual hostname. X-Forwarded-Proto header is introduced in Orenosp 0.7.4c and Orenosp-specific. Passing Client Certificate Information to Backend Servers --------------------------------------------------------- - Passing the whole client certificate to a backend server via a special request header When you want to send client certificate to backend server as a header value. set the following parameter: proxy_cert_pass_whole = X-CERT_BASE64 Then base64-encoded text of DER-format certificate is passed to a backend via X-CERT_BASE64 request header. Note that maximum length of the base64-encoded certificate must be less than 2048 bytes. Otherwise, the header value is truncated and an error message is written to event.og. - Passing partial information in client certificate to a backend servers. Not implemented yet. Adding Arbitrary Request/Response Headers ========================================= You can add arbitrary request/response headers in reverse proxy. Use "-rq_hdr" and "-rs_hdr" options in proxy_pass_by parameter. -rq_hdr : add request header client ---> Orenosp ---> backend here -rs_hdr : add response header client <--- Orenosp <--- backend here Simple Content Rewrite ====================== If you use any reverse-proxy, you can no longer use "absolute URLs" that point to pages on the same reverse-proxied server. For example, let's say "https://www.mine.com/" is reverse-proxied to "http://internal1/" and if you write an HTML link as then, users on the Internet try to go to the internal server directly, which fails. You need to rewrite the URL as "https://www.mine.com/doc/abc.html". Orenosp and Orenosv have a mechanism to do this kind of content (response-body) rewriting. mod_filt_rwt (optimized rewrite filter) implements this content rewriting functionality. It has two sub-modules, one is simle text search-and-replace filter, the other is a regular expression-based filter. How to configure content rewrite -------------------------------- - create a config file named /rewrite_simple.conf - add rewrite rules to the config file: ---rewrite_simple.conf--- = this is a comment http://internal1/=https://www.mine.com/ http://internal2/=https://www2.mine.com/ = eof ---end of rewrite_simple.conf--- Note on format of rewrite_simple.conf: - '=' is used as the separater: = - leading '=' (i.e., empty ) designates that line as a comment. - two consective '=' ("==") specifies a literal '='. This applies only to . - add the following line to sproxy.conf: # Content Rewrite - must come after HTTP compression filter in config file proxy_filter_define = rewrite-simple mod_filt_rwt rwtype=simple mtype="text/html" proxy_filter_assign = * rewrite-simple - restart Orenosp and check event.log Different rewrite rules for multiple paths ------------------------------------------ - use "-cf=" submodule-specific parameter to specify an alternate rewrite rule file. Note that "--" designates the begining of submodule-specific parameters. example: proxy_filter_define = rewrite-simple-1 mod_filt_rwt rwtype=simple \ mtype="text/html" -- -cf=rewrite-1.conf proxy_filter_define = rewrite-simple-2 mod_filt_rwt rwtype=simple \ mtype="text/html" -- -cf=rewrite-2.conf proxy_filter_assign = /vpath-1/* ext-rewrite-1 proxy_filter_assign = /vpath-2/* ext-rewrite-2 How text matching is done in Simple Rewrite ------------------------------------------- Text matching is done without any context. If rewrite rule is XXX=999 then, aaaXXXzzz is rewritten as aaa999zzz. If using "-hname=1" submodule option, then the following rule applies. The character that follows the matched target must not be a character that can constitute a hostname. For example, if rewrite rule is server-2=www2.example.com then, these are the results: server-2a -> NOT matched and rewritten server-2.com -> NOT matched and rewritten server-2:8888 -> matched and rewritten as www2.example.com:8888 server-2/path -> matched and rewritten as www2.example.com/path Trouble shooting ---------------- - Rewrites not working when called from browsers, but they work if I directly call the server with "telnet" command. -> Most likely your backend server is applying HTTP compression to the content. Orenosp doesn't decompress already compressed documents in order to apply filters. Make sure you do not apply HTTP compression to those contents. Since 0.4.3c, you can set "proxy_origin_gzip_disable = 1" to disable backend's HTTP compression. You should let Orenosp handle HTTP compression instead. Note: Orenosp can handle chunked-encoded response from a backend and "de-chunk" it. - If an HTML line are longer than 30KB bytes, the rewrite filter splits it in multiple chunks that are smaller than 30KB and work on each of them. If the string you want to rewrite happens to be in the middle of that split, the rewrite won't work. -> Make sure your HTML lines are less than 30K bytes. - Enabling trace : Setting rewrite trace level to 2 or 3 may help. (event.log will be very messy!) proxy_filter_define = rewrite-regex mod_filt_ext int=rewrite_regex \ mtype="text/html" -- -cf=rewrite-2.conf -trc=2 Regular Expression Based Content Rewrite ======================================== The configuration is basically very similar to that of Simple Content Rewrite. Refer to the above section for more info. - create a config file named /rewrite_regex.conf - add rewrite rules to the config file: --- rewrite_regex.conf --- = Header (]*>)=$1

Header Something

= Footer ()=

Footer Something

$1 --- end of rewrite_regex.conf --- Note on format of rewrite_regex.conf: - '=' is used as the separater: = - leading '=' (i.e., empty ) designates that line as a comment. - two consective '=' ("==") specifies a literal '='. This applies only to . - regex substitutions ($0,$1,...,$9) can be used in . - add the following line to sproxy.conf: # Content Rewrite - must come after HTTP compression filter in config file proxy_filter_define = rewrite-rex mod_filt_rwt rwtype=regex mtype="text/html" proxy_filter_assign = * rewrite-rex - restart Orenosp and check event.log About regular expressions The regular expression library used in this submodule is PCRE(Perl Compatible Regular Expressions). For RE rules in PCRE, see http://www.pcre.org/pcre.txt (look for "PCRE REGULAR EXPRESSION DETAILS"). Response Headers Rewrite ======================== You can rewrite many reverse-proxied response headers using the rewrite filters. example-1 # Response headers rewrite (no body rewrite) proxy_filter_define = hdr-rewrite mod_filt_rwt rwtype=simple \ headers="Server" flags=0002 proxy_filter_assign = * hdr-rewrite example-2 # Rewrite both body and headers # (rewrite both content and redirect headers (Location field)) proxy_filter_define = all-rewrite mod_filt_rwt rwtype=simple \ mtype="text/" headers="Location,Content-Location" \ flags=0007 proxy_filter_assign = * all-rewrite The proxy passes the following form of line to the filter submodule: : You can only rewrite header-values, not header-names. --- meaning of flags --- 0001 /* process response body */ 0002 /* process response headers */ 0004 /* process headers regardless of mime types */ The default flag value is 0001 (process response body only). Cookie Attribute Translation ============================ You can rewrite path= attribute in Set-Cookie: response header. See sproxy_full.txt (-ck_path option). By default domain= attribute in Set-Cookie header is dropped. You can use -ck_dom option to replace a value in domain= field with another domain. Advanced Reverse Proxy Configurations ===================================== Cookie-based Reverse Proxying ----------------------------- Example Let's say you have a large web mail system. The system is comprised of 4 servers. - login server http://login.internal/ - mail1 server http://mail1.internal/ - mail2 server http://mail2.internal/ - mail3 server http://mail2.internal/ A user first logs into the login server and the login server authenticates the user and redirects him to one of the three mail servers. The login server knows users and their designated mail servers. The assignment rule is fixed. In your intranet, you have no problem about users accessing multiple internal servers (login server -> mailN servers). However, on the extranet you want to have a single virtual server http://mail.example.com/ to handle all requests. You want to have the following rules: For user group A: https://mail.example.com/email/ -> http://login.internal/ (before login) http://mail1.internal/ (after login) For user group B: https://mail.example.com/email/ -> http://login.internal/ (before login) http://mail2.internal/ (after login) For user group C: https://mail.example.com/email/ -> http://login.internal/ (before login) http://mail3.internal/ (after login) To accomplish this, you can use "pass by cookie" sub-rule when defining pass rules. 1) First, modify the login server to issue a cookie EMAILGRP=A for group A, B for group B, and C for group C upon successful user authentication. 2) Add the following rules proxy_pass_by = url https://mail.example.com/email/ http://login.internal/ proxy_pass_by = url https://mail.example.com/email/ http://mail1.internal/ \ -pass_by_ck="EMAILGRP=A" proxy_pass_by = url https://mail.example.com/email/ http://mail2.internal/ \ -pass_by_ck="EMAILGRP=B" proxy_pass_by = url https://mail.example.com/email/ http://mail3.internal/ \ -pass_by_ck="EMAILGRP=C" When a user first access https://mail.example.com/email/, he doesn't have EMAILGRP=X cookie, so he's reverse-proxied to the login server. After successful authentication at the login server, he gets a cookie EMAILGRP=B. From then on, the user's request will always reverse-proxied to http://mail2.internal server. Outlook Web Access (OWA) ======================== The whole purpose of using Orenosp in front of OWA is to avoid exposing the OWA front-end (including IIS) to the Internet. Plus, you get an extra layer of authentication/authorization, request filtering, unified logging and all other features of Orenosp. As for SSL usage, client-to-Orenosp connection is assumed to use HTTPS. For Orenosp-to-OWA connection, you can use either HTTP or HTTPS (SSL bridging). This documentation is based on OWA included in Exchange Server 2003 (i.e., OWA 2003). Many of it should be applicable to OWA of Exchange Server 2000 product (OWA 2000) also. Quick Configurations -------------------- There are sample configuration files for OWA as described in this section. Four sample configurations: /padmin/doc/sproxy_owa_X.txt All of them assume the following info: Internal OWA server (front-end Exchange server) hostname: exchserver URL: http://exchserver/ OR https://exchserver/ External URL https://mail.company.com/ a) SSL Bridging and OWA Form Auth - OWA 2003 only Use HTTPS (SSL) for Orenosp-to-OWA (SSL bridging). OWA uses Forms Based Authentication. No access control at Orenosp level. You can add basic, form-based and/or IP-based access at Orenosp independently. b) SSL Bridging and Orenosp Form Auth - OWA 2000 and OWA 2003 Use HTTPS (SSL) for Orenosp-to-OWA (SSL bridging). OWA uses Basic Authentication. Orenosp will use its form-based authentication and pass to OWA the user's credential as that of the OWA's Basic Authentication This way, a user will only see a single log in page. c) HTTPS->HTTP and OWA Form Auth - OWA 2003 only Use HTTP for Orenosp-to-OWA. OWA uses Forms Based Authentication. No access control at Orenosp level. You can add basic, form-based and/or IP-based access at Orenosp independently. d) HTTPS->HTTP and Orenosp Form Auth - OWA 2000 and OWA 2003 Use HTTP for Orenosp-to-OWA. OWA uses Basic Authentication. Orenosp will use its form-based authentication and pass to OWA the user's credential as that of the OWA's Basic Authentication This way, a user will only see a single log in page. Instructions for a) 1) Configure SSL and OWA Forms Based Authentication per Exchange documentations. Tip: See "Instructions for creating a server certificate for IIS very quick" 2) Use /padmin/doc/sproxy_owa_a.txt as sproxy.conf. Follow "Basic Configuration and SSL certificate Setup" in readme_en.txt to correctly setup secure SSL certificate. You should now be able to log in using OWA Forms Login either on direct HTTPS connection or HTTPS via Orenosp. Instructions for b) 1) Configure SSL and OWA Basic Authentication per Exchange documentations. Tip: See "Instructions for creating a server certificate for IIS very quick" See also "Instructions for correctly configuring OWA basic authentication" down below. 2) Use /padmin/doc/sproxy_owa_b.txt as sproxy.conf. Follow "Basic Configuration and SSL certificate Setup" in readme_en.txt to correctly setup secure SSL certificate. 3) Configure Orenosp form-based authentication by following "Instructions for setting up Orenosp form-based authentication" below. You should now be able to log in using Orenosp Form Login on HTTPS via Orenosp. Instructions for c) 1) Apply the following change into your Windows server's registry: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MSExchangeWEB\OWA Value name: AllowRetailHTTPAuth Value type: DWORD Data value: 1 Then, restart the whole OS. 2) Configure OWA Forms Based Authentication per Exchange documentations. Ignore Exchange Server Manager's instruction to configure SSL. 3) Use /padmin/doc/sproxy_owa_c.txt as sproxy.conf. Follow "Basic Configuration and SSL certificate Setup" in readme_en.txt to correctly setup secure SSL certificate. You should now be able to log in using OWA Forms Login either on direct HTTP (not SSL) connection or HTTPS via Orenosp. If you need to disable HTTP(non-SSL) access to the OWA Forms Login, use "SSLOffload" registry key instead of "AllowRetailHTTPAuth". Instructions for d) 1) Configure OWA Basic Authentication per Exchange documentations. See also "Instructions for correctly configuring OWA basic authentication" down below. 2) Use /padmin/doc/sproxy_owa_d.txt as sproxy.conf. Follow "Basic Configuration and SSL certificate Setup" in readme_en.txt to correctly setup secure SSL certificate. 3) Configure Orenosp form-based authentication by following "Instructions for setting up Orenosp form-based authentication" below. You should now be able to log in using Orenosp Form Login on HTTPS via Orenosp. Instructions for setting up Orenosp form-based authentication Orenosp will use the Active Directory on the OWA server (or any other Active Directory server in the same domain) as its backend authentication service. - Modify Orenosp's sproxy.conf proxy_authck_authsrv_ldap = ldap_server= upn_domain= e.g. proxy_authck_authsrv_ldap = ldap_server=exchserver upn_domain=company.com - Create /_formauth directory (if you haven't done so) > cd > xcopy padmin\_formauth _formauth\ Instructions for creating a server certificate for IIS very quick You can create a server certificate for IIS using Orenosp-gencert program. - Create a server certificate with gencert. gencert creates a p12 certificate pack as /myca/pfxXXX.p12. You need to specify "-n" option so that gencert will not install the generated certificate into Orenosp's certificate store. > gencert -gen -n - From IIS manager's Server Certificate Wizard, just import this p12 file (p12 and pfx are same format). Note for Windows XP users: Server Certificate Wizard in XP's IIS manager does not accept a p12 file. First you have to import the p12 file using mmc certificate snap-in into "Personal Certificates" store of w3svc (World Wide Web Publishing Service, i.e., IIS) service account. See "Windows Certificate Store for Service Programs" in certmemo_en.txt. Then, using the Server Certificate Wizard, select the just imported server certificate for use by IIS. That's it! Instructions for correctly configuring OWA basic authentication (for case b and d) See http://support.microsoft.com/kb/327843/en-us What this KB basically says is: - For "/exchange" and "/Public" virtual folders, enable Basic authentication (in addition to optional Windows Integrated authentication). - For "/ExchWeb" virtual folder, enable Anonymous authentication and DISABLE both Basic authentication and Windows Integrated authentication. Allowing anonymous access on "/ExchWeb" is considered safe because 1) it contains only static OWA-product related files, and 2) it is already protected by a reverse proxy like Orenosp. I consider this is a workaround for a bug in IIS's basic authentication (which I described in detail in "iisXXX.txt"). Instructions for manually configure a rewrite filter for Public folder This procedure must be followed if you are using OWA 2000 and the OWA public folder is not accessible via Orenosp. - create a config file named /rewrite_simple.conf - add rewrite rules to the config file: --- rewrite_simple.conf --- https://exchserver/public=https://mail.company.com/public http://exchserver/public=https://mail.company.com/public https://exchserver/Public=https://mail.company.com/Public http://exchserver/Public=https://mail.company.com/Public --- end --- Make sure the command "hostname" returns "exchserver" on your Exchange server's command prompt. - add the following to sproxy.conf --- sproxy.conf --- # Manual Rewrite Filter - must come after HTTP compression filter in config file proxy_filter_define = rewrite-simple mod_filt_rwt rwtype=simple mtype="text/html" proxy_filter_assign = * rewrite-simple --- end --- Basics ------ The safest way to make OWA available via a reverse proxy is to not touch the URL, i.e., use exactly the same external URL as the internal URL. In other words, the reverse proxy and the OWA server should (1) use the same host header (2) use the same protocol (https) (3) use the same path (i.e., don't try to translate any path) As for (1) you can specify -hh="_self_" option to proxy_pass_by rules. OWA should be installed in the "Default Web Site" with no optional host header. As for (2), you can just configure OWA to use SSL also. That is, you will use Orenosp for SSL bridging: ===SSL(1)== ===SSL(2)=== For some reason if you want to use HTTP between Orenosp and OWA, you can work around the issue using a special request header (Front-end-HTTPS:ON) proxy_pass_by = ... \ -hh="_self_" -rq_hdr="Front-end-HTTPS:ON" If you are using Forms Based Authentication in OWA 2003, you also need to set a special registry key (AllowRetailHTTPAuth=1) or set another key (SSLOffloaded=1). As for (3), there's no workaround. You need to follow this rule. Example Internal OWA URL http://exchserver/ but it can accept OWA requests on any host headers External OWA URL https://mail.company.com/ # --- listen port --- proxy_listen_name = ls-https 0.0.0.0@443 https # --- pass rules --- proxy_pass_by = url ls-https://mail.company.com/exchange \ http://exchserver/exchange -hh="_self_" -rq_hdr="Front-end-HTTPS:ON" proxy_pass_by = url ls-https://mail.company.com/ExchWeb \ http://exchserver/ExchWeb -hh="_self_" -rq_hdr="Front-end-HTTPS:ON" proxy_pass_by = url ls-https://mail.company.com/Public \ http://exchserver/Public -hh="_self_" -rq_hdr="Front-end-HTTPS:ON" # --- misc parameters required --- # this needs to be set to 0 when using "Front-end-HTTPS:ON" proxy_rewrite_destination = 0 Note that we wish to publish only OWA-related virtual directories. You may also add redirect rules to redirect users who visit "/" path to "/exchange" path. # --- redirects --- proxy_redirect_by = url ls-https://mail.company.com/ \ https://mail.company.com/exchange -s # if you also use port 80 for Orenosp: #proxy_redirect_by = url ls-http://mail.company.com/ \ # https://mail.company.com/exchange -s OWA's use of WebDAV ------------------- If you use IE to access OWA 2003, OWA will make the browser use WebDAV protocol in addition to regular HTTP/HTML. If you leave the URLs intact as indicated in the above, Orenosp should be able to successfully reverse proxy OWA's WebDAV protocol. If you observe strange behavior of OWA when using IE, see if the same behavior will happen also with other browsers (like Firefox), in which case the OWA will not use any WebDAV methods. Note: if you are using either "Front-end-HTTPS:ON" or "SSLOffloaded", you should NOT use "-rw_dav=1" option to proxy_pass_by paramter. Alternative Reverse Proxy Configuration --------------------------------------- If you cannot afford to use the same url for the internal and external names, you can try enabling automatic rewriting of contents and WebDAV requests. Internal OWA URL http://xcserver.us.company.com/ External OWA URL https://mail.company.com/ # --- Pass rules --- proxy_pass_by = url ls-https://mail.company.com/exchange \ http://xcserver.us.company.com/exchange -rw_dav=1 -rw_url=1 proxy_pass_by = url ls-https://mail.company.com/ExchWeb \ http://xcserver.us.company.com/ExchWeb -rw_dav=1 -rw_url=1 proxy_pass_by = url ls-https://mail.company.com/Public \ http://xcserver.us.company.com/Public -rw_dav=1 -rw_url=1 # --- Misc parameters required --- # this needs to be set to 1 when using automatic rewrite proxy_rewrite_destination = 1 # you may want to increase this parameter #proxy_post_save_limit = 65536 User Authentication and Authorization ------------------------------------- OWA 2000 Requires ues of either NTLM(Windows-integrated) or Basic authentications. OWA 2003 In addition to Windows-integrated and Basic authentications, it can also use its own form-based authentication. The safest choice is to use Orenosp's form-based authentication plus OWA's basic authentication. Possible combination Reverse Proxy OWA Usable on ----------------------------------------------- Orenosp-form OWA-basic OWA2000/2003 Orenosp-basic OWA-basic OWA2000/2003 (* limited. see below) Orenosp-form OWA-form OWA2003 Orenosp-basic OWA-form OWA2003 If you are using Orenosp solely for reverse proxying an OWA, welcoming end users with double authentication requests may not be desirable. Since Orenosp 0.7.2, the proxy is able to pass user credential obtained for Orenosp-form or Orenosp-basic to backend's basic authentication system. Orenosp-form -> OWA-basic : doable (proxy_authck_pass_to_backend = 1) Orenosp-basic -> OWA-basic : doable (proxy_auth_pass_to_backend = 1) Orenosp-form -> OWA-form : not doable Orenosp-basic -> OWA-form : not doable Recommendation - Use the form-based authentication at Orenosp For authentication database choice, either - use Windows user database (proxy_authck_authsrv_url = ) - use independent database (proxy_authck_authsrv_file = passwd.txt) - If OWA2000, use Basic authentication. If Orenosp and OWA share the authentication database (i.e., Orenosp uses Windows user database), you can pass user credentials to the OWA. - With OWA2003, use Basic authentication only if you want your users to avoid authenticating twice. Let user credentials pass through. Othersise use OWA forms-based authentication, forcing users to authenticate at both Orenosp and OWA. Example - Prepare Orenosp form-based authentication For backend authentication service, use localhost's IIS. Steps: - Create a virtual directory "orenosp_auth" in the default website. You can use any filesystem path for this. An example is c:\InetPub\wwwroot\orenosp_auth. Make the directory "readable" and "browsable". - Directory Security: disable "anonymous access" and enable "Basic authentication". ("Integrated Windows authentication" can be left enabled.) Domain and Realm can be anything. - Configure Orenosp form-base auth to pass user credential to the OWA Basic authentication. Orenosp passes the user credential obtained for its form-based authentication to OWA's basic authentication system. proxy_authck_enable = 1 proxy_authck_pass_to_backend = 1 proxy_authck_define = noone -u="" -rlm="nobody allowed" proxy_authck_define = anyname -u="_valid_:" -rlm="anyname" proxy_authck_assign = * noone proxy_authck_assign = ls-https://mail.company.com/* anyname proxy_authck_authsrv_url = http://localhost/orenosp_auth/ Implementing Idle Session Timeout --------------------------------- If you are using OWA 2003 with its Forms based authentication, you can use OWA's built-in idle session timeout. If you are using OWA 2000 or OWA 2003 without its Forms based auth, you can use idle timeout in Orenosp's form-based auth. proxy_authck_define = fmauth1 ... -tmo=3 In this case, idle sessions are timed out in 3 minutes. However, this option alone isn't sufficient to time out WebDAV-based OWA clients (like Internet Explorer 5 or later). This is because these clients send 2-minute periodic POLL requests to OWA, which makes the session not idle from Orenosp's standpoint. To have Orenosp to recognize this issue, use "-tmo_owa=on" option in addition to "-tmo=". proxy_authck_define = fmauth1 ... -tmo=3 -tmo_owa=on Additional Info: On OWA 2000 (SP2 or later), you can adjust interval of POLL requests with an OWA registry key "NewMailNotificationInterval". See http://support.microsoft.com/kb/311342/en-us. About Logging Out ----------------- Clicking OWA logout clears away all user credentials on the browser if the browser is IE6 (SP1). If you are using IE6 SP1 or later, when you click the logout button of OWA, the browser will clear HTTP basic authentication information in the browser. This is done by a javascript code that calls "ClearAuthenticationCache". On top of this, the script also seems to clear out SSL client certificate information by calling "mimeLogoff.Logoff()". We also noticed this OWA logoff page also seems clear out all HTTP cookies for the host, including Orenosp's cookie for form-based authentication. This means that it will clear out all other cookies also, like those used in load-balancing, etc. Multiple OWA Servers -------------------- Is it possible to aggregate multiple OWA servers into a single virtual host? Case 1: Two front-end Exchange Servers(OWA servers), sharing the same back-end Exchange server. exc-front-1 exc-front-2 In this case you can use Orenosp's load balancing groups (LBgroup). proxy_lbgroup_define = lbexchange nodes="exc-front-1,exc-front-2" proxy_pass_by = url https://mail.company.com/exchange lbgrp://lbexchange/exchange -hh="_self_" -rq_hdr="Front-end-HTTPS:ON" # repeat the same for /ExchWeb and /Public Case 2: Two independent Exchange Servers xcserver-tokyo xcserver-osaka It is possible to do this if you prepare a "login" server and use Orenosp's "pass by cookie" sub-rule. References ---------- http://support.microsoft.com/default.aspx?scid=kb;en-us;307347 http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=AFAD8426-572E-40F8-99DA-EB7198F374C4 Windows SharePoint Services (WSS) ================================= Reverse-proxying WSS is very similar to that of OWA. Basically you need to keep the URL unchanged between the reverse proxy and the IIS server. One significant difference is that WSS doesn't support the special "Front-end-HTTPS:ON" request header. So you must configure SSL on the IIS server and forward all requests in HTTPS protocol. References http://www.microsoft.com/technet/prodtechnol/windowsserver2003/technologies/sharepoint/revproxy.mspx Interoperability Tips with IIS ============================== Co-existing Orenosp with IIS on a Single Server --------------------------------------------------- - By default, IIS 5.0 (Windows 2000) binds to 0.0.0.0:80 and 0.0.0.0:443 even if SSL is not enabled on the IIS. Therefore if HTTP-only IIS is already running, Orenosp will not be able to bind to port 443. To allow IIS to use port 80 and Orenosp to use port 443, you must disable IIS socket pooling. See next subsection. - IIS 6.0 has an identical problem, but you need take a different action. See the subsection for IIS 6.0 below. IIS 5.0 (on Windows 2000) ------------------------- You need to disable "socket pooling" feature of IIS. With this feature on (default), IIS 5.0 listens on all IP addresses regardless of whether they have been assigned to IIS or not. Disabling socket pooling AND assigning unique IP addresses to IIS' sites will solve the problem. 1) Assign an IP address to a IIS web site. 2) Disable socket pooling feature of the IIS web site. > cd \inetpub\AdminScripts > cscript adsutil.vbs set w3svc/disablesocketpooling true The command prompt returns the following: disablesocketpooling : (BOOLEAN) TRUE 3) Restart the Windows (or IIS only) See MS KB 259349 IIS Binds To All Available IP Addresses When It Starts See MS KB 238131 How to Disable Socket Pooling IIS 6.0 (on Windows 2003) ------------------------- IIS binds to all IP addresses on the server, not just the IP addresses that are assigned to Web sites. Setting DisableSocketPooling to True as done in IIS 5 is not effective. You can specify IP address(es) IIS should listen on using a MS-provided support program, httpcfg.exe. Httpcfg.exe is located on the Windows Server 2003 CD in the Support\Tools directory as part of the Support.cab file. You can specify the IP addresses IIS will listen on by adding them to the IP inclusion list. Don't add the IP address that your Orenosp will use. The IP inclusion list is read during startup of the IIS HTTP service. If you change the list, you must restart the service. To add an IP address to the IP inclusion list: Type the following, where xxx.xxx.x.x is the IP address you want to add: > httpcfg set iplisten -i xxx.xxx.x.x For example, > httpcfg set iplisten -i 192.168.1.100 When this succeeds, Httpcfg returns the following: HttpSetServiceConfiguration completed with 0 After the IP address is added, use the following command to list it: > httpcfg query iplisten Httpcfg returns the following: IP :192.168.1.100 See MS KB 813368 IIS 6.0: Setting Metabase Property DisableSocketPooling Has No Effect Interoperating with IIS Windows Integrated Authentication --------------------------------------------------------- By default, Orenosp will disable Windows Integerated Authentication. Specifically, Orenosp will drop any authentication requests from backend that specify either "NTLM" or "Negotiate" methods. If you set the following parameter in sproxy.conf, Orenosp will relay these authentication methods: proxy_auth_disable_ntlm = 0 proxy_auth_disable_negotiate = 0 Please refer to "Passing Backend Authentication" in Users' Guide for more info. - Reverse-proxying IIS WebDAV See padmin/doc/webdav_en.txt. Other Information ----------------- IIS Insider http://www.microsoft.com/technet/community/columns/insider/default.mspx April 2006 article has an explanation on IIS authentication and reverse proxies. Miscellaneous Parameters ======================== SSL Client Authentication ========================= This section is common between Orenosp and Orenosv FTP. In the following, please replace with sproxy (for Orenosp) or ftp (for Orenosv FTP). SSL has client authentication mechanism where server side authenticates a client using the client certifictate. Required Client side: a certificate and private key for each user Server side: certificates of CA's that the Orenosv administrator trusts. The server only accepts client certificates that are issued by these trusted CA's. How to obtain client certificate and private key: Have them issued from any CA's that you trust. Since you have control over which CA's to trust, you can create your own private CA and issue client certificates by yourself. You can use gencert program that comes with Orenosp to generate client certificates. You can also use Openssl or other full-fledged certificate management tools. Using gencert to generate client certificates >gencert -gencli -> generates a .p12 file, have your user to install/import this file into his/her browser. collection of CA certificates you (the reverse proxy) trust: a) only allow client certificates issued by your own private CA. you need certificate of that CA if you want to allow certificates from other CA's: b) use list of trusted CA's that are preinstalled in the operating system (Windows Certificate Store). WARNING: if you are using Windows XP, by default this list is dynamically controlled by the maker of the OS (i.e., Microsoft). Be sure to read notes below. c) use collection of CA certificates from Apache's modssl distribution. get http://www.modssl.org/. How to configure 1) Set SSL client authentication to "require" # enable SSL client authentication _ssl_clauth = require 2) specify certificate store of trusted CA's in SSL client authentication -- only specify certificate of your own private CA (a) -- _ssl_cacertstore = file ssl.crt/ca.crt and place the CA certificate as ssl.crt/ca.crt. This certificate must be in PEM format. If you have used gencert to generate all certificates, do: > cd or > copy myca\cacert.pem ssl.crt\ca.crt [Linux/Mac]$ cp -p myca/cacert.pem ssl.crt/ca.crt -- use list of trusted CA's preinstalled in the OS (b) -- _ssl_cacertstore = os This is the default when you enable SSL client authentication. -- use Apache modssl's list of CA certificates (c) -- If using SSLCACertificateFile in Apache, specify a single PEM certificate file: _ssl_cacertstore = file ssl.crt/ca-bundle.crt If using SSLCACertificatePath in Apache, specify a directory in which multiple PEM certificates are stored: _ssl_cacertstore = dir ssl_ca.crt The server dynamically loads these certs on demand. In order to do this, these certs must be indexed by hash of subject name and these hashes must be built before you start the server. In (or )/ssl_ca.crt, there is a batch program, called certhash.bat, along with helper batch file, namehash.bat. You can put CA cert files in this directory and run certhash.bat to build required hashes. - for certhash.bat to work, CA cert files must be named as "XXXX.crt". - specify location of openssl.exe in namehash.bat. parameters # SSL client authentication proxy_ssl_clauth = require proxy_ssl_cacertstore = file ssl.crt/ca.crt Testing SSL client authentication is done during SSL handshake. Some programs (including Orenosp!) don't give descriptive diagnostic information when SSL authentication fails. You can diagnose the problem using SSL packet tracing. a) use openssl.exe's s_client command to examine SSL negotiation process. >openssl s_client -connect localhost:443 b) capture and analyze SSL packets using SSL-enabled network sniffers recommended ssldump by Eric Rescorla Homepage http://www.rtfm.com/ssldump/ Windows binary http://home.comcast.net/~makataoka/misc/ c) turn on tracing on server side _trace_level = 1 This will dump out tracing during SSL handshake, among other things. Notes - Cautions when using method b), i.e., using Windows Certificate Store In Windows XP by default, a component called "automatic update of root certificates" is installed and enabled. This component is invoked by IE or any other SChannel-based programs (like Smartftp) when those programs detect a root CA that is not trusted. When that happens it will contact a Microsoft Windows Update site to see if the CA in question should be trusted. This decision is in sole discretion of Microsoft, and without any consent from the user, the CA's certificate is installed(recorded) in your operating system as a trusted root CA. If you, as the administrator of your site, finds this mechanism unacceptable, you should disable this component by following the directions below. From Control Panel : Add/Remove Windows Components, delete "update of root certificates" (see Knowledge Base Q283717). By the way Orenosp reads in the list of trusted CA's at its startup so it must be restarted if this list is changed. - If you want to add your private CA's certificate into the list of Windows' trusted root CA: set in config file : _ssl_cacertstore = os and follow the instructions for "Windows Certificate Store for Service Programs" section of certmemo_en.txt to add the CA certificate to Orenosv/Orenosp service's list of trusted root CAs. SSL Profiles ============ Please see "SSL Profiles" in sproxy_full.txt. When trouble-shooting, you can set "proxy_sslprof_printinfo = 1" to dump all SSL parameters in effect to event.log. --- example for using three different SSL profiles to use three SSL certificate --- # 1st listen port uses default SSL profile proxy_listen_name = lis-ssl 0.0.0.0@443 https # 2nd listen port uses SSL profile "site2" proxy_listen_name = lis-ssl2 0.0.0.0@4443 https -ssl_cli=site2 # 3rd listen port uses SSL profile "site3" proxy_listen_name = lis-ssl3 0.0.0.0@4444 https -ssl_cli=site3 # # settings for default server SSL profile # # use proxy_ssl_xxx to set required attributes # # define SSL profile "site2" # proxy_sslprof_define = site2 proxy_sslprof_site2_ptype = server proxy_sslprof_site2_mycertstore = file ssl.crt/server-site2.crt \ ssl.key/server-site2.key # # define SSL profile "site3" # proxy_sslprof_define = site3 proxy_sslprof_site3_ptype = server proxy_sslprof_site3_mycertstore = file ssl.crt/server-site3.crt \ ssl.key/server-site3.key --- Appendice ========= Setting Up a Simple Windows Raidus Server (IAS) ----------------------------------------------- - On Windows Server 2003, add IAS component. - Open "Internet Authentication Service" tool. - Under "RADIUS Clients", add Orenosp as a new RADIUS client. Specify Orenosp's IP address and a shared secret. - Under "Remote Access Policies", add a new remote access policy. Choose "Set up a custom policy", name the policy "Orenosp". - Add a policy condition specifying that attribute "NAS-Port-Type" match "Virtual[VPN]". - Choose "Grant remote access permission" if a connection request matches the specified condition. - Open "Edit Profile". Go to the Authentication tab. - Select "Unencrypted authentication (PAP,SPAP)" and unselect everything else. Or if you want to use encrypted authentication: - Select "Encrypted Authentication (CHAP)" and unselect everything else. In this case, you should add "auth=chap" to Orenosp's configuration also (proxy_authck_authsrv_radius or proxy_auth_authsrv_radius). For logging, see Windows Event Viewer (System). --- EOF