Computer/Network

[Linux] 계정별로 트래픽 제한하기

알찬돌삐 2005. 5. 24. 08:53
Apache 계정별로 트래픽 제한하기

웹호스팅 서버를 운영하다 보면 해당 서버에 보통 많은 도메인들이 들어가게 됩니다.
이때 마다 해당 계정들의 트래픽과 하루 접속자 수를 모니터링 해야 하는 필요성이 있습니다.
이때 각각의 도메인에 대해 트래픽을 관리할 수 있는 방법으로 몇가지가 있지만.. mod_throttle
라는 아파치 모듈을 이용해서 할 수가 있습니다.
아래 내용을 참조하셔서 직접 적용해 보시기 바랍니다... ^^

www.snert.com에 접속하면 어떤 아저씨(Anthony Howe)가 강아지를 안고 있는 사진이 있습니다.
강아지인지 개인지는 모르지만 안고 있을만 하니 강아지라고 하지요.
아래와 같은 메뉴에서 software를 클릭하면 다양한 모듈들이 나오네요.
Stuff from Snert
Interesting and sometimes useful software.

다들 쓸만한 것인데 이거 다 적용해 보다 보면 한달은 꼬박 걸리겠네요.
암튼 함 사이트 구경해 보세요....나도 그런 사이트 하나 운영해 봤으면 하는 생각이 절로 들겁니다.


먼저 http://www.snert.com/Software/mod_throttle/mod_throttle312.tgz 에서 관련 소스 파일을
다운로드하여 압축을 해제한다.
DSO 모듈을 빌드하기 위해서는 아파치 소스 디렉토리에서 아래와 같이 한다.
cd /path/to/mod_throttle-3.1
make install

권장하는 방법으로, static하게 모듈을 빌드하려면 아파치 소스 디렉토리에서 컴파일시 아래와 같이
mod_throttle 를 모듈에 추가하도록 한다.

./configure --prefix=/usr/local/apache --activate-module=src/modules/php4/libphp4.a
--add-module=../mod_throttle-3.1.2/mod_throttle.c

위 설정은 php4 와 mod_throttle 를 아파치에 모듈로 설정하는 화면이다.
아파치 컴파일을 완료한 후 생성된 /usr/local/apache/bin 디렉토리에서 httpd -l 을 실행하여
mod_throttle.c 이 모듈에 포함되었는지 여부를 확인한다.
# cat httpd.conf

AddModule mod_throttle.c


모듈로 포함되었음이 확인되면 일단 설치는 완료되었으니 이제 본격적으로 httpd.conf 에 설정을 해 보도록 하겠다.

#vi /usr/local/apache/conf/httpd.conf
[CODE]# 공통설정부분 <Location /throttle-status> Order deny,allow Deny from all Allow from 192.168.1.0/255.255.255.0 </Location> [/CODE]
위는 throttle-status 를 설정하였을 경우 http://domain.com/throttle-status/ 로 접속시 모든
도메인에 대한 트래픽이나 접속자수등의 중요한 정보가 그대로 노출되므로 throttlee-status 에
대해 특정 IP 대역에서만 (위의 경우 192.168.1.0 대역에서만) 접근이 가능하도록 제한하는
설정이다.

# 일반 설정 부분.
[CODE]<IfModule mod_throttle.c> ThrottlePolicy None // 기본적으로는 None 으로 설정한다. <Location /throttle-status> SetHandler throttle-status // throttle-me 등도 있는데, throttle-status 만 필요하다. </Location> </IfModule> [/CODE]

참고로 throttle-me는 http://domain.com/throttle-me/ 로 접속시 domain.com 이라는 하나의
도메인에 대해서만 정보를 확인할 수 있도록 하는 방법이다.
http://domain.com/throttle-status/ 로 접속시에는 모든 가상 도메인에 대해 정보를 볼 수 있게
된다.

# 가상 호스트 설정 부분.
[CODE]<VirtualHost 198.162.0.2) ServerAdmin admin@test.net DocumentRoot /home/data/www ServerName www.test.net ThrottlePolicy Volume 300M 1d //하루에 전송량 300M ThrottlePolicy Request 1000 1d //하루에 히트수 1000회 제한 ThrottleClientIP 100 volume 200 300 // 로그를 100K 남기며 300초간 200K 의 전송량 제한 </VirtualHost>[/CODE]

