Показаны сообщения с ярлыком apache. Показать все сообщения
Показаны сообщения с ярлыком apache. Показать все сообщения

пятница, 6 февраля 2009 г.

SUPHP и загрузка файла на сайт

Столкнулся с тем, что после загрузки на сайт файл недоступен для просмотра. Владельцем файлу назначается владелец вызываемого скрипта, но с правами доступа на чтение/запись только владельцу. В результате веб-сервер не может его прочитать. Пробовал поиграться с параметрами в «suphp.conf» — безрезультатно.
Решил проблему таким образом. Создал файл «/etc/php5/prepend.inc» и в «php.ini» путь к нему присвоил параметру «auto_prepend_file»

<?php
if (!empty($_FILES)) {
function __xxx4pre_fix_upload_umask(& $files) {
if (is_array($files)) {
foreach ($files AS & $file)
__xxx4pre_fix_upload_umask($file);
}
else {
if (is_uploaded_file($files))
chmod($files, 0644);
}
}

__xxx4pre_fix_upload_umask($_FILES);
}
Теперь у загруженных файлов права доступа будут принудительно меняться на «0644».

пятница, 19 декабря 2008 г.

Локальное зеркало для AVP Kaspersky 6

В поисках рецепта создания сабжа наткнулся на обсуждение в forum.lissyara.su. Взяв за основу опубликованный rambomax'ом скрипт, создал веб-зеркало для корпоративной сети.

