Вы читаете журнал [info]slavazanko

Треснуло стекло у моего iPhone 2G. Причём некисло так треснуло - всё трещинами покрылось. Пошёл в ремонтную мастерскую мобильников, показал Айфон и спросил, сколько будет стоить замена . Мужик повертел телефон в руках и изрёк, что такое стекло стоит чуть дешевле нового iPhone 3G. Я, малось охреневший, залез на eBay: стекло стоит $21  с доставкой, экран - $23. Возвращаюсь назад в мастерскую, говорю, что стекло и экран стоят 44 бакса, "если закажу и попозже принесу, то замените?" В ответ услышал следующее: "мы не пользуемся сторонними запчастями, заказываем только у своих проверенных и надёжных поставщиков".  Развернулся и ушёл от них. Залез в Гугель, нашёл видео замены экрана для iPhone 2G - всё просто, как два пальца об асфальт, только аккуратно надо и не спеша. Купил новый экран со стеклом на eBay, жду доставки.

Сейчас жалею, что не спросил у того перца, где можно купить iPhone 3G по цене чуть больше 44 баксов. :(

P.S. не исключаю, что они клиентам заламывают космические цены, потом лезут на ебай покупают по реальной цене, лезут в Гуголь и смотрят как заменить. Потом ещё дополнительно сдирают с клиента за "ремонтные работы".  То есть,  примерно за полтора-два часа работы.

Бизнесьмены, блин :(

UPD: пришло стекло с экраном. Аккуратно заменил. Забыл подключить всего один контакт и испугался что сломал :) Побежал в мастерскую, там мужик удивился, что я не побоялся влезть в Айфон, разобрал, сказал "ну конечно" и показал мне неподключенный контакт от батареи (он, суко, совсем уж неприметный там). Заплатил я за свою оплошность в пересчёте $3.

Итого: 44+3 = $47. Дайте, дайте мне новый IPhone-3g по такой цене!
Введение
Опишу свой вариант простого как валенок DynDNS-сервера, "слепленного" из подручных средств. Используемая операционная система: CentOS-5, что фактически означает, что на Fedora все описанные действия будут аналогичными; вероятно, описанный алгоритм будет применим к остальным дистрибутивам Unix/Linux с некоторыми изменениями.

Предварительные требования

Для поднятия своего DynDNS-сервера необходимы:
  • DNS-сервер (bind);
  • WEB-сервер с php. Будет рассмотрена настройка WEB-сервера Apache;
  • демон сервисов Internet (xinetd).
Ниже будут использоваться следующие условные обозначения:
ddns.example.net
DNS-зона, делегирование которой принадлежит Вам (ваш сервер яввляется NS для зоны)
/srv/web/ddns/wwwroot
путь, по которому будут размещены файлы DynDNS-сервера
Установка и настройка WEB-сервера

Установка WEB-сервера Apache
Установите необходимые пакеты:
yum install httpd php

Пропишите конце файла файле /etc/httpd/conf/httpd.conf строки:
NameVirtualHost *:80
include "/etc/httpd/conf/subsites/*.conf"

Создание необходимых каталогов.
Создайте каталог для настроек виртуальных хостов Апача:
mkdir -p /etc/httpd/conf/subsites

Создайте каталог для размещения файлов виртуальных хостов:

mkdir -p /srv/web/ddns/{webroot,logs}

Правила для SELinux.
Чтобы его настроить, не нужно его отключать. как это делает подавляющее большинство админов, а достаточно вдумчиво почитать маны :)
Ленивым и не желающим просвещаться манами, выполнить команды:

semanage fcontext -a -t httpd_sys_content_t '/srv/web/([^/]*/)?wwwroot(/.*)?'
semanage fcontext -a -t httpd_log_t '/srv/web/([^/]*/)?logs(/.*)?'
restorecon -R /srv/web
setsebool -P httpd_can_network_connect=1  