위와 같이 설정 후 전송량이나 히트수등을 초과하면 www.test.net 접속시 원래의 페이지가 아닌
503 에러 화면이 뜨게 되며, ErrorDocument 503 /~user/ 로 redirect 설정을 추가해 주면
트래픽 초과시 503에러화면 대신 /~user/index.html 파일을 보여 주도록 한다.
따라서 이 파일에 트래픽이나 히트수등의 초과에 대한 경고문등 적당한 메시지 화면을 만들면 된다.

그리고 아래와 같이 설정시에는,

# 일반 설정 부분.
[CODE]<IfModule mod_throttle.c> ThrottlePolicy Volume 300M 1d <Location /throttle-status> SetHandler throttle-status </Location> </IfModule>[/CODE]

# 가상 호스트 설정 부분.
[CODE]<VirtualHost 198.162.0.2) ServerAdmin admin@test.net DocumentRoot /home/data/www ServerName www.test.net ThrottlePolicy Volume 500M 1d // 하루에 전송량 500M </VirtualHost>[/CODE]

위와 같이 설정시 별도로 제한을 설정하지 않은 모든 도메인은
하루 전송량이 1일 300메가로 제한되지만 www.test.net 은 500메가로 제한된다.

주의) 이론적으로 위와 같이 설정하는 것이 맞지만 제대로 작동하지 않은 경험이 있다.
따라서 유난히 트래픽을 많이 유발시키는 도메인에 대해서
선택적으로 적용하는 것이 좋다.

모든 설정에 대한 관리는 http://www.mydomain.com/throttle-status 에서 가능하며 보다
자세한 이용 방법은 http://www.snert.com/Software/mod_throttle/ 를 참고하기 바란다.
또한 http://www.snert.com/Software/mod_watch/ 모듈을 이용하면 이 기능외에 각
가상 도메인별로 인바운드, 아웃 바운드되는 트래픽을 mrtg 그래프로도 볼 수 있다.


[참고] http://www.snert.com/Software/mod_throttle/index.shtml

Description
This Apache module is intended to reduce the load on your server & bandwidth generated by popular virtual hosts,
directories, locations, or users according to supported polices (see below) that decide when to delay or refuse
requests. Also mod_throttle can track and throttle incoming connections by IP address or by authenticated remote
user.
Every request now passes through four levels of throttling, which are: by client's IP address (ThrottleClientIP), by
authenticated remote user name (ThrottleRemoteUser), by local user ID (ThrottleUser), and by directory, location,
virtual host, or server (ThrottlePolicy).
In the list below, is a detailed description of each policy. Every policy expects two parameters: a limit and a time
period.


None
This policy imposes no restrictions on a request and used as a place holder to allow monitoring. The limit currently
serves no purpose. The period specifies how long data is accumulated before the counters are reset.


Concurrent
Impose a limit on the number of concurrent requests at any one time. The period specifies how long data is
accumulated before the counters are reset. This policy cannot be used with either ThrottleClientIP or
ThrottleRemoteUser.


Document
Excluding requests for HTML page elements such as images and style sheets, impose a limit on the number of requests
per period. When this limit is exceeded all further requests are refused, until the elapsed time exceeds the period length,
at which point the elapsed time and the counters are reset. Note that the requests (hits) column of the throttle status
display does not include the requests for page elements.


Idle
Impose a mimimum idle time between requests. When the miminum is not reached, then the request incurs a calculated
delay penalty or is refused.
First, whenever the elapsed time exceeds the period length, then the counters are reset.
Second, if the idle time between requests exceeds the minimum, then the the request proceeds without delay.
Otherwise the request is delayed between one and ThrottleMaxDelay seconds. If the delay would exceed
ThrottleMaxDelay, then we refuse the request entirely to avoid occupying servers unnecessarily.
The delay is computed as the policy minimum less the idle time between requests.


