Reverse Proxy with Squid: Difference between revisions

From RSWiki
Jump to navigation Jump to search
No edit summary
No edit summary
 
(21 intermediate revisions by the same user not shown)
Line 1: Line 1:
==Caveat==
While this HowTo was originally written based upon Ubuntu 7.10, the information below should still be valid and accurate. Certainly for the 2.7 releases of Squid - 12/04/11
== Introduction ==
== Introduction ==
If like me your ISP provides you with a single static IP address you may think that you are limited to running one web server. Or at the very best using NAT to ports other than port 80 on other servers. There are many reasons why you would wish to use more than one webserver. For example you may wish to have Apache serving one site and Microsoft IIS 6.0 serving another or even JBoss, Tomcat or some other application server.
If like me your ISP provides you with a single static IP address you may think that you are limited to running one web server. Or at the very best using NAT to ports other than port 80 on other servers. There are many reasons why you would wish to use more than one webserver. For example you may wish to have Apache serving one site and Microsoft IIS 6.0 serving another or even JBoss, Tomcat or some other application server.


== Background ==
== Background ==
For my scenario I wished to run Apache and PHP. Indeed it is this combination on which this very site is running. In addition to this I also wished to run another site on IIS 6.0. I have various domain names belonging to myself and friends that are hosted on my primary webserver. These use Apaches built in Virtual Hosts directive however one site that I was asked to host required Microsofts IIS. I explored the many options that were available and concluded that using Squid as a reverse proxy would be my best option.
For my scenario I wished to run Apache and PHP on one server and IIS on another. For this HowTo I will be configuring squid on Ubuntu 7.10. The location of your configuration files may depend on your installation. However for this howto I will be assuming that your configuration files are under /etc/squid and the cache itself is under /var/squid.
 
== Equipment ==
My scenario uses three individual servers.
 
The reverse proxy - running Ubuntu 6.06<br>
The Apache Web server - runnin Ubuntu 6.06<br>
The IIS server - running Windows Server 2003<br>
 
== Configuring the Proxy ==
I used a base install of Ubuntu 6.06 and manually compiled the most recent version of Squid which as of this time of writing is Squid 2.6-Stable14. The only configure flag that I used was --prefix=/usr
 
Once Squid was compiled and installed I now had the following directory structure:
 
/usr/etc/squid.conf - Squid configuration file.<br>
/usr/var/logs - log file locations.<br>
/usr/var/cache - location of the cache itself.<br>
/usr/sbin/squid - location of the Squid executable.


== Editing squid.conf ==
== Editing squid.conf ==
Line 28: Line 15:
By default Squid is configured to listen on TCP port 3128. As we wish to use Squid as a web server we need to tell it to listen on port 80 instead. So the first line of our new squid.conf is as follows:
By default Squid is configured to listen on TCP port 3128. As we wish to use Squid as a web server we need to tell it to listen on port 80 instead. So the first line of our new squid.conf is as follows:


http_port 80 accel defaultsite=www.sweetnam.eu vhost
<syntaxhighlight lang="squid.conf">
http_port 80 accel defaultsite=www.sweetnam.eu vhost
forwarded_for on
</syntaxhighlight>


The default site to be served is www.sweetnam.eu and we will use vhost directives to configure the other servers.
The default site to be served is www.sweetnam.eu and we will use vhost directives to configure the other servers. In addition, the forwarded_for on is required for logging the original client address to the back end server. See below.


The next lines in the configuration are merely Squids default:
The next lines in the configuration are merely Squids default:


acl QUERY urlpath_regex cgi-bin \?
<syntaxhighlight lang="squid.conf">
cache deny QUERY
refresh_pattern ^ftp:          1440    20%    10080
acl apache rep_header Server ^Apache
refresh_pattern ^gopher:        1440    0%      1440
broken_vary_encoding allow apache
refresh_pattern .              0      20%    4320
</syntaxhighlight>
access_log /usr/var/logs/access.log
 
cache_log /usr/var/logs/cache.log
cache_store_log /usr/var/logs/store.log
refresh_pattern ^ftp:          1440    20%    10080
refresh_pattern ^gopher:        1440    0%      1440
refresh_pattern .              0      20%     
The next lines are where we begin to configure the two seperate servers.
The next lines are where we begin to configure the two seperate servers.


First we add a directive to tell Squid the IP address of the first server:
First we add a directive to tell Squid the IP address of the first server:


cache_peer 172.20.1.10 parent 80 0 no-query originserver name=server_1
<syntaxhighlight lang="squid.conf">
cache_peer 172.20.1.10 parent 80 0 no-query no-digest originserver name=apache login=PASS
You can see from above that we have given a name of server_1. All sites that will be hosted on this server will be under this group.
</syntaxhighlight>
 
You can see from above that I have given a name of apache. All sites that will be hosted on this server will be under this group. Appending login=PASS at the end tells Squid to pass authentication on to the back end server. For example if you have directories password protected using .htaccess.


Next we must tell Squid the domains that will be served under server_1:
Next we must tell Squid the domains that will be served under apache:


acl sites_server_1 dstdomain www.sample.com sample.com
<syntaxhighlight lang="squid.conf">
acl our_sites dstdomain www.sample.com sample.com
acl sites_apache dstdomain www.sample.com sample.com
cache_peer_access server_1 allow sites_server_1
acl our_sites dstdomain www.sample.com sample.com
cache_peer_access apache allow sites_apache
</syntaxhighlight>


To add more domain names simply add them after the sample ones above.
To add more domain names simply add them after the sample ones above.
Line 66: Line 52:
Now we will configure the second server:
Now we will configure the second server:


cache_peer 172.20.1.4 parent 80 0 no-query originserver name=server_2
<syntaxhighlight lang="squid.conf">
acl sites_server_2 dstdomain www.sample2.com sample2.com
cache_peer 172.20.1.4 parent 80 0 no-query no-digest originserver name=iis login=PASS
acl our_sites2 dstdomain www.sample2.com sample2.com
acl sites_iis dstdomain www.sample2.com sample2.com
cache_peer_access server_2 allow sites_server_2
acl our_sites2 dstdomain www.sample2.com sample2.com
cache_peer_access iis allow sites_iis
</syntaxhighlight>


And we now tell squid to allow access to the two servers:
Next we must ensure that Squids default acl rules are in place. For this I simply copied the defaults:


  http_access allow our_sites
<syntaxhighlight lang="squid.conf">
http_access allow our_sites2
acl all src 0.0.0.0/0.0.0.0
acl manager proto cache_object
acl localhost src 127.0.0.1/255.255.255.255
acl to_localhost dst 127.0.0.0/8
acl SSL_ports port 443
acl Safe_ports port 80          # http
acl Safe_ports port 21          # ftp
acl Safe_ports port 443        # https
acl Safe_ports port 70          # gopher
acl Safe_ports port 210        # wais
acl Safe_ports port 1025-65535 # unregistered ports
acl Safe_ports port 280        # http-mgmt
acl Safe_ports port 488        # gss-http
acl Safe_ports port 591        # filemaker
acl Safe_ports port 777        # multiling http
acl CONNECT method CONNECT
</syntaxhighlight>


Next we must ensure that Squids acl rules are in place. For this I simply copied the defaults:
Next we add two entries to allow the acls that we created for the backend servers:


acl all src 0.0.0.0/0.0.0.0
<syntaxhighlight lang="squid.conf">
acl manager proto cache_object
http_access allow our_sites2
acl localhost src 127.0.0.1/255.255.255.255
http_access allow our_sites
acl to_localhost dst 127.0.0.0/8
</syntaxhighlight>
acl SSL_ports port 443
 
acl Safe_ports port 80          # http
And finally some more default configuration information:
acl Safe_ports port 21          # ftp
acl Safe_ports port 443        # https
acl Safe_ports port 70          # gopher
acl Safe_ports port 210        # wais
acl Safe_ports port 1025-65535  # unregistered ports
acl Safe_ports port 280        # http-mgmt
acl Safe_ports port 488        # gss-http
acl Safe_ports port 591        # filemaker
acl Safe_ports port 777        # multiling http
acl CONNECT method CONNECT
http_access allow manager localhost
http_access deny manager
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_access deny all
icp_access allow all


The last entries in our squid.conf are specific to your server:
<syntaxhighlight lang="squid.conf">
http_access allow manager all
http_access allow manager
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_access deny all


cache_mgr admin@sample.com
access_log /var/log/squid/access.log
cache_effective_user www-data
cache_mgr someone@somewhere.com
cache_effective_group www-data
</syntaxhighlight>
visible_hostname hostname.sample.com


You may now start Squid with the following command:
And that's it your reverse proxy should now be configured and is ready to start serving requests. So you may now start squid by entering the following at a console:


  /usr/sbin/squid -sY -f /usr/etc/squid.conf
  /etc/init.d/squid start
   
   
== Notes ==
== Notes ==


Line 118: Line 110:


The reverse proxy must be facing the internet. Either directly or by port forwarding.
The reverse proxy must be facing the internet. Either directly or by port forwarding.
If you intend on serving many domains such as I do you may find your squid.conf is getting rather ugly and difficult to manage. If this is the case then you can configure squid to lookup the domains to be served in a file instead.
To do this you you would use the following:
<syntaxhighlight lang="squid.conf">
acl sites_apache dstdomain "/etc/squid/apachesites"
acl our_sites dstdomain "/etc/squid/apachesites"
cache_peer_access apache allow sites_apache
</syntaxhighlight>
You simply add eash domain to be directed to the back end server to the file specified.


== Complete squid.conf ==
== Complete squid.conf ==
<syntaxhighlight lang="squid.conf">
http_port 80 accel defaultsite=www.sweetnam.eu vhost
forwarded_for on
refresh_pattern ^ftp:          1440    20%    10080
refresh_pattern ^gopher:        1440    0%      1440
refresh_pattern .              0      20%    4320
cache_peer 172.20.1.10 parent 80 0 no-query no-digest originserver name=apache login=PASS
acl sites_apache dstdomain www.sample.com sample.com
acl our_sites dstdomain www.sample.com sample.com
cache_peer_access apache allow sites_apache
cache_peer 172.20.1.4 parent 80 0 no-query no-digest originserver name=iis login=PASS
acl sites_iis dstdomain www.sample2.com sample2.com
acl our_sites2 dstdomain www.sample2.com sample2.com
cache_peer_access iis allow sites_iis
acl all src 0.0.0.0/0.0.0.0
acl manager proto cache_object
acl localhost src 127.0.0.1/255.255.255.255
acl to_localhost dst 127.0.0.0/8
acl SSL_ports port 443
acl Safe_ports port 80          # http
acl Safe_ports port 21          # ftp
acl Safe_ports port 443        # https
acl Safe_ports port 70          # gopher
acl Safe_ports port 210        # wais
acl Safe_ports port 1025-65535  # unregistered ports
acl Safe_ports port 280        # http-mgmt
acl Safe_ports port 488        # gss-http
acl Safe_ports port 591        # filemaker
acl Safe_ports port 777        # multiling http
acl CONNECT method CONNECT


Here is a complete squid.conf:
http_access allow our_sites2
http_access allow our_sites


http_port 80 accel defaultsite=www.sweetnam.eu vhost
http_access allow manager all
acl QUERY urlpath_regex cgi-bin \?
http_access allow manager
cache deny QUERY
http_access deny !Safe_ports
acl apache rep_header Server ^Apache
http_access deny CONNECT !SSL_ports
broken_vary_encoding allow apache
http_access deny all
 
access_log /usr/var/logs/access.log
access_log /var/log/squid/access.log
cache_log /usr/var/logs/cache.log
cache_mgr someone@somewhere.com
cache_store_log /usr/var/logs/store.log
</syntaxhighlight>
 
refresh_pattern ^ftp:          1440    20%    10080
== Configuring Logging to the back end servers ==
refresh_pattern ^gopher:        1440    0%      1440
 
refresh_pattern .              0      20%
When using a reverse proxy you may notice that the logs on the back end servers will show hits as coming from the proxy rather then the client. There is a feature in Squid as noted earlier called ''forwarded_for on''. This will pass the original clients IP address to the back end server. However you need to configure a custom log format on the back end server for logging to occur.
 
acl sites_server_1 dstdomain www.sample.com sample.com
For Apache, I edited the httpd.conf and added a new line in the logging section called ''cached''. This line as it appears in my configuration file looks like this:
acl our_sites dstdomain www.sample.com sample.com
 
cache_peer_access server_1 allow sites_server_1
<syntaxhighlight lang="apacheconf">
LogFormat "%{X-Forwarded-For}i %v %u %t \"%r\" %>s %b \"%{Referer}i\"\"%{User-Agent}i\"" cached
cache_peer 172.20.1.4 parent 80 0 no-query originserver name=server_2
</syntaxhighlight>
acl sites_server_2 dstdomain www.sample2.com sample2.com
 
acl our_sites2 dstdomain www.sample2.com sample2.com
Now you need to configure your default sites or virtual hosts so that they will use the new log format. Simply locate the entry for your host and change the CustomLog entry so that it looks like this:
cache_peer_access server_2 allow sites_server_2
 
