Достаточно создать скрипт, который будет подключаться к mldonkey на management-порт и передавать ему команды через netcat
.
Скорость выставляется в килобайтах.
Строчка crontab
выглядит следующим образом:
5 8,16,23 * * * /opt/scripts/mldonkey.sh >/dev/null 2>&1
Собственно, сам скрипт:
#!/bin/sh NC="/bin/nc" HOUR=`/bin/date +'%H'` case "$HOUR" in 08) sh -c "$NC 127.0.0.1 4000 <<EOF set max_hard_download_rate 200 set max_hard_upload_rate 350 q EOF" > /dev/null ;; 16) sh -c "$NC 127.0.0.1 4000 <<EOF set max_hard_download_rate 100 set max_hard_upload_rate 250 q EOF" > /dev/null ;; 23) sh -c "$NC 127.0.0.1 4000 <<EOF set max_hard_download_rate 400 set max_hard_upload_rate 500 q EOF" > /dev/null ;; *) exit; ;; esac
# cd /opt/src/ && wget http://stderr.net/apache/rpaf/download/mod_rpaf-0.5.tar.gz http://maloletka.ru/patches/rpaf-0.5.patch # tar xvf mod_rpaf-0.5.tar.gz # cd mod_rpaf-0.5 && cat ../rpaf-0.5.patch | patch -p0 mod_rpaf-2.0.c # less README и ставим модуль
nginx
:user nobody nogroup; worker_processes 4; error_log /var/log/nginx/error_log info; events { worker_connections 8192; use epoll; } http { include /etc/nginx/mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] ' '"$request" $status $bytes_sent ' '"$http_referer" "$http_user_agent" ' '"$gzip_ratio"'; client_header_timeout 10m; client_body_timeout 10m; send_timeout 10m; connection_pool_size 256; client_header_buffer_size 1k; large_client_header_buffers 4 2k; request_pool_size 4k; gzip off; gzip_min_length 1100; gzip_buffers 4 8k; gzip_types text/plain; output_buffers 1 32k; postpone_output 1460; sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 75 20; ignore_invalid_headers on; index index.html; server { listen 80; server_name domain.com www.domain; root /home/clients/vasiliy_pupkinson/domains/domain.com/html; location / { proxy_pass http://127.0.0.1:8080/; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_max_temp_file_size 0; client_max_body_size 10m; client_body_buffer_size 128k; proxy_connect_timeout 90; proxy_send_timeout 90; proxy_read_timeout 90; proxy_buffer_size 4k; proxy_buffers 4 32k; proxy_busy_buffers_size 64k; proxy_temp_file_write_size 64k; } location ~* ^.+.(jpg|gif|png|avi|mpg|zip|exe)$ { root /home/clients/vasiliy_pupkinson/domains/domain.com/html; valid_referers none blocked server_names; if ($invalid_referer) { return 403; } } } }
apache
:LoadModule rpaf_module libexec/mod_rpaf.so RPAFenable On RPAFsethostname On RPAFproxy_ips 127.0.0.1 APACHE_IPS Listen 127.0.0.1:8080 ServerName localhost NameVirtualHost 127.0.0.1:8080 <VirtualHost 127.0.0.1:8080> ServerName domain.com ServerAlias domain.com ServerAlias www.domain.com DocumentRoot /home/clients/vasiliy_pupkin/domains/domain.com/html CustomLog /home/clients/vasiliy_pupkin/domains/domain.com/logs/access_log combined ErrorLog /home/clients/vasiliy_pupkin/domains/domain.com/logs/error_log ScriptAlias /cgi-bin/ " /home/clients/vasiliy_pupkin/domains/domain.com/html/cgi-bin/ " <Directory "/cgi-bin/"> Options None +FollowSymLinks </Directory> <Directory /> Options All -Indexes AllowOverride All </Directory> </VirtualHost>
В итоге имеем:
nginx на 80 порту ловит все входящие соединения и отдает юзеру все файлы, что попадают под регексп. Я туда еще добавил хотлинк-протект для пущего гламуру.
В регексп успешно можно пихать html, css и т.п.
Все, что не попадает под паттерн, передается apache, который слушает на 127.0.0.1:8080.
Без модуля mod_rpaf апач в логи будет писать src ip 127.0.0.1, так что ставим его обязательно.
Основной недостаток - это необходимость переписывать правила из .htaccess под nginx, что, в принципе, не очень сложно.
А простой redirect и так должен работать.
Стадию разметки пропускаю по причине различных конфигураций для каждого отдельно взятого сетапа.
mount -t ext3 /dev/sda1 /mnt
debootstrap etch /mnt http://ftp.debian.org/debian/
proc
и чрутимся:mount -t proc proc /mnt/proc chroot /mnt
# cat > /etc/apt/apt.conf APT::Default-Release "stable"; APT::Force-LoopBreak "true";
# cat > /etc/apt/sources.list deb http://ftp.debian.org/debian etch main non-free contrib deb http://security.debian.org/ etch/updates main contrib non-free deb http://ftp.debian.org/debian etch-proposed-updates main non-free contrib
# cat > /etc/resolv.conf nameserver YOUR_NAMESERVER1_IP nameserver YOUR_NAMESERVER2_IP
# cat > /etc/fstab /dev/sda1 / ext3 defaults 0 1 /dev/sda2 none swap sw 0 0 /dev/sda3 /home ext3 defaults,errors=remount-ro,noatime,nodiratime 0 0 proc /proc proc defaults 0 0
# cat > /etc/hosts 127.0.0.1 localhost serverlabel.YOUR_DOMAIN.COM
# cat > /etc/hostname serverlabel.YOUR_DOMAIN.COM
# cat >> /etc/bash.bashrc if [ -f /etc/bash_completion ]; then . /etc/bash_completion fi
# cat > /etc/network/interfaces auto lo iface lo inet loopback auto eth0 iface eth0 inet static address СИСТЕМНЫЙ IP netmask 255.255.255.0 network СЕТЬ broadcast СЕТЬ.255 gateway ШЛЮЗ dns-nameservers YOUR_NAMESERVER1_IP YOUR_NAMESERVER2_IP
# cat > /etc/locale.gen en_GB ISO-8859-1 en_US ISO-8859-1 ru_RU.KOI8-R KOI8-R
# ln -fs /usr/share/zoneinfo/Etc/UTC /etc/localtime # cat > /etc/timezone Etc/UTC
# /usr/bin/apt-get update # /usr/bin/apt-get dist-upgrade # /usr/bin/apt-get -y -q install ssh alien aria2 arping bash bash-completion bc bridge-utils build-essential busybox bzip2 bzr checkinstall chkconfig chkrootkit coreutils cpio cron curl cvs dash debian-archive-keyring debian-keyring diffutils dmidecode dnsutils dos2unix dosfstools dselect e2fsprogs ebtables ethtool ext3grep extundelete fakeroot findutils fping fuse gcc gdb geoip-bin geoip-database git gzip hdparm hostname htop iotop ipcalc iperf ipmitool iproute iptables iputils-ping less lftp libc6-dev libwww-perl links lm-sensors locales logrotate lrzip lsb-security lsof lvm2 lzma make mdadm mercurial monit mtr mysqltuner mytop nano netcat nmap ntfs-3g ntp openipmi p7zip p7zip-full parallel parted patch pbzip2 pciutils perl pigz procps psmisc pwgen python rkhunter rsync rsyslog ruby screen sed snmp sqlite3 strace subversion sysstat tar tcpdump tcsh telnet tmux unhide unzip usbutils uw-mailutils vim wget whois xinetd xz-utils zip # /usr/sbin/ntpdate pool.ntp.org # echo "0 0 * * * /usr/sbin/ntpdate pool.ntp.org >/dev/null 2>&1" | /usr/bin/crontab - # cd /dev && MAKEDEV generic # source /etc/bash.bashrc
grub
:# cp -a /usr/lib/grub/i386-pc /boot/grub
/usr/src
:# cd /usr/src/linux
# make-kpkg --bzImage kernel_image # dpkg -i /usr/src/linux-image-x.x.x-blablabla.deb
grub
в mbr
:# update-grub # grub --no-floppy > root (hd0,0) > setup (hd0) > quit
MyConfig.cgi.sh
со следующим содержимым:#!/bin/sh CFLAGS="-O2" ./configure --prefix=/opt/php-x.x.x-fcgi \ --enable-calendar \ --enable-sysvsem \ --enable-sysvshm \ --enable-sysvmsg \ --enable-ftp \ --with-mcrypt \ --with-mysql \ --with-mysqli \ --enable-bcmath \ --with-bz2 \ --with-gd \ --with-jpeg-dir \ --with-zlib-dir \ --with-curl \ --enable-sockets \ --with-iconv \ --enable-mbstring \ --enable-mbregex \ --enable-ctype \ --enable-shmop \ --enable-wddx \ --with-imap \ --with-freetype-dir \ --with-xmlrpc \ --enable-dbase \ --with-mime-magic \ --with-mhash \ --with-gettext \ --with-imap-ssl \ --with-pear \ --with-kerberos \ --with-openssl \ --with-snmp \ --with-config-file-path=/opt/etc/phpX \ --enable-fastcgi \ --enable-force-cgi-redirect \ --enable-fpm
# sh MyConfig.cgi.sh # make # make install
fcgi.sh
со следующим содержимым:#!/bin/bash # ABSOLUTE path to the PHP binary PHPFCGI="/opt/php-x.x.x-fcgi/bin/php-cgi" # tcp-port to bind on FCGIPORT="8888" # IP to bind on FCGIADDR="127.0.0.1" # number of PHP children to spawn PHP_FCGI_CHILDREN=5 # number of request before php-process will be restarted PHP_FCGI_MAX_REQUESTS=1000 # allowed environment variables sperated by spaces ALLOWED_ENV="PATH USER" # if this script is run as root switch to the following user USERID=www-data ################## no config below this line if test x$PHP_FCGI_CHILDREN = x; then PHP_FCGI_CHILDREN=5 fi ALLOWED_ENV="$ALLOWED_ENV PHP_FCGI_CHILDREN" ALLOWED_ENV="$ALLOWED_ENV PHP_FCGI_MAX_REQUESTS" ALLOWED_ENV="$ALLOWED_ENV FCGI_WEB_SERVER_ADDRS" if test x$UID = x0; then EX="/bin/su -m -c \"$PHPFCGI -q -b $FCGIADDR:$FCGIPORT\" $USERID" else EX="$PHPFCGI -b $FCGIADDR:$FCGIPORT" fi echo $EX # copy the allowed environment variables E= for i in $ALLOWED_ENV; do E="$E $i=${!i}" done # clean environment and set up a new one nohup env - $E sh -c "$EX" &> /dev/null &
nginx
будет выглядеть таким образом:server { listen 1.2.3.4:80; server_name domain.com www.domain.com; access_log /dev/null; # max POST size in bytes client_max_body_size 1000000000; location / { root /home/clients/ftp_login/domains/domain.com/html; index index.html index.htm index.php; } location ~ \.php$ { # Commented block - for accelerated POST - nginx should be 0.5.9+ # fastcgi_pass_request_body off; # client_body_in_file_only clean; # fastcgi_param REQUEST_BODY_FILE $request_body_file; fastcgi_pass 127.0.0.1:8888; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME /home/clients/ftp_login/domains/domain.com/html$fastcgi_script_name; fastcgi_param QUERY_STRING $query_string; fastcgi_param REQUEST_METHOD $request_method; fastcgi_param CONTENT_TYPE $content_type; fastcgi_param CONTENT_LENGTH $content_length; fastcgi_param REDIRECT_STATUS 200; } # hotlink protection location ~* ^.+\.(gif|jpg|mpg|mp3|mpeg|avi)$ { valid_referers none blocked domain.com www.domain.com; if ($invalid_referer) { return 403; } } }
/usr/src
, распаковываем, заходим в директорию и стартуем ./runme set. /usr/src/linux
, а iptables
- в /usr/src/iptables
. /usr/src/linux
и делаем make oldconfig, где указываем поддержку фич ipset
модулями.Собираем и устанавливаем ядро:
# make-kpkg --bzImage kernel_image # dpkg -i /usr/src/linux-image-x.x.x-blablabla.deb
# apt-get install ipset
ipset
в /etc/modules
и либо загружаем модуль modprobe ipset, либо перезагружаемся в новое ядро.iptables
. Стоит учесть, что максимальное количество ip в списке - 65536 штук:# ipset -N blacklist iphash
#!/usr/bin/perl while ($line = <STDIN>) { if ($line =~ /^\s+(\d+) (\d+)\.(\d+)\.(\d+)\.(\d+)/) { print $2, ".", $3, ".", $4, ".", $5, "\n" if ($1 > $ARGV[0]); } }
cron
:#!/bin/bash # variables, change them to get script work BADREQUEST="GET / HTTP/1.1"; LOGPATH="/home/clients/login_ftp0/domains/domain.com/logs/access_log"; MINREQUESTS="50"; SCRIPTHOME="/root/antiddos"; # don't change anything bellow grep "${BADREQUEST}" $LOGPATH | awk -F ' ' '{ print $ 1 }' | sort | uniq -c | ${SCRIPTHOME}/num-filter.pl $MINREQUESTS >> ${SCRIPTHOME}/in_blacklist.add.pre sort -u < ${SCRIPTHOME}/in_blacklist.add.pre > ${SCRIPTHOME}/in_blacklist.add cat ${SCRIPTHOME}/in_blacklist.add > ${SCRIPTHOME}/in_blacklist for i in `cat ${SCRIPTHOME}/in_blacklist`; do /usr/sbin/ipset -q -A blacklist $i; done
iptables
:/sbin/iptables -F /sbin/iptables -X DDOS_HTTP_FILTER /sbin/iptables -N DDOS_HTTP_FILTER /sbin/iptables -A DDOS_HTTP_FILTER -d $IP -p tcp --syn --dport 80 -m set --set blacklist src -j DROP /sbin/iptables -A DDOS_HTTP_FILTER -d $IP -p tcp --syn --dport 80 -m hashlimit --hashlimit 10/min --hashlimit-burst 30 --hashlimit-mode srcip --hashlimit-name DDOS --hashlimit-htable-size 32768 --hashlimit-htable-max 32768 --hashlimit-htable-gcinterval 1000 --hashlimit-htable-expire 100000 -j ACCEPT /sbin/iptables -A DDOS_HTTP_FILTER -d $IP -p tcp --dport 80 --syn -j DROP /sbin/iptables -A DDOS_HTTP_FILTER -d $IP -p tcp --syn --dport 80 -m connlimit --connlimit-above 10 -j DROP /sbin/iptables -A DDOS_HTTP_FILTER -j ACCEPT /sbin/iptables -A INPUT -p tcp --dport http -j DDOS_HTTP_FILTER
Фильтрация с GeoIP
# apt-get install xtables-addons-source #
#!/bin/bash iptables=/usr/local/sbin/iptables ipset=/usr/sbin/ipset WHITE="195.88.52.82/32" ddos_enable() { # whitelist $iptables -N WHITELIST for i in $WHITE; do $iptables -A WHITELIST -s $i -j ACCEPT; done $iptables -A WHITELIST -j DROP $iptables -N DDOS_HTTP_FILTER $iptables -A DDOS_HTTP_FILTER -m hashlimit --hashlimit 15/min --hashlimit-burst 30 --hashlimit-mode srcip --hashlimit-name HTTPDDOS --hashlimit-htable-size 32768 --hashlimit-htable-max 32768 --hashlimit-htable-gcinterval 1000 --hashlimit-htable-expire 100000 -j ACCEPT $iptables -A DDOS_HTTP_FILTER -m connlimit --connlimit-above 15 -j DROP $iptables -A DDOS_HTTP_FILTER -j ACCEPT $iptables -N SORT_FILTER $iptables -A SORT_FILTER -p tcp --dport 80 --syn -j DDOS_HTTP_FILTER $iptables -A SORT_FILTER -p tcp -m multiport --dports 25,53 -j ACCEPT $iptables -A SORT_FILTER -p udp --dport 53 -j ACCEPT $iptables -A SORT_FILTER -j WHITELIST $iptables -N GEOIP_FILTER $iptables -A GEOIP_FILTER -m geoip --src-cc AM,AZ,BY -j SORT_FILTER $iptables -A GEOIP_FILTER -m geoip --src-cc EE,GE,KZ -j SORT_FILTER $iptables -A GEOIP_FILTER -m geoip --src-cc LV,MD,NL,RU -j SORT_FILTER $iptables -A GEOIP_FILTER -m geoip --src-cc UA,UZ,US -j SORT_FILTER $iptables -A GEOIP_FILTER -j DROP $iptables -I INPUT 1 -i lo -j ACCEPT $iptables -I INPUT 2 -m set --set blacklist src -j DROP $iptables -I INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $iptables -A INPUT -j GEOIP_FILTER } start_iptables() { # whitelist $iptables -N WHITELIST for i in $WHITE; do $iptables -A WHITELIST -s $i -j ACCEPT; done $iptables -A WHITELIST -j DROP # default rules $iptables -I INPUT 1 -i lo -j ACCEPT $iptables -I INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT $iptables -A INPUT -p tcp -m multiport --dports 25,53,80 -j ACCEPT $iptables -A INPUT -p udp --dport 53 -j ACCEPT $iptables -A INPUT -j WHITELIST } clear_iptables() { $iptables -F $iptables -X } start_ipset() { $ipset -q -N blacklist iphash } clear_ipset() { $ipset -q -F blacklist $ipset -q -X blacklist } case "$1" in normal) clear_iptables start_iptables echo "normal mode activated" ;; stop) clear_iptables clear_ipset echo "iptabes cleared" ;; hard) clear_iptables start_ipset ddos_enable echo "hard mode activated" ;; *) echo "Usage $0 {normal|hard|stop}" exit 1 ;; esac
#!/usr/bin/env bash PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/games:/usr/local/sbin:/usr/local/bin:~/bin SCRIPTHOME="/root/antiddos" function valid_ip() { local ip=$1 local stat=1 [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]] && { OIFS=$IFS IFS='.' ip=($ip) IFS=$OIFS [[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \ && ${ip[2]} -le 255 && ${ip[3]} -le 255 ]] stat=$? return $stat } } ############### [[ -d $SCRIPTHOME ]] || exit 1 if ! VALID_IP=$(valid_ip "$1") then echo "Usage: $0 <IP ADDR>" >&2 exit 1 fi sed_cmd="/$1/d;/^[[:space:]]*$/d;s/[[:space:]]*$//" if LISTS=$(grep -lIrx "$1" "$SCRIPTHOME" | grep -v "\.sh") then for i in $LISTS do echo "Removing $1 from $i" sed -i '' "$sed_cmd" ${i} done nginx -t && nginx -s reload fi