Original
Original mod_throttle 2.0 heuristic.
Impose a limit on the volume (kbytes sent) per period, which when exceeded the request incurs a
counter-based delay penalty or is refused.
First, whenever the elapsed time exceeds the period length, then the volume and elapsed time are halved.
Second, if the volume is below the limit, then the delay counter is decreased by one second if it is not yet
zero. Otherwise, when the limit is exeeded, the delay counter is increased by one second. The delay can be
between zero and ThrottleMaxDelay seconds, after which the request will be refused to avoid occupying
servers unnecessarily.

Random
Randomly accept a percentage (limit) of the requests. If the percentage is zero (0), then every request is refused; if
the percentage is 100, then all requests are accepted. The period specifies how long data is accumulated before the
counters are reset.


Request
Impose a limit on the number of requests per period. When this limit is exceeded all further requests are refused until
the elapsed time exceeds the period length, at which point the elapsed time and counters are reset.


Speed
Impose a limit on the volume (kbytes sent) per period, which when exceeded the request incurs a calculated delay
penalty or is refused.
First, whenever the elapsed time exceeds the period length, then the limit (allowance) is deducted from the
volume, which cannot be a negative result; also the period length is deducted from the elapse time.
Second, if the volume is below the limit, in which case the request proceeds without delay. Otherwise the
request is delayed between one and ThrottleMaxDelay seconds. If the delay would exceed ThrottleMaxDelay,
then we refuse the request entirely to avoid occupying servers unnecessarily.
The delay is computed as one plus the integer result of the volume times 10 divided by the limit.

Volume
Impose a limit on the volume (kbytes sent) per period. When this limit is exceeded all further requests are refused, until
the end of the period at which point the elapsed time and counters are reset.

Installation

1.
Download mod_throttle312.tgz and unpack the archive. (The previous series mod_throttle/2.11 can also be
downloaded.)
2.
Depending on your operating system, you must edit the #undef and #define found at the top of mod_throttle.c
source file to specify the semaphore & shared memory API to use.
For the semaphore support you must #define only one of the following and #undef the rest. If you do not
#define one of these, then mod_throttle will operate without semaphore support, which will have undefined
results:
USE_POSIX_SERIALIZATION
USE_FCNTL_SERIALIZATION
USE_FLOCK_SERIALIZATION
USE_SYSTEM_V_SERIALIZATION
For the shared memory support you must #define only one of the following and #undef the rest. If you do not
#define one of these, then mod_throttle will operate without shared memory, which will have undefined
results:
USE_POSIX_SHARED_MEMORY
USE_SYSTEM_V_SHARED_MEMORY
3.
To build as DSO module, just type:
cd (path to)/mod_throttle-3.1
make install
To build as a static module:
cd /usr/local/apache_1.3.14 (or where ever you keep the Apache source)
./configure \ (see below in the Notes for additional information)
--disable-shared=throttle \
--add-module=(path to)/mod_throttle-3.1/mod_throttle.c \
... (your other configuration options) ...
make install

4.
Configure the httpd.conf file. At the very least add following:
[CODE]<IfModule mod_throttle.c> ThrottlePolicy none <Location /throttle-status> SetHandler throttle-status </Location> <Location /throttle-me> SetHandler throttle-me </Location> <Location /~*/throttle-me> SetHandler throttle-me </Location> </IfModule> [/CODE]
5.
Restart the server: apachectl stop; apachectl start
6.
View the status display http://www.mydomain.com/throttle-status.

Configuration
The commands below can be added to the general Apache configuration file, httpd.conf.

SetHandler throttle-client-ip
Context: server, , ,
Displays the complete list of recently connected client IP addresses. There are command links to reset all the
clients, or reset individual clients.
Each row shows a client IP address, the percentage of the limit reached, the total number of requests (hits)
made by this client, number of requests refused to the this client, volume (kbytes sent) per period, average
volume per request, the current delay, the elapsed period time, and the time idle since the last request.

SetHandler throttle-remote-user
Context: server, , ,
Displays the complete list of recently authenticated remote users. There are command links to reset all or
individual remote users.
Each row shows the authenticated remote user name, the percentage of the limit reached, the total number of
requests (hits) made by this remote user, number of requests refused to the this remote user, volume (kbytes
sent) per period, average volume per request, the current delay, the elapsed period time, and the time idle
since the last request.