<syntaxhighlight lang="squid.conf">
http_access allow our_sites
CustomLog /home/blog/logs/access_log cached
http_access allow our_sites
</syntaxhighlight>
acl all src 0.0.0.0/0.0.0.0
acl manager proto cache_object
acl localhost src 127.0.0.1/255.255.255.255
acl to_localhost dst 127.0.0.0/8
acl SSL_ports port 443
acl Safe_ports port 80          # http
acl Safe_ports port 21          # ftp
acl Safe_ports port 443        # https
acl Safe_ports port 70          # gopher
acl Safe_ports port 210        # wais
acl Safe_ports port 1025-65535  # unregistered ports
acl Safe_ports port 280        # http-mgmt
acl Safe_ports port 488        # gss-http
acl Safe_ports port 591        # filemaker
acl Safe_ports port 777        # multiling http
acl CONNECT method CONNECT
http_access allow manager localhost
http_access deny manager
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_access deny all
icp_access allow all
cache_mgr admin@sample.com
cache_effective_user www-data
cache_effective_group www-data
visible_hostname hostname.sample.com
   
   
Once you have configured Apache you need to restart the service.
== Extras ==
Squid contains some powerful features that can be used to further secure and limit access to the back end servers. For example limiting who can access your global sites or blocking access by certain useragents. I have another tutorial about [[Blocking Bots with Squid]] which you may find interesting.
== Thanks and Credits ==


