Архів рубрики: Адміністрування

Монтування спільної директорії в VirtualBox

Тимчасове припинення публікацій в моєму блозі пов’язане з тим, що на новому робочому місці я користуюсь Window 7. Я не роблю з цього великої трагедії, але час від часу сумую за Linux. Особливо не вистачає консолі та віртуальних робочих столів.

Проте необхідність у використанні Лінукс не зникла. Так для одного проекту, мені потрібно мати тестову віртуальну машину з Лінукс. Встановити її у VirtualBox дуже просто, а от щоб налагодити доступ до спільних каталогів треба додати кілька команд.

Першим кроком створюємо спільну директорію у параметрах віртуальної машини. Нехай її ім’я буде Common. Тепер монтуємо цю директорію від рута для перевірки:

# mount -t vboxsf Common /mnt/share

Якщо все вірно, то у директорію /mnt/share гостьової Лінукс буде змонтована спільна директорія з назвою Common.

Тепер залишається налагодити автоматичне монтування цієї спільної директорії при завантаженні Лінукс. Простіше за все, це зробити через додавання рядка у файл /etc/fstab:

Common /mnt/share vboxsf uid=1000,gid=1000 0 0

Використайте власні значення для ID користувача та групи, яким буде належати змонтована директорія. Останні два нульових параметра, означають, що файлова система не потребує архівації та перевірки на помилки.

Заміна IP адреси у файлах зон BIND

Є такі люди, що люблять подорожувати. Іноді сайти та сервіси теж зриваються з насидженого місця та вирушають у дорогу. Така міграція – справжній головний біль для системного адміністратора. Коли мова йде про 1-2 сервіси, це не проблема, а от коли переїжджає цілий хостінг.

Задача: є сервер імен BIND в якому треба поміняти всі записи зі старим IP на новий. Справу ускладнює те, що не всі зони треба міняти (оновлювати serial). Зміни мають зачепити лише ті файли зон, в яких дійсно змінюється IP. Як правило, я роблю такі зміни за допомогою Perl сценарію, але сьогодні спробував вичавити по максимуму командний рядок Лінукс.

У каталозі /etc/bing/db були зібрані файли зон, але були вкладені каталоги та символічні посилання. Тому на першому етапі відбираємо лише файли з каталогу та не чіпаємо підкаталоги:

find /etc/bind/db -maxdepth 1 -type f

Через xargs направляємо файл до grep

grep -H -m 1 '75.147.252.194'

Аргумент -H обов’язково додасть ім’я файлу до виводу, а -m 1 – покаже лише перше згадування старої IP-адреси.

Тепер залишаємо лише ім’я потрібного файлу зони (перший стовпець):

cut -d: -f1

Цю конструкцію я додав до Perl сценарію і на виході мав перелік файлів, в яких потрібно було зробити заміну IP та serial номер зони:

my $db_dir = "/etc/bind/db";
my $old_ip = '75.147.252.194';

my @files = `find $db_dir -maxdepth 1 -type f |
 xargs grep -H -m 1 '$old_ip' |
 cut -d: -f1`;

3mob інтернет через модем HUAWEI Mobile у Debian

Інколи, в мене падає кабельний інтернет і я змушений переключатися на резервний 3G від 3mob (колишній Утел та Укртелеком). Як я вже писав, з першого разу я зміг без проблем підключитися до 3G мережі, але потім всі мої спроби підключення завершувались аварійно.

Тоді в мене не було часу розбиратися в чому справа, бо як правило, кабельний інтернет швидко починав робити знову і я забував про свій 3G. Але сьогодні я вирішив з’ясувати в чому справа.

Перш за все, після відмови підключитися, я продивився вивід dmesg:

# dmesg | tail -n 1
[407908.851115] modem-manager[11161]: segfault at 0 ip
 00007f3172ea60a8 sp 00007fff6ce952c8 error 4 in
 libglib-2.0.so.0.3200.4[7f3172e32000+f5000]

Segmentation fault – це завжди погано. Погугливши на тему modem-manager я знайшов багато подібних проблем і рішення у стилі “ось тобі молоток та зубильце – доопрацьовуй”.