Предполагается что веб-сервер уже настроен и работает.

  1. Устанавливаем программы из репозитария
    $ sudo apt-get install wget unzip
  2. Создаем директории
    $ sudo mkdir -p /scripts /www/avp-updates /var/samba/share/Avp
  3. Создаем скрипт обновления «/scripts/avp-updates.sh»
    #!/bin/sh
    #--- BEGIN ---
    AVURL=ftp://downloads1.kaspersky-labs.com/zips/
    FTPDIR=/var/samba/share/Avp
    AVPDIR=/www/avp-updates
    WGET=/usr/bin/wget
    UZIP=/usr/bin/unzip

    $WGET -N --random-wait --retry-connrefused -P "$FTPDIR" -t 0 $AVURL/av-i386-cumul.zip
    $UZIP -t $FTPDIR/av-i386-cumul.zip
    FLAG_C=$?

    $WGET -N --random-wait --retry-connrefused -P "$FTPDIR" -t 0 $AVURL/av-i386-weekly.zip
    $UZIP -t $FTPDIR/av-i386-weekly.zip
    FLAG_W=$?

    $WGET -N --random-wait --retry-connrefused -P "$FTPDIR" -t 0 $AVURL/av-i386-daily.zip
    $UZIP -t $FTPDIR/av-i386-daily.zip
    FLAG_D=$?

    #### EXTRACT FILES FROM ARCHIVE
    /bin/rm -f $AVPDIR/*

    if [ $FLAG_C -ne 0 ]
    then
    rm $FTPDIR/av-i386-cumul.zip
    else
    $UZIP -o $FTPDIR/av-i386-cumul.zip -d "$AVPDIR"
    fi

    if [ $FLAG_W -ne 0 ]
    then
    rm $FTPDIR/av-i386-weekly.zip
    else
    $UZIP -o $FTPDIR/av-i386-weekly.zip -d "$AVPDIR"
    fi

    if [ $FLAG_D -ne 0 ]
    then
    rm $FTPDIR/av-i386-daily.zip
    else
    $UZIP -o $FTPDIR/av-i386-daily.zip -d "$AVPDIR"
    fi
  4. Делаем скрипт исполняемым
    $ sudo chmod +x /scripts/avp-updates.sh
  5. Настраиваем crontab на запуск нашего скрипта каждый день в два часа ночи
    $ sudo -s
    # crontab -l 2>/dev/null > /tmp/avp-cron-XXX.tmp
    # echo >> /tmp/avp-cron-XXX.tmp
    # echo "0 2 * * * /scripts/avp-updates.sh" >> /tmp/avp-cron-XXX.tmp
    # crontab /tmp/avp-cron-XXX.tmp
    # rm /tmp/avp-cron-XXX.tmp
    # exit
  6. Создаем виртуальный хост в apache2 для веб-зеркала.
    Файл «/etc/apache2/sites-available/avp-updates»
    <VirtualHost *:80>
    ServerAdmin demiurg@avp-updates.www
    DocumentRoot /www/avp-updates
    ServerName avp-updates.www

    ErrorLog /var/log/apache2/avp-updates_error-log
    CustomLog /var/log/apache2/avp-updates_log common

    <Directory "/www/avp-updates">
    Options Indexes
    AllowOverride None
    Order Deny,Allow
    Allow from All
    </Directory>
    </VirtualHost>
  7. Активируем созданный хост
    $ sudo ln -s ../sites-available/avp-updates /etc/apache2/sites-enabled/050-avp-updates
  8. Проверяем конфиг и ребутаем веб-сервер
    $ sudo apache2ctl configtest
    $ sudo /etc/init.d/apache2 restart

вторник, 22 января 2008 г.

«Хитрое» зеркалирование репозиториев на freebsd

Недавно натолкнулся на статью, описывающую создание зеркала репозитория дистрибутива N, способного загружать с основного репозитория только запрашиваемые пользователями файлы. Но, поскольку все это действие предлагалось проводить с linux + fuse + че-то-там-еще, статья не вызвала особого энтузиазма.
Но что-то подобное хотелось иметь и для freebsd. В итоге родилась идея «хитрого» зеркалирования репозитория убунту. Для этого требуется: apache2.0 (mod_cache + mod_proxy + mod_rewrite) и perl.

1. Настройка apache 2.0
1.1. Сперва требуется включить проксирование (mod_proxy) в apache20. Если вы ставите apache2.0 из портов

# cd /usr/ports/www/apache20
# make WITH_PROXY_MODULES=yes all install clean

или в /etc/make.conf добавить
.if ${.CURDIR} == ${PORTSDIR}/www/apache20
WITH_PROXY_MODULES = yes
.endif

и затем
# cd /usr/ports/www/apache20
# make all install clean
1.2. Изменения в файле конфигурации apache2/httpd.conf
# Включаем необходимые модули
LoadModule cache_module modules/mod_cache.so
LoadModule disk_cache_module modules/mod_disk_cache.so
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_connect_module modules/mod_proxy_connect.so
LoadModule proxy_ftp_module modules/mod_proxy_ftp.so
LoadModule proxy_http_module modules/mod_proxy_http.so
# Создаем виртуальный хост
<VirtualHost *:80>
ServerAdmin webmaster@ubuntu.local
DocumentRoot /www/ubuntu.local
ServerName ubuntu.local
ServerAlias ubuntu.our-office.com
ErrorLog /var/log/apache2/ubuntu.local-error_log
CustomLog /var/log/apache2/ubuntu.local-access_log common
<Directory "/www/ubuntu.local/">
Options FollowSymLinks
Order Deny,Allow
Allow from All
</Directory>

<Directory "/www/ubuntu.local/ubuntu/">
Options Indexes FollowSymLinks
Order Deny,Allow
Allow from All
</Directory>

<LocationMatch "^[^/]+">
Deny from all
</LocationMatch>

# Включаем mod_rewrite
RewriteEngine On
# Ставим уровень детализации логов.
# Настоятельно не рекомендуется ставить больше 2, разве что для отладки.
# По умолчанию в лог не пишется (0).
RewriteLogLevel 1
# Пишем в лог.
RewriteLog "/var/log/apache2/ubuntu.local-rewrite.log"

# Проверяем существование запрашиваемого файла в локальном репозитории
RewriteCond %{SCRIPT_FILENAME} !-f
# Не нашли? Идем с поклоном к вышестоящему репозиторию
RewriteRule ^/ubuntu/pool/(.*)$ http://mirror.ubuntu.optilink.ru/ubuntu/pool/$1 [P,L]

# Настраиваем кеширование (mod_cache)
# Кешируем только .deb файлы.
CacheEnable disk /ubuntu/pool/
# Указываем размещение кеша.
CacheRoot /var/ubuntu.mirror/
# Размер кеша 5 гигов, с копейками (в килобайтах).
CacheSize 5120000
CacheDirLevels 2
CacheDirLength 3
# Задаем максимальное время кеширования файлов (в секундах).
CacheMaxExpire 86400

# Вырубаем левые прокси-запросы
ProxyRequests Off
# Наш местный репозиторий
ProxyPassReverse /ubuntu/pool/ http://mirror.ubuntu.optilink.ru/ubuntu/pool/
# Apache стоит внутри jail и внешний интернет ему доступен только через прокси-сервер.
ProxyRemote * http://127.0.0.2:3128

<Proxy *>
Order Deny,Allow
Deny from all
# Разрешаем запросы только с локальной сети
Allow from 192.168.0.0/24
</Proxy>
</VirtualHost>
1.3. Создаем директории /www/ubuntu.local/ubuntu и /var/ubuntu.mirror. В /www/ubuntu.local/ubuntu/ будет располагаться зеркало репозитория; в /var/ubuntu.mirror - кеш mod_proxy. Владельцем созданных директорий назначаем пользователя, под которым работает веб-сервер (обычно это www) и разрешаем ему писать.

1.4. В /www/ubuntu.local/ubuntu/ создаем dists и pool. В dists из основного репозитория заливаем файлы описаний
# sudo -u www /usr/bin/env http_proxy="127.0.0.2:3128" /usr/local/bin/wget -nH -R 'index.html*' --cut-dirs=2 -r -P/www/ubuntu.local/ubuntu/dists --no-parent http://mirror.ubuntu.optilink.ru/ubuntu/dists/
1.5. Теперь пишем скрипт на перле, копирующий кешированные файлы в зеркало репозитория. За качество кода сильно не бить :) Скрипт сохраним как /usr/local/script/move-from-cache.pl
#!/usr/bin/perl -w

use strict;

# Потрошим файл описания кешированного в mod_proxy объекта.
sub extract_name {
my $data = shift;

# iiIIqqqq
# i1 i1 I1 I1 q1 q1 q1 q1
my ($format,$status,$name_len,
$entity_version,$date,$expire,
$request_time,$response_time, $ext) = unpack('i1i1I1I1q1q1q1q1a*', $data);
my ($name) = unpack ("a$name_len", $ext);

$name =~ s/[?]?$//;
return $name;
}
# Приведенный ниже код подпрограммы взят отсюда.
# Accepts one argument: the full path to a directory.
# Returns: nothing.
sub process_files {
my $path = shift;

# Open the directory.
opendir (DIR, $path) or die "Unable to open $path: $!";

# Read in the files.
# You will not generally want to process the '.' and '..' files,
# so we will use grep() to take them out.
# See any basic Unix filesystem tutorial for an explanation of the +m.
my @files = grep { !/^\.{1,2}$/ } readdir (DIR);

# Close the directory.
closedir (DIR);

# At this point you will have a list of filenames
# without full paths ('filename' rather than
# '/home/count0/filename', for example)
# You will probably have a much easier time if you make
# sure all of these files include the full path,
# so here we will use map() to tack it on.
# (note that this could also be chained with the grep
# mentioned above, during the readdir() ).
@files = map { $path . '/' . $_ } @files;

my @value = ();

for (@files) {

# If the file is a directory
if (-d $_) {
# Here is where we recurse.
# This makes a new call to process_files()
# using a new directory we just found.
push @value, process_files ($_);

# If it isn't a directory, lets just do some
# processing on it.
} else {
# Do whatever you want here =)
# A common example might be to rename the file.
push @value, $_;
}
}
return @value;
}

# Дальше мое сочинение
# С командной строки передаются два параметра:
# Путь к кешу mod_proxy
my $ubuntu_cache = $ARGV[0] if defined $ARGV[0];
# Префикс директории локального репозитория
my $mirror_prefix = $ARGV[1] if defined $ARGV[1];

unless (defined($ubuntu_cache) && defined($mirror_prefix)) {
print "Usage: ./script.pl /path/to/ubuntu/cache /path/mirror/prefix\n\n";
exit;
}

# Формируем список файлов в кеше.
my @files = process_files ($ubuntu_cache);

foreach my $filename (@files)
{
my $file;
my $data = '';
# Если это файл описания, потрошим
if ($filename =~ /^(.*?)\.header$/) {
my $cache_file = $1 . '.data';
open $file, "<${filename}" or die "Error. Can't open file.";
while (!eof($file)) {
my $buf;
$data .= $buf if read ($file, $buf, 4096);
}
close $file;
my @path = split('/', extract_name ($data));
shift (@path);
my $name = join ('/', @path);

my $new_file = $mirror_prefix . '/' . $name;
# Если кешированный файл отсутствует в репозитории, то копируем его
unless (-e $new_file) {
print "$name\n";
my @m_path = split ('/', $new_file);
pop (@m_path);

my $a = '/';
# Проверяем и создаем отсутствующие директории
foreach my $i (@m_path) {
$a .= $i . '/';
mkdir $a unless -e $a;
}
# Копируем кешированный файл куда надо.
system ("/bin/cp $cache_file $new_file");
}
}
}

# Формат файла описания кешированных объектов в mod_proxy.
=pod
/* Our on-disk header format is:
*
* disk_cache_info_t
* entity name (dobj->name) [length is in disk_cache_info_t->name_len]
* r->headers_out (delimited by CRLF)
* CRLF
* r->headers_in (delimited by CRLF)
* CRLF
*/
#define DISK_FORMAT_VERSION 0
typedef struct {
/* Indicates the format of the header struct stored on-disk. */
int format;
/* The HTTP status code returned for this response. */
int status;
/* The size of the entity name that follows. */
apr_size_t name_len;
/* The number of times we've cached this entity. */
apr_size_t entity_version;
/* Miscellaneous time values. */
apr_time_t date;
apr_time_t expire;
apr_time_t request_time;
apr_time_t response_time;
} disk_cache_info_t;
=cut
2. Настраиваем cron
$ sudo crontab -u www -e
# Запускается каждый час
0 * * * * /usr/local/script/move-from-cache.pl /var/ubuntu.mirror/ /www/ubuntu.local/
# Обновление файлов описаний.
# Запускается один раз в день
1 3 * * * /usr/bin/env http_proxy="127.0.0.2:3128" /usr/local/bin/wget -R 'index.html*' -nH --cut-dirs=2 -r -N -P/www/ubuntu.local/ubuntu/dists --no-parent http://mirror.ubuntu.optilink.ru/ubuntu/dists/


3. Вот собственно и все. Не забываем ребутнуть веб-сервер.