Настройка VirtualHost
Создайте файл /etc/httpd/conf/subsites/ddns.example.net.conf следующего содержания:
<VirtualHost *:80>
    ServerAdmin webmaster@ddns.example.net
    ServerName
ddns.example.net

    DocumentRoot /srv/web/ddns/wwwroot
    <Directory "/srv/web/ddns/wwwroot">
            AllowOverride All
    </Directory>

    ErrorLog /srv/web/ddns/logs/error.log
    CustomLog /srv/web/ddns/logs/access.log common
</VirtualHost>

Запустите Apache командами:
chkconfig httpd on
service httpd restart

Создание файлов для виртуального хоста
Создайте каталог:
mkdir -p /srv/web/ddns/wwwroot/nic

Создайте файл /srv/web/ddns/wwwroot/nic/.htaccess следующего содержания:
RewriteEngine On
RewriteRule update?(.*)$ /nic/upd.php?$1 [QSA,L]

<Files "passwd">
    Order deny,allow
    Deny From All
</Files>


Создайте файл /srv/web/ddns/wwwroot/nic/index.php следующего содержания:
<html>
  <head><title>Current IP Check</title></head>
  <body>Current IP Address: <?php echo $_SERVER['REMOTE_ADDR'];?></body>
</html>


Создайте файл /srv/web/ddns/wwwroot/nic/upd.php следующего содержания:
<?php

if (!isset($_SERVER['PHP_AUTH_USER']) or !isset($_SERVER['PHP_AUTH_PW']))
{
  echo "badauth noauth";
  exit;
}

function getDomainName()
{
  $pswd = file("passwd");
  foreach($pswd as $line)
  {
    $line=split(":",$line);
    if ($line[0] == $_SERVER['PHP_AUTH_USER'] and $line[1] == $_SERVER['PHP_AUTH_PW'])
      return str_replace("\n","", $line[2]);
  }
  return false;
}

$domain=getDomainName();
if ($domain === false)
{
  echo "badauth wrongauth";
  exit;
}

$domain.=".
ddns.example.net";
if ($domain != $_GET['hostname'])
{
  echo "nohost ".$_GET['hostname'];
  exit;
}

if (!preg_match("/^\d+.\d+.\d+.\d+$/", $_GET['myip']))
{
  echo "dnserr ".$_GET['myip'];
  exit;
}

function runCmd($str)
{
  $addr="127.0.0.1";
  $port="12345";
  $authinfo='root:g8GkKFSxYlsDLV';

  $handle = @fopen("http://".$authinfo."@".$addr.":".$port."/".base64_encode($str), "rb");
  if ($handle === false)
     return false;
  fwrite($handle, $str);
  $str ='';
  while(! feof($handle))
    $str .= fgets($handle);

  fclose($handle);
  return $str;
}
echo "good ".$_GET['hostname'];
?>

Создайте файл /srv/web/ddns/wwwroot/nic/passwd:
touch /srv/web/ddns/wwwroot/nic/passwd
chown apache /srv/web/ddns/wwwroot/nic/passwd
chmod 0400 /srv/web/ddns/wwwroot/nic/passwd

В дальнейшем этот файл будет хранить логины и пароли пользователей, а также их доменные имена.

На этом настройка web-части нашего DynDNS-сервера закончена. переходим к настройке DNS

Установка DNS-сервера bind
Установите необходимые пакеты:
yum install bind-chroot bind-utils

Вставьте в конец файла /var/named/chroot/etc/named.conf строку:
include "/etc/ddns.example.net.zones";


Создайте файл /var/named/chroot/etc/ddns.example.net.zones следующего содержания:
zone "ddns.example.net" {
  type master;
  file "
ddns.example.net.zone";
  allow-query { any; };
  allow-transfer {
    XX.XX.XXX.XX;  // я затёр свои Secondary-DNS сервера.
подставьте адреса своих DNS-серверов.
    XXX.XX.XXX.XXX; //  Если их нет, то просто уберите весь блок "allow-transfer" из конфига.
  };
};