[[Category:Technical| ]] [[Category:Web| ]] [[Category:Linux| ]]
Many thanks are owed to Paolo Marchiori and John Moylan of the [http://www.ilug.ie Irish Linux Users Group] who helped me figure out how to pass configure the custom log format for Apache.


--[[User:Robert|Robert]] 21:51, 18 August 2007 (IST)
[[Category:Technical| ]] [[Category:Web| ]] [[Category:Linux| ]] [[Category:Squid Cache|Squid Cache]]

Latest revision as of 18:59, 5 April 2016

Caveat

While this HowTo was originally written based upon Ubuntu 7.10, the information below should still be valid and accurate. Certainly for the 2.7 releases of Squid - 12/04/11

Introduction

If like me your ISP provides you with a single static IP address you may think that you are limited to running one web server. Or at the very best using NAT to ports other than port 80 on other servers. There are many reasons why you would wish to use more than one webserver. For example you may wish to have Apache serving one site and Microsoft IIS 6.0 serving another or even JBoss, Tomcat or some other application server.

Background

For my scenario I wished to run Apache and PHP on one server and IIS on another. For this HowTo I will be configuring squid on Ubuntu 7.10. The location of your configuration files may depend on your installation. However for this howto I will be assuming that your configuration files are under /etc/squid and the cache itself is under /var/squid.

Editing squid.conf

The supplied squid.conf is over 4000 lines long. Most of this is documentation added in the comments. For my purposes I created a new squid.conf from scratch.

By default Squid is configured to listen on TCP port 3128. As we wish to use Squid as a web server we need to tell it to listen on port 80 instead. So the first line of our new squid.conf is as follows:

http_port 80 accel defaultsite=www.sweetnam.eu vhost
forwarded_for on

The default site to be served is www.sweetnam.eu and we will use vhost directives to configure the other servers. In addition, the forwarded_for on is required for logging the original client address to the back end server. See below.

The next lines in the configuration are merely Squids default:

refresh_pattern ^ftp:           1440    20%     10080
refresh_pattern ^gopher:        1440    0%      1440
refresh_pattern .               0       20%     4320

The next lines are where we begin to configure the two seperate servers.

First we add a directive to tell Squid the IP address of the first server:

cache_peer 172.20.1.10 parent 80 0 no-query no-digest originserver name=apache login=PASS

You can see from above that I have given a name of apache. All sites that will be hosted on this server will be under this group. Appending login=PASS at the end tells Squid to pass authentication on to the back end server. For example if you have directories password protected using .htaccess.

Next we must tell Squid the domains that will be served under apache:

acl sites_apache dstdomain www.sample.com sample.com
acl our_sites dstdomain www.sample.com sample.com
cache_peer_access apache allow sites_apache

To add more domain names simply add them after the sample ones above.

Now we will configure the second server:

cache_peer 172.20.1.4 parent 80 0 no-query no-digest originserver name=iis login=PASS
acl sites_iis dstdomain www.sample2.com sample2.com
acl our_sites2 dstdomain www.sample2.com sample2.com
cache_peer_access iis allow sites_iis

Next we must ensure that Squids default acl rules are in place. For this I simply copied the defaults:

acl all src 0.0.0.0/0.0.0.0
acl manager proto cache_object
acl localhost src 127.0.0.1/255.255.255.255
acl to_localhost dst 127.0.0.0/8
acl SSL_ports port 443
acl Safe_ports port 80          # http
acl Safe_ports port 21          # ftp
acl Safe_ports port 443         # https
acl Safe_ports port 70          # gopher
acl Safe_ports port 210         # wais
acl Safe_ports port 1025-65535  # unregistered ports
acl Safe_ports port 280         # http-mgmt
acl Safe_ports port 488         # gss-http
acl Safe_ports port 591         # filemaker
acl Safe_ports port 777         # multiling http
acl CONNECT method CONNECT

Next we add two entries to allow the acls that we created for the backend servers:

http_access allow our_sites2
http_access allow our_sites

And finally some more default configuration information:

http_access allow manager all
http_access allow manager
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_access deny all

access_log /var/log/squid/access.log
cache_mgr someone@somewhere.com

And that's it your reverse proxy should now be configured and is ready to start serving requests. So you may now start squid by entering the following at a console:

/etc/init.d/squid start

Notes

All the above assumes that you have DNS configured so that each domain name that you have is pointing to the IP address of the reverse proxy.

The reverse proxy must be facing the internet. Either directly or by port forwarding.

If you intend on serving many domains such as I do you may find your squid.conf is getting rather ugly and difficult to manage. If this is the case then you can configure squid to lookup the domains to be served in a file instead.

To do this you you would use the following:

acl sites_apache dstdomain "/etc/squid/apachesites"
acl our_sites dstdomain "/etc/squid/apachesites"
cache_peer_access apache allow sites_apache

You simply add eash domain to be directed to the back end server to the file specified.

Complete squid.conf

http_port 80 accel defaultsite=www.sweetnam.eu vhost
forwarded_for on

refresh_pattern ^ftp:           1440    20%     10080
refresh_pattern ^gopher:        1440    0%      1440
refresh_pattern .               0       20%     4320

cache_peer 172.20.1.10 parent 80 0 no-query no-digest originserver name=apache login=PASS
acl sites_apache dstdomain www.sample.com sample.com
acl our_sites dstdomain www.sample.com sample.com
cache_peer_access apache allow sites_apache

cache_peer 172.20.1.4 parent 80 0 no-query no-digest originserver name=iis login=PASS
acl sites_iis dstdomain www.sample2.com sample2.com
acl our_sites2 dstdomain www.sample2.com sample2.com
cache_peer_access iis allow sites_iis

acl all src 0.0.0.0/0.0.0.0
acl manager proto cache_object
acl localhost src 127.0.0.1/255.255.255.255
acl to_localhost dst 127.0.0.0/8
acl SSL_ports port 443
acl Safe_ports port 80          # http
acl Safe_ports port 21          # ftp
acl Safe_ports port 443         # https
acl Safe_ports port 70          # gopher
acl Safe_ports port 210         # wais
acl Safe_ports port 1025-65535  # unregistered ports
acl Safe_ports port 280         # http-mgmt
acl Safe_ports port 488         # gss-http
acl Safe_ports port 591         # filemaker
acl Safe_ports port 777         # multiling http
acl CONNECT method CONNECT

http_access allow our_sites2
http_access allow our_sites

http_access allow manager all
http_access allow manager
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_access deny all

access_log /var/log/squid/access.log
cache_mgr someone@somewhere.com

Configuring Logging to the back end servers

When using a reverse proxy you may notice that the logs on the back end servers will show hits as coming from the proxy rather then the client. There is a feature in Squid as noted earlier called forwarded_for on. This will pass the original clients IP address to the back end server. However you need to configure a custom log format on the back end server for logging to occur.

For Apache, I edited the httpd.conf and added a new line in the logging section called cached. This line as it appears in my configuration file looks like this:

LogFormat "%{X-Forwarded-For}i %v %u %t \"%r\" %>s %b \"%{Referer}i\"\"%{User-Agent}i\"" cached

Now you need to configure your default sites or virtual hosts so that they will use the new log format. Simply locate the entry for your host and change the CustomLog entry so that it looks like this:

CustomLog /home/blog/logs/access_log cached

Once you have configured Apache you need to restart the service.

Extras

Squid contains some powerful features that can be used to further secure and limit access to the back end servers. For example limiting who can access your global sites or blocking access by certain useragents. I have another tutorial about Blocking Bots with Squid which you may find interesting.

Thanks and Credits

Many thanks are owed to Paolo Marchiori and John Moylan of the Irish Linux Users Group who helped me figure out how to pass configure the custom log format for Apache.