Справа в тому, що Лінукс не вірно визначає ідентифікатор пристрою. Але це можна полагодити.

1. Підключаємо USB модем і дивимось вивід dmesg:

$ dmesg | tail
[408349.676873] ehci_hcd 0000:00:1a.0: setting latency timer to 64
[408349.692769] xhci_hcd 0000:00:14.0: setting latency timer to 64
[408349.896576] usb 1-1.2: new high-speed USB device number 4 using
 ehci_hcd
[408349.999615] usb 1-1.2: New USB device found,
 idVendor=12d1, idProduct=1446
[408349.999626] usb 1-1.2: New USB device strings: Mfr=2, Product=1,
 SerialNumber=0
[408349.999632] usb 1-1.2: Product: HUAWEI Mobile
[408349.999637] usb 1-1.2: Manufacturer: HUAWEI Technology
[408350.004599] scsi33 : usb-storage 1-1.2:1.0
[408350.005229] scsi34 : usb-storage 1-1.2:1.1
[408350.595754] ehci_hcd 0000:00:1d.0: setting latency timer to 64

Нас цікавить лише ідентифікатор виробника (idVendor) та пристрою (idProduct).

2. Він рута завантажуємо модуль option:

# modprobe option

3. Через команду usb-devices перевіряємо які ідентифікатори виробника та продукту вказані для нашого модему (вивід скорочено):

# usb-devices 
...
T:  Bus=03 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 15 Spd=480 MxCh= 0
D:  Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs=  1
P:  Vendor=12d1 ProdID=1001 Rev=00.00
S:  Manufacturer=HUAWEI Technology
S:  Product=HUAWEI Mobile
C:  #Ifs= 5 Cfg#= 1 Atr=e0 MxPwr=500mA
I:  If#= 0 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=option
I:  If#= 1 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option
I:  If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option
I:  If#= 3 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=06 Prot=50 Driver=usb-storage
I:  If#= 4 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=06 Prot=50 Driver=usb-storage
...

4. Видно, що виробник вказаний вірно, а от код пристрою – ні. Встановлюємо вірні значення:

# echo 12D1 1446 > /sys/bus/usb-serial/drivers/option1/new_id

Після цього мій 3G модем HUAWEI успішно підключився до мережі 3mob.

Як поставити пароль на архів tar у Лінукс

Виявляється це на так просто. Команда tar не має вбудованої підтримки шифрування. Тому робимо це у “юнікс”-way:

Шифруємо дані:

$ tar cfz - ФАЙЛ | openssl enc -aes-256-cbc -e > АРХІВ.tar.gz
enter aes-256-cbc encryption password:
Verifying - enter aes-256-cbc encryption password:

Розшифровуємо:

$ openssl enc -in АРХІВ.tar.gz -aes-256-cbc -d | tar -zxvf -
enter aes-256-cbc decryption password:

Звичайно замість файлу може бути і директорія.

Tomcat, що слухає лише localhost

У лог-файлі Томкату помітив чисельні спроби зайти у менеджер додатків (Tomcat Web Application Manager):

Sep 8, 2013 11:46:04 AM org.apache.catalina.realm.LockOutRealm authenticate
WARNING: An attempt was made to authenticate the locked user ""
Sep 8, 2013 11:46:04 AM org.apache.catalina.realm.LockOutRealm authenticate
WARNING: An attempt was made to authenticate the locked user "tomcat"
Sep 8, 2013 11:46:04 AM org.apache.catalina.realm.LockOutRealm authenticate
WARNING: An attempt was made to authenticate the locked user "tomcat"

Подібних рядків було багато, здається це якійсь павук-робот намагався підібрати пароль.

Сервер був тестовий, тому ніякої цінної інформації не містив, проте мене здивувало, як зловмисники підібралися до менеджера додатків, адже Tomcat працює як back-end і front-end Nginx проксує тільки певні URL. Мої спроби перейти на http://serverdomain/manager закінчувались 404 сторінкою.