Создайте файл /var/named/chroot/etc/ddns.example.net.zones следующего содержания:
$TTL 60 ; 3 days
@ IN SOA ns.
ddns.example.net. hostmaster.ddns.example.net. (
        2008062821    ; Serial
        60            ; Refresh
        20            ; Retry
        600           ; Expire
        100)          ; Minimum TTL
; Name servers
                   IN  NS  ns1.
ddns.example.net.
; address of domain
                   IN  A   XXX.XX.XXX.XXX
ddns.example.net.  IN  A   XXX.XX.XXX.XXX

ns                 IN  A  
XXX.XX.XXX.XXX
mail              
IN  A   XXX.XX.XXX.XXX

; Mail server(s)
                   IN  MX 10 mail
.ddns.example.net.
; ddns hosts

подставьте IP-адрес своего сервера вместо XXX.XX.XXX.XXX

Запустите DNS-сервер командами
chkconfig named on
service named restart

Установка сервера сетевых соединений xinetd
Установите необходимые пакеты:
yum install xinetd

Создайте файл /etc/xinetd/runDdnsServ следующего содержания:
service runDdnsServ
{
    id                      = runServId
    type                    = UNLISTED
    disable                 = no
    port                    = 12345
    socket_type             = stream
    protocol                = tcp
    wait                    = no
    user                    = root
    passenv                 = PATH
    server                  = /usr/local/sbin/runDdnsServ.sh
    env                     = HOME=/tmp
    bind                    = 127.0.0.1
}

Создайте файл /usr/local/sbin/runDdnsServ.sh следующего содержания:
#!/bin/bash

incrementSerialOfBindZone(){
    local zn
    zn=$1
    ZONE_SERIAL=$(( $(grep -P '^\s*\d+\s*\;\s*Serial' $zn | awk '{print $1}') + 1))
    awk '/Serial/{print "                    '$ZONE_SERIAL'       ; Serial"; next} {print $0}' \
    $zn >$zn.tmp && mv -f $zn{.tmp,} || rm -f $zn.tmp
}

AUTHINFO="root:g8GkKFSxYlsDLV"
HTTP_ROOT="/tmp/runDdnsServ";
mkdir -p $HTTP_ROOT
TERM=linux
cd $HTTP_ROOT
read SSS
while [ ${#SSS} -ne 1 ]; do
    [ $(echo "$SSS"| grep -c '^GET') -eq 1 ] && GET=$(echo $SSS|sed -r -e 's@^GET @@' -e 's@\s*HTTP.*$@@')
    [ $(echo "$SSS"| grep -c '^Authorization: Basic ') -eq 1 ] && AUTH=$(echo $SSS|sed -r -e 's@^Authorization:\s*Basic\s*@@')
    read -t 1 SSS
done

REQUEST_PAGE=$(echo "$GET"|sed -r -e 's@^([^\?]*)\?.*@\1@')
[ "$REQUEST_PAGE" = "/" ] && REQUEST_PAGE="/index.html"
QUERY_STRING=$(echo "$GET"|sed -r -e 's@^[^\?]*\?(.*)@\1@')
[ $(echo "$REQUEST_PAGE"| grep '\.\.') ] && exit

AUTH=$(echo "$AUTH"| base64 -d 2>/dev/null)

dt=$(LANG=C date)
cat <<EOF
HTTP/1.0 302 Found
Date: ${dt}
Server: runDdnsServ/0.0.1
X-Powered-By: BASH/3.1.17
Connection: close
Content-Type: text/html

EOF

[ "$AUTH" != "$AUTHINFO" ] && {
    echo "Forbidden"
    exit
}

[ -f $HTTP_ROOT/$REQUEST_PAGE ] && {
    cat $HTTP_ROOT/$REQUEST_PAGE
    exit
}

FULLCMD=$(echo "$REQUEST_PAGE"| sed -e 's@^/@@'| base64 -d 2>/dev/null)

CMD=$(echo "$FULLCMD"| awk '{print $1;}')

ddnsUpdate(){
    CMD=$1
    DOMNAME=$2
    IPADDR=$3
    FILEZONE="/var/named/chroot/var/named/
ddns.example.net.zone"
    grep -v '^'$DOMNAME $FILEZONE > $FILEZONE.tmp && {
        mv $FILEZONE{.tmp,}.
    } || {
        rm -f $FILEZONE.tmp
        exit 1
    }
    cat >>$FILEZONE <<EOF
$DOMNAME.  IN   A    $IPADDR
EOF
    incrementSerialOfBindZone  "$FILEZONE"
    /usr/sbin/rndc reload
}

case "$CMD" in
  ddns-update)
    ddnsUpdate $FULLCMD
  ;;
  *)
    echo "Forbidden"
    exit
  ;;