SetHandler throttle-status
Context: server, , ,
Displays the complete list of server, virtual hosts, directories, locations, and local users who are to be
throttled. There are command links to reset all or individual entries, and preserve & restore runtime data.
Each row shows the item being throttled, the percentage of the limit reached, the total number of requests
(hits) received, number of requests refused, volume (kbytes sent) per period, average volume per request, the
current delay, policy, limit, period, elapsed period time, and the time idle since the last request.
http://my.domain.com/throttle-status

SetHandler throttle-me
Context: server, , ,
Similar to SetHandler throttle-status in content, except it only displays one individual entry for either a ~user
or the server of which the request was made. The intent of this handler is to provide the system administrator
a means by which customers can monitor their throttles without seeing those belonging to others.
Assuming the handler has been installed as outlined above, then a URL of the form:

http://my.domain.com/~user/throttle-me
will display the throttle status for user, if a ThrottleUser was specified for the user in question; otherwise a Not
Found error page. A URL of the form:
http://my.domain.com/throttle-me
will display the throttle status of my.domain.com, if it has a ThrottlePolicy; otherwise a Not Found error page.

ThrottleClientIP size policy limit period
Context: server
Specify the size of the client IP address list and the global policy to be applied to all incoming connections
based on information recorded for a client IP address. The policy Concurrent is ignored.
When the list size is greater than zero, then throttling by client IP address is enabled (the default is zero).
Requests from a client IP address can be tracked for a short period of time and subject to the policy specified.
The period of time that a client IP address is tracked depends on the size of the client IP address list, which is
ordered most recent request to oldest. Every time a new client IP address connects, the oldest entry in the
list is lost and reassigned to the new client IP address. Every time an existing entry makes a request, it is
moved to the top of the list.

ThrottleContentType string
Context: server
Specifies the default Content-Type to be used for the throttle status display. Only two supported types:
text/html, text/plain. text/html is a nicely formatted and coloured table. text/plain is a tab separated list of columns
as seen for text/html, without headers and footers. When not specified, the default is text/html. This can be
overridden by specifying the content-type in the URL, for example:
http://my.domain.com/throttle-status?content-type=text/plain

ThrottleIndicator green percentage
ThrottleIndicator yellow percentage
ThrottleIndicator red percentage
Context: server
Specify the default thresholds used for the visual warnings by the throttle status display. The default
indicators are green 50, yellow 75, and red 90.

ThrottleLockFile string
Context: server
The lock file used with fcntl() or flock() serialization. Must be stored on a local disk.

ThrottleMaxDelay seconds
Context: server
This directive affects all policies that use delays. It imposes an upper limit on the throttle delay that can be
applied by a policy. The default is 60 seconds. A value of zero (0) disables the limit, allowing a delay to be as
high as the policy wants.

ThrottlePolicy policy limit period
Context: server, , ,
The policy parameter can be one of the previously above mentioned policies.
The limit is a number followed by an optional suffix K, M, or G for kilo-bytes, mega-bytes, or giga-bytes
respectively. When no suffix is given the default is kilo-bytes.
The period is a number followed by an optional suffix s, m, h, d, or w for seconds, minutes, hours, days, or
weeks respectively. When no suffix is given the default is seconds.
ThrottleRefresh seconds
Context: server
Specifies the refresh time for the throttle status display. When not specified, the default is 60 seconds. This
can be overridden by specifying the refresh time in the URL as well, for example:
http://www.domain.com/throttle-status?refresh=20

ThrottleRemoteUser size policy limit period
Context: server
Specify the size of the authenticated remote user list and the global policy to be applied to all requests based
on information recorded for an authenticated remote user. The policy Concurrent is ignored.
When the list size is greater than zero, then throttling by authenticated remote user is enabled (the default is
zero). When the web server restricts access to a resource, authentication is required to be sent by the remote
user. The user name supplied for that authentication is then used to control short term usage by the policy
specified. The period of time that a remote user can be tracked depends on the size of the remote user list,
which is ordered most recent request to oldest. Every time a new remote user connects, the oldest entry in
the list is lost and reassigned to the new remote user. Every time an existing entry makes a request, it is
moved to the top of the list.
ThrottleRuntimeFile filename
Context: server
The location and file name of the runtime data file used to preserve state information across shutdowns &
restarts.

