Еще раз о безопасности виртуального хостинга.
actika
В очередной раз возник вопрос как обезопасить дешевый виртуальный хостинг. Некоторые прикручивают mod_security в безнадежной попытке предвидеть все опасные запросы. Но есть старый, проверенный способ - раставить правильно права на файлы. Итак у нас один общий nginx и php-fpm (вариант apache mod_php).
nginx отдает статические обьекты - html картинки и почее. Все эти файлы должны принадлежать к одной общей с nginx пруппе например www или www-data или nginx и иметь  следующие права:
rw-r----- или 640 в числовом эквиваленте.

Скрипты php или perl работают с правами пользователя а значит они должны иметь права:
rw------- или 600 для php
rwx------ или 700 для Perl

Обратите внимание что всякие конфиги содержащие пароли к БД и другую конфиденциальную информацию тоже должны лежать с правами:
rw------- или 600 в числовом эквиваленте.
Так как после заливки по FTP права ставятся по умолчанию, после каждой заливки нужно выставлять правильные права на все файлы. Это неудобно, но нужно. Лучше для этого написать скрипт.
Если же все таки нужно скрыть от посторонних и статические файлы - положите их с правами
rw------- или 600 в числовом эквиваленте
и отдавайте их скриптами, при этом кешируя в nginx. Потеря производительности в таком случае будет минимальной.
Другой пользователь при всем желании не сможет их отдать ни скриптами ни nginx, так как эти файлы не состоят в одной группе с nginx. И даже симлинки на эти файлы не помогут.

Вернемся к тестированию влияния фрагментации.
actika
Для оценки влияния фрагментации на был придуман следующий тест: осуществляем операции записи и чтения на тестируемый диск от 0% заполненности файлами до 100% и вычисляем средние скорости чтения и записи. Как только скорости чтения и записи перестануть падать, считаем фрагментацию максимальной а скорости результирующими для данной фс. На самом деле немного сложнее:
1. Используем чтение только для тестов.
2. Записи может быть в два варианта, во первых когда диск еще не заполнен и мы пишем в любое место в файле не затирая, во вторых когда свободное место уже закончилось и мы пишем в люмое место файла предварительно затерев блок соответсвующей длины так же в любом другом месте файла.
Я некоторое время не интерисовался системеым программированием и совсем упустл из виду что реализовать вышесказанное НЕВОЗМОЖНО без перечитывания и перезаписи хвоста файла. Так что в реальной жизни не стоит бояться фрагментации файлов, всякий раз когда вы что то вписываете в середину, весь хвост перписывается, что приводит к тому, что он лежит почти одним куском (зависит от наличия и фрагментированности свободного места).
Шел 2012 год. Ни одна фс ни в Linux ни в FreeBSD ни даже в Windows не позволяет вырезать или вписать блок произвольной длины в середину файла без перечитки и последующей перезаписи обратно хвоста файла.
Бездельники.
Дармоеды.
Ну с линуксом понятно - холява Сер, а в Windows почему нету ? Скопипастить негде ?
В данный момент в linux появился этот, так называемый "Punching holes", но он позволяет вставлять блок не любой длины, а кратный блоку фс и стабильным этот функционал будет лет через 5-ть ...
Для чего это нужны эти функции ? Возьмем к примеру торренты. В данный момент они перед закачкой для резервирования места на фс просто создают файл в полный размер с нулями внутри. А могли бы просто записывать скаченный блоки. Тоже самое касается БД. Сначала данные фрагментируюися на уровне таблиц так как данные вставляемые в середину таблицы не всегда кратны блоку который данная БД пишет на диск, а потом еще сами файлы таблиц фрагментируются на диске. Здравствуй двойная фрагментация, прощай скорость.
Итак реализовать тест как планировалось невозможно. Для создания условий фрагментации файла сделаем иначе:
1) сначала заполним диск максимальным колличеством файлов по 4к;
2) потом будем стирать 1 любой файл и дописывать в наш тестовый файл 4к.
Когда все мелкие файлы окажутся стерты у нас останется тестовый файл максимально фрагментированный на диске.
В результате дебатов выяснилось что в реальных условиях диски редко заполняются больше чем на 65% поэтому мы не будем заплнять диск полность. Тестировать скорость будем операцией чтения с размером блока 4к - 64к.

Поговорим о замыканиях в Perl.
actika
Есть в Perl такая штука как OOP без OOP, называется замыканиями. Теорию можно почитать тут:
http://www.samag.ru/archive/article/625
Мы сразу перейдем к примерам:
http://pastebin.com/jPspbFL4
http://pastebin.com/nr3fSqxk
http://pastebin.com/cKsYT6sJ
http://pastebin.com/qJbtJiyJ
Как это работает можно посмтреть по выводу (обратите внимание на значения переменных) Зачем это нужно? Впервые я столкнулся с необходимостью такой логики когда работал с IO::AIO. Дело в том что aio_write может не записать все за один раз и вернуть размер записанного. Нужно сверить его с исходным заданием и вызвать aio_write опять, тоесть рекурсивно. А когда все будет записанно закрыть файл.

Отключаем RAID1 на MB и ставим FreeBSD на zfs mirror на диски c сектором 4k.
actika
Где то встретил инфу что zfs установленная поверх raid1 неоптимально распределяет нагрузку на шпиндели. Кроме того "одминоДЦ" почему то не озаботилось тем что диски с сектором в 4к. Вобщем возникла необходимость поставить FreeBSD на ZFS на HD с 4к и был написан вот такой скрипт:

http://pastebin.com/byXW9ZZA
https://github.com/nagual2/Test/blob/master/bsd_install_to_zfs_mirror.sh

#!/bin/sh
mount_cd9660 /dev/cd0 /media

DIST="/media/usr/freebsd-dist"
DISKDEV1="da1"
DISKDEV2="da2"
SWAPSIZE="1G"
LOGFILE="tmp06_first.log"
exec 1>$LOGFILE 2>&1
ZPOOL="zroot"
HOSTNAME="BSD"
MNT="/mnt2"

mkdir -p $MNT
sysctl kern.geom.debugflags=0x10

/bin/echo "Starting newfs ZFS "
/sbin/gpart create -s gpt $DISKDEV1
/sbin/gpart create -s gpt $DISKDEV2
/bin/sync

/sbin/gpart add -a 4k -b 34 -s 64k -t freebsd-boot $DISKDEV1
/sbin/gpart add -a 4k -t freebsd-zfs -l disk0 $DISKDEV1
/bin/sync

/sbin/gpart add -a 4k -b 34 -s 64k -t freebsd-boot $DISKDEV2
/sbin/gpart add -a 4k -t freebsd-zfs -l disk1 $DISKDEV2
/bin/sync

/sbin/gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 $DISKDEV1
/sbin/gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 $DISKDEV2
/bin/sync

/sbin/gnop create -S 4096 /dev/gpt/disk0
/sbin/gnop create -S 4096 /dev/gpt/disk1
/bin/sync

/sbin/zpool create -m $MNT -f -o cachefile=/var/tmp/$ZPOOL.cache $ZPOOL mirror /dev/gpt/disk0.nop /dev/gpt/disk1.nop
/sbin/zpool export $ZPOOL
/sbin/gnop destroy /dev/gpt/disk0.nop
/sbin/gnop destroy /dev/gpt/disk1.nop
/sbin/zpool import -o cachefile=/var/tmp/$ZPOOL.cache $ZPOOL
/sbin/zpool set bootfs=$ZPOOL $ZPOOL
/sbin/zpool list
/sbin/zpool status
/sbin/zfs get recordsize
/usr/sbin/zdb -U /var/tmp/$ZPOOL.cache |grep ashift
/sbin/mount
/bin/df -H
/bin/sync

/sbin/zfs set checksum=fletcher4 $ZPOOL

/sbin/zfs create -V $SWAPSIZE $ZPOOL/swap
/sbin/zfs set org.freebsd:swap=on $ZPOOL/swap
/sbin/zfs set checksum=off $ZPOOL/swap
/bin/sync

/sbin/zfs create -o mountpoint=$MNT/usr $ZPOOL/usr
/sbin/zfs create -o mountpoint=$MNT/usr/ports $ZPOOL/usr/ports
/sbin/zfs create -o mountpoint=$MNT/usr/src $ZPOOL/usr/src
/sbin/zfs create -o mountpoint=$MNT/usr/home $ZPOOL/usr/home
/sbin/zfs create -o mountpoint=$MNT/var $ZPOOL/var
/sbin/zfs create -o mountpoint=$MNT/var/db $ZPOOL/var/db
/sbin/zfs create -o mountpoint=$MNT/var/tmp $ZPOOL/var/tmp
/sbin/zfs create -o mountpoint=$MNT/tmp $ZPOOL/tmp
/bin/sync

chmod 1777 $MNT/tmp $MNT/var/tmp

cd $DIST
export DESTDIR=$MNT
for file in base.txz doc.txz kernel.txz ports.txz src.txz; do (cat $file | tar --unlink -xpJf - -C ${DESTDIR:-/}) ; done

cat << EOF >> $MNT/etc/rc.conf
#!/bin/sh
ipv6_enable="NO"
rc_info="YES" # Enables display of informational messages at boot.

keymap=ru.koi8-r
keychange="61 ^[[K"
scrnmap=koi8-r2cp866
font8x16=cp866b-8x16
font8x14=cp866-8x14
font8x8=cp866-8x8
saver="blank"
keyrate="fast"

mousechar_start="3"
moused_enable="YES"
moused_port="/dev/psm0"
moused_type="auto"

network_interfaces="auto" # List of network interfaces (or "auto").
ifconfig_lo0="inet 127.0.0.1 netmask 255.255.255.0"
defaultrouter="192.168.0.1"
ifconfig_em0="inet 192.168.0.88 netmask 255.255.255.0"

hostname=$HOSTNAME

zfs_enable="YES"
kern_securelevel_enable="NO"
linux_enable="YES"
sshd_enable="YES"
sshd_flags="-u0"
usbd_enable="NO"

#fsck_y_enable="YES"
background_fsck="NO"

sendmail_enable="NONE" # Run the sendmail inbound daemon (YES/NO).
sendmail_flags="-L sm-mta -bd -q30m" # Flags to sendmail (as a server)
sendmail_submit_enable="NO" # Start a localhost-only MTA for mail submission
sendmail_submit_flags="-L sm-mta -bd -q30m -ODaemonPortOptions=Addr=localhost"
# Flags for localhost-only MTA
sendmail_outbound_enable="NO" # Dequeue stuck mail (YES/NO).
sendmail_outbound_flags="-L sm-queue -q30m" # Flags to sendmail (outbound only)
sendmail_msp_queue_enable="NO" # Dequeue stuck clientmqueue mail (YES/NO).
sendmail_msp_queue_flags="-L sm-msp-queue -Ac -q30m"
# Flags for sendmail_msp_queue daemon.
# to their chrooted counterparts.

nfs_reserved_port_only="NO"
ntpdate_flags="ntp.ucsd.edu"
ntpdate_enable="NO"
xntpd_enable="NO"
net_snmpd_enable="NO"
inetd_enable="NO"
inetd_program="/usr/sbin/inetd" # path to inetd, if you want a different one.
inetd_flags="-wW -C 60" # Optional flags to inetd

portmap_enable="NO"
nfs_server_enable="NO"
nfs_client_enable="NO"
tcp_drop_synfin="YES"
icmp_drop_redirect="YES"
icmp_log_redirect="NO"
syslogd_enable="YES"
syslogd_flags="-ss"
accounting_enable="NO"
check_quotas="NO"
clear_tmp_enable="YES" # Clear /tmp at startup.
cron_enable="YES" # Run the periodic job daemon.
named_enable="YES" # Run named, the DNS server (or NO).

#devd_enable="YES".
#devfs_system_ruleset="devfsrules_common".
ldconfig_paths="/usr/lib/compat /usr/local/lib /usr/local/kde4/lib /usr/local/lib/compat/pkg"

# Denyhosts Startup.
denyhosts_enable="YES"

EOF

cat << EOF >> $MNT/etc/fstab
# Device Mountpoint FStype Options Dump Pass#
#linproc /compat/linux/proc linprocfs rw 0 0

EOF

cat << EOF >> $MNT/etc/resolv.conf
search $HOSTNAME
domain $HOSTNAME
nameserver 127.0.0.1
#nameserver 8.8.8.8

EOF

cat << EOF >> $MNT/boot/loader.conf
zfs_load="YES"
vfs.root.mountfrom="zfs:$ZPOOL"
ahci_load="YES"

autoboot_delay="1"
beastie_disable="YES"

linux_load="YES" # Linux emulation
#lindev_load="NO" # Linux-specific pseudo devices (see lindev(4))
linprocfs_load="YES" # Linux compatibility process filesystem
linsysfs_load="YES" # Linux compatibility system filesystem

#ipfw_load="YES" # Firewall
#ipfw_nat_load="YES"

#if_tap_load="YES" # Ethernet tunnel software network interface

# Kernel Options
kern.ipc.shmseg=1024
kern.ipc.shmmni=1024
kern.maxproc=10000

vm.pmap.pg_ps_enabled="0"
#hw.mca.enabled=1
kern.timecounter.hardware=i8254
hw.pci.enable_msix=0
hw.pci.enable_msi=0
net.inet.tcp.tso=0

EOF

cp /var/tmp/$ZPOOL.cache $MNT/boot/zfs/zpool.cache
zpool set cachefile=$MNT/boot/zfs/zpool.cache $ZPOOL
/bin/sync

/sbin/zfs unmount -a
/bin/sync

/sbin/zfs set mountpoint=legacy $ZPOOL
/sbin/zfs set mountpoint=/tmp $ZPOOL/tmp
/sbin/zfs set mountpoint=/usr $ZPOOL/usr
/sbin/zfs set mountpoint=/usr/ports $ZPOOL/usr/ports
/sbin/zfs set mountpoint=/usr/src $ZPOOL/usr/src
/sbin/zfs set mountpoint=/usr/home $ZPOOL/usr/home
/sbin/zfs set mountpoint=/var $ZPOOL/var
/sbin/zfs set mountpoint=/var/db $ZPOOL/var/db
/sbin/zfs set mountpoint=/var/tmp $ZPOOL/var/tmp
/bin/sync
rm $MNT

exit 0

Памятка по эксплуатации FS в FreeBSD и Linux.
actika
1. При эксплуатации SSD дисков необходимо оставлять 5-10% дискового пространства неразмеченным, то есть в резерве. TRIM при этом можно не включать. Это официальная рекомендация.

2. Диски SSD на контроллере SаndForce2 не брать ни в коем случае. Это те что архивируют данные перед записью в ячейки памяти. Желательно брать диски Intel как самые долго живущие.

3. При эксплуатации файловой системы ZFS не допускать заполнение диска более чем на 65% так как при этом меняется алгорим поиска свободных блоков на диске и падает скорость. Это не касается SSD дисков.

4. В FreeBSD 9.1 провайдеры Geom ловят жуткие локи и непригодны к эксплуотации, а жаль. Ну может еще починят, в RC2 ggate починили.

5. При использовании KVM с дисками виртуальных машин в LVM в самих виртуальных машинах ни в коем случае нельзя использовать LVM так как в случае сбоя это может привести к потере данных.

6. При использовании EXT4 если после сбоя файловая система смонтирована в режиме redonly, это значит что журнал испорчен невосстановимо и запускать fsck нельзя нивкоем случае, а нужно спасать данные пока они еще есть.

7. Дефрагментатор EXT4 e4defrag нельзя запускать на высоко нагруженном севере так как он не проверяет достаточно ли места для дефрагментации и лочит диск.

Поговорим о железе, продолжение.
actika
Набрел на интересную новость: 
В США заработал новый мощнейший в мире суперкомпьютер.
http://podrobnosti.ua/mobile/2012/10/29/867209.html
Дословно: ... "каждый из 18 688 вычислительных узлов системы оснащён 16-ядерным серверным процессором AMD Opteron 6274 и ускорителем nVidia Tesla K20."

PS Intel? Не не слышали ...

Шеф все пропало.
actika
Итак взникла необходимость работать с файлами по взрослому и тут началось:
1) Почему то в Perl (FreeBSD) нет функции POSIX::fallocate
Can't locate auto/POSIX/fallocate.al in @INC 
Хотя в FreeBSD она есть с 8.3-RELEASE
http://www.ex.ua/view/14314966

2) На цпане обнаружилась очепятка
https://metacpan.org/module/IO::AIO
пишут aio_allocate на самом деле aio_fallocate
В любом случае под FreeBSD не работает /usr/ports/devel/p5-IO-AIO/work/IO-AIO-4.15/libeio/eio.c

#if HAVE_LINUX_FALLOCATE
return fallocate (fd, mode, offset, len);
#else
return EIO_ENOSYS ();
#endif

Та же самая херня с splice

#if HAVE_LINUX_SPLICE
loff_t off_in_, off_out_;
RETVAL = splice (
rfh, SvOK (off_in ) ? (off_in_ = SvVAL64 (off_in )), &off_in_ : 0,
wfh, SvOK (off_out) ? (off_out_ = SvVAL64 (off_out)), &off_out_ : 0,
length, flags
);
#else
RETVAL = EIO_ENOSYS ();
#endif

Позже выяснилось что эти штуки експериментальные (хотя и встроенные в ядро) и есть пока только в линукс.
http://forums.freebsd.org/showthread.php?p=195049
 

Проблемы с pvscsi в Ubuntu.
actika
Обычно я меняю в *.vmx несколько параметров сразу после создания vm еще до инсталяции linux:

scsi0.virtualDev="lsilogic" на "pvscsi"

ethernet0.virtualDev = "em1000" на "vmxnet3"

и добавляю mainMem.useNamedFile = "FALSE" чтоб не скидывало оперативку в файл все время.

После запусков тестов диска было замечено что хост выделил более 2-х гигабайт оперативной памяти, закрытие всех виртуальных машин к высвобождению памяти не привели и пришлось перегружать хост. Vmware tools были установленны из тулсов идущих вместе с vmware 9 (модули ядра компилятся при установке). В связи с этим пришлось прописать:

scsi0.virtualDev = "lsisas1068"

Пока полёт нормальный.

Не все йогурты одинаково полезны или отключаем vmware_tools под FreeBSD.
actika
Опытным путем было определено что это не только не полезная но даже вредная херня. Итак по порядку.
Тулсы стоят из vmware-freebsd-tools.tar.gz который идет вместе с 9 варей.
vmxnet через некоторое время взглючивает, выражается это сначала в подвисаниях потом в отвалах putty.
vmxnet3 тоже но сразу.
vmblock через время сжирает весь проц и подвешивает виртуалку.
Остается vmmemctl - так вот тот драйвер который идет с vmware похоже не имеет поддержки больших страниц в памяти и нужно обязательно их отключать (vm.pmap.pg_ps_enabled="0") иначе будут глюки.
Сайчас все работает стабильно вот в такой конфигурации:

pkg_info |grep open
open-vm-tools-nox11-425873_2,1 Open VMware tools for FreeBSD VMware guests

ifconfig | grep mtu
ipfw0: flags=8801 metric 0 mtu 65536
lo0: flags=8049 metric 0 mtu 16384
vxn0: flags=8843 metric 0 mtu 1500
vxn1: flags=8843 metric 0 mtu 1500

kldstat
Id Refs Address Size Name
1 13 0xffffffff80200000 c37540 kernel
2 1 0xffffffff81012000 157f vmmemctl.ko
3 1 0xffffffff81014000 22b5 vmxnet.ko
4 1 0xffffffff81017000 2994 vmblock.ko
5 1 0xffffffff8101a000 83af vmhgfs.ko
6 1 0xffffffff81023000 201 blank_saver.ko

less /boot/loader.conf
# Kernel Options
kern.ipc.shmseg=1024
kern.ipc.shmmni=1024
kern.maxproc=10000

#vm.pmap.pg_ps_enabled="0" !!!!!!!
#hw.mca.enabled=1
kern.timecounter.hardware=i8254
hw.pci.enable_msix=0
hw.pci.enable_msi=0
net.inet.tcp.tso=0

autoboot_delay="1"
beastie_disable="YES"

less /etc/rc.conf
vmware_guest_vmblock_enable="YES"
vmware_guest_vmhgfs_enable="YES"
vmware_guest_vmmemctl_enable="YES"
vmware_guest_vmxnet_enable="YES"
vmware_guestd_enable="YES"

И вот после всего этого проблема долго не проявлялась но ... опять. Симптомы следующие в окне вари намертво подвисает интерфейс фри, в самой фре sync работает и htop нет. Удалил из ядра модули линуксатора и подгрузил их отдельно... тестирую.

Немного истории.
actika
Итак начнем издалека: шел 2011 год, мир трясло от кризиса и вероятно финансовые дела подстегнули амд к преждевременному выпуску бульдозера. Почему преждевременному? Да все очень просто. На складах полно матерей под санбридж. Сам амд матери не делает только чипы. Если бы бульдозер был быстрее санбриджа, это фактически означало что нужно уценить товар на складах. Ага во время кризиса. Щаззз. В результате все производители встретили бульдозер дружным байкотом. Производители матерей зажали обновления биосов. Микрософт зажал обновление ядра. Ну если ядро еще ладно такие вещи не один день делаются. Обновления накатываются автоматом в том числе и на сервера. Это значит что обновленное ядро должно пройти полный цикл тестирования. Это минимум пол года с момента выхода бульдозера. Когда появились первые процессоры многие оверклокерские сайты носились с недостатьями высосанными из пальца. Типа процессор достали, мать под него достали, включили - неработает, биоса нет ... Потом амд пошел на уступки - и отрезал бульдозеру ... 
http://itc.ua/news/amd_utochnila_kolichestvo_tranzistorov_v_processorah_bulldozer_56775/
После чего в тестах буль уже не хватал звезд с неба. Обратите внимание что матери на 990FX доступны только в первой ревизии и хотя бульдозер готов работать даже на более ранних моделях, это сделано исключительно для обратной совместимости и высокая производительность не гарантируется ... Короче все тесты проведенные на матери не 990 можно даже не смотреть.

You are viewing actika