esac

Выполлните команду:
chmod 0500 /usr/local/sbin/runDdnsServ.sh

Запустите xinetd-сервер командами
chkconfig xinetd on
service xinetd restart

Всё, на данном этапе Вы будете иметь собственный рабочий DynDNS сервер.

Настройка DynDNS-клиентов
Добавление клиентов на сервере
Все логины и пароли клиентов хранятся на сервере в файле /srv/web/ddns/wwwroot/nic/passwd. Формат файла следующий:
<логин>:<пароль>:<доменное имя>

Например, рассмотрим случай добавления доменного имени first-client.ddns.example.net с логином fclient и паролем hgHy7T
Добавьте в файл /srv/web/ddns/wwwroot/nic/passwd строку:
fclient:hgHy7T:first-client

Всё, больше на сервере ничего изменять не надо.

Настройка ddclient
Измените файл /etc/ddclient.conf следующим образом:
daemon=30
syslog=yes
mail-failure=root
pid=/var/run/ddclient/ddclient.pid
server=
ddns.example.net
protocol=dyndns2
login=fclient
password=hgHy7T
first-client.ddns.example.net


перезапустите ddclient:
service ddclient restart

Настройка модемов, маршрутизаторов, точек доступа
У меня нет единого рецепта по настройке сетевого оборудования. Проконсультируйтесь с документацией на Ваше оборудование, поддерживает ли оно DynDNS

Заключение
Я постарался в сжатой, но достаточной для полной настройки форме рассказать про свою реализацию DynDNS-сервиса. Моя реализация, естественно, не идеальна, но для моих собственных нужд достаточна. Из недостатков можно было бы выделить основных два:
  •  хранение паролей в открытом виде
  • слишком много возни по настройке DynDNS-сервиса
Если вас это не испугало и Вы всё-таки прошли весь этот путь тоже, то я был бы рад увидеть ваши  комментарии к этой статье (с критикой или без).

Спасибо за внимание.
Эту статью пишу по «горячим следам» после статьи Настрой себе IPv6 в Debian и Ubuntu. Описывается настройка с учётом специфики Red Hat based дистрибутивов, ну и освещены пару подводных камней. Эта статья не повторяет предыдущую, а как бы дополняет её.

Шаг 1. Регистрируем туннель


Итак, заходим на сайт Hurricane Electric, регистрируемся, логинимся на сайте, и создаём туннель. Здесь всё так же, как и в исходной статье-прототипе.

Шаг 2. Настраиваем IPv6 — сетевой интерфейс

Убедитесь, что в файле /etc/sysconfig/network присутствует строка:

NETWORKING_IPV6=yes
Если нету этой строки — добавьте.

Создайте файл /etc/sysconfig/network-scripts/ifcfg-sit1 следующего содержания:
DEVICE=sit1
BOOTPROTO=none
ONBOOT=yes
IPV6INIT=yes
IPV6TUNNELIPV4={REMOTE_IPV4}
IPV6TUNNELIPV4LOCAL={LOCAL_IPV4}
IPV6ADDR={LOCAL_IPV6}