ThrottleUser user policy limit period
Context: server
Each request for files belonging to the given user name or #ID are throttled according to the selected policy as
described above. If the user is an asterisk (*), then all the users from the system user databases are throttled
with the same policy, limit, and period. If the user is an absolute path to an htpasswd file, /etc/passwd, or a
file with one user per line, then all the users from that file are throttled with the same policy, limit, and period.
User names with no corresponding system user ID are ignored.

Notes
*
mod_throttle/3.0 tested on following platforms (please email me your platform if you've made it work on
something different):

FreeBSD 4.1.1, Apache 1.3.14
The USE_SYSTEM_V_SERIALIZATION, and USE_SYSTEM_V_SHARED_MEMORY code was successfully tested on
this platform.
The USE_POSIX_SERIALIZATION and USE_POSIX_SHARED_MEMORY compiles and links (with & without
-pthread), but fails on sem_init() when execute - help anyone?.
Mandrake Linux 7.1 (I386), Apache 1.3.?
The USE_SYSTEM_V_SERIALIZATION, and USE_SYSTEM_V_SHARED_MEMORY code has been reported to work
successfully on this platform.

RedHat Linux 5.1+ (MIPS & Intel), Apache 1.3.14
The USE_FCNTL_SERIALIZATION, USE_FLOCK_SERIALIZATION, USE_SYSTEM_V_SERIALIZATION, and
USE_SYSTEM_V_SHARED_MEMORY code was successfully tested on this platform.

Solaris 5.7, Apache 1.3.12
To build as a DSO module, Apache must be built with --enable-rule=SHARED_CORE. The
USE_POSIX_SERIALIZATION and USE_POSIX_SHARED_MEMORY code was successfully tested on this platform, but
must be linked with the library "-lrt"; when compiling DSO, edit the Makefile and uncomment the LIB= macro; when
compiling statically, specify: LIBS='-lrt' ./configure ...

Solaris 5.6, Apache 1.3.9
To build as a DSO module, Apache must be built with --enable-rule=SHARED_CORE. Recommended that you use
USE_POSIX_SERIALIZATION and USE_POSIX_SHARED_MEMORY on this platform; the module must be linked with
the library "-lposix4"; when compiling DSO, edit the Makefile and uncomment the LIB= macro; when compiling
statically, specify: LIBS='-lposix4' ./configure ...
*
The context diff "patch.proxy_util.c" should be applied to /src/modules/proxy/proxy_util.c from the Apache
1.3.14 distribution. This patch allows mod_throttle/3.0 to monitor proxy requests when mod_proxy is in use.
(This patch has been submitted to the Apache Server project.)
*
The policies Original, Speed, and Volume all impose limits on volume (kilobytes sent). The differences lie in how
adjustments are made each period and whether to delay or refuse the conection.
*
Here is a shell command that can be used for a cron job to restart the Apache server on a set schedule in
order to reload your configuration file. This assumes that you do not change the location of the "PidFile" in your
configuration and that httpd is on root's PATH.
kill -USR1 $(cat $(httpd -V | sed -n '/DEFAULT_PIDLOG/s/.*"\(.*\)"/\1/p'))

License
This source distribution is made freely available and there is no charge for its use, provided you retain this notice,
disclaimers, author's copyright, and credits.

Disclaimer
THIS SOFTWARE IS PROVIDE "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO WAY SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.

Credits
Original design for mod_throttle/1.0 goes to Mark Lovell .
Elements of the critical & shared memory code, as of mod_throttle/3.0, originally derived from the Apache Web
Server source code.
Thank You to Lu Vo for providing a Solaris POSIX compliant machine to test on; to Travis
Doherty for a FreeBSD machine for testing and several suggestions; to David M. Shirley
for constructive and helpful reports concerning design and testing.

출처 : http://www.linuxc.net
.