І тут я зрозумів свій прорахунок у системі безпеки: Tomcat слухав 8080 порт на всіх інтерфейсах! Тобто не тільки на 127.0.0.1, але й на зовнішніх. Додавши номер порту http://serverdomain:8080/manager я й сам побачив на екрані запрошення пройти аутентифікацію.

Отже змушуємо Tomcat слухати лише localhost. Для цього у файлі conf/server.xml знаходимо рядки, що починаються з “<Connector ” і додаємо у цей XML тег атрибут address=”127.0.0.1″.

Після внесених змін матимемо такий вивід:

$ grep Connector server.xml | grep port=
 <Connector address="127.0.0.1" port="8080" protocol="HTTP/1.1"
 <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
 <Connector address="127.0.0.1" port="8009" protocol="AJP/1.3"
 redirectPort="8443" />

На порт 8443 не зважайте, адже його опис закоментований. Після перезапуску Томкату слід переконатися, що порти 8080, 8009 та 8005 слухаються лише на localhost:

$ netstat -na | grep :8080
tcp6       0      0 127.0.0.1:8080          :::*            LISTEN
$ netstat -na | grep :8009
tcp6       0      0 127.0.0.1:8009          :::*            LISTEN
$ netstat -na | grep :8005
tcp6       0      0 127.0.0.1:8005          :::*            LISTEN

Лапки у rewrite правилах Nginx

Якщо пишете правило rewrite для веб-сервера Nginx в якому використовуєте регулярні вирази (regexp) – завжди беріть його у лапки!

Тоді вам не побачити помилку при старті (рестарті) цього серверу:

nginx: [emerg] directive "rewrite" is not terminated by ";" in ...

Правило мало досить безневинний вигляд:

rewrite ^/([A-Za-z0-9]{6})$ /dyn/gallery.js?link=$1 last;

А треба було писати так:

rewrite "^/([A-Za-z0-9]{6})$" /dyn/gallery.js?link=$1 last;

CentOS та svn клієнт при зміні аутентифікації на Cyrus SASL

Якщо Ви коли-небудь встановлювали svnserve (сервер для Subversion) то маєте знати, що він підтримує аутентифікацію за методом Cyrus SASL. До речі, її не так просто під’єднати до svnserve. Про всяк випадок, перевірте такі параметри в конфігурації:

$ grep sasl svnserve.conf
[sasl]
use-sasl = true

Обов’язково має стояти true.

Але після зміни методу аутентифікації, в мене перестав працювати svn клієнт під CentOS. Ось що він написав:

$ svn up
svn: Cannot negotiate authentication mechanism

Виявилось, що йому не вистачило пакунку cyrus-sasl-md5.

# yum install cyrus-sasl-md5
...
===================================================================
 Package              Arch     Version            Repository  Size
===================================================================
Installing:
 cyrus-sasl-md5       x86_64   2.1.23-13.el6_3.1  base        47 k

Transaction Summary
===================================================================
Install       1 Package(s)

Total download size: 47 k
...
Installed:
 cyrus-sasl-md5.x86_64 0:2.1.23-13.el6_3.1
Complete!

Міграція гостьових Debian у VirtualBox та проблеми з мережею NAT

Нещодавно я скопіював усі свої гостьові операційні системи з одного комп’ютера на інший. Через OVL формат – це тривіальні задача. Хоча, якщо назви у віртуальних машин однакові (а саме назви файлів для дисків), то це не виходить зробити за один раз. Доводиться кожну таку машину окремо.

Так от, всі машини запустились без проблем, а старенька Debian 4.0 – ні. Точніше вона начебто працювала нормально, але без мережевого інтерфейсу eth0:

$ /sbin/ifconfig
lo        Link encap:Local Loopback  
 inet addr:127.0.0.1  Mask:255.0.0.0
 inet6 addr: ::1/128 Scope:Host
 UP LOOPBACK RUNNING  MTU:16436  Metric:1
 RX packets:8 errors:0 dropped:0 overruns:0 frame:0
 TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
 collisions:0 txqueuelen:0 
 RX bytes:560 (560.0 b)  TX bytes:560 (560.0 b)

Спроба запустити його вручну закінчилась нічим:

# ifup eth0
Internet Systems Consortium DHCP Client V3.0.4
Copyright 2004-2006 Internet Systems Consortium.
All rights reserved.
For info, please visit http://www.isc.org/sw/dhcp/

SIOCSIFADDR: No such device
eth0: ERROR while getting interface flags: No such device
eth0: ERROR while getting interface flags: No such device
Bind socket to interface: No such device
Failed to bring up eth0.

Файл /etc/network/interfaces післе переносу не редагувався і містив стандартні рядки:

auto lo
iface lo inet loopback

allow-hotplug eth0
iface eth0 inet dhcp

Трохи погугливши вияснив, що проблема в udev. А ще точніше – у файлі /etc/udev/rules.d/z25_persistent-net.rules. На різних версіях Debian-оподібних операційних систем він може мати інші префікси, але persistent-net.rules буде присутнє. Файл мав такий зміст:

# This file was automatically generated by the
# /lib/udev/write_net_rules
# program, probably run by the persistent-net-generator.rules rules
# file.
#
# You can modify it, as long as you keep each rule on a single line.
# MAC addresses must be written in lowercase.

# PCI device 0x8086:0x100e (e1000)
SUBSYSTEM=="net", DRIVERS=="?*", ATTRS{address}=="08:00:27:a5:c0:ff",
 NAME="eth0"

# PCI device 0x8086:0x100e (e1000)
SUBSYSTEM=="net", DRIVERS=="?*", ATTRS{address}=="08:00:27:97:b2:6b",
 NAME="eth1"

Як я зрозумів, при міграції гостьової Debian, було змінено MAC адресу мережевого адаптеру. І система udev чомусь подумала, що це новий адаптер. Мені залишилось лише видалити інформацію про eth0 (перший рядок) та змінити в другому eth1 на eth0:

SUBSYSTEM=="net", DRIVERS=="?*", ATTRS{address}=="08:00:27:97:b2:6b",
 NAME="eth0"

Після перезапуску віртуальної машини – мережа піднялась автоматично.

Nginx+Tomcat7 та обмеження на розмір WAR-файлу у manager

В розробці та тестуванні програмних продуктів, що використовують Tomcat, досить зручно користуватися Web Application Manager (/manager/).

Я використовую зв’язку Nginx+Tomcat, щоб працювати з 80-м портом. Та Nginx пропускає великі WAR-файли лише за наявності такої опції:

http {
    ...
    client_max_body_size 100m;
}

Тепер файли до 100 Мб буде передано Томкату. Проте виявилось у менеджера Tomcat є власне обмеження в 50 Мб:

org.apache.tomcat.util.http.fileupload.FileUploadBase$SizeLimitExceededException:
 the request was rejected because its size (67082177) exceeds
 the configured maximum (52428800)

Виправити його можна у файлі TOMCAT_DIR/webapps/manager/WEB-INF/web.xml. Для 100 Мб я вписав таке:

<multipart-config>
  <!-- 100MB max -->
  <max-file-size>104857600</max-file-size>
  <max-request-size>104857600</max-request-size>
  <file-size-threshold>0</file-size-threshold>
</multipart-config>

Встановлення паролю для користувача root у MySQL замість порожнього

Сервер баз даних MySQL за умовчанням працює з порожнім паролем рута. Це зручно, адже не треба нічого пам’ятати для створення нового користувача чи бази даних.

Але коли MySQL встановлено на сервері, до якого мають доступ декілька користувачів, працювати з порожнім root паролем принаймні необачно.

Тому крок перший – перевіряємо чи пускає звичайного користувача як рута без паролю:

$ mysql -u root
Welcome to the MySQL monitor.  Commands end with ; or g.
Your MySQL connection id is 2
Server version: 5.1.69 Source distribution

Пускає – це погано. Встановлюємо новий пароль для рута:

$ mysqladmin -u root password НОВИЙ_ПАРОЛЬ

Перевіряємо ще раз:

$ mysql -u root
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using
 password: NO)