Вместо названий в фигурных кавычках подставьте значения, указанные в свойствах Вашего новосозданного туннеля:

  • REMOTE_IPV4 — адрес сервера, к которому будем подключаться
  • LOCAL_IPV4 — наш реальный Internet-адрес

  • LOCAL_IPV6 — наш локальный ipv6-адрес, выданный нам на сайте. Будет в формате 2001:470:XXXX:XXXX::2/64


Подводные камни — №1 (NAT)


Отдельно хотелось бы сказать про LOCAL_IPV4 — наш реальный Internet-адрес. Необходимо обеспечить хождение сорок первого протокола (6over4) в обе стороны. Что это значит? Это значит, что если Ваш компьютер подключен через NAT, то у вас возникнут сложности с подключением к туннелю, ибо для его работы необходим реальный ip-адрес. Для владельцев ADSL-модемов выходом может быть настройка файрволла модема на проброс трафика по 41-му протоколу на ваш компьютер; или указание вашего компьютера в качестве DMZ-хоста, но будьте тут осторожны — весь неизвестный трафик модем пробросит на ваш компьютер, что фактически означает доступность компьютера(не модема!) для сканинга извне. Если что — я предупредил :) Впрочем, если у вас не отключены умолчательные iptables и SELinux, то риск невелик.

В случае NAT'а и проброса 41-го протокола на ваш компьютер в качестве LOCAL_IPV4 необходимо будет указать уже ваш «серый» адрес, при этом на сайте Hurricane Electric необходимо указать реальный IP-адрес вашего модема.

Шаг 3. Настраиваем IPv6 — маршрутизация



Создайте файл /etc/sysconfig/static-routes-ipv6 следующего содержания:
sit1 ::/0


Шаг 4. Настраиваем IPv6 — iptables-фильтрация


Найдите в файле /etc/sysconfig/iptables строку:
-A INPUT -p icmp -j ACCEPT

и добавьте после неё:
-A INPUT -p 41 -j ACCEPT

Выполните команду:
service iptables restart


Шаг 5. Запускаем ipv6-туннель


Тут всё просто — выполните команду:
ifup sit1

Всё, теперь у вас есть настроенный туннель. Протестируйте его:
slavaz@notebook ~ $ ping6 -c 4 ipv6.google.com
PING ipv6.google.com(2a00:1450:8001::69) 56 data bytes
64 bytes from 2a00:1450:8001::69: icmp_seq=1 ttl=56 time=137 ms
64 bytes from 2a00:1450:8001::69: icmp_seq=2 ttl=56 time=142 ms
64 bytes from 2a00:1450:8001::69: icmp_seq=3 ttl=56 time=137 ms
64 bytes from 2a00:1450:8001::69: icmp_seq=4 ttl=56 time=142 ms

--- ipv6.google.com ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3146ms
rtt min/avg/max/mdev = 137.557/140.159/142.683/2.431 ms


Подводные камни — №2 (Dynamic IP)



Если у вас динамический адрес, то существует и здесь решение.

Добавьте в /etc/rc.d/rc.local следующие строки:

PASSWD="Ваш пароль"
USERID="Ваш пользовательский ID"
GTUNID="Global Tunnel ID"
MD5PASS=$(echo -n $PASS | md5sum | sed -e 's/ -//g')
curl -k "https://ipv4.tunnelbroker.net/ipv4_end.php?ipv4b=AUTO&pass=$MD5PASS&user_id=$USERID&tunnel_id=$GTUNID" >/var/log/6over4.log 2>&1


Можете один раз выполнить команду:
echo -n "Ваш пароль" | md5sum | sed -e 's/ -//g'

и результирующий хэш вставить в файл, чтобы пароль не светить.

Вроде всё. Надеюсь, хоть кому-то пригодится.

P.S. Про безопасность: также не забывайте про файл /etc/sysconfig/ip6tables — ваш компьютер теперь напрямую подключен к IPv6-сети, а следовательно, напрямую доступен для сканеров и брутфорсеров (благо их пока практически нет в IPv6).
Сервис, например, почтовый - это, в моём понимании, <postfix|exim|sendmail|...> + <dovecot|cyrus-imapd|...> + веб-админка + spamassasin + greylisting  + webmail + mailman  + (хранилище в MySQL, PostgreSQL или без них)

Точно также любой другой сервис. Если биллинг - то это всё от iptables+ulogd до красявых диаграмм, графиков и т.д.
Если шлюз, то это tc + shorewall + squid+вебадминка(пользователи, баннерорезка, ширина канала, время выхода, лимит на кач и т.д.)

Так вот, подумалось на досуге: сколько тысяч сисадминов (и тех, кто себя ими считает) проходит одними и теми же тропами по настройке сервисов... сколько из них настраивало однотипные конфигурации на нескольких компах? Много. И я в том числе.

Пытался как-то решить эту проблему для себя - создал набор скриптов, каждый скрипт настраивает какой-то сервис. Но так всё оно топорно, что ли... короче, самому не нравится, хочется более логичного...

Так вот, мысли: запустили скрипт, например,  mail_setup, а на "выходе" имеем установленный и настроенный почтовый сервер. Потом запустили mail-virtual_setup - и имеем всё тот же почтовый сервер, но уже донастроенный на виртуальные домены/пользователей... В общем, идея проста, как валенок: автоматизировать рутину. Вплоть до запуска одного set_up , использующего  один конфиг вида:
MAIL=1
LDAP=1
SAMBA=1
FTP=1
ROUTER=0
HTTP=1
NFS=0
NETBOOT=0
DNS=1
DHCP=1
VOIP_ASTERISK=1
и т.д.


Дополнительные параметры, необходимые для настройки сервисов, можно будет хранить либо в этом же файле, либо в отдельных небольших файликах (каждый по названию сервиса). Дополнительными параметрами просто можно достичь некислой гибкости при настройке (ибо одному серверу необходима работа одних сервисов в определённой связке, второму - уже другое, с другим взаимодействием и т.д.).

При выборе, например, LDAP=1 все остальные зависимые сервисы (SAMBA, PAM, DNS?, DHCP?) автоматом перенастраиваются на использование оного. Точно также при установке kerberos, freeradius и т.д. Нечто триггерное, короче. При этом каждый сервис может отказаться или согласиться с срабатыванием триггера (типа, SAMBA_LDAP=0,  MAIL_MYSQL=1 ).
Мысли вслух: зависимости между сервисами? Пока думаю...


В идеале я вижу такую картинку:
  1. устанавливается любой Linux-дистрибутив
  2. после установки на CD/DVD, на флэшке, по сети и т.д. подключается наша система настройки
  3. меняется конфигурационный файл этой системы
  4. запускается аналог кнопки "сделай мне зашибись" - некий скрипт set_up
  5. вуаля. наслаждаемся настроенным сервером
Из плюсов:
  1. по окончании настройки имеем практически идеальный паспорт сервера (конфиг+лог установки)
  2. можем тиражировать однотипные конфигурации настроенных серваков
  3. садимся, будучи убунтологами, за RH, пишем команду mount /bla-bla /mnt/bla-bla, правим конфиг, запускает сетап - и получаем настроенную как конфетку систему. Без глубокого знания Red Hat-подобных дистрибутивов. Ситуация наоборот (рэдхатоид на убунте, генте, арче и т.д.) также будет вполне реальна.
Ну вот, первая прицелка на идею пошла. Потом вернусь ещё к этой мысли....

P.S.Может, велосипед изобретаю?..

Tags: